开篇
上一篇文章,我们讨论了 AI 生成的代码最容易在哪些地方埋坑。
但只知道风险还不够。
真正进入开发流程时,我们还需要一套可以重复使用的审查方法:
拿到代码
↓
确认需求
↓
检查实现
↓
识别风险
↓
补充测试
↓
决定是否合并
很多人会直接把代码丢给 AI,然后问一句:
帮我审查一下这段代码。
这个问题太宽泛。
AI 可能给出一串风格建议,也可能重复描述代码做了什么,却没有指出真正会导致线上问题的地方。
我更习惯把代码审查 Prompt 写成一份“审查任务书”,明确告诉 AI:
- 当前代码要解决什么问题。
- 项目有哪些约束。
- 需要重点检查哪些风险。
- 问题应该如何分级。
- 每个问题必须提供什么证据。
这篇文章分享我的一套代码审查 Prompt,并说明它应该怎样使用。
本文不会讨论什么
代码审查 Prompt 不是自动批准工具,也不能代替开发者承担最终责任。
本文不会:
- 认为 AI 给出的审查意见一定正确。
- 让 AI 代替开发者决定所有架构方案。
- 把格式、命名等低优先级建议放在业务缺陷之前。
- 建议不提供需求和项目上下文就开始审查。
- 用一次审查结果代替测试、运行和人工复核。
本文关注的是:
如何让 AI 更像一个有审查清单的工程搭档,而不是一个只会挑语法和风格的评论器。
一、好的代码审查,至少要回答 5 个问题
一段代码是否值得合并,不能只看它能不能运行。
我通常会从下面 5 个问题开始:
1. 它实现的是正确需求吗
代码可能完成了一个功能,但不一定完成了需求。
需要确认:
- 目标和范围是否一致。
- 是否遗漏了业务规则。
- 是否擅自增加了需求外的行为。
- 状态、权限和异常是否符合约定。
2. 它在边界条件下可靠吗
需要检查:
- 空值、非法值和极端值。
- 重复提交和并发请求。
- 状态变化和数据不存在。
- 外部依赖超时、失败或返回异常。
3. 它符合当前项目的写法吗
即使代码本身合理,如果破坏了项目已有分层和约定,也会增加维护成本。
需要关注:
- 模块职责是否清晰。
- 异常和日志是否遵循现有方式。
- 数据库、缓存和事务边界是否一致。
- 是否重复实现了已有能力。
4. 它是否存在安全和数据风险
重点包括:
- 鉴权与越权。
- 敏感信息泄露。
- SQL、命令、文件和模板注入。
- 数据覆盖、重复写入和部分成功。
5. 它怎样被证明是正确的
需要知道:
- 哪些测试已经存在。
- 哪些场景还没有覆盖。
- 如何验证异常、并发和依赖失败。
- 是否需要增加日志、监控或审计。
这 5 个问题决定了审查 Prompt 的基本结构。
二、使用 Prompt 前,先准备 4 类上下文
同一段代码,在不同项目中的审查结论可能完全不同。
例如,某个项目允许 Service 直接返回数据库对象,另一个项目则要求所有返回值经过 DTO 转换。
因此,在审查前我会尽量准备以下上下文。
1. 需求和验收标准
需求:
用户可以修改自己的收货地址。
验收标准:
- 只能修改本人订单。
- 已发货订单不允许修改。
- 地址必须经过格式校验。
- 修改成功后记录操作日志。
- 修改失败时不能改变原地址。
没有验收标准,AI 很难判断“实现不完整”还是“需求本来就没有要求”。
2. 相关项目约定
- Controller 只负责参数接收和权限入口。
- 业务规则由 Service 处理。
- 业务异常统一使用 DomainException。
- 数据变更需要在事务中完成。
- 日志中不记录完整手机号和地址。
- Service 层需要有单元测试。
3. 变更范围
本次修改:
- OrderController
- OrderService
- OrderServiceTest
不应修改:
- 登录模块
- 支付模块
- 用户注册流程
把“不应修改的范围”告诉 AI,可以减少它提出大范围重构。
4. 代码和测试
至少提供:
- 变更前后的核心代码。
- 直接调用方和被调用方。
- 相关实体、接口和异常定义。
- 已有测试。
- 必要的配置或数据库约束。
不要一开始上传整个仓库。
先给最小上下文,等 AI 发现缺口后再补充,审查结果通常更聚焦。
三、我的完整代码审查 Prompt
下面这份 Prompt 可以直接复制使用:
请作为一名严格但务实的代码审查者,审查下面的代码变更。
一、需求
<填写业务需求、范围和验收标准>
二、项目上下文
<填写技术栈、模块职责、异常、鉴权、事务、日志和测试规范>
三、变更范围
本次允许修改:
<填写文件或模块>
本次不应修改:
<填写文件或模块>
四、待审查代码
<粘贴代码、Diff 或相关文件>
请按以下顺序审查:
1. 需求一致性
- 是否完整实现了需求?
- 是否存在遗漏、误解或未确认的业务规则?
- 是否增加了需求之外的行为?
2. 正确性和边界
- 空值、非法值、极端值是否处理?
- 状态流转是否正确?
- 数据不存在、重复请求和失败重试如何处理?
3. 异常和数据一致性
- 异常是否被正确区分?
- 是否存在部分成功、错误回滚或异常吞掉?
- 事务、缓存、消息和外部调用边界是否合理?
4. 安全
- 是否存在鉴权、越权、注入、敏感信息泄露或资源滥用风险?
- 用户输入是否经过正确校验、参数化或编码?
5. 并发和幂等
- 两个相同请求同时到达时会怎样?
- 请求执行成功但响应丢失后重试会怎样?
- 消息重复消费或外部接口超时后重试会怎样?
6. 可维护性
- 是否符合项目已有分层和编码约定?
- 是否有重复逻辑、过长方法、隐含依赖或不必要的复杂度?
- 是否引入了未来难以修改的设计?
7. 测试和可观测性
- 现有测试覆盖了哪些场景?
- 还缺少哪些正常、边界、异常、安全和并发测试?
- 是否需要补充日志、监控、指标或审计?
输出要求:
- 只报告有依据的问题,不要为了凑数量而提出建议。
- 每个问题必须包含:严重程度、文件位置、触发条件、问题后果和最小修改建议。
- 严重程度分为 Blocker、High、Medium、Low。
- Blocker 和 High 问题优先输出。
- 项目事实、代码推断和待确认项分开说明。
- 如果没有发现问题,也要列出审查过的范围和剩余风险。
- 暂时不要直接重写全部代码。
最后输出:
1. 必须修复的问题
2. 建议修复的问题
3. 可以暂不处理的问题
4. 建议补充的测试
5. 仍然缺少的上下文
这份 Prompt 的关键不是写得长,而是让审查过程有固定顺序、有证据要求、有优先级。
四、要求 AI 使用统一的问题输出格式
如果只让 AI 自由发挥,审查结果通常不容易执行。
我会要求它使用下面的格式:
问题编号:CR-001
严重程度:High
文件位置:OrderService.java:86
问题类型:并发 / 数据一致性
问题描述:
先查询再写入,没有唯一约束或幂等控制。
触发条件:
两个相同请求在短时间内同时到达。
可能后果:
同一个用户可能创建两条重复订单。
代码证据:
<引用相关方法或逻辑>
最小修改建议:
增加业务幂等键,并在数据库层建立唯一约束。
建议测试:
模拟两个并发请求,验证最终只产生一条订单。
这个格式有三个好处:
- 它要求 AI 指出问题发生的条件。
- 它把问题和后果联系起来。
- 它让开发者可以直接把建议转换成任务。
不要满足于:
这里可能有并发问题。
你应该继续追问:
请说明具体在哪两个操作之间发生竞态,
需要什么输入或时序才能触发,
以及如何用测试稳定复现。
五、把一次审查拆成 3 轮
复杂变更不建议一次完成所有审查。
我更推荐分成三轮。
第一轮:需求审查
目标是确认“做的东西对不对”。
请暂时忽略代码风格,只审查需求一致性。
请比较:
1. 需求明确要求的行为。
2. 代码实际实现的行为。
3. 代码遗漏的行为。
4. 代码额外增加的行为。
5. 仍然需要人工确认的规则。
这一轮重点发现业务理解错误。
第二轮:风险审查
目标是确认“这段代码是否可能在线上出问题”。
请暂时忽略命名和格式,只审查运行风险。
重点检查:
- 边界条件
- 权限和敏感数据
- 异常和回滚
- 并发和幂等
- 数据库、缓存、消息和外部依赖
- 重试、超时和部分成功
这一轮重点发现隐蔽缺陷。
第三轮:维护审查
目标是确认“未来的开发者能不能安全地继续修改”。
请审查这段代码的可维护性,但不要把个人偏好当成问题。
请只指出有实际维护成本的事项:
1. 是否违反当前项目已有约定?
2. 是否存在重复逻辑或职责混乱?
3. 是否有难以测试、难以扩展或难以排查的设计?
4. 是否需要补充注释、文档或监控?
5. 哪些问题现在修复收益最高?
分轮审查可以降低 AI 一次输出太多低价值建议的概率。
六、让 AI 区分“缺陷”和“改进建议”
代码审查中最容易产生争议的,是把偏好当成缺陷。
例如:
- 方法有 30 行,不一定就是问题。
- 没有使用某种设计模式,不一定就是问题。
- 命名风格不同,如果符合项目约定,也不一定需要改。
- 一段代码可以进一步抽象,但当前范围内可能没有必要。
可以要求 AI 使用这套区分:
| 类型 | 判断标准 |
|---|---|
| 缺陷 | 在明确条件下会导致错误、风险或违反需求 |
| 风险 | 当前未必触发,但可能造成线上问题 |
| 维护问题 | 会明显增加理解、测试或修改成本 |
| 改进建议 | 可以更好,但不影响当前交付 |
| 个人偏好 | 没有项目规范或实际后果支持 |
对应 Prompt:
请把每条意见标记为“缺陷、风险、维护问题、改进建议或个人偏好”。
如果只是个人偏好,且没有违反项目规范或产生实际后果,
请不要作为正式审查问题输出。
这能让审查结果更公平,也更容易被团队接受。
七、让 AI 反向生成测试,而不是直接改代码
发现问题后,不要总是立刻让 AI 修复。
先让它把问题转换成测试场景:
请根据已经发现的代码审查问题,生成测试设计,不要修改生产代码。
每个问题请给出:
1. 前置数据。
2. 请求或操作。
3. 关键执行时序。
4. 预期结果。
5. 需要验证的数据库、消息、缓存或日志状态。
6. 测试应该放在哪一层。
优先覆盖 Blocker 和 High 问题。
例如,针对“重复提交可能创建两条记录”,测试不应该只调用两次方法,而应该明确:
准备同一个幂等键
↓
并发发起两个请求
↓
等待两个请求都返回
↓
检查数据库最终只有一条记录
↓
检查重复请求返回符合约定
先把风险变成可验证场景,再决定如何修改,通常比直接接受 AI 的修复方案更稳妥。
八、审查意见出来后,如何继续追问
高质量审查不是一次 Prompt 结束,而是一个追问过程。
追问 1:请给出代码证据
你认为这里存在问题,请指出具体文件、方法和触发条件。
如果无法从已提供代码确认,请标记为待验证,不要当作确定缺陷。
追问 2:请区分确定问题和潜在风险
请把刚才的问题分成:
1. 可以从当前代码直接证明的问题。
2. 需要结合配置、数据库约束或运行环境确认的风险。
3. 仅属于改进建议的内容。
追问 3:请给出最小修改范围
请针对 Blocker 和 High 问题,给出最小修改范围。
请说明:
- 必须修改哪些文件。
- 哪些文件不应被顺带重构。
- 需要新增哪些测试。
- 修改后如何验证没有影响原有行为。
追问 4:请重新审查修改后的 Diff
这是根据上一轮意见修改后的 Diff。
请重点检查:
1. 原问题是否真正解决。
2. 是否引入新的行为变化。
3. 是否扩大了不必要的修改范围。
4. 新增测试是否能证明修复有效。
这样才形成:
审查
↓
定位
↓
测试设计
↓
最小修复
↓
二次审查
九、我的代码审查结果模板
除了 Prompt,我还会要求 AI 最后输出一份简短结论:
## 审查结论
### 是否建议合并
- 是 / 否 / 修复后再审
### 必须修复
- CR-001:
- CR-002:
### 建议修复
- CR-003:
### 已确认覆盖
- 需求:
- 权限:
- 异常:
- 测试:
### 仍需人工确认
- 数据库唯一约束:
- 外部接口幂等能力:
- 生产配置:
### 合并前检查
- [ ] Blocker 问题已关闭
- [ ] High 问题已有处理结论
- [ ] 关键测试已执行
- [ ] 变更范围符合预期
这份结论适合放进 Pull Request 描述、开发记录或任务评论中。
十、使用代码审查 Prompt 的 5 个注意事项
1. 不要隐藏需求中的不确定性
如果业务规则还没确认,就明确告诉 AI。
不确定的信息应该成为待确认项,而不是被模型自动补全。
2. 不要只提供修改后的代码
最好提供 Diff,或者同时提供修改前后的关键逻辑。
代码审查不仅要看现在是什么,还要看改变了什么。
3. 不要把整个仓库一次性塞进去
上下文越多不一定越好。
先提供任务相关代码、调用方、测试和约束,缺什么再补什么。
4. 不要接受没有触发条件的问题
“可能有风险”不是完整结论。
至少要问清楚输入、时序、配置或数据状态。
5. 不要把 AI 的审查结果当作最终签字
AI 可以帮助你扩大检查范围,但最终仍然需要:
- 开发者阅读代码。
- 测试验证行为。
- 必要时进行本地调试和线上观测。
- 由有上下文的同事完成人工评审。
十一、我的代码审查 Prompt 检查卡
[ ] 我提供了需求、范围和验收标准
[ ] 我提供了项目约束和相关代码
[ ] 我要求 AI 区分事实、推断和待确认项
[ ] 我要求问题包含触发条件和代码证据
[ ] 我让 AI 按严重程度排序
[ ] 我优先审查业务、边界、安全、并发和一致性
[ ] 我没有把个人偏好当成正式缺陷
[ ] 我让 AI 把风险转换成测试场景
[ ] 我根据最小修改范围处理问题
[ ] 我对修改后的 Diff 做了二次审查
[ ] 我没有把 AI 的结论当作最终合并许可
十二、总结
一份好的代码审查 Prompt,不是让 AI 说出更多意见,而是让它更准确地指出:
- 哪些行为与需求不一致。
- 哪些边界条件会导致错误。
- 哪些异常可能造成数据不一致。
- 哪些权限和输入处理存在安全风险。
- 哪些并发和重试场景没有被覆盖。
- 哪些测试可以证明问题已经解决。
- 哪些建议只是偏好,不值得扩大修改范围。
我的使用原则是:
先给上下文
↓
再给审查标准
↓
要求证据和触发条件
↓
把问题转成测试
↓
最后做最小修复和二次审查
请记住:
代码审查的价值,不是让代码看起来更漂亮,而是让未来的错误更难发生。
下一篇文章,我们做一次阶段复盘:
周复盘:把 AI 当实习生,还是当工程搭档?
如果这篇文章对你有帮助,欢迎点赞、收藏、关注专栏。
也欢迎在评论区留言:你在代码审查中最希望 AI 帮你发现哪类问题?
✍坚持原创,求关注,点赞,收藏