AI 生成代码该怎么审:一套可以直接使用的实操框架

我的核心要求:减少 BUG,减轻 Review 压力,避免生产环境出现不可逆的风险。不要怕对同一个任务开多个agent,重要的是让不同关注点能充分执行,人工做最后的审核兜底;

一、AI 写得越快,审查越不能只看“像不像对的”

AI 一分钟可以生成几百行代码,几小时就能跑完一轮 PR 流程。真正决定质量的,已经不只是 AI 写得快不快,而是我们能不能在代码生成之后,用合适的方法把它审干净。我自己每天让 AI 生成大约一半的代码改动,但最后原样合进主干的,大概只有三成。剩下的代码往往不是“完全写错”,而是“看起来很像对”:错误被 _ 接住,权限校验在调用链里悄悄漏掉,并发场景只覆盖了 happy path,或者引入了一套团队没人熟悉的依赖。这些问题可能过得了 lint、单元测试和评审,却会在生产环境里变成真正的事故。

所以,我现在不把 AI 当成“替我批准代码的人”,而是把它放在风险筛查器的位置:先帮我快速找出值得追问的地方,再由作者、人工 Reviewer 和领域负责人作最终判断。这个定位也和公开实践比较一致:OWASP 把人工代码审查定义为对自动化安全测试的补充,重点放在业务逻辑、复杂安全实现和具体上下文上;Google 的评审指南则强调,测试本身也需要人来判断是否真的有效。可参考 OWASP Secure Code Review Cheat SheetGoogle 的代码评审实践

二、先把审查输入准备好,AI 才不会对着空气猜

我以前最容易犯的错,是把一段代码直接丢给 AI,然后补一句“帮我仔细审查”。现在我会先准备一张很短的“审查输入卡”,至少包含下面五项:

  1. 目标:这次改动要解决什么问题?不解决什么问题?
  2. 不变量:哪些已有行为、权限边界、接口兼容性和数据约束绝对不能被破坏?
  3. 范围:本次 PR 改了哪些文件、调用链和配置?哪些内容只是必要上下文?
  4. 验证:新增或修改了哪些测试?正常路径、异常路径和回滚路径分别是什么?
  5. 风险:是否涉及登录、权限、支付、个人信息、文件上传、数据库迁移、加密或外部依赖?

日常 PR 我会让 AI 以 diff 为主,只补充相关接口、数据结构、配置和测试。OWASP 也把 diff-based review 作为 Pull Request 和日常开发的适用方式;新系统、重大版本、遗留系统接管或事故复盘,才更适合做全量的 baseline review。另一个有效做法是控制 PR 的大小:Google 建议一个变更尽量只做一件自洽的事,相关测试跟着代码一起提交,大型重构与功能修改分开。这样做的收益很直接:AI 看得少而准,人也更容易发现真正的行为变化。

这里有一个我会直接放进 PR 描述的模板:

改动目标:
不在本次范围内:
必须保持的不变量:
变更文件与调用链:
新增/修改的测试:
上线风险与回滚方式:
需要领域负责人关注的部分:

还有一条不能省略:不要把密钥、客户数据、生产日志或未脱敏的个人信息直接发给外部模型。先确认团队使用的模型、数据保留和权限策略,再决定哪些上下文可以提供给 AI;无法确认时,只提供脱敏后的最小上下文。

三、用一段固定提示词,让 AI 输出可验证的意见

我现在会把“找 BUG”和“修 BUG”分开。第一轮只允许 AI 审查,不允许它改代码;每条意见必须能落到具体文件、行号、触发条件和验证方式。下面这段提示词可以直接复制,再把花括号里的内容替换成当前 PR 的信息:

你是本次 PR 的代码审查助手。只审查变更,不修改代码,也不要泛泛总结风格问题。

审查目标:{改动目标}
必须保持的不变量:{不变量}
审查范围:{git diff、相关接口、数据结构、配置、测试}
风险重点:{权限/并发/错误处理/数据一致性/依赖/隐私等}

请严格按以下顺序输出:
1. 先用不超过 5 句话复述“改动意图 + 不变量”。如果信息不足,请先列出需要补充的问题。
2. 只报告可能导致错误行为、安全问题、数据损坏、性能退化或无法回滚的事项。
3. 每条意见必须包含:优先级(阻断/建议/待验证)、文件与行号、触发条件、影响、证据、验证方式、修复方向。
4. 如果只是个人风格偏好,不要报告;如果无法证明,只放入“待验证”,不要写成确定性结论。
5. 最多输出 5 条最高价值意见;没有足够证据时,明确写“未发现可确认的问题”。
6. 最后列出:已覆盖的检查项、未覆盖的检查项、建议由哪类人工 Reviewer 复核。

我会要求 AI 用下面这种格式输出,避免审查意见变成一串没有行动价值的提醒:

优先级位置触发条件与影响证据如何验证修复方向
阻断handler.go:42普通租户可读取其他租户资源调用链缺少租户校验增加跨租户访问测试并查看审计日志在资源查询层统一校验租户

我尤其看重“证据”和“如何验证”两列。AI 说“这里可能有并发问题”不算完成;它至少要说明哪两个操作可能交错、什么时序会触发,以及应该用测试、日志还是压测来确认。这样我可以很快把意见分成三类:立即修复、补证据后决定、记录但不阻断

四、把审查做成机器、AI、人工三道门

第一道是机器门,负责稳定且机械的检查:格式化、类型检查、静态分析、依赖漏洞扫描、敏感信息扫描、单元测试、集成测试,以及组织内部的 AST 规则。能接进 CI 的,就不要每次让 AI 重复描述。

第二道是 AI 门,负责把 diff 放进不同风险视角里检查:攻击者关注输入、鉴权、越权和重放;SRE 关注超时、取消、重试幂等、资源释放和观测;业务负责人关注状态流转、额度、库存和事务;合规人员关注个人信息、日志和数据留存。

第三道是人工门,负责最终取舍和责任确认。

这里有一个我实际会采用的 PR 流程:

  1. 以草稿 PR(Draft PR)开始,先写清目标、不变量、测试和风险。
  2. 先跑机器门,再让 AI 做第一轮 diff 审查;先处理高置信度的正确性、安全性和明显维护性问题。
  3. 作者逐条回应 AI 意见:修复、补测试、标记误报,或说明为什么不采纳;AI 不直接替作者闭环。
  4. 人工 Reviewer 阅读自己被分配的代码和必要上下文,不能只看 AI 指出来的几行。Google 的实践明确提醒:通常应理解被分配审查的每一行;如果不具备安全、隐私、并发等领域能力,应增加有资格的 Reviewer。
  5. 代码发生较大变化、跨服务边界变化,或涉及安全和数据敏感行为时,重新触发 AI 与人工复核。GitHub 的 PR 实践也建议在这类较大改动后重新审查(re-review)。
  6. 通过必需检查、必需审批和领域负责人确认后再合并;高风险改动还要准备 feature flag、灰度、监控和回滚方案。

对安全、支付、权限、数据库迁移、加密和个人信息处理,我不会把“AI 没报问题”当成放行依据。这类改动至少要有对应领域负责人、针对异常路径的测试,以及上线后的可观测和回滚安排。GitHub 的官方文档也提供了类似的组合方式:草稿 PR 先获得早期反馈,仓库级规则写入专门的指令文件,较大修改在合并前再次审查;如果团队使用 GitHub,可以进一步结合 CODEOWNERS 和必需审批保护关键目录。参考 GitHub Copilot 的 PR 生命周期实践GitHub Pull Request reviews

最后,把稳定规则写入 REVIEW_CHECKLIST.mdSECURITY.md 或团队使用的仓库级 AI 指令文件。规则文件要短,只写 Reviewer 真正需要作决定的内容;详细工程手册可以另放。每次审查结束后,我会把“确认过的高价值问题、误报模式、缺失测试和回滚教训”补回清单。这样 AI 才是在复用团队经验,而不是每次从零猜测。

给读者的启示

如果你今天就要开始,可以只做三件事:第一,把 PR 描述补成“目标、不变量、测试、风险、回滚”五项;第二,把上面的提示词固定下来,让 AI 只看 diff、只报有证据的问题、最多给出五条;第三,把人工复核边界写清楚——AI 做筛查,机器做门禁,领域负责人对高风险改动负责。

我对“找到高价值 BUG”和“提高 AI 干活效率”的理解,其实是同一件事的两面:方法上,用换视角、扮角色、给清单、限范围提高命中率;流程上,用小 PR、测试跟随、Draft PR、再审和经验沉淀降低成本。AI 不会因为一句“请仔细审查”就突然可靠,它会因为目标、范围、证据和责任边界都足够明确,而逐渐变得值得信赖。

对我来说,最重要的不是让 AI 替我做最终决定,而是让它把真正值得我决定的问题尽早挑出来。AI 是放大器:它能放大判断力,也会放大错误;最终责任仍然在人。