不读 Agent 代码,让它们先跑 8 道关卡|Uncle Bob 的「测试墙」被做成了开源 skill
Uncle Bob Martin 写了快 60 年代码,最近他在一个讨论里丢了一个有点极端的操作:「我不读 agent 写的任何代码。这是我能利用它们生产力的唯一方式。」听起来像偷懒,但他接着解释了底牌——他给 agent 套上极端约束,单元测试、Gherkin 测试、QA 流程、变异测试、覆盖率,agent 生成的代码必须跑赢所有约束才能过关。他不读代码,靠一面测试墙来信任。
这个思路被 0xAA 做成了一个开源 skill,名字就叫 old-coder(老码农)。安装一行命令:
npx skills add https://github.com/amazingang/old-coder
它不绑特定工具——Claude Code、Codex CLI、Cursor、Aider,或者自建的 agent loop,只要读得懂 markdown 就能用。
镶了一套 TDD 循环
old-coder 把流程拆成六个阶段:SPEC → RED → GREEN → REFACTOR → GAUNTLET → EVIDENCE。只需要读两份文档。
写代码之前,agent 先出一份 SPEC,包含行为示例和需要安装的工具。得到确认后,它才开始。写完之后,它产生一份 EVIDENCE——可复现的闯关报告,所有数据来自一次全新的运行,一行命令即可重跑验证。
中间发生的,是 agent 自己写测试、看着测试失败、写代码让它通过、重构——然后被推进 gauntlet。全程不需要打开 diff。
八个具体关卡
每个关卡对应一个明确的问题:
- 全量测试套件——有没有东西坏了?
- 类型检查 + lint + 复杂度——有没有明显错误和读不懂的乱麻?
- 变更行覆盖率——每行新代码都被测试跑过了吗?
- 变异测试——故意植入 bug,测试能抓到吗?
- 属性测试——规则在几百次随机输入下还成立吗?
- 真实执行——脱离测试框架,它真的能跑?
- 供应链 & 密钥检查——agent 有没有偷偷引入危险包,或者泄露密钥?
- 套件健康度——测试本身稳定吗?换个顺序跑还会过吗?
再往上,还有一层按风险选配的领域关卡:并发、UI 检查、API 兼容性、性能、可观测性。规则是 effort scales with risk。改个 typo 只跑几个基础检查;涉及钱、登录、数据、并发的,全部跑满,而且 agent 得先用恶意输入攻击自己的代码。
防止 agent 给自己的作业打满分
规矩定得很死:永远不能弱化测试来让它通过,永远不能报告没跑过的检查。没验证的东西必须标 unverified,不能标 pass。如果没人批准过 spec,报告必须声明并降低置信度。
还有一个坦率的上限声明:gauntlet 只能证明代码符合 spec,不能证明 spec 覆盖了所有该覆盖的东西。所以 spec 必须交给人审——目标需要人来确认。
Demo 已经跑通了
仓库带了一个 rate-limiter 的演示。跑出来的结果是:17 个测试,100% 分支覆盖率,8/8 植入的 bug 被抓住。而且这套流程还揪出了一个真实 bug——一个 NaN 时间窗口悄悄滑过了输入验证。一行命令可以复现整份报告:
cd demo-rate-limiter
python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt -e .
./tools/gauntlet.sh
回到 Uncle Bob 的那个讨论。有人问他代码质量还重不重要,他的回答是:重要,而且比以前更重要。混乱的代码会拖慢 agent。他亲眼见过 agent 在自己的烂摊子里打转,绕不出来,最后只能他亲自接手。所以他用极端约束卡死函数大小、圈复杂度和测试覆盖率——不是为了好看,是为了让 agent 保持流畅。
还有人问谁来监督约束本身。回答是工程师自己——最终负责的也是自己。就像监督人一样监督 agent——保持关注,但不必逐行读代码。
还在纠结要不要读 agent 写的每一行的话,试试这个思路:别读了,让它们先跑一遍关卡再说。