如何审查 AI 生成的代码?
未标记
考查重点:需求符合度与可触发缺陷。对照需求检查 diff 与调用链,用独立用例验正常、边界与失败行为;重点核权限、状态和副作用
本题目录
参考答案
核心回答
拿到 AI 生成的 diff,我会先把需求允许改变的行为说清楚,再沿实际调用链检查实现,最后用独立于生成结果的用例验证判断。AI 对代码的解释可以帮助导航,审查结论要落到代码位置、触发条件和实际行为。
- 对照需求和改动范围:明确输入输出、兼容性和必须保留的业务规则,查看哪些文件、依赖、配置和测试发生了变化。
- 逐文件追踪控制流与数据流:从入口读到服务、存储或外部调用,检查正常、异常和提前返回分支;追踪用户输入、身份、资源归属和敏感数据经过哪些处理。
- 验证实现与测试:检查实际依赖版本和接口,再从需求推导正常、边界与反例,确认测试会在关键行为出错时失败,而不是只验证 AI 自己的实现假设。
- 形成可验证的问题说明:指出具体文件和位置、什么输入或状态触发、预期与实际差异及影响;修复后重跑复现用例和受影响的回归。
例如知识库接口新增缓存后,正常查询可能都通过,但若缓存命中直接返回,绕过了原来的文档权限检查,就会出现数据泄露。审查时要把新增的快捷分支放回完整调用链中看,不能只看缓存代码是否写对。
先确定这份 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 是审查指导,实际执行了哪些检查仍要看代码与运行结果。
参考资料
- 国内:Onefly / zero2Agent:AI 代码分析与测试:参考代码依赖与调用关系分析、反例和最小复现的方法,组织正文的调用链审查、接口核验及独立用例验证。
- 国内:JavaGuide:单元测试到底是什么?应该怎么做?:借鉴测试替身隔离及单元、集成验证的分工,说明正文为何要检查 mock 边界、跨层契约,并在修复后做针对性回归。
- 国内:阿里云:代码评审——PR 合并前先过一遍 diff:借鉴跨文件类型对照、异常追踪及缓存作用域的审查思路,补充正文对缓存命中绕过权限的分析,并按位置、触发条件和后果组织审查意见;资料中的模型效果与耗时不作通用结论。
- 国外:Google:What to look for in a code review:依据 Functionality、Tests、Every Line 与 Context 的审查要点,说明正文中理解真实行为、检验测试有效性及回读调用上下文的要求。
- 国外:GitHub:Review AI-generated code:参考 Verify context and intent、Scrutinize dependencies 与 AI-specific pitfalls 的建议,补充正文对需求偏差、虚构依赖和 API,以及删改失败测试的检查。
相关面经
12 篇网易
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写的代码?



