--- name: transcription-corrector homepage: https://github.com/cat-xierluo/legal-skills author: 杨卫薪律师(微信ywxlaw) version: "1.0.9" license: MIT description: 转录稿纠错与轻度优化。本技能应在用户需要按用户词典纠正 ASR 转录稿同音字与英文专有名称漂移时使用。不要用于:重写为课程章节、报告、总结,或完全空白的素材创作。 --- # Transcription Corrector > 首次使用流程见 [references/first_use.md](references/first_use.md)。工作流中的判断准则见 [references/correction_patterns.md](references/correction_patterns.md)。 ## 概述 把 raw 转录稿里"听得对但写不对"的同音/形近/拼写错误按用户词典统一改对,并按需做轻度润色。**不做**:改写、总结、删减、改事实、生成课程章节。 | 模式 | 触发 | 输出 | |---|---|---| | **纠错模式(默认)** | 拿到 raw 转录稿,要先做"校对" | `archive/.../{原文件}_corrected.md` + 校对对照日志 | | **纠错 + 轻度润色** | 还要顺手把发言人合并/标点整理 | 在纠错基础上再润色,输出到 `archive/.../{原文件}_polished.md` | **与下游处理工作的边界**: - 本 skill 不输出课程大纲、不重组章节、不改写为书面课程;只做"读起来对、不再丢脸"这一步。 - 用户词典 YAML 格式(`version` + `terms` 列表)已成为本 skill 公开的接口约定;其他下游处理工作可以按需读取同一份词典文件。 ## 工作流程 工作流按 **5 个 Phase** 组织,每个 Phase 含 1-3 个 Step。默认开启 Phase 1-3,Phase 4 默认关闭(需要用户明确开启)。 ``` Phase 1 准备 Step 1.1 读取配置(词典) Step 1.2 TXT → MD 转换(如需要) Phase 2 识别 Step 2.1 识别文件结构 Step 2.2 通读识别高置信误转写 Phase 3 修正(默认开启) Step 3.1 词典统一替换(改字) Step 3.2 基础空白清理(改空白) Step 3.3 口语词精简(删字) Phase 4 润色(默认关闭) Step 4.1 发言人合并 Step 4.2 标点规范 Step 4.3 段落切分 Phase 5 输出 Step 5.1 主归档(必出) Step 5.2 源文件目录镜像(必出) ``` **为什么这样分组**: - **Phase 1 准备** vs **Phase 2 识别** vs **Phase 3 修正**:准备不接触文本内容;识别是"看";修正是"改"。三者性质分明 - **Phase 3 内部三个 Step** 改的是三类不同对象:3.1 改字(语义)、3.2 改空白(格式)、3.3 删字(语言字符)。三类操作各自独立,可单独审计 - **Phase 3 vs Phase 4**:Phase 3 是"读起来对"(无损 / 轻损),默认开启;Phase 4 是"看起来专业"(结构调整),默认关闭。两者泾渭分明 - **Phase 5 输出** 与前 4 个 Phase 解耦:无论前 4 步做了什么,输出阶段都按相同策略双写 --- ## 工作机制 转录稿修正的本质是"对每一处误转写做出独立判断"。这个判断的输入是上下文,输出是一处 Edit,三者必须由同一个 agent 在同一个上下文里完成。 **为什么按"每处 Edit"展开** - **每处误转写是否成立,取决于它在上下文中的指向**。例如"style"可能是 skill 名,也可能是真正的"风格"——批量替换不能区分。 - **ASR 错误无穷无尽**(大小写漂移、空格漂移、断词重连、音节吞并、形近字……),任何静态规则都会漏。 - **词典是"目标值参考表"**,不是"错误词 → 正确词"的映射。`terms: ["WorkBuddy"]` 告诉 agent "正确的写法是 WorkBuddy",但不告诉 agent "这处原文是否需要改"。 由此推出**自然的执行流**: 1. agent 用 `Read` 把源文件读进上下文(必须通读全文) 2. 对每一处候选误转写,agent 在上下文中独立判断"换 / 不换" 3. 用 `Edit` 把每一处的决策落盘 4. 用 `Write` 写出 `correction_log.md` / `meta.json` / 源目录镜像 **为什么这个流是自洽的** - 上下文只在 Read 之后才完整;判断必须在 Read 之后进行 - Edit 是"局部变更"工具,自然对应"每处决策" - Write 写整文件,对应日志/元数据这种"一次性产出" - 这三步组成了最小可执行闭环。任何其他方式(脚本批量、sub-agent 转交、regex 列表)都至少缺失其中一步的语义保证 --- ## Phase 1:准备 ### Step 1.0:加载 skill 配置(开关默认值) skill 各项润色开关由 `config/config.env` 控制。加载顺序: 1. 命令行/调用参数传入的 `key=value` 覆盖 2. `config/config.env`(本 skill 自带) 3. `config/config.env.example`(默认值的"母本",缺失 step 2 时用) 4. 若 step 2 和 step 3 都不存在,Phase 4 所有 Step 全部关闭,仅 Phase 1-3 跑 **配置示例**(`config/config.env.example`): ```env # Phase 4 润色开关(默认全开,按需关闭) POLISH_MERGE_SPEAKERS=true # Step 4.1 POLISH_PUNCTUATION=true # Step 4.2 POLISH_PARAGRAPH_SPLIT=true # Step 4.3 POLISH_TOPIC_SECTION=true # Step 4.4 POLISH_SUMMARY=true # Step 4.5 # 输出策略 SOURCE_MIRROR=true # 源文件目录镜像 SOURCE_MIRROR_CONFLICT=timestamp # 冲突加时间戳 # 日志详细度 LOG_VERBOSITY=verbose # verbose | compact ``` 缺失的键统一按本节表格的"默认值"列取值(不在文件中硬编码,每个 Step 自己的 § 段注明默认值)。 ### Step 1.1:读取词典 1. 词典文件查找顺序(找到第一个存在的即用): - 命令行/调用参数传入的 `dictionary` 路径 - `config/user_dictionary.yaml`(本 skill 自带) - 若都不存在,提示用户复制 `config/user_dictionary.example.yaml` 为 `config/user_dictionary.yaml` 2. 词典 YAML 格式: ```yaml version: 1 terms: - "WorkBuddy" - "Claude Code" - "Codex" ``` 3. 词典的角色:**目标值 + 置信度权重**,不是触发器 - 词典项是"正确写法"——告诉 AI 目标值是什么 - 词典项**不直接触发替换**:AI 仍然必须先做上下文判断(这个词在当前上下文里是否指向词典项所代表的对象) - 词典项**提高候选替换的胜出权重**:当 AI 在多个候选写法中二选一时,词典登记的写法优先级更高 - 也就是说:词典让"workbody / work body / Workbuddy"在竞争中更倾向被改写为"WorkBuddy",但前提仍然是上下文明显指向 WorkBuddy 这个产品;脱离上下文的同形词不会被词典"硬拉"过去 - **不要**把词典当作"错误词 → 正确词"映射表来使用 - **不要**为了使用词典而强行替换普通词 - 模糊或低置信场景一律保持原文 ### Step 1.2:TXT → Markdown 转换(如需要) 当输入是 `.txt` 文件时,先做格式转换再进入 Phase 2。 **触发条件**:输入文件扩展名是 `.txt`。 **转换规则**(保守——只做格式包装,不改内容): 1. **发言人 + 时间戳行**(如 `发言人 1 00:33:09`): - 识别正则:`^(发言人|说话人|Speaker|S)\s*[\d一二三四五六七八九十]+[\.、]?\s*(\d{1,2}:\d{2}(?::\d{2})?)$` - 转成 Markdown 加粗行:`**发言人 1 00:33:09**` 2. **段落间空行**:连续的非空行视为同一段(保留原始换行),段落之间补一个空行 3. **不删除任何文字**:空行、空白、ASCII 装饰线(`---`、`===`)等全部保留 4. **不识别 H3 / H4 标题层级**:只到 H2 层级——H2 标题在 Phase 4 Step 4.4 中按"主题分章"原则插入;不主动把某段升级为 `###`/`####` 5. **不识别列表**:不把 `- xxx` 改成 markdown 列表——保持原样 **输出**: - 中间产物:`{原文件 basename}_converted.md`,保留在 archive 子目录 - 后续 Step 2.1~5.2 在 converted 副本上进行 - 原始 `.txt` 文件保持不动 **示例**: 输入(`raw.txt`): ``` 发言人 1 00:33:09 我先说一下比较好的部分,就是整个最终的报告篇幅是比较充分的。 然后大家在一开始不知道怎么样一个报告是比较完善的,也知道怎么样去借鉴他山之石。 从这个阿尔法 gpt里面的这报告相当于蒸馏他的一个一个想法啊。 这个这个在前期一开始搭基建的时候确实是很有必要的一个措施。 发言人 1 00:33:57 呃然后。我注意到咱们在最终生成法律服务意见书的时候... ``` 输出(`raw_converted.md`): ```markdown **发言人 1 00:33:09** 我先说一下比较好的部分,就是整个最终的报告篇幅是比较充分的。 然后大家在一开始不知道怎么样一个报告是比较完善的,也知道怎么样去借鉴他山之石。 从这个阿尔法 gpt里面的这报告相当于蒸馏他的一个一个想法啊。 这个这个在前期一开始搭基建的时候确实是很有必要的一个措施。 **发言人 1 00:33:57** 呃然后。我注意到咱们在最终生成法律服务意见书的时候... ``` **不识别的格式**(保持原文): - 没有时间戳的"发言人 1:"→ 保留为正文 - "Speaker A:" → 保留为正文 - 纯文本无发言人标记 → 整段视为正文 --- ## Phase 2:识别 ### Step 2.1:识别文件结构 通读 raw 稿,识别组织方式: - **按发言人 + 时间戳分块**(如 `**发言人 1 00:33:09**`)— 多数 ASR 输出 - **自由段落**(无显式分块) - **混合**(标题 + 段落 + 引用) 识别目的:决定 Phase 4 润色时是否合并同发言人连续发言。**不要改写分块结构**,保留原貌。 ### Step 2.2:通读识别高置信误转写 **必须完整通读全文**,以 Agent 视角扫描。**不列静态错误表**——ASR 错误无穷无尽(大小写漂移、空格、漏词、错位、同音字、形近字、断词重连、音节吞并…),任何预设列表都会漏判。 **核心原则**: > **仅在上下文明确指向某个词典术语时,才将近似误转写替换为该术语。** > **模糊或低置信场景保持原文,不做猜测式替换。** **启动扫描的高频易错类别**(不是错误表,是判断启动点): 1. **人名**:律师、当事人、证人姓名是否首次出现 + 后续引用是否一致 2. **英文产品/工具/平台名**:是否在工具使用、命令行、平台介绍等场景 3. **机构/活动/品牌名**:律协、青训营、训练营、赛题 4. **法律术语同音/形近**:代理 vs 带理、抵押 vs 抵压、知情 vs 至清 5. **数字/单位/时间戳**:1/7、0/6、中英文逗号混用;**保守原则** **形式漂移识别**(参考但不穷举): - 大小写漂移(WorkBuddy vs workbuddy vs WORKBUDDY) - 空格漂移(work body / Work Buddy) - 连字符(Claude-code / Claude-Code) - 拆分被识别为中文("克劳德 code") - 漏字残字("body" 残留在"让,如果 body帮我们") - 同音/形近字("张律师 / 张老师 / 章律师" 类推) - 断词重连("然后让" 被拆成"让,如果") **禁止**: - 只用 grep/正则匹配清单(必然漏)—— 详见 §"工作机制"为什么按每处判断展开 - 把"我"改成"我们"等无明确对照的"风格化"改写 - 替换词典外的术语 - 强行补全"看上去缺字"的句子——除非能确定是组合错误 --- ## Phase 3:修正(默认开启) > Phase 3 三个 Step 改的是**三类不同对象**——Step 3.1 改字(语义)、Step 3.2 改空白(格式)、Step 3.3 删字(语言字符)。三类操作各自独立、可单独审计、单独计日志。 ### Step 3.1:词典统一替换 对 Step 2.2 识别出的高置信误转写: 1. **三重确认**: - 词典里有对应目标值 - 上下文明确指向该目标值所代表的对象 - 形式漂移证据成立(大小写/空格/连字符/漏字/同音/形近/断词) 2. 三重任一不满足 → **不替换**,保持原文 3. 替换完成后在 correction_log.md 记录:`{原文}` → `{改后}`,并标注行号和上下文片段 4. **绝不修改原始文件**,所有输出写到 archive/ 下的新文件 ### Step 3.2:基础空白清理(默认开启,无损) **为什么独立于 Phase 4 润色**:基础空白清理是"格式标准化",不改变原文语义、不删减任何信息;与 Phase 4 发言人合并 / 标点规范 / 段落切分那种"风格调整"性质不同,所以默认开启(用户不需要为此做开关决策)。 **清理动作清单**(仅做以下五类,不做任何超出此范围的事): | 类别 | 动作 | 触发条件 | |---|---|---| | 行首/行尾空白 | 删除 | 任意行 | | 连续空行 | 压缩为单个空行 | 任意位置 | | 全角/半角空格 | 统一为半角空格 | 出现在英文单词之间或英文标点旁 | | 专有名称内部断裂空格 | 合并 | 上下文明确指向词典中的专有名称(如"Work Buddy" → "WorkBuddy") | | 中文数字 + 空格 + 级/章/节 | 合并 | 模式:`[一二三四五六七八九十百千]+ +级/章/节` 合并为 `[一二...]+级/章/节`(如"二 级" → "二级") | **标点周围空白规则**: - 中文标点 `,。、;:?!""''「」()` 前后不留空格(若出现则删除) - 英文标点 `, . ; : ? ! " ' ( )` 后空一格(中文段落中保留) - 半角空格夹在中文之间 → 删除 **安全执行(避免越段吞并)**:本步的"中文标点前后多余空格"清理有一个结构性陷阱——speaker 块的边界(`**说话人 N HH:MM:SS**` + 内容 + 空行 + 下一块标题)依赖"内容末标点 → 换行 → 空行"这一序列。如果清理正则用 `\s+` 把标点之后的换行+空行也吃成单个空格,会跨块吞并,speaker 标题、H2 标题、speaker 块都会被合并成单行。执行时**按行处理、禁止跨行匹配 `\s+`**,仅做"行内"动作(行尾空格、同句内的 `X, Y` → `X,Y`)。如必须做跨段清理,先单独诊断再决定。 **严格不做**(避免越界): - 不删除任何文字、标点、字母、数字 - 不改变段落结构(不合并段落、不切分段落——这是 Phase 4 范畴) - 不修改数字、时间戳、金额、日期 - 不改发言人分块标记(如 `**发言人 1 00:33:09**`) - 不重排、重组、归纳 **与 Step 3.1 的关系**:基础空白清理在 Step 3.1 词典替换之后执行;遇到"Work Buddy" → "WorkBuddy" 这类专有名称合并时,优先走 Step 3.1(词典替换路径),Step 3.2 仅做 Step 3.1 不覆盖的"无词典目标的纯格式"清理。 **校对日志记录**:所有 Step 3.2 的清理动作也写到 `correction_log.md`,在"基础空白清理"小节集中记录(与 Step 3.1 高置信替换区分开),便于审计。 ### Step 3.3:口语词精简(默认开启,AI 上下文判断) **为什么独立于 Phase 4 润色**:与 Step 3.2 基础空白清理性质相同——属于"读起来对"的范畴,不改变原意(口语词不携带信息);与 Phase 4 发言人合并 / 标点规范 / 段落切分那种"风格调整"性质不同,所以默认开启(用户不需要为此做开关决策)。 **白名单(可删的纯填充词)**——AI 通读时识别"作为填充词 vs 作为实义",仅删独立出现且无语义负担的: | 词 | 典型位置 | 删除条件 | |---|---|---| | 呃 | 段中独立 / 句首 | 认知停顿,不构成回答 | | 啊 | 段中独立 / 句末 | 感叹停顿 | | 哦 | 段中独立 | 过渡停顿(不作"明白了"回应) | | 哎 | 段中独立 | 过渡停顿 | | 那个 | 独立使用 | 纯指代填充(不指代具体名词) | | 就是说 | 独立使用 | 纯连接填充 | | 然后呢 | 段末 | 纯过渡填充 | | 对吧 | 段末 | 纯反问填充 | | 你知道吗 | 段中 | 纯引导填充 | | 怎么说呢 | 段中 | 纯思考填充 | | 这样子 | 独立使用 | 纯总结填充 | | 其实呢 | 段首 | 纯转折填充 | | 但是呢 | 段首 | 纯转折填充 | **保留规则**(不删): - **表态类**:"嗯"/"对"/"是的"/"不是"/"好的"/"是" 作肯定 / 否定 / 回应 → 保留(删了会丢失说话人态度) - **逻辑连接**:"然后"作逻辑连接词("先 A 然后 B")→ 保留(删了破坏时序) - **认知停顿后接完整内容**:"呃……这个怎么解释呢" 整段保留——"呃"虽属白名单,但"认知停顿 + 完整内容"是说话人思考过程的真实记录,整段保留比逐字删更尊重原文 - **段尾的语气停顿**("嗯"/"啊"/"呃"出现在段末)——保留(标记说话节奏收束) - **紧邻关键名词 / 动词**——保留(可能是说话人强调) - **实义词**(名词 / 动词 / 形容词 / 副词)——一律不删 **段首 vs 段尾 vs 段中 决策树**: | 位置 | 判定标准 | 处理(v2 激进版起)| |------|----------|---------------------| | **段首** | 紧跟 `**发言人 X HH:MM:SS**` 之后第一个非空行的第一个词 | **删除**(v2 起激进)| | **段中独立** | 句中位置、不是紧邻关键名词/动词 | **删除** | | **段中并列停顿 啊** | 两个名词/动名词之间 + 顿号/逗号 | **保留**(删除会破坏并列结构)| | **段尾** | 一段内容末尾的最后一个词 | **保留**(标记节奏收束)| 详见 `references/correction_patterns.md` §11 段中并列停顿 啊 的识别模式。 **判断原则**: - 与 Step 3.1 一样遵循"通读全文 + 三重确认"思路 - 三重确认:① 该词在当前上下文是否属于白名单词类;② 在当前位置是否独立使用、是否承担实义;③ 删后不破坏说话人态度 / 时序 / 强调 - 任一不满足 → **不删**,保留原文 - 模糊或低置信场景一律保留原文 **严格不做**(避免越界): - 不删整句、不删段落 - 不删实义词(即使重复) - 不删关键信息(数字、人名、专有名、术语) - 不改写为书面语、不补全、不改语气 - 不删"呃 / 啊"作认知停顿后接完整内容的版本 - 不删"段尾"的关键节奏标记(v2 激进版起,段首节奏标记默认删除) **校对日志记录**:所有 Step 3.3 的精简动作写到 `correction_log.md` 的"口语词精简"小节,格式: ``` | 行号 | 原文片段 | 被删词 | 理由 | |------|----------|--------|------| | L207 | "呃 这个怎么说呢,我们今天来" | "呃" | 段首认知停顿,后接"怎么说呢"+完整内容,整段保留——本行不删(认知停顿后接完整内容的"呃"按 §3.3 保留规则例外)| | L312 | "对,所以呢,我们" | "所以呢" | "所以呢" 不在白名单,保留 | | L451 | "然后呢我们看一下" | "然后呢" | 段首过渡填充,可删 | ``` **与 Step 3.2 的关系**:Step 3.2 动空白字符,Step 3.3 动语言字符。两者都是"读起来对"操作,都默认开启,都在 correction_log.md 单独小节集中记录。 **必检(防止漏跑整节)**:跑完必须 grep 自检(详见 `references/correction_patterns.md` §12): - `correction_log.md` 必须包含 `## 口语词精简` 小节 - `correction_log.md` 必须包含 `## 高置信替换` / `## 基础空白清理` / `## 口语词精简` / `## 未处理` 四个小节 - `meta.json` 必含 `summary` / `process_time` / `dictionary_source` / `polish_enabled` 字段 - v1.0.2 漏跑 Step 3.3 整节无日志——本必检项是那次 bug 的复盘产物 --- ## Phase 4:润色(可选,按 config 开关决定) Phase 4 下的所有 Step 由 `config/config.env` 配置文件中的开关决定是否启用。每个 Step 默认值的来源: - 缺失 `config.env`:用 `config.env.example` 的值(即默认值) - 缺失 `config.env.example`:用本节速查表的默认值 | Step | 类别 | 动作 | 边界 | 配置开关 | 默认值 | |---|---|---|---|---|---| | Step 4.1 | 发言人合并 | 同一发言人连续多段、可合并为一段时,合并 | 仅去重分块,**不删任何原话** | `POLISH_MERGE_SPEAKERS` | true | | Step 4.2 | 标点规范 | 中英文标点统一、句末补全 | 不改语气词、不删"呃/啊"等自然语流标记 | `POLISH_PUNCTUATION` | true | | Step 4.3 | 段落切分 | 极长段(>500字)按语义边界切 | 不重组、不重排、不总结 | `POLISH_PARAGRAPH_SPLIT` | true | | Step 4.4 | 主题分章 + H2 标题 | 在明确的话题切换点插入 `## 一、标题` 行(带中文大写序号) | 仅在切换点插入,**不重组内容、不改写、不总结** | `POLISH_TOPIC_SECTION` | true | | Step 4.5 | 会议纪要 / 总结 | 每章"本章摘要"+"关键洞察"**就地嵌入对应 H2 标题下**;文首主标题 + 文末关键词各一行 | **不引入新事实、不重切 H2、不评价、不另设顶部聚合块** | `POLISH_SUMMARY` | true | ### Step 4.4:主题分章 + H2 标题插入(默认开启) **触发条件**:话题发生明确切换(不同讨论对象 / 不同议程 / 不同主体焦点)时,插入 `## 一、标题` 行;同一话题内部的子切换**不**插入。 **识别原则**: - **硬切换信号**:双方反复回到同一对象 → 突然讨论另一对象(如"工具 → 律所管理"、"产品 → 客户关系"、"代码 → 知识库")→ 插入 H2 - **软切换信号**:仅是追问或深化(如"工具 A → 工具 A 的细节")→ 不插入 - **不强行覆盖全文**:开头寒暄 / 中间过渡闲聊 / 结尾收束 → 不强制加 H2,让它归在第一个/最后一个 H2 之下 **锚点定位流程(避免行号漂移)**:H2 锚点必须从 converted.md 上的结构标记(`**说话人 N HH:MM:SS**` 或杨卫薪行)的实际行号取,**不得从上游 raw 文件的早期阅读印象猜行号**——raw 与 converted 之间存在 metadata 块位移(Phase 1.2 包装前几行),且肉眼从 raw 数行号与脚本扫出来的真实行号常常差几行,把 H2 插错章节。**先写 5 行扫描脚本打印 converted.md 的全部 speaker 行真实行号,再据此填 H2 锚点表**;插完按"## 标题行 + 后 5 行"抽检,确认落在正确章节。 **标题文本从何而来**: - **不**编造标题——agent 从该段上下文中提取 3-10 字主题词(如"工具选择与日常使用"、"本地部署与脱敏"、"知识库维护") - 标题文本应**不与发言人姓名、时间戳、专有名重复**——避免与原文混淆 - 同一段内多次 H2 用相同主题词时,去重 **编号规则**: - 全文 H2 标题按出现顺序加中文大写数字序号:`一、`、`二、`、`三、`... - 数字与标题文本之间用 `、` 顿号分隔(中文正式排版惯例):`## 一、工具选择与日常使用` - 序号连续编号,不跳号;中途若发现需要补插,agent 重新连续编号(不留断号) - 同一份 `corrected.md` 中序号唯一,不重复 **严格不做**: - 不重组内容顺序 - 不改写任何正文 - 不总结或提炼(标题文本只是该段已说内容的提取,不引入新信息) - 不加 H3 / H4(本 skill 只到 H2 层级) - 不为单个话题切分加 H2(哪怕该话题横跨 1000 字) **校对日志记录**:所有 Step 4.4 的插入写到 `correction_log.md` 的"主题分章"小节(与 Step 4.1/4.2/4.3 区分),格式: ``` | 行号 | 标题文本 | 上下文锚点(前后 50 字)| 切换类型 | |------|----------|------------------------|----------| | L487 | ## 律所管理与本地部署 | "...他就不会愿意去做这个事事情。" | 硬切换 | ``` **与 Phase 4 其他 Step 的关系**:Step 4.1-4.3 是"风格调整",Step 4.4 是"结构标注"——前者改分块形式,后者只插入锚点,**不重排**。 **为什么本 skill 做这个而不下游做**:原 §1.2 早期版本说"下游做章节重组时再处理",但下游 skill(如 course-generator)做的是"基于转录稿生成课程",与"忠实标注原话结构"是不同任务。H2 主题分章是"忠实标注",放在本 skill 更合身。 ### Step 4.5:会议纪要 / 总结生成(按 `POLISH_SUMMARY` 开关) **触发条件**: - 配置开关 `POLISH_SUMMARY=true`,或用户在调用时显式声明("生成纪要" / "总结" / "AI 洞察") - 必须 Step 4.4 已先跑过——没有 H2 边界就没有"按章节"颗粒度 **核心原则(v1.4 修订:摘要就地嵌入,不聚合到顶部)**: - 每个章节的"本章摘要 + 关键洞察"**直接写在对应 H2 标题之下、该章原话正文之前**——不另设顶部聚合块 - 不使用 `` markers,不产生"所有章节摘要汇聚在一起"的独立区块 - 全文级元信息(主标题、关键词)只各占一行,轻量置于文首 / 文末,不与逐章摘要混聚 **输出位置**: - **修改 `corrected.md`**:① 文首 H1 下加一行主标题;② 每个 H2 标题下就地嵌入本章摘要 + 关键洞察;③ 文末加一行关键词 - 不创建独立 `_summary.md`,不写 markers - 源文件目录镜像随 corrected.md 同步 **就地嵌入格式**(每个 H2 之下): ```markdown ## 一、章节名(Step 4.4 标题,原样) **本章摘要**:50-100 字概括本章节核心内容(引用原话中的具体事实/数字/专有名,不引入新事实,不评价) **关键洞察**: - 洞察 1(15-30 字,横向观察本章节) - 洞察 2 **发言人 1 00:02:09** (该章原话正文,全部保留,紧跟在摘要 / 洞察之后) ... ``` **文首主标题 / 文末关键词**: - 文首:H1 标题之下、第一个 H2 之前,单行写主标题:`**主标题**:5-15 字概括全文核心议题` - 文末:最后一个 H2 章节原话之后,单行写关键词:`**关键词**:词1, 词2, ...(5-8 个,逗号分隔)` - 两者各占一行,不展开为区块,不与逐章摘要聚合 **为什么改为就地嵌入(v1.4)**: - 顶部聚合块把所有章节摘要堆在一处,读者在正文某章想看概要时要回滚到顶部对照——摘要与正文分离 - 就地嵌入让"摘要 / 洞察"紧贴它所概括的原话,一章自洽,阅读和后续复用(如抽成课程章节)都更顺 - 主标题 / 关键词保留为单行全文元信息,不丢失,但不再聚合成块 **生成原则**: 1. **主标题**(文首单行):从全文最核心议题提取 5-15 字主题词 2. **逐章摘要**:与 Step 4.4 的 H2 **一一对应**(**不重切话题**) - 长度:50-100 字 - 引用原话中的具体事实/数字/专有名(不抽象化) - 不引入原话外的事实 - 不评价(除非有原话支持) - 紧贴本章节原话概括,不跨章节 3. **逐章关键洞察**:每章 2-3 条(段落短就 2 条) - 长度:每条 15-30 字 - 来自本章节的横向归纳,不来自某一段 - 不带"应该""必须""建议"等评价语气 - 形如"X 群体呈现 Y 趋势"、"X 与 Y 之间存在 Z 鸿沟" 4. **关键词**(文末单行): - 数量:5-8 个 - 来源:原话中反复出现或具有区分性的名词/产品名/概念词 - 格式:逗号分隔一行 **严格不做**: - 不引入原话外的事实 - 不重切 H2 边界(逐章摘要必须与原话 H2 一一对应) - 不评价(除非有原话明确支持) - 不另设顶部 `## AI 摘要` 聚合块、不写 `` markers - 不在 H2 下加 H3 / H4 包裹摘要(摘要 / 洞察用粗体标签行,不升级标题层级) - 不写"行动项 / 决议 / 后续 TODO"(除非原话明确提到) **与 Step 4.4 的边界**: | | Step 4.4 | Step 4.5 | |---|---|---| | 输出文件 | corrected.md(修改) | corrected.md(修改,就地嵌入)| | 操作 | 在原话章节前插入 H2 标记 | 每个 H2 标题下、原话前嵌入摘要 / 洞察;文首主标题、文末关键词各一行 | | 保留原话 | 全部保留 | 原话全部保留 + 摘要中引用片段 | | 引入新信息 | 不允许 | 不允许 | **幂等与验证**: - 再次跑批时,就地替换每个 H2 下的"本章摘要 / 关键洞察"块、文首主标题行、文末关键词行 - 跑完后验证:① 每个 `^## ` 二级标题之下紧跟一个 `**本章摘要**` 行;② 全文无 `