Files
vrsub/AGENTS.md
T
cat-shark 966f3e6b4b docs: AGENTS.md 只保留代理规则,项目信息迁入 README 与 docs/
把 AGENTS.md(545 行)中的项目知识按性质拆开,只留下对代理的要求:

- AGENTS.md(176 行)只写规则:读文档指引、提交许可、等待规则、TDD、
  测试规则(模块边界/三段结构/功能覆盖优先)、注释规范、目标运行环境、
  PowerShell 规则、文档维护规则;
- 项目信息新建 docs/ 专题:architecture、node-protocol、workflows、
  configuration、operations、testing、decisions;
- README 改为项目索引(定位、快速开始、文档导航、目录、工作流、结论摘要);
- 修正旧文档错误:README 的"详细约定见 AGENTS.md"与"100% 行覆盖率"
  (pytest 已移除该门槛);环境变量表补齐 WOV_AUTO_VAD 等 3 项。

新增 scripts/check_doc_links.py 校验相对链接与锚点,当前 14 个文档全部可达。
2026-09-13 15:40:31 +08:00

180 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md — VRSub 协作规则
本文件只写**对 AI 编码代理的要求**(行为规则、流程约束、执行环境)。
项目信息(架构是什么、有哪些节点、怎么配置)不写在这里,按需阅读:
| 想了解 | 阅读 |
| --- | --- |
| 项目定位、快速开始、目录结构、文档导航 | [README.md](./README.md) |
| 架构、核心机制、北极星不变式、单体化说明 | [docs/architecture.md](./docs/architecture.md) |
| 节点输入输出协议、模型权重解析、长音频、OCR 并发 | [docs/node-protocol.md](./docs/node-protocol.md) |
| 内置工作流、参数标注约定、切换模型、产物命名 | [docs/workflows.md](./docs/workflows.md) |
| 环境变量全表、启动方式、uv 依赖管理 | [docs/configuration.md](./docs/configuration.md) |
| 批量处理、暂停/继续、孤儿清理、进度日志 | [docs/operations.md](./docs/operations.md) |
| 测试资产清单、真实模型集成测试 | [docs/testing.md](./docs/testing.md) |
| 设计决策与踩坑记录(含实验结论) | [docs/decisions.md](./docs/decisions.md) |
| 代码缺陷跟踪与修复验收标准 | [docs/代码审查问题跟踪.md](./docs/代码审查问题跟踪.md) |
**开工前先做两件事**:读 [README.md](./README.md) 建立项目认知,
再读 [docs/architecture.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 600``timeout 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`
## 开发流程:TDD(红-绿-重构)
- 任何新功能/修复必须先写失败测试(红),再实现最小代码让其通过(绿),
最后重构保持整洁;不允许先写实现后补测试。
- 小改动只跑相关测试,避免每次都完整跑全量测试;改动影响面大时才跑全量。
- 测试运行方式与资产说明见 [docs/testing.md](./docs/testing.md)。
## 测试规则
### 模块的边界
「模块」指**由独立功能、在程序运行时会真实被使用到的代码块构成的代码上下文**:
它可独立运行,也可和其他代码上下文组合运行。
例如 `nodes/whisper.py``nodes/llm_filter.py``src/wov_app/batch.py`
`src/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](./docs/testing.md#目录结构与模块对应)。
### 数据 / 测试过程 / 验证结果
- 每个测试必须写成**数据 → 测试过程 → 验证结果**三段结构:先准备输入数据,
再调用真实生产代码,最后断言输出结果;顺序清晰、一读即懂。
- **测试必须可独立运行**:单个测试文件或单个模块目录被单独执行时结果不变。
**不依赖全局 `conftest.py`(不保留全局 conftest**,不依赖仓库其他测试的
配置、执行顺序或共享状态。
- **数据与产物目录就是测试代码所在目录**:模块专用数据(JSON/期望输出等)
写在测试代码内的常量或模块目录下;视频、音频等无法写进代码的大体积素材,
放**同一个模块目录内**(如 `data/`)与其他测试区分,不使用仓库根级中央数据目录。
- 测试过程**必须调用真实的生产代码**(导入 `nodes/``wov_app``wov_sdk`
的真实实现),我们只构建测试数据、验证输出结果;
不得在测试里重写业务逻辑来模拟被测功能,也不得用伪造结构冒充被测数据。
- 需要磁盘或环境隔离时,由**模块自己的 fixture**(模块目录下的 `conftest.py`
或测试文件内部)创建临时目录并设置变量,不依赖外部预先存在的配置。
### 功能覆盖优先,不追求代码覆盖率
- **不追求测试的代码覆盖率 100%,追求功能性代码覆盖率 100%**。
- 一个大模块的功能正常,就无须对这个大模块中的辅助函数单独测试:
私有工具函数、内部转换、仅供主流程调用的分支,由主功能用例顺带覆盖即可,
**不为了凑行覆盖率给辅助函数补无意义用例**
- 但**每个独立功能模块必须被测试覆盖**(即上文“模块的边界”中定义的模块),
不得出现“完全无测试的模块”。模块清单与当前覆盖状态见
[docs/testing.md](./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](./docs/testing.md#真实模型集成测试))。
- 测试素材必须**一次性准备后随模块目录入库**(放模块目录内),禁止在测试执行时
现场生成;缺失时跳过而非生成。
- **外部环境状态缺失时应跳过而不是判失败**:未配置的密钥、账户余额/配额、
限流、模型/服务不可达、缺失的真实素材都属于环境状态,不是被测代码的行为;
这类用例用 `pytest.skip()` 并说明原因(如 `pytest.mark.integration` 用例)。
但代码抛异常、返回结构错误、断言不成立仍必须失败,不得用跳过掩盖回归。
- 测试只保证代码路径被执行,不覆盖端口占用、防火墙、权限等外部环境状态;
端口问题用启动检查、端口检查与 uvicorn 冒烟测试补充。
- 本地出现 `WinError 10013` / `WinError 10048` 时,先用
`netstat -ano | findstr :<port>` 确认是否有残留监听进程。
## 代码注释规范
- 本仓库所有源码(Python、JavaScript、HTML、CSS、TOML 等支持注释的文件)
必须配有详细中文注释,说明模块/文件职责、核心类与函数的作用以及关键逻辑,
确保后续维护人员无需通读全部实现即可快速理解工作原理。
- 新增或修改代码时,必须同步补充或更新对应注释;不得删除已有注释。
- 测试代码同样必须配有中文注释,说明每条测试验证的行为与覆盖的路径。
- JSON 数据文件(如 `manifests/*.json``workflows/*.json`)按 JSON 规范不支持
注释,字段语义以 `src/wov_sdk/models.py` 的模型注释和 [docs/](./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 语法交给 PowerShell`python - <<'PY'``cat <<EOF``export`
`source``rm -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.md](./README.md) 或 [docs/](./docs/)
不得写进本文件。
- 新增/移动文档时同步更新 README 的文档导航表与本文件顶部的索引表,
保证链接可达;文档中的相对链接指向真实文件。
- 决策与踩坑("为什么这样做")写 [docs/decisions.md](./docs/decisions.md)
缺陷跟踪写 [docs/代码审查问题跟踪.md](./docs/代码审查问题跟踪.md)
专题文档只保留结论并链接过去,避免同一内容多处维护。