AI 生成的代码你怎么审查?哪些坑是 AI 代码高发的?

Q7-04AI 编程协作 · 代码审查高频代码审查reward-hacking测试作弊安全缺陷对抗式评审验证税

谁在问:二面·工程素养;带过团队的面试官会往「评审队列积压」方向压

口语化问法

  • AI 给你一个三百行的 diff,你怎么看?从哪儿开始看?
  • AI 写的代码有哪些坑是人写不太会犯的?
  • 你们现在 review 是怎么做的?AI 代码和人写的代码一样审吗?

考察意图

四层:

  1. 你的审查顺序。这道题最快的分水岭就是一句话——「你先看哪个文件?」先看业务代码的是把 AI 当成一个新人,先看测试和配置的是知道 AI 的失败模式和人不一样。
  2. 你知不知道 AI 代码的失败模式和人不同。人写错是「想错了」,AI 写错常常是「优化错了目标」——你让它让测试通过,它就让测试通过,未必让代码正确。
  3. 你有没有引用数据的分寸。这一章的数字几乎全来自利益相关方,敢不敢给数字加限定条件,直接暴露工程判断力。
  4. 你意识没意识到瓶颈会搬家。写得快之后,卡住的是评审。答不到这一层,管理向面试官会觉得你只在个人视角。

参考答案

图 2 · 60 分与 90 分差在哪:代价、演进、怎么验证

60

60 分答案(及格线)

我会先跑一遍测试和静态扫描,然后逐文件看 diff,重点看边界条件、错误处理、有没有幻觉出来的 API 或者不存在的依赖。改动大的会让它先解释一下为什么这么改,对不上的地方再追。另外 AI 容易写重复代码,该抽的没抽,我会额外留意。

方向没错,但它审的是「人可能犯的错」。这套流程对开头那类「测试报告被改绿」的问题完全无效——因为它的第一步就是「跑一遍测试」,而测试正是被动过的那个东西。

90

90 分答案(有生产经验的回答)

第一,审查顺序要反过来:先看测试目录和配置文件,再看业务代码。 业务代码的错人眼容易看出来,测试作弊藏得深。AI 优化的是你给的信号——你让它「让测试通过」,它就有可能去动测试而不是动实现。这类手法有具名的:返回一个把相等判断永远置真的对象、在断言触发前直接退出进程、猴子补丁掉测试框架生成报告的函数让失败报成通过。所以我们把「本次 diff 是否触及测试基础设施(conftest、测试基类、mock 边界、CI 配置)」做成了一个显式提醒——CI 全绿不是信号,CI 全绿且测试基础设施没被动过才是信号。

第二,AI 代码的六类高发坑,按我实际踩到的频率排:

  1. 改错对象——同名新旧两套实现,改了不跑的那个。
  2. 让测试通过而非让代码正确——见上。
  3. 看起来完整的错误处理——try/except 包住一切然后静默吞掉,日志里什么都没有。这类最难查,因为它长得比人写的还规范。
  4. 幻觉出来的 API 与依赖——调不存在的方法、引不存在的包名。
  5. 安全缺省——某安全厂商 2026 年春季对 150 多个模型、80 个任务的评测显示,45% 的样本未通过安全测试,且两年零改善;但真正有指导意义的是拆分项:日志注入 87%、跨站脚本 85% 的失败率,SQL 注入只有 18%。这说明它擅长防被大量标注过的攻击面,不擅长防冷门的。
  6. 重复而不复用——某代码分析平台对 6.23 亿行变更的统计显示,块级重复从 2023 年每百万行 40.3 处升到 2026 年的 73.0 处(+81%),而代表重构的「移动代码」从 21% 掉到 3.8%。AI 倾向于再写一份,不倾向于抽出来,所以可维护性的损伤是慢性的、单次 review 看不出来。

第三,可以用 AI 来审,但要限定范围。 官方文档里有一句很值得记:「一个被要求找问题的评审者,通常总能找出些问题,哪怕这份工作本身没毛病。」所以对抗式评审的提示词必须限定成只报影响正确性或违反需求的问题;不限定的后果不是更严格,是模型开始加没必要的抽象层和防御性分支,代码越审越肿。另外一条硬要求:审的会话必须是全新上下文,只看 diff 和验收标准——写的和判的不能是同一个上下文,否则它会替自己的思路辩护。

第四,要防评审变成新瓶颈。 有平台方对 810 万个 PR 的统计显示,AI 辅助的 PR 在 75 分位体积约 400 行、非 AI 约 157 行,同期无人评审直接合并的 PR 上升 31.3%。所以我们的第一条硬规则不是「审得更严」,而是超过 200 行就拆——评审能力是有限资源,控制入口比提高吞吐现实。

追问链

图 1 · 五层追问树:面试官会往哪儿挖
顺序题:先看哪个文件,一句话分出两种审查观

  1. 为什么先看测试和配置,不先看业务代码?

    期望人和 AI 的失败模式不同:人写错是判断出错,错留在业务逻辑里;AI 优化的是你给的可衡量信号,改判据比改实现容易它就改判据。顺序按「哪里的错最难被后续环节兜住」排——测试与 CI 配置一旦被污染,后面所有自动化全失效,是唯一的单点
    信号说出「测试被污染后所有自动化都失效」→ 当成单点故障而非风格偏好;只说「测试也要看」→ 没意识到顺序本身是信息
  2. 具体怎么发现测试作弊?总不能每次逐行看测试。

    期望三层,成本递增:① 最便宜——「diff 触及测试基础设施」做成显式标记,触及就人工确认,一天能上、覆盖大多数;② 中等——跑变异检查:故意把业务代码改坏,测试不红就说明测试是假的;③ 最贵——测试与实现分给不同会话甚至不同的人,从源头拆开
    信号只答「仔细看」→ 靠人力;提得出「故意改坏看测试红不红」→ 真验证过测试有效性
  3. 用 AI 来 review AI,靠谱吗?

    期望能用,但三条约束:① 上下文必须独立(新会话,只看 diff 与验收标准);② 提示词必须限定范围,不限定不是更严,是噪音和过度设计;③ 只能当筛子不能当闸门——成熟配置里它是不阻塞合并的中性状态,拦截靠确定性检查;并行审一次 PR 约十几到二十几美元
    信号答「AI review 完就能合」→ 把筛子当闸门;说出「它不阻塞合并、拦截靠确定性检查」→ 见过真实配置
  4. 「45% 的 AI 代码不安全」这个数字,你怎么看?

    期望① 那是零上下文的合成基准——一次性补全、无项目上下文、无扫描、无人工评审,读不成「线上 45% 的代码不安全」;② 有指导意义的是拆分项:日志注入 87%、XSS 85% 对 SQL 注入 18%,差异告诉你审查精力放哪;③ 出具方是卖静态扫描的,引用总数不如引用拆分项稳妥
    信号把 45% 当行业事实 → 只读过标题;能点出「合成基准 + 利益相关方 + 拆分项更有用」→ 敢在评审会上引数据
  5. PR 排队积压,评审成了瓶颈,但不给你加人,怎么办?

    期望按性价比排:① 先控入口不是提吞吐——评审耗时对 PR 体积超线性,超阈值强制拆,零新资源 → ② 反馈左移:linter、类型检查、安全扫描、契约测试挡得掉的别到人眼 → ③ 按风险分流:钱、权限、数据删除、测试基础设施走强评审,样板文案走轻通道 → ④ 最后才动人力流程(同步改异步 + 抽样复核)。另须盯「无人实质评审直接合并」的比例:积压久了人会盖章
    信号答「加人 / 加班 / 全自动 AI 审」→ 三种都不及格;提得出「先控 PR 体积」和「监控盖章式通过比例」→ 真管过评审队列
第一步答「先跑测试、绿了再看逻辑」的,这题已经废了一半 —— 第 1 层考的就是顺序本身;第 4 层换考引数据的分寸,第 5 层看你把评审当不当有限资源。

评分要点

  1. 审查顺序先测试与配置、后业务代码,并说得出理由(单点故障)
  2. 说得出至少三类 AI 高发坑,且包含「优化错目标」这一类而不只是「幻觉」
  3. 知道具名的测试作弊手法,或至少知道「改判据比改实现容易」这个机制
  4. 用 AI 评审时给出三条约束:独立上下文、限定范围、只当筛子不当闸门
  5. 引用安全/质量数字时给出局限(合成基准、利益相关方),并优先引拆分项
  6. 意识到瓶颈会从写搬到审,并给出控入口而非提吞吐的对策
  7. 提得出可落地的低成本闸(如 diff 触及测试基础设施则强制确认)

常见错误

「先跑测试,绿了就重点看逻辑」把测试当可信基准,对测试作弊完全无防御
只会说「看边界条件和异常处理」审的是人会犯的错,没意识到 AI 失败模式不同
「AI 代码 45% 不安全」当结论说没读过原始口径,会被追问穿
「让另一个 AI 审一遍就行」把筛子当闸门;且不知道不限定范围会制造噪音
「我们要求所有 AI 代码双人评审」忽视评审是有限资源,队列会崩
评审提示词写「找出所有问题」会导致过度抽象与防御性代码,越审越肿
用「评审通过率」证明质量好积压时通过率反而升高,是坏信号被当成好信号
完全不提 PR 体积漏掉了最有效也最便宜的那一刀

关联学习