AI 编码 PR 评审:用验收标准衡量通过与否

AI 编码 PR 评审:用验收标准衡量通过与否
Spec Coding 编辑部 · Spec-First 工程实践内容

如何用验收标准评审一个 AI 生成的 PR:哪些要肉眼看,哪些要实际跑,以及 LLM 写的代码最容易混过快速浏览的失败模式。

发布于 2026-03-10 · ✓ 已更新 2026-05-06 · 阅读约 7 分钟 · 作者:Spec Coding 编辑部 · 审校:编辑与事实核查政策

改变一切的心态转变

当我评审一个工程师手写的 PR 时,我会看风格、看习惯用法、看判断力。当我评审一个 LLM 写的 PR 时,我只看一件事:它是否满足了 spec 里的验收标准,而且没有做任何 spec 没授权的事情?这就是全部工作。Spec 就是评分标准。如果 spec 没覆盖某件事,我就没法有意义地评审它,这时我会把作者打回去写一份更好的 spec,而不是批准一个谁都没办法判断对错的东西。

我不再问“这段代码看起来合理吗?”,而是开始问“这一行存在是为了满足哪一条验收标准?”任何答不上来的行都是可疑的。

跑测试,不要相信那个绿勾

CI 过了。绿色的对勾在那儿。这几乎不能说明任何问题。我会把分支拉下来在本地跑测试,或者至少打开 CI 日志读一下实际执行了什么。我已经数不清有多少 AI 生成的 PR 拿着干净的绿勾,因为测试文件 import 了模块、构造了类,然后几乎什么都没断言——或者把那个本可以抓住 bug 的函数给 mock 掉了。还要留意那些测试通过、但它声称覆盖的生产路径其实被一个 feature flag 挡住、而测试从不启用那个 flag 的情况。绿的。没用。

把每一条标准映射到一个测试

现在我打开 spec。对每一条验收标准,我在 diff 里搜索验证它的那个测试。如果我没法指着一个具体的测试说“这覆盖了第三条”,那第三条就是没覆盖,不管这个 PR 看起来多完整。我在这一步拒掉的 PR 比任何其他步骤都多。解决办法不是我自己去补测试;而是把 PR 退回去,列出缺失的标准,让作者再试一次。在这里我也坚持要求 PR 描述里列出关闭了哪些验收标准。如果作者在 PR 顶上写不出“closes AC-1, AC-2, AC-4”,那他就不知道自己建了什么。我也不知道。

偷偷扩大的范围和缺失的错误路径

LLM 喜欢“帮忙”。一份要求做一个日期解析函数的 spec,回来的是一个日期解析函数,外加一个新的 utility 文件,外加一个项目本来没用过的日期库依赖,外加一个无关 helper 的重构,因为模型觉得它“可以更干净一点”。这些都没被授权过。我会把 diff 走一遍,找任何 spec 没要求的文件、import 或抽象,然后删掉它,或者拒掉这个 PR。未授权的扩张就是代码库烂掉的方式——一次一个“善意的建议”地烂。

然后反过来看。LLM 是 happy-path 机器。我会专门找这些:输入为 null、网络失败、文件不存在、用户未授权、队列满。如果 spec 列出了这些情况,我就期待有测试。我经常看到一个 try/except 把所有异常都吞了、什么都不 log、返回一个默认值。那比直接崩溃还糟;它是一次崩溃,外加证据被删除。

捉幻觉,然后手动变异

模型很自信地调用一个不存在的方法、import 一个模块从没 export 过的函数、给一个接收两个参数的东西传三个参数。类型检查能抓住大部分。有些会在测试从不触发的代码路径上溜过去。我会把每个被 import 的符号和方法调用手工 grep 去对照真实的库。十分钟的怀疑胜过凌晨两点的报警。

然后是大多数评审者会跳过、而我最信任的一步。我在新代码里挑一行,把它改成错的。翻转一个 boolean,return null,把那行注释掉。跑测试。如果什么都没挂,那这些测试就是摆设。它们执行了代码,但没有测试代码。两分钟,就能抓到最常见的 AI 测试失败:测试断言的是代码做了什么,而不是 spec 要求什么。

验收标准属于 Given/When/Then

评审的质量上限就是验收标准的质量。当 spec 用 Given/When/Then 写时,评审就变成机械操作:

Given a logged-in user with an expired session token
When they submit the checkout form
Then the request is rejected with a 401
And the client shows the re-authentication modal
And no partial order is written to the database

四条断言,四个测试。如果 PR 里只有三个,它就没做完。如果这条标准原本写成“优雅处理过期会话”,那这个 PR 可以是任何样子,我也没有立场把它打回去。模糊的标准产出模糊的评审,模糊的评审产出上线的 bug。

一个看起来还行的 PR

上个月我差点批准了一个在支付 webhook handler 里加重试逻辑的 PR。diff 干净。CI 绿。两个新测试都通过。agent 甚至写了一个工整的 PR 描述。我出于习惯做了那个变异检查,把整个重试循环注释掉。两个测试都还是通过。测试断言的是 request 对象的形状,而不是重试是否发生了——happy-path 测试第一次尝试就成功了,failure-path 测试 mock HTTP 客户端的方式悄悄短路了重试。这个 webhook 在生产里会失败一次,然后永远放弃。我把它退回去,引用了那条重试标准,要求加一个“去掉重试就会失败”的测试。第二版 PR 花了十五分钟。那个 bug 会花掉一个周末。

把它退回去,不要自己修

最诱人的做法是把小问题顺手修掉、然后合进去。每次我这么做,我都在教团队:评审者会给模型擦屁股,于是下一个 PR 带着更多窟窿到来。我的默认做法:把违反 spec 的地方列出来,关掉 PR,如果原 spec 有歧义就要求用更紧的 spec 再试一次。agent 三十秒就能再试一次。我还会在每个 AI PR 上 grep 那些反复出现的问题——留下的 TODO、配置 key 不存在时悄悄 fallback 到默认值、什么都不 log 的裸 except 块、spec 里明明写了环境变量却硬编码的常量。这些都不是风格问题,全都是违反 spec。

盖橡皮图章才是真正的风险

团队是会漂移的。第一个 AI PR 会被仔细评审。第十个会被快速扫一眼。到了第五十个,有人看着绿勾就批准了。LLM 写的代码就是这样悄悄接管一个代码库的。纪律很无聊:拉分支、跑测试、检查标准、变异一行。每一次都做。当 spec 够锐利,评审要十五分钟,我能为每一次批准辩护。当它模糊,我就拒绝评审直到它被修好。验收标准不是形式——它们是我能把信号和听起来很自信的噪声区分开的唯一依据。

评审时看什么

这篇文章适合用在评审 AI 生成的 PR时。别从“原则”聊起,直接拿一条真实改动来对照,看看规格里还缺什么。

最后留下的不是一句“AI 写得还行”,而是一张 AC 到测试的映射表。映射不出来,就退回去补规格或补测试。

评审时先问一个很笨的问题

我看 AI PR 时,会先把 diff 放一边,逐条读验收标准。每一条都问:这条行为在哪个测试里被证明?哪个文件实现了它?失败时会暴露成什么日志或错误?如果回答不上来,代码写得再整齐也先退回。

Acceptance review row:
- Criterion: used reset link cannot be reused
- Code path: src/auth/reset-token.ts
- Test: reset-token.spec.ts / rejects already_consumed token
- Evidence: test output attached in PR
- Reviewer note: UI copy uses generic expired message, no account leak

边界:不要让验收标准变成“所有测试通过”。通过测试只是证据的一种。AI 最擅长写出匹配自己实现的测试,所以 reviewer 要看测试是不是覆盖了原始 spec,而不是覆盖了 diff。

可复制产物:AI 编码评审包

在 AI 生成 diff 进入代码评审前使用。它把提示词范围、允许变更和证据要求合并成一个可审查产物。

AI 编码评审包:AI 编码 PR 评审:用验收标准衡量通过与否

本次要做的决策:
- 确认 AI 只在批准范围内生成变更,并为每条验收标准提供证据。

责任人检查:
- 产品责任人:
- 工程责任人:
- QA 或运维评审:

范围边界:
- 本次包含:
- 本次不包含:
- 仍需确认的假设:

验收证据:
- 测试或 fixture:
- 日志、指标或截图:
- 人工复核步骤:

AI 边界:生成变更必须留在书面范围内,每条验收标准都要能找到证据。

评审追问:
- 没参加需求会的人还会误解哪里?
- 哪个证据能证明这次改动足够安全,可以发布?

旗舰使用路径

这是 Spec Coding 用来承接「AI 生成 PR 评审」主题的核心参考页之一。建议把它放到真实工单、PR 或发布评审里使用,而不是只当背景文章阅读。

旗舰页使用路径:
- 在计划或评审时打开本文。
- 把对应产物复制到工单或 PR。
- 用自己的系统、责任人和失败模式替换示例值。
- 如果证据行仍为空,就不要进入实现。

二次审阅记录:验收标准就是评审表面

这次复看时,我检查文章是否一直回到同一个标准:每个 AI 生成改动都要映射到一条验收标准和一份证据。没有这张映射,评审者只是在给代码风格打分。

PR 评审行:
- 验收标准:
- 为满足它而修改的文件:
- 测试或证据:
- 未自动化时的人工检查:
- 合并前必须移除的越界改动:

编辑复核记录

复核日期:2026-04-29。本次补充了可复用产物,按相关主题 Hub 检查了文章定位,并收紧下一步链接,让页面更像可操作参考,而不是孤立长文。

关键词:AI pull request review · acceptance criteria rubric · LLM code review · Given-When-Then · mutation testing by hand · hallucinated APIs

专题阅读路径

这篇文章归入 验收标准 主题。先读 Hub,再结合下面的清单、模板或工具落到具体项目里。

编辑说明与免责声明

最近复核:2026-04-29。编辑部检查了示例、内链和可复制评审片段,确保内容更适合真实项目使用。

本文用于软件工程教学与实践参考,不构成法律、税务或投资建议。示例场景用于解释规格方法,不对应真实客户数据。