Files
cat-shark 5b263171f2 docs: 归档翻译上下文/字幕审校方案的评审结论与实测数据
- 待办:会话式长上下文方案标记为已技术评审且不实施;补记问题 A 的阶段性结论(暂缓)
- 新增 docs/实验数据-字幕审校定位与修复实验.md:LLM 定位触发率/召回、合成正样本、逐条修复前后对照、成本与复现方式
- 新增 docs/实验数据-字幕重生成成本与耗时.md:单价口径、功率画像、全量推算
- decisions:补充两条决策(会话式长上下文否决、审校定位+定向修复暂缓)
- scripts:归档一次性探测脚本 probe_subtitle_review_stage0.py(含 rebuild 子步骤)
- AGENTS/README:补充实验与改动许可规则、文档索引
2026-09-19 18:33:28 +08:00

15 KiB
Raw Permalink Blame History

AGENTS.md — VRSub 协作规则

本文件只写对 AI 编码代理的要求(行为规则、流程约束、执行环境)。 项目信息(架构是什么、有哪些节点、怎么配置)不写在这里,按需阅读:

想了解 阅读
项目定位、快速开始、目录结构、文档导航 README.md
架构、核心机制、北极星不变式、单体化说明 docs/architecture.md
节点输入输出协议、模型权重解析、长音频、OCR 并发 docs/node-protocol.md
内置工作流、参数标注约定、切换模型、产物命名 docs/workflows.md
环境变量全表、启动方式、uv 依赖管理 docs/configuration.md
批量处理、暂停/继续、孤儿清理、进度日志 docs/operations.md
测试资产清单、真实模型集成测试 docs/testing.md
设计决策与踩坑记录(含实验结论) docs/decisions.md
代码缺陷跟踪与修复验收标准 docs/代码审查问题跟踪.md
待办:翻译上下文复用与 ASR 语义纠错 docs/待办-翻译上下文复用与语义纠错.md
字幕重生成的成本/耗时/功率实测 docs/实验数据-字幕重生成成本与耗时.md
字幕审校(定位+定向修复)实验与暂缓结论 docs/实验数据-字幕审校定位与修复实验.md

开工前先做两件事:读 README.md 建立项目认知, 再读 docs/architecture.md 确认不能破坏的硬约束。

提交规则(强制,2026-08

  • 未经用户明确许可,禁止执行 git commit / git push,包括"小步提交"。
  • 完成改动后只汇报改动内容与验证结果,等待用户指示;用户明确说出 "提交 / push / 推上去" 等指令时才可执行提交。
  • 需要用户确认的场景:新增功能、修复、文档改动、工作流/清单数据改动等 一切涉及 git 写操作的行为。

等待规则(强制,2026-09

  • 单次等待时间不得超过 10 秒。需要长时间运行时,把它放到后台 setsid ... & / nohup ... &)写日志,然后每 10 秒轮询一次结果 for i in $(seq 1 6); do sleep 10; ...; done),而不是用一个长 sleep 或长 timeout 把用户的对话阻塞住。
  • 反例(禁止):sleep 600timeout 1800 uv run pytest——即使命令本身 很快,把 timeout 设成 30 分钟也是错的:它无法预判耗时,只会在出问题时 让用户白等半小时。应当先用 10 秒轮询确认它是否结束。
  • 正例:把任务丢后台 → for i in $(seq 1 N); do sleep 10; <检查是否完成 && break>; done 耗时任务写日志到 data/experiments/...,事后读日志汇报。
  • 测试与构建也遵循此规则:已知 uv run pytest 全量约 70 秒,用后台+轮询, 不要写 timeout 1800

实验与改动许可(强制,2026-09

  • 未经用户明确许可,禁止编写或修改任何代码(含 scripts/nodes/src/tests/ 以及 /tmp 等目录下的临时脚本)——单次性实验脚本同样属于此列
  • 未经用户明确许可,禁止编写/运行实验:包括跑数据集、调用模型或 LLM API 做 效果验证、调节参数试探、批量重跑等。先说明「要验证什么、打算怎么做、预计代价」, 等用户同意后再执行。
  • 只读排查不受限:读文件、rg/ls/statgit status|log|diff、查看服务与日志、 查询数据库。需要写文件、改代码、跑实验时,一律先请求许可。
  • 一次许可只对当次明确范围生效,不自动延伸到后续实验、相邻改动或“顺手修一下”。

开发流程:TDD(红-绿-重构)

  • 任何新功能/修复必须先写失败测试(红),再实现最小代码让其通过(绿), 最后重构保持整洁;不允许先写实现后补测试。
  • 小改动只跑相关测试,避免每次都完整跑全量测试;改动影响面大时才跑全量。
  • 测试运行方式与资产说明见 docs/testing.md

测试规则

模块的边界

「模块」指由独立功能、在程序运行时会真实被使用到的代码块构成的代码上下文: 它可独立运行,也可和其他代码上下文组合运行。 例如 nodes/whisper.pynodes/llm_filter.pysrc/wov_app/batch.pysrc/wov_sdk/models.py 各是一个模块;nodes/subtitle_ocr.py 与其 nodes/adaptive_pool.py 是两个模块(后者可独立使用)。

按模块组织测试代码

  • 测试代码必须按模块编写:一个模块对应测试目录下的一个模块目录, 不得把同一模块的测试拆成多个互不相干的平铺文件。
  • 单文件过长时,在同一模块目录内拆成多个文件(按行为分组,如 test_rules.py / test_llm_layer.py),而不是拆到模块目录之外。
  • 目录布局固定为 tests/<层级>/<模块>/<层级> 对应被测代码位置 nodes/tests/nodes/src/wov_app/tests/app/ src/wov_sdk/tests/sdk/),模块目录名即模块名。
  • 每个模块目录必须有 __init__.py,保证不同模块目录下的同名测试文件可共存。
  • 具体目录示例见 docs/testing.md

数据 / 测试过程 / 验证结果

  • 每个测试必须写成数据 → 测试过程 → 验证结果三段结构:先准备输入数据, 再调用真实生产代码,最后断言输出结果;顺序清晰、一读即懂。
  • 测试必须可独立运行:单个测试文件或单个模块目录被单独执行时结果不变。 不依赖全局 conftest.py(不保留全局 conftest,不依赖仓库其他测试的 配置、执行顺序或共享状态。
  • 数据与产物目录就是测试代码所在目录:模块专用数据(JSON/期望输出等) 写在测试代码内的常量或模块目录下;视频、音频等无法写进代码的大体积素材, 放同一个模块目录内(如 data/)与其他测试区分,不使用仓库根级中央数据目录。
  • 测试过程必须调用真实的生产代码(导入 nodes/wov_appwov_sdk 的真实实现),我们只构建测试数据、验证输出结果; 不得在测试里重写业务逻辑来模拟被测功能,也不得用伪造结构冒充被测数据。
  • 需要磁盘或环境隔离时,由模块自己的 fixture(模块目录下的 conftest.py 或测试文件内部)创建临时目录并设置变量,不依赖外部预先存在的配置。

功能覆盖优先,不追求代码覆盖率

  • 不追求测试的代码覆盖率 100%,追求功能性代码覆盖率 100%
  • 一个大模块的功能正常,就无须对这个大模块中的辅助函数单独测试: 私有工具函数、内部转换、仅供主流程调用的分支,由主功能用例顺带覆盖即可, 不为了凑行覆盖率给辅助函数补无意义用例
  • 每个独立功能模块必须被测试覆盖(即上文“模块的边界”中定义的模块), 不得出现“完全无测试的模块”。模块清单与当前覆盖状态见 docs/testing.md
  • 新增独立功能模块时,必须同时补上覆盖其功能的测试,并同步更新上述清单; 只写生产代码不补测试的改动视为未完成。

测试质量与运行

  • 测试以保证功能可用为目标,不强制 100% 行覆盖率pytest 已移除 --cov-fail-under=100 门槛);需要查看覆盖率时可手动追加 uv run pytest --cov=src --cov=nodes
  • 测试必须使用真实数据:真实音频(合法 WAV/PCM)、真实 JSON/数据库/文件; 禁止用占位字节(如 b"x")或伪造结构冒充被测数据——假数据测试只能凑覆盖率, 无法验证真实行为,视为无意义测试。
  • 只允许在 I/O 边界使用 mock/stub:文件系统、网络、子进程、环境变量、时间、 模型推理(重模型不进入单元测试;注入的假模型必须返回结构真实的分段)。
  • 真实模型集成测试必须配套:真实 faster-whisper 模型 + 真实音频素材验证 端到端转写,本地缺模型/素材时跳过,有则必须执行(清单见 docs/testing.md)。
  • 测试素材必须一次性准备后随模块目录入库(放模块目录内),禁止在测试执行时 现场生成;缺失时跳过而非生成。
  • 外部环境状态缺失时应跳过而不是判失败:未配置的密钥、账户余额/配额、 限流、模型/服务不可达、缺失的真实素材都属于环境状态,不是被测代码的行为; 这类用例用 pytest.skip() 并说明原因(如 pytest.mark.integration 用例)。 但代码抛异常、返回结构错误、断言不成立仍必须失败,不得用跳过掩盖回归。
  • 测试只保证代码路径被执行,不覆盖端口占用、防火墙、权限等外部环境状态; 端口问题用启动检查、端口检查与 uvicorn 冒烟测试补充。
  • 本地出现 WinError 10013 / WinError 10048 时,先用 netstat -ano | findstr :<port> 确认是否有残留监听进程。

代码注释规范

只写代码真实逻辑

  • 注释只回答两个问题:这段代码做什么为什么必须这么做(不这样写会出 什么错)。读代码的人需要的是当前逻辑,不是它的来历。
  • 禁止写进代码注释(这些属于 docs/decisions.mddocs/代码审查问题跟踪.md):
    • 修改/决策时间(“用户 2026-08 决定”、“2026-09 起”);
    • 历史版本对比(“旧版是 X,现在改为 Y”、“修复前……”);
    • 实测数据与实验结论(具体条数、耗时、模型名、实验目录);
    • 事故与缺陷编号(run_xxxxbatch_xxxx、R01/R02 等):改用一句 “否则会出现什么问题” 描述后果即可;
    • 变更原因的长篇叙述、将来计划、TODO 式背景;需要时在 docs 记录并链接。
  • 例外:当前生效的约束可以写(如“默认 60 秒一块,切块失败回退整段”), 但不能附带它何时、因何改为如此。

精简可读

  • 单段连续注释不超过 3 行(含行)。超过说明它很可能在讲历史或设计辩论, 应压缩为 1~3 行;确实需要展开的写进 docs/ 并在此链接一句。
  • 函数/类 docstring 用一句话概括职责,必要时补 1~2 句关键行为或参数语义; 不重复函数名已表达的信息(def parse_srt 不必再写“解析 SRT”)。
  • 不写“废话注释”:逐行翻译代码、# 返回结果# 循环处理 这类无信息量的 句子;只在非显然处加注释(业务规则、边界、易错点、外部约束)。
  • 中文说明,术语与代码标识符保持英文;保持注释与代码同步,改代码必须 同步改注释(不留过期注释),但不要为了“补充说明”把注释越写越长

覆盖范围

  • 模块/文件职责、公开类与函数的职责与非显然行为必须有注释;私有工具函数 仅在逻辑非显然时加简注。
  • 测试代码同样配中文注释,但只说明验证什么行为(一句话),不重复测试 步骤的机械描述。例外:回归用例可保留简要的溯源(如"曾因 XX 导致 时间轴错位"一句),因为它解释了"为什么必须有这条用例";但仍不写长叙事、 不贴大段实测数据,详细经过放 docs/decisions.md
  • JSON 数据文件(如 manifests/*.jsonworkflows/*.json)按 JSON 规范不支持 注释,字段语义以 src/wov_sdk/models.py 的模型注释和 docs/ 文档为准; 修改 JSON 字段时须同步更新文档。

目标运行环境

  • 本服务的最终部署目标是 Linux,通常以 Docker/Kubernetes 容器运行。
  • 当前 Windows 只作为本地开发环境,不允许在业务代码中写死 Windows 路径、 盘符或 Windows 专用命令。
  • 路径处理统一使用 pathlib
  • ffmpeg 在 Linux 上可使用系统包,也允许通过 imageio-ffmpeg 使用内置 二进制,节点代码不能假设 ffmpeg 一定在 PATH。
  • 测试必须可以在 Windows 和 Linux 上运行;涉及平台分支的代码应同时覆盖 两种路径解析。

Windows / PowerShell 执行规则

  • 默认 shell 视为 Windows PowerShell 5.1;不要假设 Bash、zsh 或 PowerShell 7。 必要时先查 $PSVersionTable.PSVersion
  • 禁止把 Bash 语法交给 PowerShellpython - <<'PY'cat <<EOFexportsourcerm -rf、Bash 后台 & 等。
  • PowerShell 中 & 是调用运算符;URL 或参数含 & 时整体单引号引用。
  • 避免 PowerShell 5.1 下使用 Bash 风格 && / ||;顺序步骤用多行 PowerShell。
  • 参数含空格、括号、中文、&|;><$ 或引号时默认用单引号。
  • 外部程序路径可能有空格时,用 & 'C:\path with spaces\tool.exe' arg1
  • 文件操作优先 PowerShell 原生命令和 -LiteralPath
  • 复杂 Python 不用 python -c;涉及 SQL、JSON、中文、反斜杠、换行或 多层引号时,用仓库脚本或临时 .py 文件。
  • 禁止在 PowerShell 用 Bash here-doc。临时传 Python 源码只允许 PowerShell here-string,且尽量保持 ASCII。
  • Python 源码含中文常量时,不通过 PowerShell 管道传给 python -;用 UTF-8 脚本文件、仓库脚本或 \uXXXX
  • 搜索文本/文件优先 rg / rg --files
  • 数据库或生产内容写操作前先查询当前数据;写入必须有明确筛选条件,禁止 无条件 DELETE / UPDATE
  • 同一 PowerShell 命令连续失败两次后,停止微调长命令;改短命令、脚本文件、 数组 splatting 或分步验证。

文档维护规则

  • 本文件只放对代理的要求。新增项目知识(架构、协议、参数默认值、运维语义、 实验结果)写进 README.mddocs/ 不得写进本文件。
  • 新增/移动文档时同步更新 README 的文档导航表与本文件顶部的索引表, 保证链接可达;文档中的相对链接指向真实文件。
  • 决策与踩坑("为什么这样做")写 docs/decisions.md 缺陷跟踪写 docs/代码审查问题跟踪.md, 专题文档只保留结论并链接过去,避免同一内容多处维护。