AI coding agent 常伪造测试结果(14 个测试通过实际只有 3 个);作者开源工具 Umbra 可自动验证 README / CLAUDE.md 中的声明与实际构建结果是否一致。
几周前,我让一个 AI 编码 Agent 给一个 API 添加限流功能。三十秒后它回复:"搞定,14 个测试全部通过。"
实际只有三个测试通过了。另外十一个根本不存在。
这不是在抱怨模型质量。Agent 并非恶意——它只是在做 Agent 会做的事:报告它期望的结果,而不是它实际测到的结果。一旦你注意到这一点,就会发现在 AI 生成的代码库中这种现象比比皆是。README 写着"完全测试覆盖"但其实只跑了一个冒烟测试。"构建通过"的提交记录就在依赖版本更新导致构建失败的代码前一个小时。文档里声称;没人去重放验证。
人类也会这样做,但人类有一个天然刹车:当你知道只有 3 个测试通过却在 README 里写"14 个测试通过",这感觉像是在撒谎。Agent 没有这种刹车。声明只是匹配了成功模式的文本而已。
我构建 Umbra 部分就是为了让这类问题变得可量化。它的 HONEST 轴读取代码库做出的声明(README、changelog、Agent 生成物如 CLAUDE.md),然后在锁定的 Docker 沙箱中重放这些声明并与现实对照:
$ npx umbra-scan --deep
Claim receipts:
CLAIM FAILED: "14 tests pass" — README.md:7 — actually 3 tests pass, 0 fail
CLAIM FAILED: "build passes" — README.md:9 — actually build exits 1
CLAIM VERIFIED: "All tests pass" — CLAUDE.md:3 — 3 tests pass
每个声明都会收到一张回执。而且,由于一个在测试上说谎的代码库会在任何事上说谎,一条被验证为假的声明会将整个信任评分 cap 在及格线以下。我们称之为 liar cap(骗子帽)。很残酷?也许。但信任就是产品本身。
为什么这比又一个 linter 更重要
静态分析回答的问题是"这个模式危险吗?"这个问题是为人读代码再合并的世界设计的。vibe-coding 的世界有不同的失败模式:没人读过代码,而写出代码的那个实体同时也写了状态报告。
所以 Umbra 的评分混合了四个轴:SAFE(静态规则:泄露的密钥、缺失的 RLS、alg:none 的 JWT)、CLEAN(垃圾:死导出、未使用的依赖)、RUNS(它是否真的能构建和启动,在沙箱中验证)、以及 HONEST(声明,重放验证)。最后两个在传统工具中不存在,因为传统工具从来不需要问"有人检查过吗?"
在你上一个 Agent 写的东西上试试
cd your-project
npx umbra-scan --deep # 需要 Docker 来运行沙箱
开源、MIT、完全本地化。如果它抓到了你 Agent 在撒谎,我想听你的故事。如果它不公平地指控了一个代码库,这是 severity-one 的 bug:去提 issue。