AI 时代,Code Review 的重点彻底变了
上周Review一个PR的时候,遇到了一个挺典型的场景。同事用AI给公司的SaaS后台加了RBAC权限拦截器,200多行代码,格式工整、命名规范、单测全绿。

说实话,我差点就点Approve了。
结果多看了一眼角色校验的逻辑——AI写的是 userRole.contains("admin"),用String的contains方法来判断用户是不是管理员。
编译当然没问题,单测也全绿。因为测试用例里传的role就是"admin"这个字符串,contains精确命中,通过了。但生产环境里,系统还同时存在"superadmin"和"content_admin"这两个角色。contains("admin")直接把所有非管理员角色全部放行了——任何一个带admin子串的角色名都能绕过整个权限体系。
同事看了一眼我的注释,挠了挠头:"AI写的,我看着逻辑挺对的……没往contains那边想。"
这种"看起来全对,一上线就出事故"的事情,现在越来越常见。Black Duck的2026 OSSRA报告显示,代码库平均漏洞数同比上升了107%(来源:Black Duck, "2026 OSSRA Report")。更隐蔽的威胁来自npm生态里正在蔓延的"slopsquatting"攻击——AI在生成代码时幻觉出一个看起来完全合理的包名,比如lodash-utils-sync,开发者直接npm install,装了一个恶意仿冒包进去。代码能跑,行为"正常",直到数据被泄露才发现问题。
这些事故有个共同特征:
代码"看起来全对"——编译过、测试绿、逻辑通顺——但实际暗藏雷管。
数据比直觉更残酷
先看一组数字。
Faros AI在2026年3月发布了一份覆盖22,000名开发者、4,000个团队的报告(来源:Faros AI, "State of AI in Software Engineering 2026")。团队从低AI采用率过渡到高AI采用率后:
- 代码变更量上升了
861%
- 事故/PR比上升了
242.7%
- 开发者缺陷率从9%飙升到
54%
- 审查中位耗时增加了
441.5%
- 最触目惊心的数字:
31.3%的PR在零审查下直接合并
不是有人决定不审查,而是审查者根本跟不上产出量。代码在没有人类阅读的情况下就上线了,然后这变成了"正常"。
CodeRabbit对比了470个开源仓库的AI生成代码与人工代码(来源:CodeRabbit, 2025.12),结论是
AI代码的缺陷密度是人工的1.7倍
Black Duck的2026 OSSRA报告更直接:代码库平均漏洞数同比上升了
107%
一句话总结:代码产出翻了4倍,人类阅读速度没变。
瓶颈从"写"转移到了"审"。
而且旧的CR方法,已经审不动AI的代码了。
AI代码在CR中的六种典型"假动作"
旧的CR检查清单管用,是因为人类写代码时的错误模式是可预测的:命名不规范、边界条件漏判、逻辑写反了。但AI的失败模式完全不同。它不是"写错了",而是
"写了个看起来对但其实不对的东西"
以下六种模式,在AI生成的PR里大概率遇到过。
1. 幻觉依赖——名字看起来像真的
AI知道Spring Boot有十几个官方starter,也知道命名规则是spring-boot-starter-xxx。于是当它需要接入一个认证中间件时,它会自然地给pom.xml或build.gradle里加一个spring-boot-starter-auth-v3。
这个名字完全符合命名规范,版本号也合理。但它不存在于Ma ven Central。AI不是"查了官方仓库发现没有",它是根据见过的几百个starter名字自己拼出来的。
更隐蔽的变体是npm生态里的slopsquatting——AI幻觉出一个包名,恰好有一个恶意行为者注册了同名的仿冒包,你的npm install装进去的不是幻觉,是一颗定时冲击波。
怎么查
2. 正确但不对——读起来流畅,逻辑全错
AI写的代码读起来极其通顺,但一到边界条件就崩。
复制代码// AI写的一个企业数据同步服务——读起来完全没问题
public void syncEmployees(List dataList) {
List entities = new ArrayList<>();
for (EmployeeDTO dto : dataList) {
entities.add(convert(dto));
}
employeeMapper.batchInsert(entities);
}
看起来:遍历、转换、批量入库。没什么问题。
实际上:dataList传入5000条没问题,生产环境上游系统一次推了30万条——MyBatis批量插入直接撑爆内存,事务超时回滚。同步任务卡死,下游所有依赖这个同步数据的报表全部空白。
AI不会自动加分批处理、不会设置批次上限、不知道你们的JVM堆只有2G。它只生成"最直接的实现",不生成"最安全的实现"。
怎么查
3. 装饰性安全——写了,但没用
AI知道"安全检查"是好的,所以它会加。但它加的是
看起来有、实际上能绕过的
复制代码// AI加了一个auth检查
@PreAuthorize("hasRole('USER')")
public UserDto getUser(Long id) {
// 但如果传别人的ID,没做归属校验
return userMapper.selectById(id);
}
注解在、角色检查在,但任何人都能通过改URL里的ID参数看到其他用户的数据。AI完成了"有安全检查"这个任务,但没有理解"这个API真正需要保护什么"。
怎么查
4. 测试只绿不验证
AI写的测试最容易迷惑人——绿了,就以为过了。
复制代码@Test
public void testSyncEmployees() {
// AI生成的测试——测了等于没测
service.syncEmployees(Arrays.asList(mockDto1, mockDto2));
// 没有断言!只要不报异常就绿
}
或者更隐蔽的:
复制代码@Test
public void testSyncEmployees_HappyPath() {
service.syncEmployees(createTestData(100));
List result = employeeMapper.selectAll();
assertEquals(100, result.size());
// 这个断言是真的在验结果,但只有happy path
}
第一个测试什么都不验证。第二个验证了主路径——100条数据同步成功——但你没看到它没测30万条会怎样、没测空列表、没测单条格式损坏。
怎么查
5. 偷偷扩大修改范围
你让AI改登录逻辑,它顺便"优化"了旁边的注释、重构了一个工具类、删了一个它觉得没人用的常量。
"顺手"是AI的默认行为,不是Bug。但每次超范围的修改都是额外风险。
怎么查
6. 注释和代码说了两套话
AI写的注释通常比代码质量高——因为注释是自然语言生成,是它的强项。代码逻辑是结构化生成,反而容易歪。
复制代码// 当任务执行超时时,重新入队
if (task.getStatus() == TaskStatus.FAILED) {
taskQueue.enqueue(task);
}
注释说"任务超时",代码判的是"任务失败"。超时和失败是两个完全不同的状态。人和AI读注释时被"超时重试"这四个字带跑了注意力,以为这段代码处理了超时场景。实际上超时的任务根本没进到这个分支。流程里超时任务永远卡在队列里不动。
怎么查
AI时代的CR新检查清单
旧的CR检查清单(变量名、缩进、用const还是let)已经没意义了——格式化工具和linter在保存那一刻就处理完了。
以下是基于metacto.com和aipolicydesk.com两份2026年最佳实践(来源:metacto.com "Code Review for AI-Generated Code: 2026 Standards";aipolicydesk.com "Reviewing AI-Generated Pull Requests"),做了本土化的AI专属CR清单:
1. API真实存在且版本匹配。
2. 没有幻觉依赖。
3. 没有硬编码密钥。
secretKey = "abc123"。
4. 输入校验落实到每个外部入口。
5. 认证和授权覆盖每个新增端点。
@PreAuthorize就完事。
6. 异常处理是真的在"处理"。
catch(Exception e) {}——空块,这就叫"装饰性异常处理"。
7. 测试覆盖失败路径。
8. CI没被弱化。
9. 架构边界完整。
10. 作者能解释代码。
不是让你更慢,是让你把时间花对地方
读到这里可能在想:10条检查清单,每条都手动查,PR永远审不完。
实际做法不是手动逐条过。是用三层策略把审查量分层消化。
Cloudflare公开过他们内部AI Review系统的数据(来源:Cloudflare, internal metrics, 2026):30天内处理了131,246次AI Review,中位耗时3分39秒,成本$1.19/次,人工跳过率仅0.6%。
模型是这么排的:
L1:自动检查——零人力。
L2:AI Review——自动跑,人看结果。
L3:人类判断——时间和注意力集中在正确的地方。
判断业务逻辑是否正确、判断架构是否健康、判断这个改动是否真的解决了问题。
人的时间花在AI做不了的事情上。
落地:三个动作这周就做
1. PR模板加一栏。
AI参与度:≥80% / 50% / ≤20% / 0%。不是追责,是给Reviewer一个信号——高AI参与度的PR,默认用AI专属CR清单审查。
2. 400行硬上限。
3. 问责铁律。
这三条不需要买新工具,不需要改CI,今天就能在团队里推行。
CR过去是"代码的质检",现在是"AI产出的安全门"。
跳过CR的代价不是代码质量稍微降一点。Faros AI那份报告里,31.3%的PR在没有人类阅读的情况下直接上线。相当于每三个AI写的改动,就有一个未经任何审查进了生产环境。
这才是AI时代CR真正的重点——不是查格式、不是查命名、不是跟你争论三目运算符该不该换行。是确保"看起来全对"的代码,是真的对了。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名