# Doco 文稿整理子项目 Brief

> 主项目 → 子项目的"交接宪法":红线、技术栈、出入口接口
> 起草日期:2026-06-12
> 状态:主项目签发,子项目内部不修改

---

## 一、为什么做

**痛点**:《军事科技》每期节目播出后,产出一份贴近实际播出的终版文稿,过去靠人工对照 A 稿(编导定稿)+ 录音转写 + OCR 字幕反复核对,**单期 4-6 小时**,且容易遗漏错字、整段重写、编导笔误。

**升级目标**:把"三方文本 → 终版文稿 + 差异报告"做成可自动化的流水线模块。

**现状起点**:demo 已用《现代防空反导大对决》一期跑通,效果达标。栏目组改变了素材输出方式——直接产出"黑底白字+干净人声"的特殊视频——使物理输入从 3 路(A 稿+B 稿+ASR)收敛到 2 路(A 稿+视频),但**逻辑上仍然三方融合**(A 稿+B 路视频字幕 OCR+音轨 ASR)。

---

## 二、做什么(功能边界,只列名)

| 模块 | 简述 |
|---|---|
| 视频双路拆分 | ffmpeg 抽帧+字幕变化检测+OCR → B 稿;ffmpeg 抽音轨 → 16k WAV |
| 讯飞 ASR 适配层 | 复用 demo 跑通的 `xfyun_asr_standard.py`,替换凭证 |
| 三方融合引擎 | 规则层(Python)+ AI 层(Claude Sonnet 4.6),demo 已锁 |
| 单期处理接口 | CLI + Python API,契约见主项目回复 §Q3 |
| Golden test | 用 demo 那期视频做零回归验证 |
| 23 期批量调度入口 | 单期接口的批量调用方式,具体编排不在本子项目 |

**具体怎么做,子项目内部讨论,本 Brief 不预设方案。**

---

## 三、怎么用(目标流程)

**单期处理**:
1. 责编/编排层在 episodes 表落库该期,拿到 INT 主键
2. 拼出 episode_id:`ep{NNN}_{YYYYMMDD}_{slug}`
3. 把视频和 A 稿放进 `programs/{episode_id}/source/`
4. 调 doco:`doco.process_episode(episode_id, video_path, a_draft_path, output_dir)`
5. 产物落 `programs/{episode_id}/output/`:终版 docx + 差异报告 + needs_review JSON
6. 编导/制片人审 needs_review 队列,决定接受 / 拒绝 / 编辑

**23 期批量**:用同一接口循环调用 23 次,失败重试 + 进度跟踪由调用方负责。

**降级回退**:若某期视频不符合"黑底白字+干净人声"条件,通过 feature flag 切换到旧流程(独立 mp3 + 上游 OCR)。

---

## 四、不做什么(红线)

子项目设计任何方案,**绝不**触碰以下:

- ❌ **不动 demo 已锁的算法层**(三方融合优先级 / 时间戳容忍 ±5s / 口语清理三档 / 改动确信度阈值 0.85/0.6 三段)
- ❌ **不引入 `ffmpeg-python` 等 wrapper**(用 subprocess 调系统 ffmpeg)
- ❌ **不替换 AI 融合层模型**(Claude Sonnet 4.6 已锁,不临时换 DeepSeek 等)
- ❌ **不复用主 project 那把 DeepSeek key**(Cline 工具用的 key 跟生产业务分开)
- ❌ **不把凭证写进主 project 的 `backend/.env`**(子模块自治,各自 .env)
- ❌ **不假设 episode_id 命名规则**(由调用方给定,doco 只当字符串用)
- ❌ **不引入主 project 没有的技术栈**(继续 Python 3.x + Claude API + 讯飞 API)
- ❌ **不自己实现批量调度**(失败重试 / 并发控制 / 进度跟踪属于编排层职责)
- ❌ **不在子项目里写中台密钥服务**(那不属于 doco 范围)

---

## 五、技术栈约束(继承主 project)

- **运行环境**:Python 3.x(版本对齐 backend),Windows / Linux 都可跑
- **系统依赖**:ffmpeg ≥ 4.x(子模块文档明确列出)
- **AI 融合**:Anthropic Claude API,模型 `claude-sonnet-4-6`
- **OCR**:DeepSeek Vision API(主项目已批,Q1)
- **ASR**:讯飞开放平台 录音文件转写标准版(**不要用大模型版**——`language` 参数被阉割)
- **音频规格**:16kHz / 单声道 / 16bit WAV(讯飞规格)
- **数据格式**:句子级时间戳统一 `[Nm Ns] 句子` 格式

---

## 六、交付什么(出口接口)

子项目最终交付物以下面形式回到主 project,**必须满足以下接口**:

### 6.1 模块交付物
- `doco/` Python 包,可被主 project 编排层 import
- CLI 入口:`doco process ...`
- 单元测试 + golden test(demo 那期零回归)
- `README.md`:系统依赖、安装、使用、配置

### 6.2 配置与凭证
- doco 自己的 `.env`(讯飞 + DeepSeek + Claude 三套 key 各自管)
- 主项目仓库根目录的 `docs/api_credentials_inventory.md` 登记一行 doco 的凭证元信息(不存真实 key)

### 6.3 数据资产沉淀(可入 TPS 中台共享)
- A 稿术语表(每期处理时从 A 稿提取,可入主 project 数据库的 terms 维度)
- OCR 错字映射表(demo 已整理,固定字形混淆对)

### 6.4 不接受
- 子项目自己改主 project 的 backend 代码、schema、迁移
- 子项目自己写主 project 的前端 UI(编导确认 UI 属于上层,不在 doco 范围)
- 子项目自己定 episode_id 命名规则(由主项目给定)

---

## 七、入口接口(子项目要知道的主 project 现状)

- **主项目没有 OCR 子模块**(已确认,Q1)
- **主项目没有视频处理服务**(已确认,Q2)
- **主项目没有节目素材批量编排层**(已确认,Q3)
- **主项目没有中台密钥服务**(已确认,Q4)
- **主项目没有节目素材目录规约**(已确认,Q5,本子项目带头定 `programs/{episode_id}/...`)
- **主项目有 episodes 表**(INT 自增主键),doco 用 episode_id 时假定调用方已落库

---

## 八、未决项(归子项目自己拍板)

以下不在本 Brief 内预设,**由子项目和制片人讨论决定**:

- 视频抽帧的具体策略(关键帧检测算法 / 抽帧密度 / 字幕变化阈值)
- DeepSeek Vision 调用的具体 prompt 设计
- 规则层 OCR 错字映射表的具体扩展机制
- AI 融合层的具体提示词迭代
- needs_review JSON 的具体字段(在 demo 基础上演化)
- 单元测试覆盖率目标
- 子项目内部的 git 分支策略 / 版本号约定

---

## 九、决策史指向(不重复内容)

子项目讨论前必读:
- `doco_project_design.md / .docx`(三方融合算法层,demo 沉淀,已锁)
- `doco_xfyun_integration_notes.md / .docx`(讯飞 ASR 接入 15 个坑)
- `doco_handoff_to_opus_chat.md / .docx`(子项目立项前的 opus 接手提示)
- `PRD_doco_文稿整理子项目_v2.md`(当前子项目的请求稿)
- `主project对Doco_PRDv2的回复.md`(主项目的批复)

---

## 十、本 Brief 自身的修订规则

- 本 Brief 不在子项目内修改
- 红线 / 技术栈如有变更,**主 project 这边发新版**,通过寄存条同步
- 子项目可在自己的 chat 里讨论"建议主 project 调整某条红线",调整动作只能在主 project 发生
- 子项目每次出新版 PRD,主项目顾问发新版回复;两者形成 PRD vN ↔ 回复 vN 的对照关系
