审查 AI 生成的代码,要先查差异,再查行为:确认每个新依赖和 API 真实存在,先看测试改动再看代码改动,证明至少有一个测试在没有修复时会失败,自己在最终差异上重跑检查,最后从正常入口使用功能,并读回保存后的结果。下面的清单覆盖这两部分,并附一份可留存的简短证据记录。
能跑通一次演示,只是一条观察。验收要回答的是:这个具体版本,是否在约定条件下完成了用户任务,结论是否有可复查的证据?
本清单适用于获授权环境中的小型应用功能、API 改动或缺陷修复。从用户正常入口开始,检查到最终可持久保留的结果。清单可以手动使用;相关 Skill 用来组织工作,并非填写模板的前提。
先做这些
当你需要决定「这段 AI 写的改动,在约定范围内能不能验收通过」时,按下面五步执行,再填写后文的证据记录。
- 固定准确版本(commit 或 diff 哈希)、角色、环境和一条可观察的验收标准。
- 做完四项 AI 专属检查:依赖真实存在、先看测试差异、证明测试能失败、在最终差异上自己重跑检查。
- 从用户正常入口走到可持久读回的结果——不要只看成功提示。
- 至少填一行证据:PASS / FAIL / BLOCKED / NOT RUN / N/A(N/A 必须写理由)。空白证据不能支撑 PASS。
- 由人明确拍板:本范围接受、拒绝,或暂停。不要把智能体摘要当成最终决定。
这是本指南可直接执行的结论;后文展开每一步并给出教学演练,不能代替证据记录。
适合与不适合的范围
适合审查范围明确、基线和需求可识别、能够访问相关运行环境的改动。检查深度由行为风险决定,不由修改文件数决定。
它不替代渗透测试、无障碍合规评估、受监管系统认证或生产压测方案。支付、身份、敏感数据、破坏性迁移和安全关键系统需要额外的专业审查。打勾不构成法律或安全保证。
代码审查还是验收:这次改动需要哪一个?
大多数 AI 生成的改动两者都需要。代码审查回答差异是否安全、合理;验收回答这个功能对用户是否真的可用。GitHub 的 AI 生成代码审查指南、Sentry 的 AI 生成代码审查手册等常见指南,重点都在读差异。本文补上后半部分。
代码审查回答:这份差异是否正确、安全、没有越界?
- 主要输入:差异、测试和依赖。
- 典型检查:虚构的 API 或包、超出范围的改动、权限、密钥、测试质量。
- 典型证据:审查记录、扫描输出、CI 日志。
- 单独使用会漏掉:能编译、但保存后就出错的流程。
验收回答:这个具体版本能否为真实用户完成约定任务?
- 主要输入:运行中的应用、测试账号和保存后的数据。
- 典型检查:正常入口、持久化读回、失败与恢复路径。
- 典型证据:关联到具体版本的修改前后证据。
- 单独使用会漏掉:用户看不到的安全漏洞。
本清单面向用 Claude Code、Codex、Copilot 等智能体交付小范围改动的独立开发者和小团队。
1. 固定验收对象
记录基线、候选提交或构建产物、环境、浏览器或运行时、角色、获准的数据来源及副作用范围。存在未提交修改时,还需保存差异快照或哈希。先附上需求来源并分配 REQ/AC 编号,再看测试结果。
每项需求都写成独立于代码实现的可观察结果。“执行了 Save 处理函数”不够;“有权限的用户重新打开记录后仍看到新值”才是结果。关键规则缺失时标为 BLOCKED,不从生成代码反推正确需求。
使用 PASS、FAIL、BLOCKED、NOT RUN 或 N/A。N/A 必须说明为何确实不适用,不能用来掩盖工具缺失。没有证据不能判 PASS。例外应记录决策人、范围和后续事项,不可悄悄改成通过。
2. 执行适用检查
- [ ] 需求: 将每项 REQ/AC 对应到实现入口、用例和结果。检查差异中完全缺失的承诺,记录已同意的排除项,并确认没有擅自增加业务规则或权限。
- [ ] 核心功能与持久化: 从对应角色的正常入口完成任务。写入后刷新或重新打开,在允许的访问范围内读回权威状态,并关联同一对象和请求。成功提示不能单独证明保存成功。
- [ ] 边界与状态: 按实际规则检查缺省、空值、非法值及上下界两侧,确认计数单位。按风险覆盖合法和非法状态转换、重复点击、旧页面及并发更新。
- [ ] 错误与恢复: 仅在获准的隔离环境测试超时、拒绝、部分失败和中断。确认用户能理解错误并恢复操作;重试不重复产生副作用,迟到响应不能覆盖更新的操作。
- [ ] 安全基础: 检查实际动作及对象的服务端授权,包括归属不同的第二个测试账号。拒绝请求不得改动数据;按攻击面检查输入校验、输出编码及构建文件或日志中的凭据泄露。只做授权检查,不攻击无关系统。
- [ ] 可访问性与交互: 用键盘完成受影响流程,检查焦点、名称和标签、错误及弹窗关闭。检查缩放、窄屏、可读对比度和有意义的替代文本;按产品需要增加辅助技术检查。这些基础检查不等于合规评估。
- [ ] 性能: 先约定操作、数据规模、设备和网络条件、测量方法与阈值。测完整用户操作,不只测 API 耗时;同条件比较基线并保留样本及资源观测。无阈值时报告测量结果并等待决策,不自设及格线。
- [ ] 回归与审查: 运行受影响的现有检查及仓库要求的 lint、类型、构建和测试。覆盖共享调用方及相邻合法和非法路径,审查最终差异是否遗漏需求或削弱断言。修复要保留修复前失败、修复后通过的信号。
- [ ] 证据与交付: 每个结论都关联被测版本、实际步骤或命令、预期、实测及原始证据。明确标注 Mock、固定样本、合成数据及静态审查;确认最终差异没有使证据过期。本地验证、部署和目标运行环境验收分开报告。
普通审查常漏掉的四项 AI 专属检查
这四项检查针对上述审查指南专门指出的 AI 改动问题:虚构的依赖、被削弱的测试、不可能失败的测试,以及从未在最终差异上运行过的“测试已通过”。
1. 确认每个新依赖都存在,而且就是你要的那个。 安装前,在官方包仓库和锁文件里逐个核对新包。一项发表于 USENIX Security 2025 的研究测试了 2024 年 1 月选定的 16 个代码生成模型:生成的 Python 和 JavaScript 代码共引用约 223 万个包,其中 19.7% 并不存在;商业模型平均至少 5.2%,开源模型平均 21.7%。新模型可能更好,但今天不存在的包名,明天可能被攻击者抢注。
2. 先看测试差异,再看代码差异。 删除的测试、新加的 skip、被改动的预期值、替换了被测代码的 Mock,都是智能体在替你决定什么叫“正确”。GitHub 的指南专门提醒要留意被删除或跳过、而不是被修好的测试。先确认这些决定,再读实现。
3. 证明至少有一个测试会失败。 把新增或修改的测试放到修复前的版本上运行,或临时破坏它保护的那一行,确认它会失败。如果仍然通过,它就什么也没保护。Stryker 等变异测试工具会自动插入小缺陷并检查测试是否失败,原理相同。
4. 自己在最终差异上重跑检查。 智能体的总结不是测试结果。记录命令、实际运行的测试数量、退出码,以及对应的提交或差异。最后一次修改之前的结果不算数。
这次改动需要检查到什么程度?
按改动触及的范围决定检查深度,而不是按行数。以下分级是我们的工作判断;高风险触发条件参考了 OWASP 安全代码审查指南中关于何时加深审查的建议。
- 低: 文案、样式、文档,或测试不变的独立重构。最低要求:构建、lint、现有测试,并看一眼结果。
- 中: 现有边界内的功能、界面状态,或不涉及新权限的新接口。最低要求:低级全部要求、上面四项 AI 专属检查,以及一个从正常入口出发并读回结果的验收用例。
- 高: 登录认证、权限、支付、个人数据、数据迁移、删除、CI/CD 或部署配置、新依赖。最低要求:中级全部要求、清单中所有适用部分,以及合并前的第二次独立审查。
一个人审查:没有第二个审查者时怎么办
独自工作时,让检查独立于写代码的那个智能体,并写下哪些部分没有被审查。团队指南默认有第二个人:OWASP 要求由作者以外的人批准。独立开发者无法完全满足,那就尽量接近:
- 用全新会话或另一个智能体做审查,只给它需求和差异,要求它给出有证据的问题,而不是一句结论。
- 对照运行中的系统核实,而不是对照智能体的报告:打开页面、重新打开记录、确认已部署的版本。
- 高风险改动保持足够小,小到你能逐行读完。
- 在证据记录里把“没有独立人工审查”记为未关闭的缺口,而不是悄悄跳过。
3. 保存可复查的小型证据记录
每例记录:CASE 编号 → REQ/AC → 角色和数据来源 → 精确步骤 → 预期 → 实际 → 状态 → 通过或失败证据 → 环境及版本 → 缺口与负责人。
截图只能证明可见状态,不能证明持久化;200 响应不能证明目标对象正确变更;Mock 测试通过不能证明真实依赖可用。证据必须匹配结论,隐去秘密,只分享给获准查看的人。
可使用配套 Markdown 模板,或复制下方记录格式。模板包含九个起始检查项及可复制的用例记录;每行是覆盖提示,不代表整个类别已通过。
- CASE / REQ / AC: ____
- 角色 / 初始状态 / 数据来源与替代数据许可: ____
- 可复现的精确步骤或命令: ____
- 预期结果与规则来源: ____
- 实际结果: ____
- 状态(PASS / FAIL / BLOCKED / NOT RUN / N/A): ____
- 通过证据:产物或脱敏日志、时间、版本: ____
- 失败证据:准确差异及产物、时间、版本: ____
- 持久化 / 外部最终状态读回: ____
- N/A 理由或剩余缺口 / 负责人 / 下一步: ____
- 修复前结果 / 修复后结果 / 受影响回归: ____
- 最终差异审查证据: ____
4. 合成演示:保存显示名称
以下仅为合成教学演示。输入和观察结果均为说明记录方式而虚构,未在用户生产项目或任何真实验收会话中执行。
假设已明确约定:去除首尾空白后,显示名称允许 1–40 个 Unicode 码点,用户只能修改自己的名称。这只是示例规则,不是通用推荐限制。
CASE-NAME-01 / AC-NAME-01:从正常菜单打开个人资料,保存“River”,重新打开。预期:名称仍为“River”,获准的读回结果属于同一账号。假设观察:成功提示出现,但重新打开显示旧名称。演示状态:FAIL。真实执行时应采集修改前后画面、脱敏请求及同账号同版本的权威读回证据;本文并未提供这些运行证据。
CASE-NAME-02:尝试去空白后为空,以及 1、40、41 个码点的输入。按假设规则,空值和 41 应拒绝,1 和 40 应接受。这些仅为计划用例,状态 NOT RUN;使用前先核实样本实际计数,码点、字节和用户感知字符并不相同。
CASE-NAME-03:在授权测试环境用账号 A 尝试修改账号 B。预期拒绝且 B 不变。CASE-NAME-04:中断保存,按约定恢复规则重试并检查最终状态。未使用授权测试账号和故障条件执行前,两项均保留 NOT RUN。
完整教学演练(合成数据——不是线上验收)
上面的用例是计划清单。下面这一行演示:中等风险「保存显示名」在真实观察后,证据表可以长什么样。数据均为虚构,只教格式;不是 Boloop 生产证据,也不是任何用户项目的实测结果。
| 字段 | 教学填写 |
|---|---|
| 范围 | 仅登录用户改自己的显示名 |
| 风险分级 | 中(既有边界、无新权限) |
| 版本 | 教学 diff demo-name-001(非真实部署) |
| CASE / AC | CASE-NAME-01 / AC-NAME-01 |
| 角色 / 入口 | 用户 A / 个人资料菜单 |
| 步骤 | 打开资料 → 填 “River” → 保存 → 再打开 → 读回 |
| 预期 | 同一账号读回为 “River” |
| 修复前 / 弱提示 | Toast「已保存」但读回仍是 “Old” → 验收 FAIL |
| 修复后(示意) | 持久化后读回 “River” → 仅本用例 PASS |
| 依赖 / 安全 | 无新依赖;第二账号不得改用户 A(此处 NOT RUN) |
| 未跑测试 | 空值/长度 CASE-NAME-02(NOT RUN);跨账号 CASE-NAME-03(NOT RUN) |
| 人工决策 | 拒绝合并,直到最终 diff 上 CASE-NAME-01 为 PASS,且 CASE-NAME-03 已跑或书面延期并指定负责人 |
5. 决定哪些部分真正就绪
分别报告仓库规范、需求覆盖和运行时验收。约定范围内仍有 FAIL、BLOCKED 或 NOT RUN 的验收项,就不能宣称整体完成。“本次差异未发现可证明的缺陷”只是限定范围的审查结果,不是无缺陷保证。
失败后保留证据,区分产品、测试、环境、数据或需求问题。不要削弱断言、删除用例或反复重跑碰运气。仅在授权范围内修复,再跑原始用例及受影响路径,审查最新差异。
用准确交付状态:已实现、本地已验证、已部署、真实路径已验收。本地验收不授权部署;部署也不能单独证明用户任务可完成。
常见问题
只做代码审查,对 AI 生成的代码够吗?
不够。代码审查能看出差异是否正确、安全,但看不出功能在保存、刷新或请求失败之后是否仍然正常。凡是用户会用到的改动,两者都要做。
AI 智能体能审查自己写的代码吗?
可以辅助,但不应作为最后一道检查。写代码的智能体可能把同一个错误假设带进审查;OWASP 的 AI 安全验证标准(AISVS)也明确写道,AI 智能体本身不算人工审查者。请用单独的会话审查,并亲自核实结果。
怎么知道 AI 写的测试真的有效?
让每个重要测试故意失败一次:放到修复前的版本上运行,或破坏它保护的那一行,确认它会失败。再检查它断言的是具体结果,而不只是某个 Mock 被调用,或者没有抛出错误。如果是缺陷修复,如何验证 AI 生成的缺陷修复逐步说明了修复前后的记录方法。
审查 AI 生成的 PR,先看什么?
先看范围和测试:差异是否符合需求,有没有测试被删除、跳过或改动?然后看新依赖、权限和密钥,最后实际运行这个功能。
每一行都要读吗?
高风险改动要。低风险改动通常检查通过、再看一眼结果就够了。按上面的分级执行,并写下你选择了哪一级。
我不太会看代码,还能检查 AI 做出来的软件吗?
能。检查你看得见的行为:用大白话写下预期结果,以新用户身份使用功能,重新打开保存过的数据,试试空输入和错误输入,再用第二个账号确认看不到第一个账号的数据。涉及登录、支付和个人数据时,请找懂技术的人审查。
选择相关工作流程
- talking-us: 成功规则不明确或产品决策待定:澄清需求,不修改产品。
- write-design-doc: 需求已确认,但 API、数据或状态契约不清:整理可直接实施的设计。
- test-case: 由需求推导用例。design 用于规划,validation 用于已授权的现有检查;模式名不授予修复或替代数据权限。
- bug-fixing: 已有可复现失败:追踪首先破坏规则的地方,获准后修复并验证相关路径。
- code-review-multiagent: 对照需求和调用方审查最终差异。默认深入 Solo;独立智能体按风险和宿主能力启用。
- develop-closed-loop: 将已授权且规格明确的改动推进至实现、测试、修复、回归、审查和交付证据。所需配套流程须另行安装。
已知局限与参考资料
本文是基于六个工作流程包整理的原创实用指南,不是它们跨模型行为的测试报告。Skill 不提供账号、浏览器、数据、部署访问或权限;单个下载不等于完整合集。部分界面设计分支依赖未打包的外部 frontend-design-lab。
模板用于记录证据,不能自行发现缺陷。抽样需要说明等价依据及未覆盖分支;合成示例不能替代要求的真实业务数据。访问缺失时,保留待验收状态,继续不依赖该条件的安全检查。
安全基础可参考 OWASP 关于逐请求权限校验及在正确可信边界执行授权的建议:OWASP Authorization Cheat Sheet。基础可访问性检查及其局限见 W3C WAI Easy Checks。这些参考不意味着本清单构成完整审计。
关于 AI 专属的审查风险,可参考 GitHub 的 AI 生成代码审查指南、Sentry 的审查手册和 OWASP 安全代码审查指南。依赖包数据来自 Spracklen 等人的论文《We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs》(USENIX Security 2025)。“证明测试会失败”背后的思路,可参考 Stryker 的变异测试文档。
540 文章浏览
记录符合条件的页面浏览并过滤短期重复,不代表独立读者人数。