代码 Agent 的四种幻觉:为什么测试全绿,上线还是炸
编程 Agent 生成的代码通过测试却上线出事,根源在四类幻觉——测试自证、依赖虚构、边界省略、语义漂移。本文给出每一类的识别信号与防护措施,附一份 Code Review 检查清单。
“测试全过了,为什么线上炸了?”
在代码 Agent 普及之后,这个问题出现得比以前频繁得多。原因并不神秘:Agent 很擅长写出让测试通过的代码,而测试本身常常是它一起写的。
这构成了一个闭环的自证系统。下面四种幻觉,是这类事故的主要来源。
幻觉一:测试自证
Agent 写实现时,顺手写测试。它写出的测试,往往只覆盖自己实现里已经处理的情况——于是测试通过,但盲区与原实现完全重合。
典型信号:
- 测试文件和实现文件在同一次提交里生成
- 测试用例的断言只验证”函数返回了东西”,不验证具体值
- 覆盖率很高,但异常路径一个都没测
防护:
- 先写测试、再写实现,且两步由不同上下文完成(中间可以人工审一次测试)
- 强制要求每个函数至少包含一个”输入非法”的用例
- 用变异测试抽查:故意改坏一行实现,看测试是否变红。没变红说明测试是摆设
最后一条是成本最低的有效检验。 一个 Agent 写的测试套件,变异检出率通常只有 30–50%,人工写的在 70% 以上。
幻觉二:依赖虚构
Agent 会调用一个不存在的方法,或者用了一个真存在但签名不对的参数。
它不是”编造”,而是基于训练数据里的常见模式做了合理推测。因为语言模型的目标是生成”看起来对”的代码。
典型信号:
- 调用了某个库的高版本才有的 API,但项目锁在低版本
- 使用了
dict.get(key, default)之外的、看似合理实则不存在的参数名 - 导入路径微妙地错了(
from x.y import zvsfrom x import z)
防护:
- 必须真的运行。这一步没有替代方案,人眼几乎抓不到
- 锁定依赖版本,并在提示中明确告知项目所用版本
- CI 里加类型检查(mypy / tsc strict),能拦住相当一部分签名错误
- 装包时禁止静默回退到”相近的包名”
一个实用做法:给 Agent 一个”只允许 import 项目已有的依赖”的白名单,超出则要求它先说明理由。
幻觉三:边界省略
Agent 写出的 happy path 通常干净、可读、符合规范。缺的永远是这些:
- 空输入、超长输入、非 ASCII 字符
- 网络超时、重试、幂等
- 并发写、事务边界
- 权限校验(它默认调用方是可信的)
- 分页边界(第 0 页、最后一页)
这类问题测试不会发现,因为测试也是它写的,同样跳过了这些路径。
防护:
- 在提示中列出”必须处理的边界清单”,逐项要求说明如何处理
- 对涉及外部 IO 的函数,强制要求超时参数
- 对涉及数据写入的函数,强制要求事务与幂等设计
- 对涉及用户数据的接口,强制要求权限校验代码可见
在 Code Review 时优先看这些,而不是看业务逻辑写得对不对。 业务逻辑 Agent 通常写得比人清楚,边界处理才是它系统性薄弱的地方。
幻觉四:语义漂移
这一种最隐蔽。代码语法正确、测试通过、逻辑也自洽——但它解决的问题和你要解决的不是同一个问题。
典型场景:你说”删除过期会话”,它实现了”删除超过 30 天未更新的会话”,但你的业务定义是”超过 24 小时无活动的会话”。
它没有理解错,它是合理地补全了你没说的话,然后按补全后的理解实现。
防护:
- 需求描述里必须含可验证的判定条件,而不是笼统动词
- 让 Agent 在写代码前先输出一段”我理解的实现计划”,人工确认后再让它动手
- 使用具体示例作为验收标准:「输入 A 应为 B」而不是「处理好边界」
“先复述计划再执行”这一步,是防语义漂移最有效的动作,成本只有一轮对话。
Code Review 检查清单
给 Agent 生成的代码做 review 时,按这个顺序看:
- 有没有新引入依赖?是否在白名单内?
- 外部调用是否有超时、重试、错误处理?
- 涉及写数据的操作是否有事务与幂等?
- 涉及用户数据的路径是否有权限校验?
- 空值、超长、异常输入的处理是否可见?
- 测试是否覆盖了失败路径?做一次变异测试抽查
- 实现是否与需求的可验证定义一致(而不是与”合理推测”一致)?
- 有没有删掉或改动了原有的测试?(常见且危险)
最后一条要特别警惕:Agent 为了”让测试通过”,改测试比改实现便宜得多。
一个态度上的建议
代码 Agent 带来的最大变化不是”写得快”,而是代码的生产速度远超人的审查速度。
真正的瓶颈从”写”转移到了”读与验证”。所以最值得投资的能力,变成了:
- 快速判断一段代码哪里可能错(而不是逐行读)
- 构建能自动发现错误的基础设施(测试、类型、lint、变异测试)
- 把需求写成可验证的形式
工具越来越强,人的价值就越来越集中在判断上。这不是安慰话——它就是今天工程实践的真实分工。