TapCanvas agents-team-book-metadata
启用 agents-team 协作,双代理完成小说逐章元数据抽取与完整性审校(parser + checker),并写入可续跑的记忆索引。
install
source · Clone the upstream repo
git clone https://github.com/anymouschina/TapCanvas
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/anymouschina/TapCanvas "$T" && mkdir -p ~/.claude/skills && cp -r "$T/apps/agents-cli/skills/agents-team-book-metadata" ~/.claude/skills/anymouschina-tapcanvas-agents-team-book-metadata && rm -rf "$T"
manifest:
apps/agents-cli/skills/agents-team-book-metadata/SKILL.mdsource content
agents-team-book-metadata
目标:在小说章节级输入上,生成完整且可落库的章节元数据 JSON,并将关键结果写入
.agents/memory 形成可检索、可续跑的记忆资产。
必要前置
- 必须先加载
。agents-team - 必须先加载
。cognitive-memory - 若任一步骤缺失,直接报错并停止,不允许静默降级。
Team 角色
必须使用 agents team 工具并显式分工:
(优先parser
)agent_type: research
- 负责逐章抽取元数据。
- 输出必须覆盖每个 chapter。
(优先checker
,必要时再补一个agent_type: reviewer
)editor
- 负责完整性检查、缺失补全、重复清理、字段标准化。
- 保证最终输出结构稳定并校验关系网可用性。
目录与记忆布局(强制)
先生成
BookSlug(lower-kebab-case),然后创建目录:
.agents/memory/books/<BookSlug>/metadata/progress.json.agents/memory/books/<BookSlug>/metadata/chapters.json.agents/memory/books/<BookSlug>/metadata/character-graph.json.agents/memory/books/<BookSlug>/metadata/index.json
index.json 至少包含:
{ "book": { "slug": "my-book", "title": "..." }, "updatedAt": "2026-02-27T00:00:00.000Z", "chapters": { "total": 12, "path": "chapters.json" }, "characterGraph": { "path": "character-graph.json", "nodeCount": 10, "edgeCount": 18 }, "checkpoint": { "phase": "done", "next": "ready-for-storyboard" } }
执行流程
启动spawn_agent
或主代理自己先做输入切分。orchestrator
启动 parser。spawn_agent
等 parser 完成,再把 parser 结果传给 checker。wait
或spawn_agent
启动 checker。send_input
等待 checker 完成。wait- 主代理汇总 checker 结果,形成最终 JSON。
- 用
写入四个 metadata 文件。write_file - 用
写入长期记忆:memory_save
: 角色关系网、角色主特征、章节核心冲突摘要semantic
: 本次抽取规则、去重策略、命名策略procedural
: 本次运行的输入范围、完成时间、异常与修复episodic
- 用
复查写入结果可检索(至少 1 次)。memory_search
输出约束(严格)
最终回复给用户时:
- 只输出 JSON,不要 markdown、不要解释文本。
- 顶层必须包含:
{ "book": { "slug": "my-book", "title": "..." }, "chapters": [ { "chapter": 1, "title": "...", "summary": "...", "keywords": ["..."], "coreConflict": "...", "characters": [{ "name": "...", "description": "..." }], "props": [{ "name": "...", "description": "..." }], "scenes": [{ "name": "...", "description": "..." }], "locations": [{ "name": "...", "description": "..." }] } ], "characterGraph": { "nodes": [ { "id": "role_a", "name": "角色A", "importance": "main|supporting|minor", "firstChapter": 1, "lastChapter": 20, "chapterSpan": [1, 2], "unlockChapter": 1 } ], "edges": [ { "sourceId": "role_a", "targetId": "role_b", "relation": "coappear|conflict", "weight": 3, "chapterHints": [1, 2] } ] } }
质量要求
- 不漏章:
必须与输入章节数量一致。chapters.length - 每章字段必须完整:
、title
、summary
、keywords
、coreConflict
、characters
、props
、scenes
。locations - 实体数组去重(按
,不区分大小写)。name - 章节序号稳定,不重排。
至少覆盖 main/supporting。characterGraph.nodes
去重、无自环,edges
只能是relation
或coappear
。conflict- 如关键字段无法确定,必须继续推导补全;禁止输出
。unknown/null/待补充 - 任何解析失败必须显式报错并给出原因,禁止静默兜底。
续跑规则
当用户说“继续”时,先做:
读取read_file
+progress.json
。index.json
查询memory_search
+BookSlug
+metadata
。characterGraph- 仅在状态一致时继续,否则先返回冲突原因并停止。