# Transcription Corrector

> 转录稿纠错与轻度优化。本技能应在用户需要按用户词典纠正 ASR 转录稿同音字与英文专有名称漂移时使用。不要用于：重写为课程章节、报告、总结，或完全空白的素材创作。

- Skill: `cat-xierluo/transcription-corrector` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add cat-xierluo/transcription-corrector`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cat-xierluo/transcription-corrector/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: cat-xierluo (https://skillmd.com/u/cat-xierluo)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/cat-xierluo/transcription-corrector

---


# 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"） |
| 中文数字 + 空格 + 级/章/节 | 合并 | 模式：`[一二三四五六七八九十百千]+ +级/章/节` 合并为 `[一二...]+级/章/节`（如"二 级" → "二级"） |

**标点周围空白规则**：
- 中文标点 `，。、；：？！""''「」（）` 前后不留空格（若出现则删除）
- 英文标点 `, . ; : ? ! " ' ( )` 后空一格（中文段落中保留）
- 半角空格夹在中文之间 → 删除

**严格不做**（避免越界）：
- 不删除任何文字、标点、字母、数字
- 不改变段落结构（不合并段落、不切分段落——这是 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 之下

**标题文本从何而来**：

- **不**编造标题——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 标题之下、该章原话正文之前**——不另设顶部聚合块
- 不使用 `<!-- AI-SUMMARY -->` 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 摘要` 聚合块、不写 `<!-- AI-SUMMARY -->` markers
- 不在 H2 下加 H3 / H4 包裹摘要（摘要 / 洞察用粗体标签行，不升级标题层级）
- 不写"行动项 / 决议 / 后续 TODO"（除非原话明确提到）

**与 Step 4.4 的边界**：

| | Step 4.4 | Step 4.5 |
|---|---|---|
| 输出文件 | corrected.md（修改） | corrected.md（修改，就地嵌入）|
| 操作 | 在原话章节前插入 H2 标记 | 每个 H2 标题下、原话前嵌入摘要 / 洞察；文首主标题、文末关键词各一行 |
| 保留原话 | 全部保留 | 原话全部保留 + 摘要中引用片段 |
| 引入新信息 | 不允许 | 不允许 |

**幂等与验证**：

- 再次跑批时，就地替换每个 H2 下的"本章摘要 / 关键洞察"块、文首主标题行、文末关键词行
- 跑完后验证：① 每个 `^## ` 二级标题之下紧跟一个 `**本章摘要**` 行；② 全文无 `<!-- AI-SUMMARY` 字样；③ 主标题 / 关键词各一行存在
- 验证摘要总字节数 > 200（防止空摘要）

**校对日志记录**：Step 4.5 的产出写到 `correction_log.md` 的"会议纪要"小节，格式：

```
| 字段 | 值 |
|------|-----|
| 主标题（文首单行）| 主标题文本 |
| 章节数 | 8（与 Step 4.4 H2 一致）|
| 总洞察数 | X 条 |
| 摘要字数总计 | Y 字 |
| 关键词（文末单行）| 词1, 词2, ... |
| 嵌入方式 | 就地嵌入每个 H2 之下；无顶部聚合块；无 markers |
```

---

**Phase 4 整体边界**（适用于 Step 4.1-4.4）：

- 改写为书面语
- 总结、提炼、删除"啰嗦"内容（Step 4.5 是唯一例外——它明确做"摘要 + 洞察"）
- 补全或推测说话人意图
- 改事实、改数字、改时间戳

---

## Phase 5：输出

输出采用 **双写** 策略：主归档在 skill 内部，源文件目录同步一份易访问副本。原始文件保持不动。

### Step 5.1：主归档（必出）

输出位置：`{skill 目录}/archive/{YYYYMMDD_HHMMSS}_{原文件 basename}/`

文件：
- `{原文件}_corrected.md` — 纠错后的完整文本（保留原始分块结构）
- `{原文件}_polished.md` — 仅在用户开启润色时生成
- `correction_log.md` — 校对对照日志
- `meta.json` — 处理时间、词典来源、是否润色、原始文件路径

### Step 5.2：源文件目录镜像（必出）

输出位置：原始文件所在目录（与原文件同目录）。

文件：
- `{原文件 basename}_corrected.md` — 与 5.1 内容完全一致，仅是易访问副本
- 命名规则：原文件名后追加 `_corrected` 后缀，扩展名改为 `.md`（原文件是 `.md` 时，输出仍为 `.md`；原文件是 `.txt` 时，输出为 `.md`）

**为什么双写**：
- 主归档承担"可追溯 + 校对日志 + 元数据"的完整档案职责
- 源文件目录副本让用户在日常文件管理器中能直接看到"已校对版"，免去每次去 skill 内部目录翻找
- 双写的内容是字节级一致的 `_corrected.md`（polished 副本与 log 不镜像——它们的主归档位置就在 skill 内部）

**冲突处理**：
- 源文件目录已存在同名 `_corrected.md` → 用时间戳后缀区分（`_corrected_20260608_153022.md`），避免覆盖历史校对结果
- 源文件目录只读 / 不可写 → 静默跳过源文件目录镜像，仅输出主归档；在 `meta.json` 记录 `source_mirror: "skipped"`
- 源文件路径无法解析（如 stdin 输入）→ 同样静默跳过源文件目录镜像

**原始文件保持不动**——双写策略只生成"新文件"，绝不就地修改原文件。

### Step 5.3：稳定版标记（可选）

当某次跑出的 `_corrected.md` 经用户确认无问题、视为该转录稿的"稳定版"时，在该 archive 子目录下加 `STABLE.md` 标记文件：

```markdown
# Stable Version Marker

**v3 (2026-06-08 12:00) 标记为该转录稿的稳定版本。**

## 为什么 v3 是 stable

- v1.0.0 (2026-06-07 14:30) — 7 处，仅 Step 3
- v1.0.2 (2026-06-08 00:41) — 42 处，Step 3 + 3.5，漏跑 Step 3.6
- v2 (2026-06-08 11:00) — 170 处，补跑 Step 3.6（84 处）
- v3 (2026-06-08 12:00) — 226 处，激进版段首删除（+52 处）

## 锁定本版本

- 后续不再对 `260606_AI技能创新大赛_corrected.md`（v3）做改动
- 源文件目录三个版本并列保留供对比
- 如发现新的误转写需要补判，新建 `archive/<新时间戳>_*` 目录重跑，不就地修改 v3
```

**为什么需要 STABLE.md**：
- archive 目录会累积多轮迭代产物（v1.0.0 / v1.0.2 / v2 / v3 ...），未来 agent / 用户 / 下游 skill 进来不知道哪个是终版
- 源文件目录的镜像文件（`_corrected_v3_20260608_120000.md`）按时间戳命名，本身是"稳定"暗示，但 archive 内部 `260606_AI技能创新大赛_corrected.md` 没 STABLE 标记会被误认成"最新版"
- STABLE.md 让"哪个是终版"显式可查

**什么时候不写 STABLE.md**：
- 一次性试跑、用户没确认 / 校对量少 / 转录稿本身还要后续处理——不必强行标记
- 已经有更新的版本稳定了——避免给旧版加 STABLE 误导下游

### Step 5.4：旧版本清理策略

archive 目录会保留每次跑的全量产物（主归档 + correction_log + meta.json），不主动清理历史版本。但当 archive 下子目录数 ≥ 5 时，建议在 STABLE.md / DECISIONS.md 备注保留策略：

- **保留**：每次的 `_corrected.md` / `correction_log.md` / `meta.json`（记录完整迭代轨迹）
- **可清理**：当 archive 累积 ≥ 5 个目录时，旧的 `analysis_report.md` 等中间产物可手动归档
- **禁止清理**：被 STABLE.md 标记的稳定版目录的 `_corrected.md`（用户可能要从源文件目录镜像之外的路径找回终版）

#### 校对对照日志格式（correction_log.md）

```markdown
# 校对对照日志

- **原始文件**：/path/to/raw.md
- **处理时间**：2026-06-07 14:30:22
- **词典来源**：`config/user_dictionary.yaml`（含 18 项术语）
- **润色开关**：关闭

## 高置信替换

| 原文 | 改后 | 出现次数 | 上下文示例 |
|------|------|----------|------------|
| workbody | WorkBuddy | 3 | "通过第二版呢进行测试..." |
| work body | WorkBuddy | 2 | "我们把这个实践中办案..." |
| claude-code | Claude Code | 1 | "...重新调回那个 claude-code 里面..." |

## 未处理（保留原文）

- "智能件" — 上下文不足以判断是否为"智能体"
- "代理" — 同上

## 润色变更（如开启）

- 合并发言人 1 连续 3 段为 1 段
- ...
```

## 适用场景 / 不适用

见 [references/scope.md](references/scope.md)。

## 配置示例 / 配置解耦原则

见 [references/config-decoupling.md](references/config-decoupling.md)。

## 参考文档

- [references/scope.md](references/scope.md) — 概述 / 适用边界
- [references/config-decoupling.md](references/config-decoupling.md) — 配置示例 / 配置解耦原则（评价规范相关）
- [references/first_use.md](references/first_use.md) — 一次性配置引导（复制 example.yaml、跑试跑、多用户软链）
- [references/correction_patterns.md](references/correction_patterns.md) — 工作流判断准则（误转写识别、口语词精简、并列停顿、必检清单、ASR 高频模式）
- [config/user_dictionary.example.yaml](config/user_dictionary.example.yaml) — 词典公开模板

