如何审查 AI 生成的代码?

考查重点:需求符合度与可触发缺陷。对照需求检查 diff 与调用链,用独立用例验正常、边界与失败行为;重点核权限、状态和副作用

本题目录

参考答案

核心回答

拿到 AI 生成的 diff,我会先把需求允许改变的行为说清楚,再沿实际调用链检查实现,最后用独立于生成结果的用例验证判断。AI 对代码的解释可以帮助导航,审查结论要落到代码位置、触发条件和实际行为。

  1. 对照需求和改动范围:明确输入输出、兼容性和必须保留的业务规则,查看哪些文件、依赖、配置和测试发生了变化。
  2. 逐文件追踪控制流与数据流:从入口读到服务、存储或外部调用,检查正常、异常和提前返回分支;追踪用户输入、身份、资源归属和敏感数据经过哪些处理。
  3. 验证实现与测试:检查实际依赖版本和接口,再从需求推导正常、边界与反例,确认测试会在关键行为出错时失败,而不是只验证 AI 自己的实现假设。
  4. 形成可验证的问题说明:指出具体文件和位置、什么输入或状态触发、预期与实际差异及影响;修复后重跑复现用例和受影响的回归。

例如知识库接口新增缓存后,正常查询可能都通过,但若缓存命中直接返回,绕过了原来的文档权限检查,就会出现数据泄露。审查时要把新增的快捷分支放回完整调用链中看,不能只看缓存代码是否写对。

先确定这份 diff 应该改变什么

先读任务说明、接口契约和已有实现,整理出几项能判断对错的行为:什么输入应成功,什么情况应拒绝,返回什么,是否允许改变数据,以及哪些旧调用方必须继续工作。

接着看文件清单和整体 diff,分清业务实现、测试、配置、依赖与生成文件。局部修复如果顺带改变了公共接口、删除回归用例或升级核心依赖,就要查明这些变化与需求的关系。锁文件变化也需要核对原因,不能只看业务源码。

AI 的改动摘要可用来找到入口,但要对照真实 diff。尤其检查删除项:原来的权限过滤、错误处理、超时传播和数据校验,可能在“简化代码”时被一并删掉。审查应理解修改后的行为,也要知道旧行为为什么存在。

沿调用链阅读,而不是只看新增行

先找主要入口,例如 API 路由、任务执行函数或用户操作处理器,再看其调用的服务、存储层和相关测试;遇到不清楚的约定,回读完整函数与调用方。

阅读时可以选一条正常路径和一条失败路径,把具体值代入:

  • 控制流:条件分支、提前返回、异常捕获、重试和清理分别会走到哪里?失败后是否仍继续写入成功状态?取消或超时是否真正终止后续工作?
  • 数据流:参数从哪里来,是否转换过类型、单位或时区?身份和租户信息是否一直传到查询条件?敏感字段是否进入日志、缓存或返回值?
  • 跨文件契约:调用方传的类型、被调方要求的参数、返回结构和异常语义是否一致?返回值由列表改成迭代器后,旧调用方是否仍按列表使用?

性能和并发也要结合这条路径判断。看到数据库调用在循环里,就查实际查询次数;看到共享状态和重复请求,就检查状态更新、幂等和事务边界。不能仅凭一个函数较长就判定性能差,也不能只因为出现某个算法或库名就判定安全。

一个审查示例:缓存命中绕过文档权限

下面是用于说明方法的简化场景:原知识库回答接口按用户的文档可见范围检索;新 diff 增加按问题文本共享的答案缓存,命中后提前返回。

审查要分别走两条路径。未命中时,程序仍经过权限过滤,看起来正常;命中时,却可能完全不再检查答案依赖的资料是否对当前用户可见。关键位置是缓存命中后的提前返回分支,根因是它改变了原有授权检查的执行条件。

可以构造反例:用户甲有权阅读某篇内部文档,先查询并写入缓存;用户乙无权阅读该文档,再提出相同问题。预期是乙的回答不包含该文档内容。测试必须走真实接口和缓存命中路径,并保留用户权限差异;如果把检索和鉴权全部 mock 成成功,测试就检测不到这个缺陷。

修改应同时检查缓存作用域、授权检查位置和撤权后的失效策略,例如按租户及授权范围隔离缓存,并在使用缓存证据时核对当前可见性。只缩短 TTL 不能证明权限正确。这里的结论来自触发路径与反例,不是“用了缓存就有风险”的泛泛判断。

依赖与 API 要查当前项目实际使用的版本

遇到陌生方法或可疑参数,先看项目依赖声明、锁文件和实际安装版本,再查对应版本的官方文档、类型定义或源码。接口名称看起来合理,不代表这个版本真的提供;IDE 没报错,也可能只是依赖缺少类型信息。

若发现不存在的 API、同步函数被当成异步调用、参数语义变化或不兼容的返回结构,应沿调用点做最小复现,确认错误发生在哪一层。修复优先使用项目已有依赖的有效接口;需要升级时,再检查调用方兼容性和升级影响,而不是为了适配 AI 代码直接更新全部依赖。

新增依赖要确认真实存在、来源可靠,并与项目当前运行环境兼容。检查重点跟随本次新增或改变的依赖和接口。

测试是否有独立判断能力

先从需求写出预期结果,再检查测试是否验证这些结果。重点看断言内容、测试数据和替身边界:只断言“没有异常”、把待验证逻辑本身 mock 掉,或用实现代码计算期望值,都可能让错误实现通过。

可以挑一个关键业务规则做反向验证:暂时移除权限条件、改错边界比较或破坏返回字段,观察对应测试是否失败。这个办法用于检验重要测试的有效性,不要求每次审查都做完整变异测试。对新增行为,确认旧实现会因缺少该行为而失败;对缺陷修复,确认用例能复现修复前的错误。

运行范围与改动对应:先跑复现用例及相关单元测试,涉及接口、数据库或权限链路时再跑必要的集成验证;UI 行为要实际操作关键路径。类型、lint 和安全扫描能补充发现问题,但无法代替业务预期。若测试失败,还要区分本次回归、原有失败和环境问题,不能通过删用例或放宽断言掩盖差异。

怎样把审查发现写清楚

一条有用的意见应包含:位置、触发条件、预期与实际差异、业务后果,以及可验证的修改方向。例如:“缓存命中分支在文档可见性检查前返回;无权限用户命中其他用户生成的缓存时会得到内部资料,应验证用户隔离和撤权场景。”

确定的缺陷与待确认的问题要区分。若只看到调用点,还没读到权限中间件,就先查实现,不能直接报“缺少鉴权”;若某处依赖环境才能判断,说明缺少哪项配置或运行证据。风格建议与会导致错误的缺陷也要分开,避免重要问题被大量细枝末节淹没。

修复后检查新的 diff,确认问题路径已改变、反例通过且原有正常行为保留。AI 互审可以补充疑点,但第二个模型的“通过”不能代替这些证据;整套生成约束与反馈流程可继续看如何约束并验证 AI 生成代码的质量。

追问:不熟悉这段代码,还能审吗?

可以先复述输入输出与调用关系,再查陌生接口和业务规则,用可复现的小例子验证理解。AI 可以协助解释代码、列出潜在分支,但解释需要与实现对照。涉及自己无法可靠判断的并发、权限或数据迁移逻辑,应请熟悉该模块的人补充审查,并明确自己已经检查的范围,不能用“测试绿了”替代未完成的判断。

对应教程

  • 第 27 章:Skills 技能与 AI 编程工具实践:§10 的代码审查 Skill 示例给出安全、正确性、性能、测试缺口及问题定位的基本要求;本文进一步落到具体 diff 的调用链阅读、独立反例和修复验证。Skill 是审查指导,实际执行了哪些检查仍要看代码与运行结果。

参考资料

相关面经

12 篇

网易

AI 应用开发工程师
日常实习一面、二面
查看原面经 →
当系统上线后 AI 生成了大量代码导致人工看不过来时,人工审查的重点究竟应该看什么?
打开 GitLab 看到 AI 为某个需求或单子提交了大量的文件和代码时,具体应该看哪些文件或内容?

阿里巴巴

AI 应用开发工程师
秋招二面
查看原面经 →
项目追问
这个项目中哪些代码和设计是你亲自完成的,哪些是 AI Coding 辅助完成的?你如何验收 AI 生成的代码?

华勤

大模型算法工程师
秋招
查看原面经 →
自己会看代码吗

懂车帝

Agent 应用开发工程师
秋招一面
查看原面经 →
追问
在使用Vibe Coding辅助开发时,人工代码审查应该重点关注哪些内容?

腾讯

测试开发工程师
实习一面
查看原面经 →
怎么审查AI生成的代码
展开剩余 7 篇面经

亚信科技

Java 开发工程师
实习
查看原面经 →
AI存在大模型幻觉,开发过程中是否独立思考代码逻辑?遇到依赖不符怎么处理?

杭州可见信号科技

AI 应用实习生
实习
查看原面经 →
那你怎么去保障 AI 所编程出来的东西不会有一些潜在的风险呢?

阿里巴巴

AI 应用开发工程师
实习一面
查看原面经 →
ai生成代码很好,但它是不负责的,怎么进行一个代码的review;功能完备,安全,性能要不要考虑

蚂蚁集团

Agent 开发工程师
实习一面
查看原面经 →
你怎么确保AI写的代码没问题?用的是单agent吗?

蚂蚁国际

AI 应用 / Agent 开发
暑期实习一面
查看原面经 →
你怎么确保AI写的代码没问题?用的是单agent吗?

阿里巴巴

AI 应用开发工程师
暑期实习二面
查看原面经 →
对AI代码的审查你用的是开源框架还是什么方式

米哈游

AI 应用 / Agent 开发
查看原面经 →
你会怎么去测试ai写的代码?

收录题集

2 个来源,共2 份题集

Vibe Coding 面试题

卡码笔记 · 个人整理 · 1 条原题

查看题集 →

AI 编程面试题

小林 Coding · 个人整理 · 1 条原题

查看题集 →

相关题目

4 题