评审与验证
Agent 的产出速度会把评审变成新的瓶颈。评审者如果只扫一眼 diff 就批准,批准记录反而会制造虚假信心。一次变更能不能合并,应当看它留下了什么证据,而不是只看有没有人点过批准。
单条测试可信,不等于整次变更可以合并。合并前要组合三类证据:确定性检查给出可重复的结果,AI 评审查找遗漏和风险,人对机器无法判断的意图、取舍与实际行为负责。
14.1 三层验证与风险分档
三层验证各管一种问题,不能互相替代:
| 层 | 管什么 | 产出 | 失败后果 |
|---|---|---|---|
| 确定性检查 | 测试、构建、类型、lint、格式、密钥与安全扫描 | 命令、退出状态和报告 | 必需检查失败就停止 |
| AI 评审 | 规格是否落实、改动是否越界、有没有遗漏回归和安全风险 | 带证据的问题清单 | 每条意见都要处置 |
| 人工验收 | 需求取舍、风险接受、用户可见行为和高风险结果 | 验收结论与责任记录 | 未达到约定条件就不放行 |
确定性检查只能证明已检查的项目通过,不能证明实现整体正确。AI 评审能扩大检查范围,但会误报和漏报。人负责判断证据是否足够,以及剩余风险是否可以接受。
三层的使用强度跟着任务风险走:
| 任务情况 | 合并前的最低要求 |
|---|---|
| 低风险、容易回退 | 跑完适用的确定性检查,留下结果证据 |
| 改动跨模块、边界较多或回归影响较大 | 在确定性检查之外,增加一次独立 AI 评审 |
| 高风险、难回退或用户直接可见 | 增加人工验收;必要时再加一个独立评审方 |
这套分档约束的是最低强度。项目可以提高某类任务的要求,但不要让所有改动都机械地走最重流程。流程一旦过重,检查更容易被跳过,质量却未必提高。
一次变更通常按下面的顺序收口:
实现完成
→ 本地运行适用的确定性检查
→ 按风险做独立 AI 评审并处置意见
→ commit / push
→ CI 运行合并前必需检查
→ 处理测试、CI 配置和验收基线的变化
→ 按风险完成人工验收
→ 合并进主干
AI 评审可以在提交前进行,也可以在 PR 上进行。关键是评审对象明确,并且后续改动会触发相应的复查。格式化、修复评审意见或解决冲突后,原来的评审结论不能自动覆盖新版本。
能由机器判断的规则,如果没有接进本地检查或 CI,就只是提醒。例如”测试必须通过”需要实际运行测试并阻止失败版本合并。架构取舍和风险接受无法改写成简单命令,仍由评审和人工验收处理。
14.2 本地检查与独立评审
本地检查用于尽早发现修复成本较低的问题。项目应当写清需要运行哪些命令,而不是统一规定所有仓库使用同一套工具。格式、lint、类型检查和变更相关的测试适合在送审前运行;耗时较长的完整测试可以留给 CI,但实现阶段仍要运行与本次改动直接相关的部分。
Git 提交钩子可以减少遗漏,却不能充当最终边界。钩子需要在每个克隆仓库里单独安装,也可以被跳过。合并前真正必须执行的检查还要在 CI 中重跑。
会改写文件的格式化工具应在评审前运行。不要为了评审一次局部改动而顺手格式化全仓库;无关变化会淹没真正的 diff。全仓整理应当单独立项。
独立 AI 评审至少满足两个条件:使用不继承实现过程的新上下文,评审方只读取代码和材料,不直接修改工作区。换模型可以增加视角,但不是独立性的必要条件;更换账号或凭据也不会自动带来独立判断。
送审材料要足够让评审方判断这次改动,而不是让它漫无目的地浏览整个仓库:
| 材料 | 评审时回答的问题 |
|---|---|
| 意图、验收条件与不可改范围 | 改动是否解决了正确的问题 |
| 当前 diff 与受影响的调用链 | 有没有越界或破坏相邻行为 |
| 项目规则与安全基线 | 有没有违反必须遵守的约束 |
| 测试基线与实际运行结果 | 验收证据有没有缺失或被削弱 |
评审先检查规格和验收条件,再检查正确性、回归与安全风险,最后处理可维护性问题。每条意见应包含严重程度、文件位置、成立依据和建议动作,不能只写”这里可能有问题”。
意见按三档处理:
| 等级 | 处置 |
|---|---|
| 阻断 | 经确认成立后必须修复;如果判断不成立,写明反证后关闭 |
| 重要 | 修复,或由有权接受风险的人记录理由和后续安排 |
| 建议 | 可以采纳或拒绝,但要留下结论 |
安全基线被违反时按阻断处理。需要改变安全基线,应先单独修改并批准基线,不能在实现评审里临时豁免。
修复后复核原问题和修复所影响的范围,无需让两个 Agent 无限互审。如果意见反复出现却没有新证据,交给人裁决;如果修改持续引出新问题,缩小改动或回到方案阶段重做。所有意见最终都应处于已修复、不成立、已接受风险或转成后续任务之一。
通过标准:送审材料对应当前版本;评审方没有继承实现会话,也没有修改工作区;每条意见都有证据、等级和最终处置。
14.2.1 把互审和修复做成一条命令
上面这套”独立评审 → 处置意见 → 修复后复核”手动做容易走样:人会忘记换新上下文、会把两个评审方的意见搅在一起、会在修复后忘记复查,或者反过来陷进无限互审。template 里有一对提示词把这些规矩固定下来,让结果不依赖当时的措辞和记性。
/td-review-cross 做互审本身,一条命令跑完、不用手动切模型。它把评审对象解析成一份确定的 diff(空参默认整个工作区改动,连未跟踪的新文件也用 git add -N 纳进来),交给两个跑在不同模型上的只读评审子 agent,强制两轮:第一轮两方互相不可见地独立审;第二轮各自拿到对方的清单去交叉质证,用自己的工具实跑复现,逐条标 CONFIRMED / REFUTED / INCONCLUSIVE;最后一个仲裁子 agent 按质证结论(而非”几人报过”)汇成一张去重后的裁决表,并落盘到 docs/reviews/。两轮质证比单轮贵,但单轮会放过只有一方发现的真漏洞——评审是发布闸门,第二轮不给省。
/td-review-fix 消费那张裁决表去修,是互审的下游。它必须传入一份 docs/reviews/ 里的评审文件(不空参猜最新的,猜错就修错东西),把每条意见分进四桶:CONFIRMED 的 P0/P1 现在就修;CONFIRMED 的 P2/P3 按建议动作处理(可能是记一条约定而非改代码);REFUTED 的放着不动——那是评审已经驳回的误报,再修就是把噪声和已被否的行为塞回去;INCONCLUSIVE 的、以及任何压在”未定前提”上的意见,停下来用大白话问人,不替人选边。修的时候守一条根治规则:复用真实的那一份来源,不要另写一个等价实现——“修复不收敛”最常见的病根就是修复为了对齐某机制的行为、却自己手写了一份会漂移的等价物,下一轮评审又发现漂移。修完强制重跑一次 /td-review-cross 复核,然后停下把新结论交回给人,绝不自动 loop。收敛线是”没有 CONFIRMED 的 P0/P1 存活”即可合并,不是把意见清到零;BLOCK PENDING HUMAN 是需要人拍板的决策门,不是还没修完。
上手只要记一条主线:先 /td-review-cross——空参审整个工作区的改动,或带参数指定范围——跑完去 docs/reviews/ 看它生成的那张裁决表;再 /td-review-fix 把那份裁决表的路径传给它(必须指明是哪一份,不让它猜最新的),它按四桶处置,修完会自己重跑一次 /td-review-cross 复核。你只在两个地方插手:它把某条标成 INCONCLUSIVE 或抛出 BLOCK PENDING HUMAN 时,停下来等你拍板;以及最后由你确认”没有 CONFIRMED 的 P0/P1 存活”,这轮就可以合并。
14.3 CI 闸门与基线保护
CI 是合并前的强制边界。本地命令和提交钩子可以被跳过,CI 必需检查则应接入主干保护:检查失败不能合并,需要批准的变更没有批准也不能合并。
CI 契约按项目实际情况选择,不要求所有仓库机械地凑齐同一组工具:
| 检查 | 证明什么 | 常见失败 |
|---|---|---|
| 测试或等价验收检查 | 已覆盖的行为仍满足预期 | 新行为不符、已有行为回归 |
| 构建与类型检查 | 代码可以按项目方式生成或运行 | 编译、打包或类型错误 |
| lint 与格式检查 | 代码满足项目的静态规则 | 风格或规则违规 |
| 密钥与安全扫描 | 没有命中项目定义的安全禁项 | 凭据入库、已知漏洞或危险模式 |
| 验收基线检查 | 保护测试、CI 配置和阈值的变化已被看见 | 检查被删除、跳过或调松 |
文档、配置或数据项目未必有构建步骤,也未必使用传统测试。它们仍要选择能直接证明结果的等价检查,并把命令写进项目的验证契约。
CI 全绿不代表验收标准没有被改松。测试文件、快照、CI 配置、lint 规则、安全基线和阈值发生变化时,应把这些变化单独列出来,要求说明理由并取得相应批准。机器可以标出文件被删除、跳过标记增加、阈值变化等信号;断言是否在语义上变弱,仍要由评审方对照开工前的基线判断。
覆盖率可以显示趋势,也可以用来防止明显倒退,但不能单独证明测试有效。项目如果设置覆盖率闸门,应同时检查新增行为有没有对应断言、原有验收条件有没有被削弱,而不是只追一个总百分比。
团队仓库可以通过主干保护要求必需检查和批准。单人项目无法制造第二个人的批准,应保留 CI 结果、独立 AI 评审和自己的风险接受记录;高风险或用户可见行为仍要亲自验收。
通过标准:项目已经声明适用的 CI 契约;必需检查失败时不能进入主干;测试、CI 配置或验收基线有变化时,合并记录里能找到差异说明和批准结论。
14.4 人工验收与合并记录
人工验收只做机器无法替代的判断。低风险变更可以凭确定性检查和适用的评审结果合并;高风险、难回退或用户直接可见的行为,要由人运行验收场景或观察实际结果。
人工验收不是再听 Agent 复述一遍。CI 日志可以证明命令确实运行过,不必为了仪式重复执行;人要核对的是结果是否符合验收条件、风险是否可以接受,以及用户实际看到的行为是否正确。
逐行读代码只是人工验收的一种形态。人的介入可以很深,也可以很浅:深的一端是逐行读代码,浅的一端是人读不懂代码,主要依靠确定性检查、独立评审、上线前的端到端实测和可回滚兜底。具体深度由团队的规模和能力决定,但无论深浅都有一条底线:人退出的地方,证据强度不许降,而且要破掉同源盲区。如果写代码、写测试、做评审、跑端到端都出自同一个 Agent,它的盲区就会在每一步重复,等于没有独立验证。补法是给验证换一个独立来源:新上下文、黑盒视角,或换一个独立的判断者。读不懂代码不等于免除验证,而是要把验证换成自己能判断结果的形式。
合并记录至少回答下面几件事:
| 记录项 | 内容 |
|---|---|
| 变更对象 | 对应的提交、PR 或其他不可混淆的版本标识 |
| 确定性证据 | 执行过的命令、结果和报告链接 |
| 评审结论 | 发现的问题及其最终处置 |
| 人工验收 | 需要时记录场景、观察结果和验收人 |
| 剩余风险 | 已接受的问题、理由、责任人和后续安排 |
记录可以放在 PR、合并请求或项目约定的交付记录里,重点是能回到当时真正检查过的版本。代码后来又变了,就要重新运行受影响的检查,并更新评审或验收结论。
合并判据是:适用的确定性检查全部通过,阻断问题已经清零,验收基线的变化已有处置,需要的人工验收已经完成,记录指向最终合并版本。缺一项就继续处理,不能用”已经有人看过”代替证据。
本章小结
低风险变更至少留下确定性证据,风险升高后再增加独立 AI 评审和人工验收。CI 负责阻止失败检查进入主干;评审与验收负责判断机器无法理解的意图、基线变化和剩余风险,所有结论都要指向最终合并的版本。人退出得越多,越需要独立来源的证据补位,不能让写、测、审出自同一个 Agent 的盲区贯穿每一层。
参考与出处
- 互审与修复命令正本:
template/.kiro/prompts/td-review-cross.md、td-review-fix.md(配套标准_reviewer-rubric.md、_reviewer-arbiter.md,评审子 agent 在template/.kiro/agents/td-reviewer-{sol,auto,arbiter}.json) - 从批准动作转向行为证据,以及确定性检查、AI 评审和人的判断三层分工:Anthropic: How the Claude Code team does code review
- 削弱 CI 的改动应停止合并,评审需要关注关键路径和跨模块影响:GitHub: Agent pull requests are everywhere—here’s how to review them
- Git 提交钩子的安装范围、触发阶段和运行方式:pre-commit 官方文档
- 同一会话自审的局限:arXiv 2603.12123
- 跨模型评审与同模型全新会话评审的比较:arXiv 2610.01471
- 跨模型评审效果的方向差异:arXiv 2607.21656