AI 生成代码怎么审查?从可运行到可维护的验收清单
AI 编程工具已经能很快生成函数、组件、接口甚至一整套脚手架,但真正的问题不是“AI 能不能写代码”,而是“AI 写出来的代码能不能放心合并”。
很多人用 AI 编程时只看两个结果:代码有没有生成、运行有没有报错。这个标准太低了。AI 生成代码最常见的问题不是语法错误,而是需求理解偏差、边界条件遗漏、测试不足、权限判断缺失、错误处理粗糙,以及未来维护成本变高。
这篇文章整理一套 AI 生成代码审查清单,适合你在使用 GitHub Copilot、Cursor、Claude Code 或其他 AI 编程工具后,对代码做最后验收。它不是工具推荐,而是一套工程实践流程:让 AI 提速,但不让 AI 降低代码质量。
先记住一句话:AI 代码必须按人工代码标准验收
AI 生成代码不能因为“是 AI 写的”就降低标准,也不能因为“看起来能跑”就直接合并。你应该把它当成一个初级开发者提交的 PR:可以很快,但必须审查。
最基本的验收顺序是:
| 阶段 | 要回答的问题 |
|---|---|
| 需求验收 | 它解决的是不是原始问题? |
| 行为验收 | 正常路径和异常路径是否都正确? |
| 测试验收 | 是否有能证明行为的测试? |
| 安全验收 | 是否引入权限、注入、泄露等风险? |
| 可维护性验收 | 未来的人是否能理解和修改? |
| 集成验收 | 是否影响现有功能、构建和部署? |
只要其中一项回答不清楚,就不应该急着合并。
第一步:确认 AI 有没有理解需求
AI 很擅长“顺着你的话写代码”,但不擅长判断你的需求是不是完整。它可能会补出看似合理、但并不是你想要的实现。
审查时先问这几个问题:
- 代码解决的是原始需求,还是 AI 自己扩展出来的需求?
- 有没有多做不需要的功能?
- 有没有漏掉关键业务规则?
- 有没有把临时脚本写成长期架构?
- 有没有引入新依赖、新配置、新环境变量?
比如你让 AI “给登录页加一个验证码校验”,它可能顺手加了新的状态管理、错误提示组件、接口重试逻辑。看起来更完整,但如果项目原本有统一表单校验方案,这就是过度实现。
AI 生成代码第一轮审查的重点不是代码风格,而是确认它没有偏题。
第二步:检查正常路径之外的边界条件
AI 生成代码经常能覆盖 happy path,但边界条件容易漏。尤其是输入为空、接口失败、重复提交、权限不足、数据格式异常这些情况。
建议按下面的清单逐项看:
| 类型 | 检查点 |
|---|---|
| 空值 | null、undefined、空字符串、空数组是否处理? |
| 非法输入 | 类型错误、格式错误、超长输入是否处理? |
| 重复操作 | 重复点击、重复提交、重复请求会怎样? |
| 异步失败 | API 超时、网络失败、服务返回错误会怎样? |
| 权限问题 | 未登录、无权限、角色不匹配会怎样? |
| 数据缺失 | 后端字段缺失或历史数据不完整会怎样? |
如果 AI 只写了正常路径,你可以继续让它补边界测试,但最终判断要由你来做。边界条件不是“锦上添花”,它决定代码能不能进入真实环境。
第三步:测试不是数量,而是证明行为
很多 AI 工具会生成一堆测试,但这些测试经常只是“调用函数,然后断言返回值存在”。数量看起来多,证明力很弱。
好的测试要证明具体行为:
- 给定什么输入。
- 执行什么动作。
- 期待什么输出或副作用。
- 为什么这个场景重要。
审查 AI 生成测试时,重点看三件事:
- 是否覆盖核心业务规则。
- 是否覆盖失败路径和边界条件。
- 测试失败时能不能定位问题。
如果一个测试只是在验证实现细节,比如“某个内部函数被调用了一次”,但没有证明用户可见行为,那它的价值有限。
更推荐的做法是让 AI 先列测试场景,而不是直接写测试代码。你确认场景后,再让它生成测试。这样能避免 AI 只围绕自己的实现写测试。
第四步:重点查安全风险
AI 生成代码最危险的地方之一,是它可能复制常见但不安全的写法。尤其是 Web 项目、接口层、数据库查询、文件上传、用户输入处理。
重点检查这些风险:
| 风险 | 常见表现 |
|---|---|
| XSS | 直接渲染用户输入或 HTML 字符串 |
| SQL 注入 | 拼接 SQL 字符串而不是参数化查询 |
| 权限绕过 | 只在前端隐藏按钮,后端不校验权限 |
| 敏感信息泄露 | 把 token、API key、错误堆栈返回给用户 |
| 文件上传风险 | 不限制类型、大小、路径或文件名 |
| 命令注入 | 把用户输入拼进 shell 命令 |
| SSRF | 允许用户控制服务端请求的 URL |
AI 有时会为了“代码简单”省略安全边界。你不能只看功能是否完成,还要看输入从哪里来、输出到哪里去、中间有没有越权可能。
如果代码涉及认证、支付、用户数据、文件系统、数据库写入,建议把安全检查单独列为一个 review 步骤,而不是和普通代码风格一起看。
第五步:看错误处理是不是给用户看的
AI 生成代码很容易写出两种糟糕错误处理:一种是直接吞掉错误,另一种是把内部错误原样抛给用户。
好的错误处理应该做到:
- 用户能知道发生了什么。
- 开发者能定位问题。
- 系统不会暴露敏感信息。
- 失败后状态不会乱。
例如前端提交表单失败,不应该只 console.error;后端接口失败,也不应该把数据库堆栈直接返回。更好的方式是:用户看到可理解的提示,日志里保留足够排查信息,状态能回滚或保持一致。
审查时可以问:
- 错误信息对用户有意义吗?
- 有没有记录足够的日志?
- 会不会泄露内部实现?
- 失败后按钮、loading、缓存状态是否恢复?
这些细节 AI 很容易漏,但真实用户一定会遇到。
第六步:检查是否破坏现有架构
AI 不一定理解你项目的长期架构。它可能为了完成当前任务,绕过已有封装、复制一套逻辑、引入新的状态管理方式,或者把本该放在服务层的逻辑写进 UI 组件。
审查时重点看:
- 有没有复用项目已有工具函数?
- 有没有绕过已有 API 封装?
- 有没有在错误层级写业务逻辑?
- 有没有和现有命名、目录结构、数据流不一致?
- 有没有为了一个小需求引入过重抽象?
AI 生成代码如果和项目风格不一致,短期能跑,长期会让代码库变碎。真正的可维护性,不是每段代码都很“聪明”,而是大家能用同一套规则理解它。
如果你使用 Claude Code 这类工具,建议先把项目规则写进 CLAUDE.md,让 AI 在动手前知道哪些事情不能做。站内这篇 Claude Code 进阶实战 里有更完整的上下文配置思路。
第七步:避免 AI 生成“看起来高级”的过度设计
AI 很容易写出过度设计:一个简单函数,被拆成策略模式、工厂类、抽象接口、配置系统,看起来很专业,但完全没必要。
判断是否过度设计,可以看三点:
- 这个抽象现在是否真的有两个以上使用场景?
- 删除这个抽象后,代码是否更容易理解?
- 未来维护者是否需要先理解一套额外概念?
如果答案偏向“没必要”,就应该让 AI 简化。不要因为代码看起来像“架构”就接受它。很多项目变复杂,不是因为业务复杂,而是因为每次 AI 都顺手加一点“可扩展设计”。
AI 生成代码的最佳状态是:解决当前问题,符合现有结构,不为不存在的未来需求买单。
第八步:上线前跑一遍最小验收清单
合并 AI 生成代码前,建议至少过一遍这个清单:
- 原始需求已完成,没有额外偏题功能。
- 正常路径、失败路径、边界条件都看过。
- 关键逻辑有测试覆盖。
- 权限、安全、输入输出边界已检查。
- 错误处理对用户和开发者都可用。
- 没有引入不必要依赖。
- 没有绕过项目已有封装。
- 构建、测试、lint 至少跑过必要项。
- 代码变更范围和需求规模匹配。
- 你能向别人解释这段代码为什么这样写。
最后一条很重要:如果你自己解释不清楚 AI 生成的代码,那它就还不是你的代码。不要合并你无法维护的东西。
给 AI 的审查提示词模板
你可以把下面这段作为 AI 代码审查提示词的起点:
请审查下面这段代码,重点检查:是否完整满足需求,是否有多做或漏做;是否遗漏边界条件和失败路径;是否存在 XSS、注入、权限绕过、敏感信息泄露等安全风险;是否符合现有项目结构,是否重复造轮子;测试是否能证明行为,而不是只覆盖实现细节;有没有可以删除的过度设计。请按“必须修改 / 建议修改 / 可以接受”三类输出。
提示词不是为了让 AI 替你做最终决定,而是让它帮你先扫一遍。真正的判断仍然要回到需求、测试和项目上下文。
总结:AI 负责提速,人负责质量
AI 编程最大的价值是提速:更快写样板代码,更快生成测试草稿,更快解释陌生逻辑。但代码质量不能外包给 AI。
一套可靠的 AI 生成代码验收流程,应该覆盖需求、边界、测试、安全、错误处理、架构一致性和可维护性。这样你才能既享受 AI 的速度,又不把技术债一起合并进代码库。
工具会不断变化,今天是 Copilot、Cursor、Claude Code,明天可能是新的 AI IDE 或 Agent。但无论工具怎么变,代码上线前都要回答同一个问题:这段代码能不能被团队长期维护?如果答案不确定,就继续审查,而不是急着合并。




