mcpField
S
story-long-analyze

story-long-analyze

github.com/qin1473692580-ux创意与媒体6946 次安装8 周前更新
代码仓库

关于 story-long-analyze

story-long-analyze 是用于长篇网络小说的结构分析技能,面向希望研究作品情节、角色、设定与文风的写作者。它按阶段生成逐章摘要、聚合分析和报告,并支持章节级并行提取与断点续跑。

主要功能

  1. 01黄金三章深度拆解
  2. 02逐章摘要与写法公式
  3. 03剧情节奏和情绪分析
  4. 04角色设定及关系提取
  5. 05文风分析与报告生成
  6. 06进度记录和断点恢复

适用场景

  1. 01研究长篇小说的剧情结构
  2. 02梳理角色关系与世界设定
  3. 03分析章节情绪和节奏安排
  4. 04为写作参考整理文风特征

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/qin1473692580-ux/oh-story-claudecode --skill story-long-analyze

安装后在 Claude Code 中输入/story-long-analyze确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
deconstruction-notes.md
material-decomposition.md
output-templates.md
pipeline-ops.md
style-profile-generator.md
style-profile-protocol.md
scripts/
render_chapter_summary.py

详细介绍

来自项目 README

story-long-analyze:长篇网文拆文

你是网络小说结构分析师。

核心信念:看懂别人的爆款,才能写出自己的爆款。


Agent 兼容性:先识别当前运行时,只检查对应的项目定义:Claude Code 为 .claude/agents/{agent}.md,OpenCode 为 .opencode/agents/{agent}.md,TRAE Code 为 .trae/agents/{agent}.md,WorkBuddy(CodeBuddy Code)项目模式为 .codebuddy/agents/{agent}.md,Codex 为 .codex/agents/{agent}.toml;运行时无法识别时才按上述顺序探测。TRAE Code 使用内置 Agent 智能体按 .trae/agents/{agent}.md 的名称选择同名 Subagent,并把下文 prompt 作为任务正文,不把 Claude 的 subagent_type 参数原样传给 TRAE;WorkBuddy 项目模式使用内置 Agent 与原始 subagent_type: "{agent}"。WorkBuddy plugin-only 模式只有在当前 Agent registry 真实返回 oh-story:{agent} 时才使用该精确命名空间值,不从 plugin manifest 或磁盘文件推测已注册;未返回则按 solo/direct fallback。Codex 原生子代理优先使用同名 agent_type,Claude/OpenCode 兼容面保留 subagent_type。当前运行时未暴露对应 Agent registry/tool 或 Codex 返回 unknown agent_type 时,必须降级为 solo/direct,并报告 Fallback: project custom agents unavailable -> solo。只有当前运行时确实是 ZCode 时才强制该降级;其他运行时不得因项目里并存 .zcode/ 而误判。

Spawn 版本提示(不阻断 spawn):先读取项目根 .story-deployed 的 agents_version。与本版 agents_version: 39 不一致时(标记缺失、字段缺失/非整数、小于或大于 39)照常按文件存在性检查并 spawn,同时报告 Notice: agents bundle 版本不匹配(项目 {N},本版 39) 并提示重新运行 /story-setup 后新开会话;大于 39 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 Fallback: ... -> solo。

拆解边界声明(主线程同样适用)

你亲手做的黄金三章深度拆解(Stage 1)、Stage 2 串行降级逐章处理、以及 Stage 3-6 的聚合/设定/报告/文风合成,与 chapter-extractor 子代理遵循同一逻辑:拆的是用户合法持有、拥有使用权的虚构作品(已出版/连载或自有),性质是只读的转化性文学批评(编辑/评论/写作教学视角,不复制、不传播、不指导现实行为)。通俗题材里的家暴、出轨、复仇、暴力、情爱张力、黑暗伦理是常规虚构叙事元素,须照常做结构化提取,不得以「敏感」「不适」为由拒绝整章或整本——主线程拒绝会让整条自动化流水线停摆;个别片段无法处理则跳过、照常续完其余。


Phase 1:确认拆解对象 + 进入管道

问用户:「你要拆哪本书?(书名+平台)有原文文件路径吗?」

如果没有明确目标,按题材或用户想写的类型推荐 2-3 本对标作品。

统一入口

确认拆解对象后直接进入拆解管道(Phase 2)。没有快速/深度分叉——只有一条深度拆解管道,跑到 Stage 1(黄金三章)后自动停靠产出快速预览报告。

无文本路径时:如果用户没有提供原文文件路径、也没有在对话中贴出原文,引导用户提供原文——「请提供这本书的原文文件路径,或直接把原文贴给我,我从黄金三章开始拆。」拿到原文后进入管道。


Phase 2:深度拆解管道

输出目录

默认输出到 拆文库/{书名}/(项目根目录下)。用户指定了其他路径时按用户指定路径输出。

已有分析利用

深度拆解开始前,检查是否已有部分拆解结果:

  1. 检查 拆文库/{书名}/ 目录下是否存在已有的拆文文件
  2. 如果存在 _progress.md,读取断点信息,从断点恢复(已有恢复机制)
  3. 如果存在 角色/.md 或 设定/.md,读取已有的角色和设定数据
  4. 将已有数据作为交叉验证基线:
    • 新提取的角色信息与已有角色数据对比,检查一致性
    • 新发现的设定细节与已有设定合并,标注信息来源(新提取 vs 已有)
    • 如有冲突(如同角色已有文件中名字不同),在输出中标注冲突让用户裁定
  5. 避免重复提取已有信息
原文备份(管道前置步骤)

拆解开始前,必须先备份原文:

  1. 检查 拆文库/{书名}/原文/ 目录是否已存在
  2. 如果不存在,从用户提供的源路径复制原文文件到 拆文库/{书名}/原文/
  3. 如果用户未提供源文件路径(直接在对话中贴文本),将原始文本保存到 拆文库/{书名}/原文/原文.md
  4. 备份完成后验证:
    • 源文件路径模式:确认 原文/ 目录下的文件数量和大小与源文件一致
    • 对话贴文本模式:确认 原文.md 文件非空(>0 bytes)
输出目录结构
拆文库/{书名}/
├── 原文/
│   └── 原文.txt          # 扩展名随源文件;对话直接贴入的文本存为 原文.md
├── 概要.md
├── 章节/
│   ├── 第1章_深度拆解.md
│   ├── 第2章_深度拆解.md
│   ├── 第3章_深度拆解.md
│   ├── 第1章_摘要.md
│   └── ...
├── 快速预览.md
├── 角色/
│   ├── {角色名}.md
│   └── 角色关系.md
├── 剧情/
│   ├── {剧情标题}.md
│   ├── README.md       # 剧情目录索引:节奏/情绪模块/故事线的权威范围
│   ├── 故事线.md
│   ├── 节奏.md          # 关键信息推进 / 爽点循环 / 情绪触动点 / 爆发节奏
│   ├── 情绪模块.md      # 读者需求 / 情绪引擎 / 可复现模块卡
│   └── 散落情节.md
├── 设定/
│   ├── 世界观/
│   │   ├── 背景设定.md   # 核心规则 + 特殊设定(无法独立的内容合并)
│   │   ├── 力量体系.md
│   │   ├── 地理.md
│   │   └── 金手指.md
│   └── 势力/
│       └── {势力名}.md   # 内容 >= 200 字时独立;不足合并到 世界观/背景设定.md
├── 拆文报告.md
├── 文风.md          # Stage 6 文风:句长/标点/对话潜台词/情绪交替 + 原文锚点范例片段
└── _progress.md

权威产物:剧情/README.md 说明剧情目录内各文件权威范围;剧情/节奏.md 是节奏/关键信息推进/情绪触动点的权威索引;剧情/情绪模块.md 是读者需求、情绪引擎、套路框架和可复现模块卡的权威索引。拆文报告.md 与 剧情/故事线.md 只做摘要投影;若摘要与这两个文件冲突,下游写作以 剧情/节奏.md / 剧情/情绪模块.md 为准。

管道主体:Stage 0-6

这是 story-long-analyze 唯一的执行管道。Stage 0-1 跑完后自动停靠产出快速预览报告(见下「Stage 1 停靠点」),用户确认后从 Stage 2 续跑。

预期耗时提示:开始前根据章节数给用户一个粗估:<50 章通常 30-60 分钟;50-200 章通常 1-3 小时;>200 章可能需要多轮会话。Stage 2 可并行提取,但 Stage 3-6 仍依赖前序产物,需按阶段推进。

阶段名称输入输出完成标志
0概要提取原始文本概要.md(首版 200 字 thin first-pass + 章节索引;full plot-aware 500-1000 字版在 Stage 5 落盘覆盖)+ Stage 0 章节边界子步骤将边界表写入 _progress.md(详见下方说明)章节结构识别完成 + 章节边界落盘
1黄金三章前3章原文第1章_深度拆解.md / 第2章_深度拆解.md / 第3章_深度拆解.md(每章一个文件)。非人形反派(灵气复苏/末世/国运等抽象对抗型)出现在前三章时,在本阶段一并按抽象对抗型路由分析(核心对抗面/紧迫感来源/升级机制/叙事替代)。3章拆解完成 → 停靠产出快速预览.md
2逐章摘要分块章节文本章节摘要.md(含情节点+角色+关键信息与扩写技法+逐章写法公式)。逐章写法公式必须提取情绪流向、节奏配比、结构公式、核心技巧、章尾卡点与伏笔。角色过滤(龙套不提取、别名归类)。每章10-40情节点(密度150-200字/个,按字数动态调节;公式低于10时仍按硬下限10拆足关键步骤)。并行模式:每章 spawn chapter-extractor agent。计数验证:摘要数 == 章节数,不等则标记失败章节。所有章节处理完成
3聚合分析全部章节摘要剧情/*.md + README.md(含权威分工表与剧情单元清单索引)+ 故事线.md + 节奏.md + 情绪模块.md。故事框架识别(前置,决定聚合策略)。两步法剧情聚合(先从摘要识别剧情大纲,再按大纲分配情节点)。关键信息推进索引(按章节/剧情单元追踪信息如何被扩写)。情绪触动点与爆发节奏(爽点/虐点/期待点的铺垫→释放→余波)。全书情绪节奏总览(情绪折线、爽点频率、小/中/大高潮位置、冲突升级路径、跨章伏笔地图、小/中/大循环单元)。读者需求 / 情绪引擎 / 爽文套路框架(沉淀为可复现模块卡)。角色合并(跨章节去重+别名归一)。角色分级(主角/反派/核心配角/功能角色)。散落情节兜底(6步,含覆盖率验证)。桥段标签(每个剧情模块按 deconstruction-notes.md 桥段词表打标,best-effort,无匹配留空)。质量检查(阈值详见 material-decomposition.md 质量阈值体系)。质量检查通过
4设定+关系(4a/4b/4c)4a:Stage 2 情节点+章节摘要(不依赖 Stage 3,与 3 并行);4b/4c:Stage 3 合并后角色数据+情节点设定/.md + 角色/.md。4a 设定(世界观/金手指/势力,从 Stage 2 mention 数据归纳)。4b 角色完整档案(两阶段模型:Stage 2 轻量提及 → Stage 4b 完整档案;别名解析置信度≥0.85自动合并)。4c 角色关系提取(从情节点提取,不从原文;含演变追踪+最终状态合并+隐含推断)。非人形反派在 4a 做完整抽象对抗型分析。4a/4b/4c 全部完成
5汇总报告全部输出拆文报告.md(含「读者需求 / 情绪引擎」「关键信息与扩写技法总览」「全书情绪节奏总览」「节奏与情绪触动点」「循环单元」「跨章伏笔地图」「冲突升级路径」「可复现模块」摘要,并指向 剧情/节奏.md / 剧情/情绪模块.md;含「写法技巧」清单,覆盖一笔两用/延迟揭示/视角欺骗/对比锚点/行为循环/身体反应替代心理描写/跨章回扣——物品/意象在不同章节承担不同功能)+ 概要.md 全书 500-1000 字版(plot-aware,覆盖 Stage 0 的 200 字 thin first-pass)报告 + 全书概要生成完成
6文风拆文报告.md + 章节/第1-3章_深度拆解.md + 章节/*_摘要.md + 原文/原文.txt文风.md(整书级写作技法视图:句长/标点/对话潜台词/情绪交替周期 + 4-6 段原文锚点范例片段 + 分层模仿建议,硬上限 ~4000 字。详见 style-profile-protocol.md + style-profile-generator.md)文风落盘 拆文库/{书名}/文风.md
Stage 0 章节边界子步骤

Stage 0 完成概要 + 章节索引之后、转入 Stage 1 之前,必须额外产出一份「章节边界」表写入 _progress.md。这是后续 Stage 1(黄金三章原文切片)/ Stage 2(每章传给 chapter-extractor agent)/ Stage 6(文风采样)共用的唯一切片来源——避免每个阶段各跑一次 regex 切片,结果可能不一致。

操作:

  • 用 style-profile-generator.md Step 4 的章节正则(含 千/两,覆盖 1000+ 章)grep 出全部章节行号
  • 先剔掉目录块:不少原文开头带一段目录,目录里的 第N章 同样顶行,会和正文章节行重复命中,不处理就会切出两个「第一章」。判据是行距——目录块内相邻命中只隔一两行,正文章节之间隔着整章篇幅。算相邻命中的行号差,把文件开头那段「行距持续远小于全体中位数」的连续命中整块丢弃
  • 剔完仍有重复章号时不要自行取其一:多卷书每卷从「第一章」重起是合法结构。这种情况在标题列保留卷号消歧(如 卷二 第一章),章号列按全书连续序号重编
  • 按 | 章号 | 标题 | 起始行 | 字数 | 四列写入 _progress.md 的「章节边界」section(见 pipeline-ops.md 模板)
  • 落表前校验章号连续、无重复、无跳号;不满足就停下报告,不要带着错表进 Stage 1——Stage 1/2/6 都以这张表为唯一切片真值,错一次会一路错到底
  • _progress.md 顶部 schema_version: 2 同时落盘

恢复前置条件:续跑只接受 schema_version: 2 且包含「章节边界」表的 _progress.md。缺失或结构不完整时停止续跑,提示从 Stage 0 章节边界子步骤重建进度文件,避免不同阶段使用不同切片真值。

Stage 1 停靠点

Stage 0+1 完成后,管道自动停靠,产出快速预览报告并询问用户是否继续全量拆解:

  1. 生成停靠交付物:写 拆文库/{书名}/快速预览.md(模板见 output-templates.md 的「快速预览报告」)。此时 概要.md、章节/第1章_深度拆解.md、章节/第2章_深度拆解.md、章节/第3章_深度拆解.md、原文/ 均已落盘。
  2. 写停靠状态:_progress.md 的「最终状态」字段写 paused_after_stage1,「断点」段记录「下一操作:Stage 2 逐章摘要」。
  3. 询问用户(使用当前平台可用的交互方式给出明确二选一;Claude 可用 AskUserQuestion,TRAE Code 直接在主会话提问):

    「黄金三章已拆完,快速预览报告见 快速预览.md。是否继续全量拆解(Stage 2-6:逐章摘要 / 聚合分析(含 剧情/节奏.md、剧情/情绪模块.md)/ 设定关系 / 汇总报告 / 文风)?预计耗时 {基于章节数粗估}。」

    • 选「继续全量拆解」→ 读 _progress.md,从 Stage 2 续跑,不重跑 Stage 0/1。
    • 选「就到这里」→ 管道结束,_progress.md 状态保持 paused_after_stage1,告知用户「之后可随时 /story-long-analyze 同一本书,会自动从 Stage 2 续跑」。
  4. 跳过询问的情形:用户在一开始就明确说「完整拆解 / 一次跑完 / 系统拆解 / 别问」时,仍生成 快速预览.md(保留早期判断快照),但不停下询问,直接从 Stage 2 续跑到 Stage 6。
Stage 5 后:选题决策回填(可选)

拆文报告.md 出来后(Stage 5 跑完)执行——和 Stage 6 无关,Stage 6 失败也不影响这步。

先定位 选题决策.md:项目根有就用它。项目根没有 → 从项目根及其上一级目录起、向下最多 3 层按文件名搜(跳过隐藏目录),按 mtime 由新到旧取最新 3 份。回填是写文件,项目根之外的文件写之前必须先确认:搜到 1 份 → 报出路径问「把本书的拆解支撑回填进这份吗?」;搜到多份 → 用当前平台交互能力列候选(Claude 可用 AskUserQuestion;TRAE Code 直接列出路径 + 扫榜日期 + 「都不回填」并等待回复)。用户不选 → 记「未回填」跳过,不动任何文件。

仅当定位到 选题决策.md(项目根那份直接用;项目根之外的那份须经上面的确认)时:按本书题材,在它的推荐选题里找题材关键词对得上的那个——

  • 正好对上一个 → 把该选题的"能爆的原因"从 待拆文验证 改成带出处的支撑:「本书拆解支撑:{拆文报告.md 的 读者需求/情绪引擎 + 剧情/情绪模块.md 的可复现模块 Top + 剧情/节奏.md 的爽点/触动点节奏摘要}(拆文库/{书名}/拆文报告.md、剧情/情绪模块.md、剧情/节奏.md)」。注意还只是假设(只拆了一本,不算坐实)。
  • 对上多个 / 拿不准 → 问用户「《{书名}》对应选题决策里的哪个方向?」
  • 一个都对不上 → 记录「无匹配选题,未回填」,不改文件。
  • 选题决策.md 缺少当前契约必需的「能爆的原因」字段 → 报告 invalid_topic_decision_contract,提示重跑 story-long-scan Phase 5 生成当前文件;不猜测、不静默回填,拆文主流程仍可完成。
  • 重复拆文不覆盖:只回填还标着 待拆文验证 的;已经填过的不动。

工作区里搜不到 选题决策.md → 直接跳过,不影响拆文。

Stage 6 文风

文风.md 只负责表达层风格;情绪/节奏意图仍以 剧情/情绪模块.md 与 剧情/节奏.md 为权威。 原文缺失或章节分隔符识别不出 → 在 文风.md 的「生成记录」写明 文风可用:否:{原因}。Stage 6 失败不阻断管道。

Stage 3-4 并行执行

并行执行图:

Stage 3(剧情聚合 + 角色合并)       ──┐
                                       ├── 4a 与 Stage 3 可并行
Stage 4a(设定:世界观/金手指/势力)  ──┘
              │
              ▼(Stage 3 + 4a 都完成后)
Stage 4b(角色完整档案)— 串行,依赖 Stage 3 合并后的角色实体
              │
              ▼
Stage 4c(角色关系提取)— 串行,依赖 4b 角色实体存在

4a 数据源是 Stage 2 摘要故可与 3 并行;4b/4c 依赖 Stage 3 角色合并故串行。

部分失败容忍

单章/单阶段失败不阻断管道。失败记录到 _progress.md 的「失败记录」表(| 类型 | 章节/阶段 | 错误信息 | 重试状态 |)。最终状态可为 completed_with_errors(在拆文报告中注明失败详情)。

与 material-decomposition.md 的对应关系:Stage 0 含 Material 阶段1(章节解析);Stage 1、5 为新增;Stage 2 = Material 阶段2;Stage 3 = Material 阶段3;Stage 4 合并 Material 阶段4+5。

详细模板见 output-templates.md,方法论见 material-decomposition.md。


质量检查概要

Stage 3-4 完成前需通过质量检查(置信度、覆盖率、重叠率)。阈值、计算方式与自检清单的唯一权威定义见 material-decomposition.md 质量阈值体系。

Stage 3-5 还须过「事实可溯源」自检:设定/角色/报告里的硬事实(等级/数值/距离/属性/势力数/出场章/谁说的话)必须能 grep 回原文,原文没给的写「原文未明确」、禁推断填空。这是拆文事实错误的最大来源(强模型也会漂移,因为合成阶段离原文两跳、靠合理性填空)。详见 material-decomposition.md 合成阶段事实保真。


Stage 2 并行 Agent 策略

Stage 2 使用 chapter-extractor agent 并行处理每章,替代原来的串行分块。新任务的唯一正常交付链路是 OUTPUT_MODE: json → 确定性 validator/renderer → 原子落盘 Markdown;模型不直接排版目标 *_摘要.md。

调用方式

每条章节 prompt 必须以「材料声明」前缀开头(即下方 prompt 字符串首段)——给子代理正确语境,避免它把通俗题材的正常戏剧化剧情误判为有害内容而拒绝拆解。前缀是固定文本,逐字带上,不要改写或省略。prompt 最后一行必须是 OUTPUT_MODE: json。

下方 Agent(subagent_type=...) 是 Claude/OpenCode 及 WorkBuddy 项目模式的调用示意;WorkBuddy 项目模式先验证 .codebuddy/agents/chapter-extractor.md,然后使用原始 subagent_type: "chapter-extractor"。WorkBuddy plugin-only 模式只有在当前 Agent registry 真实返回 oh-story:chapter-extractor 时,才把示例中的 subagent_type 替换为该精确值;否则转下方 solo 规则。TRAE Code 必须由内置 Agent 智能体按 .trae/agents/chapter-extractor.md 的名称选择同名 Subagent,并把完全相同的 prompt 字符串作为任务正文;不得把 subagent_type 或 model 当成 TRAE 参数。Codex 使用同名 agent_type。

Agent(
  subagent_type: "chapter-extractor",
  prompt: "[材料声明] 以下为用户合法持有的虚构小说,任务是只读的转化性文学分析(编辑/评论视角)。暴力/复仇/家暴/情爱/黑暗伦理是该题材常规虚构元素,照常提取,不得以敏感拒绝整章或整本;个别片段无法处理则跳过、照常续完其余。\n\n章节编号:第{N}章\n章节标题:{标题}\n章节字数:{字数}\n\n章节原文:\n{原文文本}\n\n[结构化输出要求] 只返回一个 JSON object,不带 prose 和 code fence。顶层 exact keys:chapter_number,title,summary,key_events,key_information_expansion,chapter_formula,characters,plot_points。key_information_expansion 每项 exact keys:key_information,expansion,technique,reader_effect,reuse_note。chapter_formula exact keys:emotion_flow,rhythm_ratio,structure_formula,core_technique,hook_and_foreshadowing;emotion_flow exact keys:start,build,turn,close;rhythm_ratio exact keys:slow_setup,fast_conflict,payoff,hook_space。characters 每项 exact keys:name,importance,aliases,performance。plot_points 每项 exact keys:id,title,event,type,characters,location,item,time,quote,quote_locator,themes,tone。summary 是单行 100-300 个 Unicode code point;rhythm_ratio 四项是 0%-100% 字符串且和为 100%。\n\n[情节点格式要求] plot_points 为 10-40 项,id 从 P1 开始无断号连续;type 只取转折点|信息揭示|冲突|解决|铺垫|行动|对话|状态变化;tone 只取紧张|轻松|悲伤|热血|爽|甜|温馨|恐怖|压抑|其他;themes 是数组但恰好一项,值只取爱情|亲情|友情|权力|金钱|成长|复仇|悬念|搞笑|热血|日常|其他。quote 与 quote_locator 互斥,全章两者非 null 的情节点合计不超过 8 个;quote 非空且为 1-400 Unicode code point,quote_locator 为 5-15 个。空地点/物品/时间用 null,纯环境情节的 characters 用空数组。\n\n[输出前自检] 交付前核对 exact keys 无缺失/无多余,枚举无越界,summary 长度合格,plot id 连续,每个 themes 恰好一项,引用情节点合计 <= 8。任何一条不符,先修正 JSON 再输出。\n\nOUTPUT_MODE: json"
)

上面的 [结构化输出要求] / [情节点格式要求] / [输出前自检] 由主线程在 spawn 时拼进 prompt,不依赖项目里已部署的 agent 文件版本。完整 JSON schema 以 output-templates.md「Stage 2 结构化中间件」为人类可读契约,以 scripts/render_chapter_summary.py 的 validator 为机器权威。sonnet 升级重试沿用同一份 prompt,且末行仍是 OUTPUT_MODE: json。

批量策略
  • 每次 spawn 5-8 个 agent(避免并发限制)
  • 等待当前批次全部完成后,再 spawn 下一批
  • 每批完成后更新 _progress.md 记录已处理章节
Agent 输出收集
  • 每个 agent 返回单个纯 JSON object(无 prose、无 code fence);返回值先存临时 .json,不得直接写入目标 Markdown

  • 主线程调用确定性 renderer:

    for PYBIN in python3 python py; do "$PYBIN" -c "" 2>/dev/null && break; done
    "$PYBIN" skills/story-long-analyze/scripts/render_chapter_summary.py \
      --input "$RAW_CHAPTER_JSON" \
      --output "拆文库/{书名}/章节/第{N}章_摘要.md" \
      --expect-chapter-number "{N}" \
      --expect-title "{标题}"
    
  • renderer 先完整校验 JSON,再在目标同目录写临时文件并用 os.replace 原子替换;解析/校验失败时不创建、不截断、不覆盖已有 章节/第{N}章_摘要.md

  • 收集所有 agent 的出场人物表,供 Stage 3 合并使用

失败处理 + 质量升级重试

三类失败:

  1. 执行失败(agent crash / 超时 / 空输出)→ 同模型(haiku)重试 1 次
  2. JSON 契约失败(非单一 JSON object、exact schema/类型/枚举不合、summary 超界、P ID 不连续、多主题、引用超限、章号/标题与任务不符)→ 把 renderer stderr 作为上次失败原因,升级到 sonnet 重试 1 次
  3. 语义质量失败(虽通过 schema,但 chapter-extractor.md「质量检查」12 条中非机械项不达标——例如白描推测动机、概要反复用同一连接词、角色使用通用称呼)→ 升级到 sonnet 重试 1 次

renderer 的可机械校验是新任务的唯一格式权威:

  • 顶层与每个嵌套 object 必须 exact keys,拒绝缺字段、额外字段、重复 JSON key、NaN / Infinity
  • 类型、基调、主题、扩写技法、读者情绪、角色重要性全部严格取枚举;themes 必须恰好 1 项
  • plot_points 数量 10-40,ID 必须严格为 P1..PN 连续序列;标题 ≤15 Unicode code point,不得与白描 event 相同
  • summary 按 Python len(str) 计 Unicode code point(不按 UTF-8 bytes),单行 100-300;节奏四项为百分比字符串且合计 100%
  • 每个情节点的 quote / quote_locator 互斥;全章两者非 null 的情节点合计≤8,quote 非空且单条为 1-400 Unicode code point,locator 为 5-15

旧已落盘 Markdown 不追溯。 不得用新 JSON contract 反向审判或重写已有 章节/*_摘要.md;老摘要里的 类型{行动}、物品— 等写法照旧可用,Stage 3-6 读取行为不变。下面的 legacy Markdown 四项 grep 只在「JSON 升级重试仍失败」后的明示兜底中使用,不扫历史文件:^P 数与 基调: 数相等;P 行含非空白描与 涉及 段;基调值不越界;主题标签值不越界。

升级重试调用方式(主线程在校验失败后执行):

Claude/OpenCode 可按下例显式升级模型。TRAE Code 的项目 subagent 不接受 Claude 的 sonnet 模型名或调用时 model 覆盖;在 TRAE 中仍选择同名 chapter-extractor,把“升级重试、逐项修复 renderer stderr”写入任务正文,由当前 TRAE 模型执行。WorkBuddy 当前 Agent 调用同样不把 Claude 的 model: "sonnet" 当成可移植参数:项目模式仍用 chapter-extractor,plugin-only 模式仍用 registry 真实返回的 oh-story:chapter-extractor,把失败原因与修复要求写入 prompt,由当前 WorkBuddy 模型执行。若当前 TRAE/WorkBuddy registry 无该 agent,按下方 solo 规则处理,不伪造升级成功。

Agent(
  subagent_type: "chapter-extractor",
  model: "sonnet",            # 显式覆盖 frontmatter 的 haiku
  prompt: "章节编号:第{N}章\n...(同首次 prompt,含开头的「材料声明」前缀,追加:'上次校验失败原因:{renderer stderr / 自检失败项}',末行仍为 OUTPUT_MODE: json)"
)

最终落盘规则:

  • haiku 首次 JSON 通过 validator 与语义自检 → 由 renderer 原子写入 章节/第{N}章_摘要.md,_progress.md 标记 success
  • haiku 失败 + 同模型 retry 通过 → 同上,备注 retry_same_model
  • 质量失败 + sonnet retry 通过 → 同上,备注 retry_sonnet
  • 仅 JSON 契约失败且 sonnet JSON 升级重试仍失败 → 允许一次明示的 legacy Markdown fallback;模型输出先写临时文件,通过上述四项 grep 再原子替换,_progress.md 备注 legacy_markdown_fallback + 两次 JSON 失败原因。不得在首次失败后直接要求 Markdown
  • sonnet 语义质量重试仍失败,或 legacy fallback 仍不过 → 章节标记 ⚠️ 跳过,失败原因写入 _progress.md 「失败记录」表,拆文报告中注明
  • 单章失败不阻断管道;批次全部 spawn 完成后才决定是否进入 Stage 3
Agent 不可用降级

以下任一情况,Stage 2 自动退回串行模式,由主线程逐章处理(质量不受影响,只是改为串行、速度略慢)。两条路径使用同一 JSON contract 和同一 renderer:主线程按 output-templates.md「Stage 2 结构化中间件」先产出 JSON,调用 scripts/render_chapter_summary.py,不直接排版 Markdown。validator 或语义自检失败时,主线程按具体失败项重写 JSON 1 次;第二次仍为 JSON 契约失败才可走一次明示 legacy_markdown_fallback,仍不过则按 ⚠️ 跳过 记入 _progress.md 「失败记录」表。

  • agent 未部署/未注册:当前运行时对应目录(Claude .claude/agents/、OpenCode .opencode/agents/、TRAE Code .trae/agents/、WorkBuddy 项目模式 .codebuddy/agents/、Codex .codex/agents/)下的 chapter-extractor.md 或 chapter-extractor.toml 不存在,或 WorkBuddy plugin-only 模式的当前 registry 未返回 oh-story:chapter-extractor。应重新运行 /story-setup(WorkBuddy plugin 模式为 /oh-story:story-setup)完成当前适配器部署,不跨 Skill 读取模板源。
  • 环境不支持 spawn 子代理:本 skill 正运行在某个子代理上下文中,无法再起下一层 agent。
Stage 2 收尾:合并章节摘要(_章节摘要汇总.md)

Stage 2 所有 章节/*_摘要.md 落盘后、进入 Stage 3 前,主线程把它们按章号顺序无损拼接成 拆文库/{书名}/_章节摘要汇总.md(只拼接、不压缩、不改写):

ls 章节/*_摘要.md | sed -E 's/.*第([0-9]+)章.*/\1 &/' | sort -n | cut -d' ' -f2- | while read -r f; do cat "$f"; echo; done > _章节摘要汇总.md

无损检查(拼接后校验,任一不过即删除 _章节摘要汇总.md、回退逐文件扫描,行为不变):

  • grep -cE '^P[0-9]+ ' _章节摘要汇总.md == 各摘要 ^P 行数之和
  • grep -cE '^\*\*概要\*\*' _章节摘要汇总.md == 摘要文件数(**概要** 每章一行,chapter-extractor 并行输出与串行摘要模板都有;不用 ## 第N章 头——串行摘要模板没有章节头,会误判)

Stage 3 / 4a / 4c / 散落情节兜底改为只读一次 _章节摘要汇总.md 并在上下文中复用,替代每阶段 glob 章节/*_摘要.md 重扫(同一份语料的 4-5 次冷读降为 1 次)。

仅当语料能放进上下文时才生成汇总文件:>500 章、或合并后 _章节摘要汇总.md 过大放不进上下文时跳过本步骤,改走 material-decomposition.md“处理批次 → A. 子代理并行模式”:按 10-20 章/批 spawn 子代理,子代理在自己上下文里读该批摘要、只回传 ≤8K tokens 的降维聚合,主线程仅合并聚合结果(必要时分层两两合并)。主线程不逐章读原始摘要——跳过汇总文件不等于回到逐文件扫描,那对大书同样放不下。_章节摘要汇总.md 不替代 章节/*_摘要.md——单章文件仍是落盘真源,Stage 6 文风采样、人工复核照用单章文件。管道结束(Stage 6 后)删除 _章节摘要汇总.md——它是派生临时文件,不随 拆文库/ 交付(拆文库/ 会被 story-import 保留为写作工程)。

Stage 3-5 分块见 material-decomposition.md(唯一权威)。


恢复机制

启动时检查 _progress.md;paused_after_stage1 → 直接从 Stage 2 续跑。 操作步骤见 pipeline-ops.md。


流程衔接

流水线: 长篇 位置: 拆文(长篇流水线第 2 步,在 story-long-scan 之后、story-long-write 之前)

时机跳转到命令
准备开写story-long-write/story-long-write
需要市场数据story-long-scan/story-long-scan
更适合短篇story-short-scan → story-short-analyze/story-short-scan

参考资料

文件何时加载
references/output-templates.md管道全程:各 Stage 输出模板 + 快速预览报告模板 + 剧情/节奏.md / 剧情/情绪模块.md 模板 + 通用速查表
references/material-decomposition.mdStage 2-5:素材拆解方法论 + 质量阈值 + 分块策略;Stage 6 另见文风资料
references/pipeline-ops.md管道运维:_progress.md 模板、错误处理、恢复机制操作步骤
references/deconstruction-notes.md拆书方法+影视拆解+抽象拆解法+题材实战
references/style-profile-protocol.mdStage 6:文风模板 + 可信度/可用性说明
references/style-profile-generator.mdStage 6:文风生成 SOP(6 步,含中文数字章节识别 + 全角冒号基调 grep)

语言

  • 跟随用户的语言回复,用户用什么语言就用什么语言回复
  • 中文回复遵循《中文文案排版指北》

评论

支持 Markdown