AI 生成的代码是待验证的变更
语法正确、测试通过都不等于解决了正确的问题;六类失败模式与一套按证据链检查的顺序。
一句话结论
AI 生成的代码应该被当作待验证的代码变更,而不是正确答案。需要检查的是:它是否解决了正确的问题、是否使用真实且适用的 API、边界条件是否正确、有没有安全问题,以及测试是否真的证明了需求。
为什么「看起来对」不够
一段代码可以同时做到语法正确、能编译、跑通一次 happy path,甚至有测试通过,仍然是错的。它可能误解需求、漏掉边界、调用不存在或已过时的接口,也可能通过修改测试来掩盖实现问题。
审查的重点不是「像不像专业代码」,而是证据是否支持它满足当前任务。
六类常见失败模式
1. 解决了错误的问题
最危险的不一定是语法 bug,而是实现与需求错位。任务只是阻止同一进程内的重复执行,AI 却引入 Redis 分布式锁。代码能跑,但问题规模和方案不匹配。
检查:原任务的输入、输出和约束是什么;改动是否超出必要范围;新增的复杂度有没有真实需求支撑。
2. 编造或误用 API
模型可能生成真实存在但版本不适用的接口,也可能生成根本不存在的参数、包或方法。函数名「很像真的」不能作为接受理由。
检查顺序:项目实际版本 → 官方文档或类型定义 → 真实运行或最小实验。
3. 忽略边界和错误路径
典型遗漏包括空输入、0、负数和最大值,null / undefined,超时与网络失败,并发与重复提交,文件不存在或权限不足。
有效做法是拿具体输入手动走一遍关键路径,再用测试覆盖容易出错的边界。
4. 引入安全问题
AI 代码仍然需要正常的安全审查:SQL 是否参数化,用户输入是否验证和编码,secret 是否写进源码、日志或 URL,新权限是否超出任务需要,错误响应是否泄露实现细节。
「这是 AI 写的」既不增加也不减少这些要求。
5. 产生不必要的复杂度和技术债
缺少项目边界时,AI 容易给出一个「完整方案」,里面包括当前根本不需要的抽象、依赖、缓存、队列或重构。
判断方法很简单:没有这层复杂度,当前需求是否仍然能可靠完成?如果能,就需要说明为什么还要引入它。
6. 测试看似通过,但没有证明需求
低价值测试包括:复制实现逻辑、只覆盖 happy path、删掉或 skip 失败测试、修改断言迎合错误实现、mock 掉真正需要验证的边界。
所以「tests passed」只是证据的一部分,还要看测试究竟验证了什么。
按证据链检查,而不是找「AI 味」
- 原任务与验收标准
git diff:到底改了什么- 关键路径与边界
- API、依赖与版本事实
- 安全与数据边界
- 测试、build、日志或实测
- 是否存在无关改动
第一步说不清,后面的代码质量判断很容易失去目标。
一个最小例子
function monthNumber(date) {
return date.getMonth();
}
语法正确。但如果需求是返回人类习惯的 1~12 月,它就少了 + 1。问题不是能不能运行,而是返回值语义是否满足需求。
最小记忆版
- AI 输出是候选改动,不是事实。
- 先看是否解决正确问题,再看代码风格。
- API 与版本事实去真实来源验证。
- 边界、安全和错误路径不能等模型主动提醒。
- 测试通过不等于测试有效。
- 最终验收看 diff、测试、日志和真实运行证据。