Files
tps-dashboard/doco/CLAUDE.md
T

145 lines
13 KiB
Markdown
Raw Normal View History

# 项目协作主控文件 (doco/CLAUDE.md)
<!--
Claude Code 每次开 session 自动读取。两个角色:
1. 给 AI 的项目说明书(项目是什么、用什么、怎么跑)
2. 双账号/多工具之间的"活快照"交接区(现在到哪了、下一步、刚做的决定)
维护原则:增量更新,不要整篇重写。改动写进对应小节即可。
3. 每次结束session或通哥明确说结束今天的工作,应由Claude修改更新本文件,交接备注和待确认等部分内容应为最新。
-->
---
## 🔖 状态栏 (STATUS — 每次结束 session 前必须更新这三行)
- **最后更新**:账号A 2026-06-17
- **当前状态一句话**:P3-C2 讯飞 ASR 跑通并收口(真转写《现代防空反导大对决》27分钟→310句带时间戳,热词命中良好);**下一步进 C3,但卡在 B稿_v2.txt 未就位**。
- **下一个动手的人从这里开始**:见下方「⏩ 交接备注」
---
## 🤖 给 AI 的工作约定 (READ FIRST)
- 开始任何工作前,先读完本文件,特别是「状态栏」「交接备注」「关键决策」三节。
- 完成一段工作后**增量更新**:「已完成」追加一条、「待办」勾掉或新增、必要时更新「关键决策」,最后改「状态栏」三行。不要重写整份文件,不要删历史,只追加/勾选。
- 涉及发送、发布、删除、改权限、付款等不可逆操作前,先在对话里跟通哥确认。
- **本文件与项目设计文档并列,构成 doco 子项目宪法。冲突时优先级:本文件 STATUS/交接 > `doco_P3续接快照_C1完工C2起步.md` > `doco_P3_设计稿.md` > `doco_project_design.md`(越新越权威,尤其"LLM 提供方"那条以快照为准)。** 新对话接手时连同上述文档一并阅读。
------
**Claude(Opus 高级技术顾问)与制片人刘通协作原则**
1. 全程使用简体中文。
2. 通哥不懂代码编程,解释要简明扼要,说人话,不堆术语。
3. 为了节省Claude的Token,你主要的工作是plan和审核cline的报告,除非cline3次及以上修改过不去的坎,你可以直接动手改代码。
4. 给 Cline 的指令一律用代码块封装,并明确标 ACT / Plan,方便复制。
5. 回复简明扼要,不解释太多中间过程;**独立核验 Cline 自报结果,对着源数据查证,不轻信口头诊断**(本项目已多次靠核验抓到 Cline 偷换模型/术语源、误判字数)。
6. 长批处理(OCR/ASR)放独立终端跑,不要让 Cline 盯。
7. git 直接推 main,不开分支。
---
## 1. 项目概览
- **项目名**:doco 文稿整理模块(《军事科技》TPS 工作台子模块)
- **目标**:把 **A稿(编导定稿)+ B稿v2(屏幕字幕,P2 产出 743 行)+ ASR(口语实况)** 三方交叉融合,产出两个内容一致、形态不同的交付物:
- **融合B稿**(给爱德华):碎句 + 密集字幕级时间戳 `[XmYs] 文本`
- **融合A稿**(给编导):公文格式 docx,保留【导视】【主持人N】【解说N】【专家N】【隔断】分段
- 一致性约束:融合A稿**由融合B稿生成**(按 A 稿分段归拢 + 套格式),不是事后比对硬凑。
- **范围边界(别越界去做)**:本模块只做"三方文本 → 终版"。**不做** OCR 识别(P2 已产出 B稿v2)、**不做**音频转码本身(属 ASR 适配层)、**不做**档案入库、**不做**编导确认 UI。
---
## 2. 技术栈与运行方式
- **语言**Pythonopenai SDK 走 DeepSeek 兼容端、ffmpeg、python-docx
- **关键目录**
- `src/doco/llm.py` — DeepSeek 统一客户端,`chat(messages, model=None, thinking=None, max_tokens=...)`,从 `doco/.env` 读 key/base_url/model
- `src/doco/term_extract.py` — C1:规则层 + AI 层提取 + 词典累积 + 热词清洗
- `src/doco/asr_adapter.py` — C2 讯飞 ASR 适配层(已完工):`get_hot_words(episode_id)` 读热词表、`transcribe()` 返回 `(句子, raw)``write_asr_result()``asr_v2_timed.txt` + `asr_result_raw.json`
- `src/doco/video_split.py` — P1:含 `extract_audio()`16kHz/单声道/16bit WAV),C2 直接复用,不另写 ffmpeg
- `src/doco/cli.py` — 命令入口(split / terms / asr
- `doco/data/term_dict.json` — 累积词典(当前 110 条)
- `doco/programs/<episode_id>/` — 每期产物(热词表、各阶段输出)
- **常用命令**
- C1(已实现):`doco terms --episode-id <id> --a-script <path> [--no-ai]`
- C2(已实现):`doco asr --episode-id <id> --input-video <绝对路径mp4> --output-dir <绝对路径 doco/programs/<id>>``--skip-asr` 只分离不转写)。**务必传绝对 `--output-dir`,否则落到当前工作目录的 `programs/` 会与 doco 产物分家。**
- C3/C4:待实现
- **环境变量 / 密钥**:只放 `doco/.env`(已在 `.gitignore`)。需要的 key`DEEPSEEK_API_KEY` / `DEEPSEEK_BASE_URL` / `DEEPSEEK_MODEL``XFYUN_APP_ID` / `XFYUN_SECRET_KEY`。**代码与对话里只引用变量名,绝不出现真值。**
---
## 3. 当前进度(核心交接区,以最新快照为准)
- **正在做**:C2 已收口,准备进 C3(B稿v2 ⊕ ASR 交叉复审)。
- **卡点 / 待解****C3 输入 `B稿_v2.txt`743行)不在 `doco/programs/ep001_.../` 内,doco 子项目内全盘搜不到** —— P2 产出但未拷进 episode 目录。C3 开工前通哥需把它放进 `doco/programs/ep001_20260612_fangkong_fandao/`
---
## 4. 已完成(只追加,最新在最上)
- [2026-06-17 |账号A] **P3-C2 收口**:密钥外置三验收点全过(硬编码已删/读 .env/已 gitignore+ 旧 key 已轮换;`asr_adapter.py` 并入讯飞上传·轮询·解析,复用 P1 `extract_audio` 分离 16kHz/单声道/16bit WAV;新增 `doco asr` 命令读 C1 64条热词。**真转写《现代防空反导大对决》27分钟音频 → 310句带时间戳**,萨德×6/塔米尔/爱国者/箭二箭三/见证者等术语命中良好,raw json 730KB 落盘。(顺带修 `extract_audio` 在 Windows 的 `text=True` 解码崩溃。)
- [2026-06-16 |账号A] **P3-C1 收口**A稿→规则+DeepSeek AI 提取→累积词典110条→热词清洗→本期热词表64条;AI 44 候选已逐个回查 A 稿原文无幻觉,算术对账一致。
- [P2 |本轮之前] 本地 OCRDeepSeek-OCR/Ollama+ 扒词流水线,产出 **B稿_v2.txt 743 行**
- [P1 |本轮之前] 帧筛流水线完工。
---
## 5. 待办(按优先级,做完打勾)
- [ ] **C3(下一步,先解卡点)**:B稿v2 ⊕ 新ASR 交叉复审 → 融合B稿(保持743行碎句粒度 + 密集时间戳原样,ASR只复审纠错不改行结构)+ `fusion_review.csv`。**前置:把 `B稿_v2.txt`743行)放进 `doco/programs/ep001_.../`。**
- [ ] **C4**:融合B稿 + A稿语义对齐 → 融合A稿(公文 docx,用 docx skillGB/T 9704 格式)。
- [x] **C2** 讯飞 ASR 适配层(密钥外置 + asr_adapter 并入 + `doco asr` 命令 + 真转写310句)
- [x] P3-C1 术语提取 + 词典 + 热词表
- [x] P2 本地 OCR + B稿v2
- [x] P1 帧筛
---
## 6. 关键决策(为什么这么做 — 跨 session 最易丢,别推翻)
- [2026-06-17] **C2 音频分离复用 P1 `video_split.extract_audio()`,不另写 ffmpeg。** WAV 落 `programs/<episode>/audio_16k.wav`,已存在则复用(避免 1GB 视频重复解码)。实测产物 `pcm_s16le/16000Hz/1ch/16bit/1620s`,符合讯飞硬要求。
- [2026-06-17] **`doco asr` 不传 `--output-dir` 会落到当前工作目录的 `programs/`**(命令在 repo 根 `E:\tps-dashboard` 跑时尤其坑),与 doco 产物分家。**命令一律用绝对 `--input-video` + 绝对 `--output-dir`。**
- [2026-06-17] **ASR 输出是口语形态,型号不规范属正常**(如「箭二箭三」非「箭-3」、「高超音速/高超声速」混用)。按设计稿口语信 ASR、型号规范信 A/B 稿,**这些归一交给 C3,别回头改 C2**。
- [2026-06-16] **AI 融合层 LLM = DeepSeek v4-pro,不是 Claude。** 制片机无 Anthropic keyDeepSeek key 现成。接入:OpenAI 兼容,`base_url=https://api.deepseek.com``/chat/completions`、模型名走 `DEEPSEEK_MODEL=deepseek-v4-pro`。C1、C4 都用它。**(此条覆盖 `doco_P3_设计稿.md` 里写的 Claude API。)**
- [2026-06-16] **抽取类任务必须关 thinking。** DeepSeek V4 默认开 thinking,不关则正文 `content` 为空(已踩坑)。做法:`chat(..., thinking=False)``extra_body={"thinking":{"type":"disabled"}}`,给足 `max_tokens`C1 用 4000)。**C4 语义融合可开 thinking**(单轮调用,质量优先)。
- [2026-06-16] **旧模型名 `deepseek-chat`/`deepseek-reasoner` 禁用**2026-07-24 退役且现指向 flash)。只认 `deepseek-v4-pro`。Cline 曾擅自退回 deepseek-chat,已纠正。
- [2026-06-16] **C1 术语源 = A稿(规范写法),不是 B稿。** Cline 曾擅自换成 B稿v2,已纠正。
- [2026-06-15] **讯飞用「录音文件转写标准版」,不要大模型版**(免费包阉割 `language` 参数,会报误导性 `language verify fail`)。参数锁定:`pd=mil``eng_smoothproc=true``eng_colloqproc=true``hotWord=<C1热词>``language=cn`。签名 `signa=base64(HmacSHA1(MD5(appid+ts), secretKey))``/upload` 拿 orderId,轮询 `/getResult` 到 status=4。
- [2026-06-15] **B稿v2 权威升级**:屏幕术语/型号/番号 **B稿v2 ≈ A稿 并列权威**(B稿是屏幕实打的字,更贴近播出)。口语/语序/语气信 ASR;书面结构/分段信 A稿;同音事实错(美以→美伊)用 A稿/B稿v2 覆盖 ASR。
- [设计期] **分层不变**:OCR 错字纠正、术语统一、时间戳对齐走**规则层**(确定性);段落归属、整段删除判定、编导笔误识别走 **AI 层**(需语义判断)。
- [设计期] **顺序约束**:术语提取(C1,产热词)必须在 ASR(C2)之前——已成立。
- [工程纪律] 各阶段解耦、中间产物落缓存、可断点续跑、可单独重跑;长批处理放独立终端。
---
## 7. ⏩ 交接备注(写给下一个接手的 session)
> 下次开工读完这段应能 0 摩擦续上。接手后可清空重写。
- **第一句话该干的**:C2 已收口。进 C3 前**先确认 `B稿_v2.txt`743行)已就位**于 `doco/programs/ep001_20260612_fangkong_fandao/`——目前不在,是硬卡点,没它 C3 开不了工。
- **C3 输入已就位的部分**:同目录下 `asr_v2_timed.txt`310句带 `[XmYs]` 时间戳,C2 新产)、`本期热词表.txt`、A稿 docx。缺的就是 B稿v2。
- **C3 目标**B稿v2 ⊕ asr_v2_timed 交叉复审 → 融合B稿(**保持 743 行碎句 + 密集时间戳原样,ASR 只复审纠错不改行结构**)+ `fusion_review.csv`。权威优先级见关键决策「B稿v2 权威升级」那条。
- **重跑真转写命令**(复用已分离 WAV,27分钟音频讯飞轮询等几分钟别中断):
`doco asr --episode-id ep001_20260612_fangkong_fandao --input-video "E:\tps-dashboard\doco\programs\ep001_20260612_fangkong_fandao\现代防空反导大对决VA0.mp4" --output-dir "E:\tps-dashboard\doco\programs\ep001_20260612_fangkong_fandao"`
- 通哥连轴转了几轮,回复要紧凑。
- **已知坑(务必记住)**
1. **A稿真实约 65007300 汉字**(栏目常态 60008000),**不是 2.2 万**——那是用 `wc -m` 把 UTF-8 字节当字数的乌龙(一个汉字 3 字节)。docx 无文本框无表格,`python-docx` 提取的 ~7.5k 字符就是全文。
2. **A稿分段编号有坑**:解说2/解说10 各出现两次、主持人4/5 带空格、专家1–8 齐全。分段对齐**别假设编号单调或唯一,按出现顺序走**(顾问曾误说"跳6号",作废)。
3. Cline 会偷换模型/术语源、误判字数——**自报结果一律对源数据核验**。
- **C1 已知小尾巴(评估后不修,无害)**:热词条数报告 64、顾问数 65,差 1,远在 200 上限内;几对技术前缀未合并(光学红外/红外、诱饵弹前缀等),再收敛有过度合并风险,故止步。
- **C4 字体坑**:大标题用方正小标宋(商业字体),出稿前确认制片机/编导机已装,否则脚本里配回退(标宋→宋体加粗)。
---
## 8. 待确认 / 开放问题(需通哥拍板,AI 别自行假设)
- **B稿_v2.txt 就位**(C3 硬卡点):需通哥把 P2 产出的 `B稿_v2.txt`743行)拷进 `doco/programs/ep001_20260612_fangkong_fandao/`。当前 doco 子项目内搜不到。
- ~~**讯飞旧 key 轮换**~~:已完成(新值已在 `doco/.env`,旧 appid `84eff996` 代码内无残留)。
- **方正小标宋字体可用性**:C4 出稿前确认两台机器是否已装。
- **OCR 并发提速**(P2 遗留):`OLLAMA_NUM_PARALLEL` 4–8 路,预计把 ~30 分钟压到十分钟出头;**correctness 全部验证后再做**,现在不动。
- **讯飞单源依赖**(远期):是否接阿里云 ASR 做备份/交叉验证。