# TPS · 三方融合子模块 设计文档（project_design.md）

> 归属：《军事科技》中台 TPS · 终版文稿生成（Three-source Pipeline Synthesis）
> 文档目的：把 demo 阶段的实测结论沉淀为可被中台其他子模块（含 opus_chat）调用的明确接口与约束
> 当前状态：demo 已跑通一期完整节目（《现代防空反导大对决》），进入正式开发阶段
> 文档版本：v0.1（2026-05-15）
> 维护：刘统制片组 / Claude

---

## 0. TL;DR（给 opus_chat 的最短摘要）

- 本子模块的输入是三份资料，输出是一份贴近实际播出的 docx 文稿 + 一份逐段差异报告。
- **三份输入：**
  1. **A 稿**：编导手写定稿（docx，带【主持人N】【解说N】【专家N】【动画N】【隔断：…】结构标签）
  2. **B 稿**：OCR 扒词文档（txt，带 `[Nm Ns]` 句级时间戳，存在 OCR 错字）
  3. **ASR 结果**：讯飞录音文件转写（txt，带 `[Nm Ns]` 句级时间戳，存在同音误识）
- **核心信念**：三方各有短板，单源不可信；融合后才是"播出真相"。
  - A 稿 → 术语 / 人名 / 装备型号 / 事实 的**权威**
  - ASR → 播出语序与口吻的**骨架**
  - B 稿 → 独立**交叉验证**（同时验证 A 与 ASR）
- **架构两层：**
  - **规则层**（Python）：术语字典纠正、OCR 错字映射、时间戳对齐、口语词清理、数字规范化
  - **AI 层**（Claude API）：段落对齐、改动类型判定、整段改写边界、编导笔误识别
- **请 opus_chat 注意：** 本模块依赖讯飞 ASR 与 Claude API，**两套密钥**互不复用；调用本模块前应确认 A 稿术语表已入库。

---

## 1. 业务背景与定位

### 1.1 上游 / 下游

```
[节目编导] ──A稿(docx)──┐
                       │
[OCR 服务（旧流程）]──B稿(txt+时间戳)──┐
                                    ├──► [本模块 三方融合] ──► [终版docx] ──► [节目档案库]
                                    │                       └► [差异报告docx] ──► [编导回顾 / 训练素材]
[节目纯净声音文件]──[讯飞 ASR]──ASR(txt+时间戳)─┘
```

### 1.2 在 TPS 中台的位置

本子模块是 TPS（终版文稿生成中台）的**核心算法子模块**，位于上游"素材接收"和下游"档案入库 / 编导确认 UI"之间。

- 它**不**负责音频转码（由 ASR 适配层处理）
- 它**不**负责 OCR 识别（B 稿来自既有 OCR 流程）
- 它**不**负责最终入库（由档案子模块负责）
- 它**只**负责"三方文本 → 一份贴近播出的终版文稿 + 差异报告"

### 1.3 为什么不能省略某一方？

| 缺哪一方 | 后果 | 实例 |
|---|---|---|
| 缺 A 稿 | 术语 / 人名 / 装备型号易错；ASR 同音错难发现 | "美以两国"被 ASR 识别成"美伊两国"——句子通顺、语义荒谬，无 A 稿无法纠正 |
| 缺 ASR | 无法知道实际播出语序与口吻；专家口语词全丢 | A 稿用"观众朋友们，你们好"，播出实际是"各位观众你们好" |
| 缺 B 稿 | 失去独立交叉验证；ASR/A 稿冲突时无第三方仲裁 | A 稿与 ASR 在某段不一致时，B 稿与谁一致就以谁为准 |

**结论**：B 稿可以视为弱必需（demo 证明 A+ASR 二方融合也能跑），但建议保留 B 稿做 sanity check。

---

## 2. 输入规范

### 2.1 A 稿（编导定稿）

- **格式**：`.docx`（实际为 markdown 风格的纯文本，也兼容真 docx）
- **结构标签**（出现在自然段开头，方括号包裹）：
  - `【导视】` `【主持人N】` `【解说N】` `【动画N】` `【专家N】`
  - `隔断：【…】` 用于章节分隔
- **特点**：
  - 内容偏书面化；可能存在编导笔误（如本期【专家7】【专家8】内容字符完全相同 = 复制粘贴失误）
  - 术语严格、人名 / 装备型号完整（"爱国者-3"、"霍拉姆沙赫尔-4"、"见证者-136"）
  - 标点 / 顿号 / 引号规范

### 2.2 B 稿（OCR 扒词）

- **格式**：`.txt`
- **行格式**：`[Nm Ns] 句子内容`，每行一句
- **特点**：
  - 句子时间戳精度到秒
  - **存在 OCR 错字**：字形相近字混淆（肘↔时、娈↔变、夭↔天、井↔并、末↔未、纺↔防、观↔现、忽↔您、岳↔越、改命↔致命）
  - 标点弱（多为空白分隔，缺逗号 / 句号）
  - 句子切分较碎（一句话常被切成 2–3 行）

### 2.3 ASR（讯飞录音文件转写）

- **格式**：`.txt`
- **行格式**：`[Nm Ns] 句子内容`，每行一句（与 B 稿对齐）
- **特点**：
  - 标点合理（讯飞已自动加句号、逗号、问号）
  - 经 `eng_smoothproc + eng_colloqproc` 处理，已**部分**清理"嗯/呃"
  - **存在同音误识**："中端↔中段"、"末端↔末段"、"中诚↔中程"、"美伊↔美以"、"高超声速↔高超音速"
  - 数字 / 百分比识别准确
  - 句子级时间戳精确，可与 B 稿做交叉对齐

### 2.4 三方时间戳的对齐口径

A 稿无时间戳；B 稿与 ASR 都有 `[Nm Ns]` 但**不严格一致**（B 稿来自 OCR 字幕显示时点，ASR 来自语音波形起点；常相差 1–3 秒）。融合时**容忍 ±5 秒**的时间漂移作为同段判定的辅助条件。

---

## 3. 输出规范

### 3.1 终版文稿（主产物）

- **格式**：`.docx`
- **结构**：保留 A 稿的段落标签（【导视】【主持人1】…）
- **内容来源策略**：
  - 默认以 ASR 文本为骨架
  - A 稿术语 / 人名 / 装备型号回填
  - B 稿 OCR 错字修复（用 ASR / A 稿覆盖）
  - 标点采用 ASR 的版本（最自然）
  - 口语词处理强度由"清理档位"参数控制（见 §5.3）

### 3.2 差异报告（副产物）

- **格式**：`.docx`
- **内容**：
  1. 改动总览（段落数 / 改动类型分布）
  2. 逐段对照（A 稿原文 vs 终版，标注改动类型与依据）
  3. 关键差异专题：整段删除 / 整段改写 / 术语变化 / 编导笔误 / OCR 错字修复 / ASR 错字修复 / 口语词处理
  4. 依据图例（三方一致 / ASR 为主 / A 稿权威 / …）
- **价值**：差异报告本身就是编导工作回顾，长期累积可分析编导删改偏好。

### 3.3 改动类型枚举

| 枚举值 | 含义 | 处置 |
|---|---|---|
| `unchanged` | 三方一致或语义等价 | 直接采用 A 稿 |
| `minor_edit` | 标点 / 顿号 / 简称差异 | 自动以 ASR 版本输出 |
| `term_normalize` | 术语 / 字形 / 同音修正 | 规则层处理 |
| `rewrite_large` | 整段重写（A 稿与播出版差异较大） | AI 层处理 + **建议编导确认** |
| `segment_delete` | A 稿有但播出无 | AI 层判定 + **建议编导确认** |
| `segment_add` | A 稿无但播出有 | AI 层判定 + **建议编导确认** |
| `editor_typo` | A 稿编导笔误（整段重复 / 明显错位） | AI 层提示 + **必须编导确认** |

---

## 4. 模块架构

### 4.1 顶层流程

```
            ┌───────────────────────────────────────────────────┐
            │             三方融合引擎（本子模块）              │
            │                                                   │
A 稿 ──────►│  解析层 ──► 段落对齐层 ──► 规则纠错层 ──► AI 融合 │──► 终版docx
B 稿 ──────►│                                       ↓          │──► 差异报告
ASR ──────►│                              [Claude API]         │
            └───────────────────────────────────────────────────┘
                          ▲
                          │
                  [A 稿术语表 / OCR 错字字典 / 口语词字典]
```

### 4.2 各层职责

#### 解析层（parser）
- A 稿：按 `【…】` 切段，识别隔断标签，输出 `[(label, text)]`
- B 稿 / ASR：按 `[Nm Ns]` 行切句，输出 `[(start_ms, end_ms, text)]`

#### 段落对齐层（aligner）
- 目标：把 B 稿 / ASR 的句子聚合并归到 A 稿的段落标签下
- 算法：
  - **强信号**：通过 A 稿首末锚点句做语义匹配（demo 用了人工锚点列表，正式版应用 Claude API 做语义匹配）
  - **弱信号**：时间戳的单调推进
- 容错：允许 ±5 秒漂移、允许中间出现专家发言被识别为"解说"

#### 规则纠错层（rule-based corrector）
- **A 稿术语字典**：从 A 稿提取专有名词，扫描 ASR / B 稿，发现字形不同但拼音相同的同音字 → 用 A 稿覆盖
- **OCR 错字字典**：维护固定映射表（肘→时、娈→变、夭→天…），扫描 B 稿
- **数字规范化**：`百%` → `100%`、`数10` → `数十`、`马赫数10` → `10马赫`
- **标点规范化**：去重逗号、补齐句号

#### AI 融合层（Claude API）
- 输入：经规则层处理后的三方对齐结果
- 任务：
  1. 段落对齐的最终校验（解决规则层算不准的边界）
  2. 改动类型标记（`unchanged` / `minor_edit` / `rewrite_large` / `segment_delete` / `segment_add` / `editor_typo`）
  3. 高把握改动直接产出终版
  4. 低把握改动标记原因 + 给编导待确认列表
- 提示词要点：见 §6

### 4.3 双层划分的依据

| 任务 | 走哪层 | 理由 |
|---|---|---|
| OCR 错字纠正 | 规则层 | 字形错误是确定性映射 |
| 术语统一 | 规则层 | A 稿术语表是封闭集 |
| 时间戳对齐 | 规则层 | 数值比较 |
| 段落归属 | AI 层 | 需要语义判断（"这句专家发言到底归【专家3】还是【解说5】"） |
| 整段删除判定 | AI 层 | 需要判断"A 稿这一段，是否在 B 稿 + ASR 都找不到对应内容" |
| 编导笔误识别 | AI 层 | 需要"【专家7】【专家8】内容相同" + "ASR 第 N 句到第 M 句讲了完全不同的内容"的联合判断 |

---

## 5. 关键决策与参数

### 5.1 三方冲突时的优先级

| 冲突类型 | 优先采用 | 例 |
|---|---|---|
| 术语 / 人名 / 装备型号 | **A 稿** | "美以两国"（ASR 错识"美伊"） |
| 标点 / 句式 / 口吻 | **ASR** | "各位观众你们好"（A 稿"观众朋友们，你们好"） |
| 字形错字 | **ASR / A 稿** 覆盖 B 稿 | "肘→时""纺空→防空" |
| 整段存在性 | **B 稿 + ASR 联合** 优先 | A 稿"雷达被誉为眼睛..."B 稿/ASR 都没有 → 删 |
| 数字 / 百分比 | **ASR**（已确认 ASR 100% 准确） | "5%"、"100%" |
| 同音 / 字形错 | **A 稿术语字典** | "中端→中段""高超声速→高超音速" |

### 5.2 时间戳容忍度

- 同段判定：B 稿 / ASR 时间戳差 ≤ **5 秒** 视为同一播出位置
- 锚点匹配：A 稿首句对应的 ASR 时间位置 ± **10 秒** 为搜索窗

### 5.3 口语词清理档位（可配置）

| 档位 | 行为 | 适用场景 |
|---|---|---|
| `keep_all` | 完全保留"那么""呢""啊""这个" | 反映播出真相、用于事后复盘 |
| `medium`（**默认**） | 保留专家段口语词，清理解说段 | 平衡可读性与真实性 |
| `clean` | 全部清理，按 A 稿书面化 | 用于外部传播 / 文稿出版 |

### 5.4 改动确信度阈值

- AI 判定结果带 `confidence ∈ [0,1]`
- `confidence ≥ 0.85`：自动应用，记入差异报告
- `0.6 ≤ confidence < 0.85`：自动应用 + **黄色标记**，编导可在 UI 中翻看
- `confidence < 0.6`：**不自动应用**，进入编导待确认队列

---

## 6. AI 融合层提示词设计纲要

提示词应包含以下要素（正式实现时按需扩展）：

```
[系统角色]
你是《军事科技》节目终版文稿生成助手。已知:
- A 稿是编导手写定稿，术语 / 人名 / 装备型号权威
- ASR 是讯飞录音转写，标点与口吻接近播出真相，但存在同音误识
- B 稿是 OCR 扒词，存在字形错字，用作交叉验证
三方冲突时按"§5.1 三方冲突优先级"裁决。

[输入]
A 稿全文（含 【…】 标签）：{a_doc}
ASR 结果（带时间戳）：{asr_sentences}
B 稿 OCR（带时间戳）：{b_sentences}
A 稿术语表：{terms_dict}
OCR 错字字典：{ocr_typos}
口语清理档位：{level}

[任务]
1. 把 ASR / B 稿的句子按时间顺序聚合并归到 A 稿的段落标签下
2. 对每段标记改动类型（unchanged / minor_edit / rewrite_large / segment_delete / segment_add / editor_typo）
3. 对每段给出 confidence ∈ [0,1]
4. 对 confidence ≥ 0.85 的段落直接产出终版文本
5. 对 confidence < 0.85 的段落产出"建议版本 + 待确认原因"
6. 识别 A 稿与 ASR 的术语 / 同音 / 字形差异，自动应用 A 稿权威
7. 识别 A 稿的编导笔误（如整段复制粘贴）并标记

[输出]
JSON：
{
  "segments": [
    {
      "label": "【主持人1】",
      "change_type": "rewrite_large",
      "confidence": 0.92,
      "final_text": "...",
      "evidence": {"asr_lines": [...], "b_lines": [...]},
      "reasons": ["A 稿首句被改写为口语化"]
    }
  ],
  "needs_review": [...]
}
```

---

## 7. 外部依赖

### 7.1 讯飞 ASR（必需）

- **服务**：讯飞开放平台「**录音文件转写（标准版）**」
- **不要用**：讯飞「大模型版」——免费包阉割了 `language` 参数，会报误导性的 `language verify fail`
- **认证**：APP_ID + SECRET_KEY；本期 demo 已申请到一组测试凭证（见 `xfyun_asr_standard.py`，正式上线需替换）
- **音频规格**：**16kHz / 单声道 / 16bit WAV**；其他规格讯飞会拒收
- **领域参数**：`pd=mil`（军事节目专用，提升术语识别率）
- **顺滑参数**：`eng_smoothproc=true` + `eng_colloqproc=true`
- **热词机制（关键）**：
  - 每期节目从 A 稿提取专业术语（武器装备 / 技术概念 / 人名 / 军方机构），上限 200 个，每个 2–16 字
  - 用 `|` 分隔传入 `hotWord` 参数
  - demo 实测 35 个热词后，关键术语识别率接近 100%
- **计费**：0元购买"5 小时免费试用包"（注意：看到额度但未走 0 元购买流程**不会激活**），1 年有效期
- **签名算法**：`signa = base64(HmacSHA1(MD5(appid + ts), secretKey))`

详见 `xfyun_asr_standard.py`（demo 已跑通的本地脚本，可直接作为正式适配层的起点）。

### 7.2 Claude API（必需）

- 用于 AI 融合层
- 调用模型：建议 `claude-sonnet-4-6` 或更高（涉及长文本理解与语义对齐）
- 单期节目（26 分钟）的预估上下文：A 稿 ~6k 字 + ASR ~5k 字 + B 稿 ~5k 字 ≈ 16k 字，远在 Sonnet 上下文窗口内
- 调用频次：每期节目 1–3 次（首次全量融合 + 若干次低确信段重判）

### 7.3 OCR 服务（已有）

- B 稿来自上游既有 OCR 流程
- 本模块只消费 B 稿 txt，不调用 OCR 服务

### 7.4 密钥管理

> **opus_chat 注意**：以下是常见混淆点，请勿用错。

| 密钥 | 用途 | 来源 |
|---|---|---|
| 讯飞 **消费端** | 讯飞听见 App（人工录音转写） | 讯飞听见 App 内 |
| 讯飞 **开发端** | 录音文件转写 API（本模块用） | 讯飞**开放平台** console |
| Claude API | AI 融合层 | Anthropic console |

三套密钥**互不相通**。

---

## 8. 编导确认 UI（属于上层 UI 子模块，本模块只提供数据）

本模块按以下结构输出供 UI 子模块消费的 JSON：

```json
{
  "program_id": "xxx",
  "segments": [...],
  "needs_review": [
    {
      "segment_label": "【解说6】",
      "reason": "整段改写边界不确定",
      "candidates": [
        {"text": "...", "source": "A稿"},
        {"text": "...", "source": "ASR"}
      ]
    }
  ],
  "diff_report_path": "...",
  "final_docx_path": "..."
}
```

UI 子模块应至少提供（参考 demo 复盘 §3.4）：

- **左中右三栏 diff 视图**：A 稿原文 | 终版 | ASR/B 稿（带时间戳，可点击播放对应音频）
- **改动类型颜色编码**：删除红 / 改写黄 / 术语修正蓝 / 无变化白
- **逐段确认按钮**：接受 / 拒绝 / 编辑 / 标记疑问
- **口语清理强度滑杆**：切换 `keep_all / medium / clean`
- **导出按钮**：终版 docx / 差异报告 / 复盘 CSV

---

## 9. 数据资产

### 9.1 应入库的"中台共享资产"

1. **A 稿术语表**（核心资产）
   - 每期节目处理时从 A 稿提取后入库
   - 同时作为讯飞热词来源 + 规则层纠错字典
   - 字段：`term`, `domain`（武器 / 技术 / 人名 / 机构 / 栏目），`first_seen_episode`, `frequency`
2. **OCR 错字映射表**
   - 固定字形混淆对（肘↔时、娈↔变、夭↔天…）
   - 随版本演进可扩展
3. **节目编导风格档案**
   - 长期累积每位编导的删改偏好（口语词保留度、术语简称习惯…）
   - 用于参数自适应

### 9.2 demo 阶段产物的处置建议

| 文件 | 处置 |
|---|---|
| `xfyun_asr_standard.py` | 作为 ASR 适配层的起点代码 |
| `asr_result_timed.txt` | 单元测试 fixture |
| `B稿_..._扒词.txt` | 单元测试 fixture（含典型 OCR 错字） |
| `A稿_..._定稿.docx` | 单元测试 fixture |
| `现代防空反导大对决_终版.docx` | 集成测试**期望输出**（黄金对照） |
| `差异报告.docx` | 集成测试**期望输出**（差异报告格式参考） |
| `实测复盘.md` | 设计文档背书 + 长期归档 |

---

## 10. 性能与耗时基线（实测）

来自 demo（26 分钟节目）：

| 阶段 | 耗时 | 占比 |
|---|---|---|
| 讯飞 ASR 转写 | ~5 分钟 | — |
| 三方解析 | ~5 分钟 | — |
| 段落对齐 | ~15 分钟（demo 手工） | 正式版预计 ≤2 分钟（AI 调用） |
| 术语规范化 + 口语清理 | ~5 分钟 | — |
| 终版 docx 生成 | ~5 分钟 | — |
| 差异报告生成 | ~15 分钟（demo 手工） | 正式版预计 ≤3 分钟 |
| **正式版预估单期** | **~15–30 分钟** | 取决于改动幅度与人工确认次数 |

---

## 11. 已知风险与未决事项

| 项 | 当前态 | 建议 |
|---|---|---|
| ASR 第三方依赖 | 讯飞单源 | 接入阿里云 ASR 做备份 / 交叉验证 |
| 整段改写的边界 | demo 中默认取 ASR 短版 | 必须接入编导确认 UI，不能全自动 |
| 编导风格差异 | 硬编码"中度清理" | 需配置文件或编导画像 |
| 隔断标签的处置 | demo 直接保留 A 稿 | 待确认是否需要根据音频静音段重新切分 |
| A 稿与 ASR 都缺失的旁白 | 不处理 | 极小概率事件，靠 B 稿兜底；记录用例 |

---

## 12. 给 opus_chat 的提示（重要）

如果 opus_chat 在其他场景中被问到本模块，请按以下口径回答：

1. **本模块的边界**：只做"三方文本 → 终版文稿 + 差异报告"，不负责音频转码、不负责 OCR、不负责档案入库、不负责编导 UI。
2. **依赖与约束**：依赖讯飞 ASR（标准版）和 Claude API；A 稿术语表必须先入库；音频规格必须 16kHz/单声道/16bit WAV。
3. **三方权威优先级**：A 稿（术语）> ASR（口吻）> B 稿（验证）；任何与此相反的处理都是 bug。
4. **未来扩展**：编导风格画像、第二 ASR 供应商、口语清理档位是后续路标。

如遇到与本文档不一致的描述，**以本文档为准**；如发现本文档需要更新，请同步刘统制片组。

---

## 附录 A：项目文件清单（demo 阶段）

```
project/
├── A稿_现代防空反导大对决_定稿.docx            # 输入1：编导定稿
├── B稿_现代防空反导大对决_扒词.txt             # 输入2：OCR扒词
├── asr_result_timed.txt                       # 输入3：讯飞ASR输出
├── xfyun_asr_standard.py                      # ASR调用脚本
├── 现代防空反导大对决_终版.docx                # 输出1：终版文稿
├── 差异报告.docx                              # 输出2：差异报告
├── 实测复盘.md                                # demo复盘（设计文档原料）
└── project_design.md                          # 本文档
```

## 附录 B：与"实测复盘.md"的对应关系

| 复盘章节 | 本文档对应位置 |
|---|---|
| 一、ASR环节实测数据 | §7.1 讯飞 ASR |
| 二、三方融合关键决策点 | §5 关键决策与参数 |
| 三、对正式开发的启示 | §4 模块架构 / §6 提示词设计 / §8 UI |
| 四、实测耗时分解 | §10 性能基线 |
| 五、给制片人的建议 | §9 数据资产 / §11 风险 |
