doco P3-C2: 讯飞ASR适配层接入 + 修复 doco/programs 忽略规则
- C2: asr_adapter 并入讯飞上传/轮询/解析,复用 extract_audio 分离音频, 新增 doco asr 命令读 C1 热词;真转写 ep001 出 310 句带时间戳 - 补提交 C1 代码(llm.py / term_extract.py)与累积词典 - .gitignore: 挡 doco/programs 下 png/wav/mp4 及中间帧目录、本地 settings Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
# 主 project 对 Doco PRD v2 的回复
|
||||
|
||||
> 来源:TPS 主 project 顾问(Claude Opus 4.7)
|
||||
> 日期:2026-06-12
|
||||
> 针对:`PRD_doco_文稿整理子项目_v2.md` 第四章 5 个问题
|
||||
> 性质:正式批复,Doco 子项目据此出 v3 后启动 P1
|
||||
|
||||
---
|
||||
|
||||
## 总体意见
|
||||
|
||||
**5 个问题的子项目推荐**,**整体方向 4 个批准、1 个调整**:
|
||||
- Q1 OCR 选型:**批准 DeepSeek API,但有附加条件**(见下)
|
||||
- Q2 ffmpeg 入口:**批准,有补充约束**
|
||||
- Q3 单期 vs 批量接口:**批准,加交付契约**
|
||||
- Q4 密钥管理:**调整方案** — 走"自管 + 中台登记 inventory"
|
||||
- Q5 目录规约:**批准草案,但 episode_id 命名规则需主项目定**
|
||||
|
||||
5.3 §"23 期是否常态化":**这是一个产品问题,我代制片人答不了。子项目可以按"先按 23 期一次性做完、保留兜底回退路径"开干,常态化的事跟栏目组确认后再回头审。**
|
||||
|
||||
---
|
||||
|
||||
## Q1. OCR 方案选型 — 批准 DeepSeek API
|
||||
|
||||
### 主 project 现状
|
||||
- **主 project 没有 OCR 子模块/能力**(已确认)。旧设计里 B 稿来自"上游既有 OCR 流程",指的是栏目组那边人工跑的 OCR,不是 TPS 内部的服务。
|
||||
- 主 project `backend/.env` 里有 `DEEPSEEK_API_KEY`,但**只用作 Cline 工具的 Plan/Act 模型**——没有任何业务代码在调 DeepSeek。所以 doco 调 DeepSeek 视觉模型相当于**新增一条业务调用**,不是"复用现有基础设施"。
|
||||
|
||||
### 批复
|
||||
|
||||
**Doco 子模块新增 DeepSeek Vision 调用,自管 API key。**
|
||||
|
||||
- API key 独立申请,**不复用 Cline 用的那把 key**。理由:Cline 的 key 是开发工具用的,doco 是生产服务,生命周期、配额、监控都该独立。
|
||||
- 6900 张图 × 几厘 / 张 ≈ 50-150 元,在制片人手上的 API 余额范围内,**不存在配额冲突问题**(主 project 业务代码侧没人在花)。
|
||||
- 黑底白字字幕场景对 LLM 视觉模型确实是舒适区,**实施前先在 demo 那期视频上跑 10 帧抽样,验证识别准确率达到目标后再扩到 23 期**。
|
||||
- **降级路径**:如果 DeepSeek Vision 在某些边角 case 上不达标(比如有同期声同步显示双行字幕、字号变化等),回退到 PaddleOCR 本地。**不要回退到讯飞 OCR**(余额独立 + 单期 ~13 元成本太高)。
|
||||
|
||||
---
|
||||
|
||||
## Q2. 视频处理依赖(ffmpeg)入口 — 批准方案 A
|
||||
|
||||
### 主 project 现状
|
||||
- **没有视频处理子模块/服务**(已确认),dev_plan 也没规划。
|
||||
|
||||
### 批复
|
||||
|
||||
**Doco 自带 ffmpeg 系统依赖 + Python subprocess 调用。**
|
||||
|
||||
附加约束:
|
||||
- **不引入 `ffmpeg-python` wrapper**——subprocess 足够,不增加新依赖。
|
||||
- ffmpeg 命令封装在 `doco/video_split.py` 内,**对外只暴露 Python 函数接口**,不让上层调用方直接 shell 调 ffmpeg。
|
||||
- 在 doco 的 `README.md` 明确写"系统依赖:ffmpeg ≥ 4.x"——这是部署的前置条件。
|
||||
- 未来如果主 project 真做了统一的视频处理服务,**doco 的封装方式应该使迁移成本最低**(把 subprocess 调用换成 HTTP 调用即可,业务逻辑不动)。
|
||||
|
||||
---
|
||||
|
||||
## Q3. 23 期批量 vs 单期接口 — 批准方案 A,加契约
|
||||
|
||||
### 主 project 现状
|
||||
- **没有节目素材批量处理编排层**(已确认)。dev_plan 提到的"批量导入工具 v1/v2"是收视数据和报题单的批量,跟视频处理是两回事。
|
||||
|
||||
### 批复
|
||||
|
||||
**Doco 只对单期负责。同时提供 CLI 和 Python API 两套接口。**
|
||||
|
||||
**接口契约(子项目正式实现时按这个出)**:
|
||||
|
||||
```python
|
||||
# Python API
|
||||
def process_episode(
|
||||
episode_id: str, # 调用方给定,doco 不管命名规则
|
||||
video_path: Path, # 输入视频
|
||||
a_draft_path: Path, # A 稿 docx
|
||||
output_dir: Path, # 产物存放目录
|
||||
cleanup_level: str = "medium", # keep_all / medium / clean
|
||||
) -> ProcessResult
|
||||
|
||||
# ProcessResult 必含字段
|
||||
@dataclass
|
||||
class ProcessResult:
|
||||
episode_id: str
|
||||
status: Literal["success", "partial", "failed"]
|
||||
final_docx_path: Optional[Path]
|
||||
diff_report_path: Optional[Path]
|
||||
needs_review_json_path: Optional[Path]
|
||||
errors: List[str]
|
||||
stage_timings: Dict[str, float] # 哪个 phase 用了多久
|
||||
```
|
||||
|
||||
```bash
|
||||
# CLI 等价形式
|
||||
doco process \
|
||||
--episode-id ep023 \
|
||||
--input-video /path/to/video.mp4 \
|
||||
--input-a-draft /path/to/a_draft.docx \
|
||||
--output-dir /path/to/output \
|
||||
--cleanup-level medium
|
||||
```
|
||||
|
||||
**关于 23 期推进**:**先单期跑通再批量**——拿 demo 那期《现代防空反导大对决》视频做 golden test(P4),与 demo 已有产物比对零回归,再扩到 23 期。一次性 batch 23 期风险太大。
|
||||
|
||||
未来主 project 若开节目素材批量处理编排层,**会反过来调 doco 的单期接口**,不会改 doco。
|
||||
|
||||
---
|
||||
|
||||
## Q4. 讯飞密钥管理 — 调整方案:自管 + Inventory 登记
|
||||
|
||||
### 主 project 现状
|
||||
- **没有中台密钥管理子模块**(已确认),也不在 dev_plan 排期内。
|
||||
- 主 project 凭证都在 `backend/.env`,各模块走环境变量。
|
||||
|
||||
### 批复
|
||||
|
||||
不走子项目推荐的"申请新凭证 + 写入中台密钥资产文档"(因为中台密钥服务不存在,不能凭空捏一个)。改为:
|
||||
|
||||
**1. Doco 自管凭证。** 讯飞、DeepSeek 各自的 API key 放 doco 自己的 `.env`,**不放进主 project 的 `backend/.env`**——保持子模块自治。
|
||||
|
||||
**2. 主 project 仓库根目录新增一份登记文档:`docs/api_credentials_inventory.md`**
|
||||
|
||||
这份文档:
|
||||
- **不存储真实凭证**(那些在各自子模块的 .env 里)
|
||||
- 只存储**元信息**:每个外部 API 用了什么、所属子模块是谁、开通时间、激活状态、到期日、续费责任人
|
||||
- 子模块申请新 key、key 到期更换,都更新这份文档
|
||||
- 这是主 project 帮所有子模块做"凭证清单"的最小落地——比起"中台密钥服务",轻得多,但解决"忘了谁管哪把 key"的问题
|
||||
|
||||
**3. Inventory 文档的字段**(供子项目和未来其他子模块参考):
|
||||
|
||||
```markdown
|
||||
| 子模块 | API 服务 | Key 类型 | 开通日 | 激活状态 | 到期日 | 责任人 | 备注 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| doco | 讯飞开放平台 - 录音文件转写 | APP_ID + SECRET_KEY | 2026-06-12 | 已激活 5h 试用包 | 2027-06-12 | 制片人 | demo 凭证已过期,新申请 |
|
||||
| doco | DeepSeek Vision | API_KEY | 2026-06-12 | 已激活 | — | 制片人 | doco OCR 用 |
|
||||
| (主) | Anthropic Claude API | API_KEY | ... | ... | ... | ... | AI 融合层用 |
|
||||
```
|
||||
|
||||
**4. 制片人现在要做的事**(代答 Q4 里"新申请的讯飞开发端密钥应该登记在哪里"):
|
||||
- 去讯飞开放平台 console 申请新的开发端凭证
|
||||
- 走 0 元购买流程激活 5 小时免费试用包
|
||||
- 把 APP_ID / SECRET_KEY 写到 doco 的 .env 里
|
||||
- 在 `docs/api_credentials_inventory.md` 登记一行
|
||||
|
||||
---
|
||||
|
||||
## Q5. 目录结构与命名规约 — 批准草案,episode_id 命名由主项目定
|
||||
|
||||
### 主 project 现状
|
||||
- **没有节目素材目录的统一规约**(已确认)。主 project 处理的是数据维度的 `episodes` 表,episode_id 是 INT 自增主键。
|
||||
- 但是,**素材文件名跟数据库 ID 是两层东西**,不能直接套。
|
||||
|
||||
### 批复
|
||||
|
||||
**子项目提的 `programs/{episode_id}/source|work|output/...` 结构批准。**
|
||||
|
||||
**关于 episode_id 命名规则**——这是主项目要定的规约,定如下:
|
||||
|
||||
**episode_id 格式:`ep{NNN}_{YYYYMMDD}_{slug}`**
|
||||
|
||||
- `ep{NNN}` = episodes 表自增 INT 主键,零填充到 3 位(如 ep023)
|
||||
- `{YYYYMMDD}` = 首播日期
|
||||
- `{slug}` = 节目名称的拼音缩写或简称中文(无空格、无特殊字符)
|
||||
|
||||
举例:
|
||||
- `ep023_20260612_haishang_xianfeng`
|
||||
- `ep007_20260201_马年军事图鉴`
|
||||
|
||||
**理由**:
|
||||
- INT 主键稳定可关联到 episodes 表
|
||||
- 日期方便文件系统按时间排序
|
||||
- slug 让人眼可读
|
||||
|
||||
**约定**:
|
||||
- episode_id **由调用方给定**(主项目编排层 / 责编 / CLI 调用者),doco 不生成
|
||||
- doco 只把它当一个字符串使用
|
||||
- 主项目责编/编排层在调 doco 前**先在 episodes 表落库该期、拿到 INT ID**,再拼出 episode_id
|
||||
|
||||
**work/ 中间产物保留时长**:
|
||||
- 节目入档案库后保留 **30 天**,然后可清理(由编排层负责,doco 不管)
|
||||
- 出问题需要复查时,30 天窗口够定位
|
||||
|
||||
---
|
||||
|
||||
## §5 第 3 条:23 期是常态化吗?
|
||||
|
||||
**这是产品问题,不是技术问题。我代制片人答不了。**
|
||||
|
||||
**建议子项目的处理**:
|
||||
- 按"23 期一次性"开干,先把这批做完
|
||||
- 算法层零侵入是硬保证,即使将来变常态化,流水线也能继续跑
|
||||
- **保留旧的 mp3+独立 OCR 流程作为回退路径**(代码不删,加 feature flag 或环境变量切换)。万一某期视频不符合"黑底白字+干净人声"特殊条件,降级到旧流程
|
||||
- 23 期完成 + 制片人跟栏目组确认后,再决定是否清理回退路径
|
||||
|
||||
---
|
||||
|
||||
## 子项目可以启动的部分
|
||||
|
||||
按 PRD v2 §七 的回复期望:
|
||||
- ✅ **Q1 已答**(DeepSeek API + 附加条件) → P1 可开始
|
||||
- ✅ **Q2 已答**(subprocess + 不引入 wrapper)→ P1 可开始
|
||||
- ✅ **Q3 已答**(单期 + 契约) → P5 推进时按契约
|
||||
- ✅ **Q4 已答**(自管 + inventory 登记) → 制片人先申请讯飞新凭证 + 建 inventory,P2 可开始
|
||||
- ✅ **Q5 已答**(目录草案批准 + episode_id 规则) → P1 输出有处可放
|
||||
|
||||
**Doco 子项目现在可以出 PRD v3,启动 P1。**
|
||||
|
||||
---
|
||||
|
||||
## 顺便给子项目的两条提醒
|
||||
|
||||
1. **demo 的 5 份 fixture 必须进 git**(transcripts / A 稿 / B 稿 / ASR / 终版 / 差异报告),作为单元测试 + golden test 黄金对照。这件事属于 Doco 内部自治,主项目不管,但提醒一下。
|
||||
2. **AI 融合层模型选 Sonnet 4.6**(PRD v2 §二 已锁),不要在子项目里临时换成别的模型。主项目这边也不会推翻这个选择。
|
||||
|
||||
---
|
||||
|
||||
*主 project 顾问(Claude Opus 4.7)签发,2026-06-12*
|
||||
Reference in New Issue
Block a user