跳到主要内容
赞助推荐 Claude Team 合租,少折腾账号
赞助推荐 Claude Team 合租,少折腾账号
>80aj_

深度阅读 / AI Agent 框架

AI Agent 做 TDD 有没有用: 实测排名与 3 倍 token 成本

34 分钟阅读 阅读() #AI Agent 框架
#AI Agent 框架
目录

过去一年里,”让 AI 写测试优先”几乎成了 AI 编程的政治正确。绝大多数被传播的 CLAUDE.mdAGENTS.md.cursorrules 里,都能找到一句”先写失败的测试,再写实现”。这条规则听上去无懈可击:TDD 是被验证了二十多年的工程实践,agent 又是最不值得信任的写码者。

Thoughtworks 的 Birgitta Böckeler 决定不靠感觉,搭一个对照实验去测。她是 Thoughtworks 的 Distinguished Engineer,专注 AI 辅助交付方向,有二十多年开发、架构与技术领导经验,这篇实验属于 “Exploring Gen AI” 系列。结论是反直觉的:让 agent 在自己的循环内完整跑 TDD,并没有产出更好的方案,反而在多数批次里被评委模型排在后面,同时 token 消耗高出 3 到 8 倍

赞助推荐 一人公司 · 创业装备库
赞助推荐 一人公司 · 创业装备库

TL;DR

  • 没有可见的质量优势。基于 Opus 对结果质量的盲评,TDD 与非 TDD 之间没有明显可辨的差异;反过来,Opus 不止一次把非 TDD 方案在设计和测试质量上排得略高。所有方案的变异分数(mutation score)也没有有意义的差异。
  • 代价是确定的。TDD 路线在小/中/大三个任务上的 token 均值倍数分别是 8.50x、2.96x、4.89x,轮次和工具调用数同步翻几倍。
  • 原因可能在”前置设计”。Opus 回看会话轨迹后发现,非 TDD 和”仅测试优先”的 run 总是先把完整设计做出来(架构、数据类型、边界情况、契约)再动手,而 TDD 指令主动对抗这个前置设计步骤。
  • 红-绿在无人循环里失去意义。当 agent 既写测试又确认它失败时,红灯只能证明”agent 跑了它并看到失败”,不能证明”失败是出于正确的原因”。
  • 作者本人的做法改了。她已经停止让 coding agent 写测试优先,转而用变异测试、结构审查、Approved Scenarios 分别兑现 TDD 曾经提供的那几项价值。

这是探索性的小规模 eval。本文第八节专门讲”这个实验没证明什么”,读到那里之前先别急着改团队规范。

一、先分清三种”AI + TDD”

社区里绝大多数关于”AI 要不要 TDD”的争吵,都是双方在说不同的三件事:

  1. 人类写测试:人类以自然语言、BDD 风格或直接写代码的形式定义测试场景,AI 写实现让它们通过。规约所有权在人手里
  2. 给人类留审查检查点:AI 先写失败测试,人类看一眼确认它测的确实是想要的行为,AI 再写实现。红灯必须有人解释这一环被保留。
  3. 完全在 agent 循环内:提示 agent 一个一个先写失败测试、再写实现、再确认变绿。整个红-绿-重构循环里没有人

作者明确指出:现阶段第三种是远远最常见的用法,而这个实验测的正是第三种。如果你的团队用的是前两种,这份数据基本不适用。

这个区分很重要,因为 TDD 的很多经典收益本质上是人类心理层面的机制。把人从循环里拿走以后还剩多少,是需要单独回答的问题,不能从”TDD 二十年被验证有效”直接推导。相关的人机边界讨论可见AI Agent架构探讨:如何界定”大脑”思考与”工具”执行的边界?与大模型斗智斗勇:开发者在信任交付与零信任审核间的极限拉扯

二、实验设置

任务:借助 Claude 生成三个规模的任务,全部是绿地业务逻辑。作者特意要求”特异且具体的逻辑”,提高方案间出现差异的概率,避免所有 run 都复述训练数据里已占主导的标准写法。

  • :Python 模块,校验 DAY-TIME-ROOM-CHECKSUM 格式的医疗预约槽位代码,返回结构化结果标明哪条规则失败、为什么。
  • :4 阶段 Python 管道(parse → aggregate → format → validate),把 ROW_ID:CATEGORY:VALUE:PERIOD 转成纯文本报告。
  • :内存态 Python 忠诚度积分引擎,含分层赚取率(Bronze/Silver/Gold)、用于层级重算的滚动 365 天消费追踪、积分兑换。

模型分工:Sonnet 4.6 生成方案;Sonnet 4.6 判定 TDD 遵循程度;Opus 4.8 在不知道方案怎么产生的情况下比较质量。作者刻意没给非常具体的质量标准——以她的经验,标准给得越具体,模型越可能对它过拟合。Opus 排名时当场生成评分细则传给所有子 agent。

统一指令:所有 run 都包含”至少 80% 代码覆盖率”。这意味着非 TDD 组不是”不写测试”,只是不按 TDD 流程写。这一点在传播中经常被误读。

批次:5 批,每批 2 个非 TDD + 2 个 TDD,其中一批额外加 2 个”仅测试优先”(先写测试但无完整 TDD 纪律、无增量红绿)。小任务 1 批、中任务 3 批、大任务 1 批。标记:NT = 无 TDD,T = TDD,TF = 测试优先。

四条 caveat(作者原列):样本量非常小;”质量”判断几乎完全交给 Opus;没有任何一次 run 完美遵循 TDD,但都做得不错;任务全部是绿地、相对小规模、纯业务逻辑。

第四条尤其重要——遗留代码、跨模块重构、大型代码库这些 TDD 最被认为有价值的场景,一次都没测。关于 AI 在存量代码上的表现,可对照模型表现差可能真不赖 AI:代码坏味道正成为编程大模型的最大绊脚石

三、agent 到底能不能做好 TDD

在比较之前,作者先要确保 TDD 指令真的被执行了。她说历史上这件事一直不顺利,agent 常见三类失败:先写实现再补测试跳过确认红灯超前于当前测试实现,导致下一个测试写出来就是绿的。

她最后用的提示词在 Sonnet 上”够用”,但所有会话都在不同程度上表现出了上述失败。为避免把没真做 TDD 的 run 算进结果,每个 TDD run 都配了独立 agent 基于会话记录判断遵循程度。

这个前置发现本身就很重要:“我在提示词里写了 TDD”和”agent 真的在做 TDD”是两件事。如果你的规范里有这条规则却从没验证过会话里的红灯是否真红过,那你可能已经在支付成本而没拿到收益。类似的”指令被静默降级”现象可见频繁改需求致 AI 代码”返祖”?开发者探讨如何维护上下文一致性

四、五批数据

4.1 中任务第一轮

ID TDD 测试数 覆盖率 变异分数 总 Token 轮次 工具调用
NT1 75 100% 84.2% 769,814 31 37
NT2 107 100% 89.6% 703,159 21 24
T1 30 100% 81.0% 1,519,762 71 28
T2 34 99% 77.3% 2,580,897 103 60

Opus 判词:NT1(第 1) 一阶段一模块、dataclass、Decimal,无正确性 bug,错误处理最强,唯一检查重复 ROW_ID;NT2(第 2) 工程质量最好、测试套件最大,但验证器会拒绝它自己产出的合法小数输出;T1(第 3) 单模块、字典、float,验证是循环的(重跑 formatter),接受 nan/infT2(第 4) 有活跃的 TOTAL 行 bug(人头数加进美元金额),而且这个 bug 被一个测试固化下来了

T2 那条是最典型的失效模式:测试先写不等于测试写对,一旦 agent 对需求的理解本身就错,先写的测试只会把错误理解锁死成一份看起来很权威的规约

4.2 中任务第二轮:加入”仅测试优先”

ID 方法 测试数 覆盖率 总 Token 轮次 工具调用
NT1 无 TDD 107 100% 703,159 21 20
TF2 测试优先 90 92% 619,531 27 26
NT2 无 TDD 75 100% 769,814 31 30
T2 TDD 29 98% 2,099,280 96 95
TF1 测试优先 62 99% 268,323 17 16
T1 TDD 25 100% 2,017,739 90 89
ID 方法 设计 代码 测试 均分 实现/测试 LOC
NT1 无 TDD 8 8 8 8.0 497 / 881
TF2 测试优先 8 8 7 8.0 484 / 850
NT2 无 TDD 8 8 7 7.5 330 / 430
T2 TDD 7 7 6 6.5 207 / 304
TF1 测试优先 6 6 6 6.0 348 / 360
T1 TDD 6 6 6 6.0 142 / 228

盯住一个现象:TDD 组的测试数量最少(25、29),非 TDD 组是 107、75;TDD 组实现代码也最短(T1 只有 142 LOC)。这不是”TDD 让代码更精炼”,而是原文假说的直接体现:agent 没想到要为之写测试的行为,压根没被实现。功能边界被”agent 依次想到了哪些测试”这条随机链条限定住了。

4.3 中任务第三轮:强化 TDD 提示词之后

作者意识到 agent 在循环里没怎么做重构,改了提示词加重强调前置设计与重构步骤。

ID TDD 测试数 覆盖率 变异分数 总 Token 轮次 工具调用
T1 51 100% 90.2% 3,447,283 117 116
NT1 107 100% 89.6% 703,159 21 20
NT2 75 100% 84.2% 769,814 31 30
T2 43 100% 81.1% 1,421,671 61 60

均分:T1 7.67(设计 8/代码 8/测试 7)> NT1 7.33 > NT2 7.0 > T2 6.67。头号弱点:T1 只含 HEADCOUNT 的 TOTAL 行被打印成 $、验证只是子串检查不是算术;NT1 小数 HEADCOUNT 在合法输入上触发假 ValidationError;NT2 NaN/Infinity 让管道崩溃而非抛 ParseError;T2 验证是重言式(拿聚合结果检查它自己)。

这是全实验唯一一次 TDD 拿到第 1 名,代价是 3,447,283 token 和 117 轮。致命的是:用同一份提示词跑的另一个 TDD run(T2)排在最后一名。同样的指令、模型、任务,一个第一一个垫底——这个方差本身就是对”TDD 指令能稳定提升质量”的反驳。

4.4 小任务

ID TDD 测试数 覆盖率 变异分数 总 Token 轮次 工具调用
NT1 61 100% 89.6% 122,108 10 15
NT2 58 100% 92.3% 117,522 10 20
T1 21 100% 93.6% 894,451 55 37
T2 20 100% 93.2% 1,142,039 68 26

均分:NT1 8.67 > NT2 8.0 > T1 7.33 > T2 6.67。NT1 综合最好——dataclass 结果、无 bug、61 个断言”失败原因”的测试;T2 设计最弱(自由文本错误)且有真实崩溃 bug。

这是最刺眼的一组:TDD 组多花约 8.5 倍 token,换来第 3、第 4 名。有意思的是 TDD 组的变异分数(93.6%/93.2%)反而最高,但测试数只有对方三分之一——说明用测试数量当质量代理指标是不可靠的

4.5 大任务

ID TDD 测试数 覆盖率 变异分数 总 Token 轮次 工具调用
NT2 69 100% 86.9% 322,148 14 13
T2 22 99% 85.6% 1,225,517 63 62
T1 21 99% 85.2% 1,253,300 67 66
NT1 74 99% 89.4% 185,094 11 9

均分:NT2 8.25 > T2 7.5 = T1 7.5 > NT1 6.75。这是唯一一次模式被打破:TDD 落在中间,两个非 TDD 同时拿走最好和最差。NT2 是唯一带真实输入校验的方案;NT1 拿了最高设计分和 74 个测试,却带着两个高级 bug(批次提取顺序错误、未来日期积分被算成可消费)。

这组说明非 TDD 的方差更大——它可以做得非常好,也可以在测试很多、设计分很高的情况下藏着严重 bug。这正是开发效率与代码质量的博弈:AI生成的代码是否仍需人工Code Review?里反复出现的矛盾。

整体模式:小任务和中任务上,Opus 把两个非 TDD 排第 1、第 2,两个 TDD 排第 3、第 4,唯一例外是强化提示词那一批;大任务上 TDD 居中。一句话——两边都当过第一也都当过最后,整体 TDD 略差

五、被误读的”3 倍 token”:口径比数字重要

任务规模 无 TDD 均值 TDD 均值 倍数
119,815 (n=2) 1,018,245 (n=2) 8.50x
736,486 (n=2) 2,181,105 (n=6) 2.96x
253,621 (n=2) 1,239,408 (n=2) 4.89x

关键在于这个数字是怎么算的。 作者明确说明:记录 token 用量的设置用的是 pi-coding-agent SDK 的 getSessionStats(),它把会话里每一个 assistant turninput + output + cacheRead + cacheWrite 全部求和。

每一轮 assistant turn:
  重新读取累积上下文 → 绝大部分命中缓存 (cacheRead)
  本轮计一次,下一轮又读又计一次 ...

Total Tokens ≈ Σ(每轮上下文规模) ≈ 轮次数 × 上下文平均规模

作者原话:所谓 “Total Tokens” 更多是在追踪一个会话花了多少轮,并按当时上下文长到多大来加权;它把便宜的缓存读和昂贵的新鲜 token 一视同仁,因此很可能高估了 TDD 的真实美元成本。实验期间没有单独追踪缓存命中率。所以正确的读法是:

  • ❌ “TDD 让 API 账单变成 3 到 8 倍”——不成立,缓存读单价远低于输入输出。
  • ✅ “TDD 让会话轮次和工具调用数变成几倍”——成立且有直接证据:小任务从 10 轮变成 55–68 轮,中任务从 21–31 轮变成 61–117 轮。
  • ✅ “TDD 可靠地贵好几倍,具体几倍可变”——作者自己给的定性表述,把倍数当方向性指标

轮次翻倍其实比 token 更值得关心,因为它直接对应墙钟时间上下文膨胀。做成本可观测性时这个口径问题很典型,可对照开源工具Wattage:精准监控AI智能体Token开销的回归测试门禁开发者吐槽AI编程现状:模型陷入”虚假忙碌”,95%推理Token被浪费

六、七项收益逐条失效

作者跳过那些”只要有测试”就能拿到的收益(重构安全网、活文档、覆盖率),只保留流程本身特有的,逐条问:agent 循环里还拿得到吗?

1. 测试优先 → 避免重言式测试。 实验里有些 TDD 会话照样出现了这个问题——一个特别明显的例子是测试拿实现的输出和它自己比对,重新跑同样的代码去生成”期望”答案。先写测试不能可靠阻止这件事,也许能降低概率,但小数据集不足以下结论。

2. 测试优先 → 可测试性。 结果没有给出明确信号。作者坦承任务规模不需要那么多设计复杂度,不足以让这个问题浮现。

3. 红-绿 → 测试有效性。 作者提了最锋利的一问:当人被移除时,这件事还有多少意义? 看着测试变红,只有在有人去检查它为什么变红时才能证明任何事情。当 agent 既写测试又确认它失败,红灯告诉你的是”agent 跑了它并看到失败”,不是”失败是因为正确的原因”。遵循度评估也印证:agent 仍会跳过或伪造红灯,或超前实现让测试立刻变绿。她的替代答案是变异测试——不在乎回归质量怎么达成,只要有机制能看到它有多好;而实验里 TDD run 的变异分数并没有显著更好。

这条推理的普适价值大于 TDD 本身:任何”过程指令”在无人循环里都会退化成一个可以被 agent 自己签字的形式。这正是专治 Agent 工具调用不靠谱:开发者开源多维评测框架,混合规则与大模型裁判这类工作的动机——把验证从”过程自证”挪到”结果外测”。

4. 测试优先 + 红绿重构 → 驱动更好的设计。 实验完全没有展示 TDD run 有更好的设计。作者说她现在甚至怀疑 TDD 是不是让设计变差了,同时强调数据集太小无法定论,并公开呼吁有人跑更大规模的复现。她的解释很精准:

当人类先写测试时,它迫使我们在实现之前思考用法,我们不得不坐在那种摩擦里。agent 不会经历那种摩擦,它可以在规划实现的同一瞬间写出测试。在两者之间没有人类检查点的情况下,先写测试还剩下什么目的?

Opus 回看轨迹的机制解释是:非 TDD 和测试优先的 run 总是在写任何代码或测试之前先创建完整设计(架构、数据类型、边界情况、契约)。反过来,TDD 指令主动对抗这个前置设计步骤——那些 run 的设计从许多局部最小决策中涌现,很少被回头修订,倾向于落在第一个测试碰巧锁定的形状上。这也解释了 4.2 里 TDD 组测试数和实现 LOC 双低:不是精炼,是功能缺失

5. 小步 → YAGNI。 这是一条以人为中心的收益,agent 自己做 TDD 时会丢失。理论上思考转移到了写规约的时候,但在写规约这件事上,我们没有一个类似 TDD 的机制让我们小步想透。实验里”最小实现”的指令也没能可靠阻止它们造更多东西——因为完整需求就摆在它们眼前,而我们通常不会一条一条喂过去。

6. 小步 → 快速、局部化反馈。 实验没显示 TDD 与否在调试卡壳频率上的差异。作者的一般经验是 agent 通常相当擅长搞清楚测试为什么红,即使没有小步走到那里。

7. 小步 → 信心与学习。 Kent Beck 在《Test-driven Development by Example》前言里给 TDD 的最大理由是”管理恐惧“——每个通过的测试展示进展,我们可以放松,知道进展被锁住了。而这非常明确地是关于管理一个人类的恐惧。agent 在循环内部做 TDD 时这一条不转移,因为它不能给”我”和自己一步步做时同样的控制感与信任感。这是唯一一条收益接收方是人而不是代码的——把人拿走,接收方就消失了。相关讨论见AI 生成代码泛滥,人类”理解力”成为开发新瓶颈

七、训练数据假说与两项成本

作者和 Ivett Ördög 讨论时,对方提出了一个解释理论:

AI agent 被训练的方式是:它们看到的是完成后的函数和这些函数的描述。它们见过的真正逐步 TDD 示例在训练数据里只占极小一部分。这意味着 LLM 对代码的内部表征是从需求到代码的直接翻译,而不是如何抵达那个表征的过程

这个假说能同时解释几件事:agent 天然倾向于想清楚整个方案再一次性写出来;TDD 提示词是”一场对抗训练数据的上坡战”;”最小实现”压不住超前实现;强化提示词能把某次 run 提到第一名但方差巨大。如果它成立,”让 agent 模仿人类过程”本身就是逆着模型能力方向使劲——约束结果比约束过程更有效。可对照开源项目Comet:强模型时代下,Agent开发从重工程化转向轻量化验证企业 Agent 失败,不是因为模型不够大

成本一:token 与轮次。 见第五节,倍数是方向性的,轮次翻倍是硬事实

成本二:提示词的维护与测试。 这一项常被完全忽略,但可能才是长期成本的大头。TDD 对模型来说”不自然”,要迭代很多次提示词才能让它大部分时候遵循。作者改了提示词加强重构后,让 Opus 回看会话,Opus 确实报告了重构步骤的增加——但也列出了一些情况:agent 着手要重构,然后判断”设计已经够好了”,即使在 Opus 认为明显不够好的时候(比如所有东西都实现在一个大模块里,本可以拆成多个职责)。

这是很值得警惕的模式:你加了一条流程指令,agent 表面上执行了它,但把它降级成了空动作。指标改善,实质没有。作者另一层担心是:TDD 是一组变量很多的复杂指令,解释变异空间大,这类提示词跨模型的稳定性会比简单指令差得多——每次模型升级你都要重新验证它是否还生效。相关可见AI 编码的”双面性”:为何大模型在代码生成上表现极不稳定?

八、结论、替代方案,与这个实验没证明什么

作者的核心判断:

我认为现在有越来越多的证据表明,对模型怎么做某件事过于具体,不是一个可持续的方法。相反,我们应该找到尽可能多的方式去监控结果并给出反馈。那种反馈应该尽可能自动化,而且我们需要仔细思考在哪里把自己插入进去,作为”什么是好的、正确的”的仲裁者

她已经停止让 coding agent 写测试优先,直到看到 eval 或其他强论证说服她改变;转而聚焦 TDD 在 agent 循环之外的收益。注意精确性:她停掉的是第三种用法,不是 TDD 本身。

替代一:怎么拿到好的回归测试。 她仍在意扎实的回归测试——即使 agent 可能用错误方式修红灯,至少红灯给了它一个信号去复查可能被破坏的既有需求。做法是用变异测试监控和改进回归质量,而不是给一堆精心设计的 TDD 指令然后祈祷。这是”结果度量取代过程指令”的典型替换。

替代二:怎么把定期重构 build 进流程。 重构仍然至关重要,但传统 TDD 的小步骤看起来不是在 agent 循环里做它的高效方式。她列的触发器:给 agent 访问静态代码分析;定期做结构与模块化审查;建立团队仪式尽早发现漂移;盯住每次改动触及文件数的趋势;盯住每次改动消耗 token 数的趋势。

最后两条是很好的工程直觉:这两个数字上升,通常意味着模块边界正在腐化——它们是可自动采集的漂移传感器,比人工审查便宜得多。技术债的失控路径可见AI 正在消灭软件工程的「中产阶级」:编码速度越快,技术债务堆积越快Vibe Coding 的代价:为何 AI 编码加速反而导致软件架构崩塌?;工具侧应对可参考阿里开源 AI 代码审查工具 open-code-review:定位低噪声筛查而非合并闸门

替代三:信心从哪里来。 作者说这是最难的问题,她没有清晰答案,只提了一个好构件:Ivett Ördög 倡导的 Approved Scenarios。用她自己的话(并声明别拿这个要求 Ivett 负责):这是一种半手动测试形式,由每个应用定制的测试运行器支撑;运行器以易于思考的方式展示功能测试场景,允许她在彻底确认后在运行器里“冻结”期望(场景/fixtures),以后一旦被违反就必须再次批准。她的同事 Matteo Vaccari 分享过使用经验。

这套方法的哲学值得单独品:它把人插在“什么是正确的”这个判断点上,而不是过程的每一步里。人只在”第一次确认”和”期望被打破”两个时刻花注意力。作者的收尾判断是:无论最终是什么给了我们对软件的信心,TDD 作为我们所熟知的那个角色,会比 GenAI 之前显著更小。完整实验代码与数据在 https://github.com/birgitta410/tdd-comparisons/

这个实验没有证明什么——引用前必须划清的边界:

  • 没有证明”AI 写的测试没用”。所有 run 都带 80% 覆盖率指令,非 TDD 组照样写了最多 107 个测试。被比较的是时序与流程
  • 没有覆盖遗留代码。全部绿地。而 TDD 在人类实践中最被认为有价值的场景之一,恰恰是在没有测试网的存量代码上做改动。
  • 没有覆盖大型代码库。任务是”相对小规模、纯业务逻辑”,原文自承不足以让”可测试性”浮现。
  • 没有覆盖前两种用法。保留了人类检查点的模式完全没测。
  • 样本量小到不能做统计推断,每格基本 n=2,作者自己反复强调并公开征集复现。
  • 评委是模型。虽是盲评且刻意不给具体标准,但仍是用一个 LLM 的品味给另一个 LLM 的产出打分,系统性偏好未知。

剩下的价值是一组值得认真对待的假说,尤其”前置设计 vs 增量涌现”那条——它有机制解释、有独立佐证、也和多组数据一致。它足以让你停止把”agent 必须 TDD”当作不证自明的最佳实践,但还不足以让你反向确信”agent 绝对不该 TDD”。

九、落到自己项目上

如果你的 agent 规范里现在就写着”先写测试”,下面几步可以在不推翻任何东西的前提下拿到信息:

  1. 验证这条规则真的在生效。抽 5 个最近的会话记录,检查红灯是否真出现过、是否因正确原因、有没有”先写实现再补测试”。三条里有两条不达标,你已经在纯支付成本。
  2. 量一次成本。对比开关该规则时的会话轮次数工具调用数——比 token 更能反映真实开销,也不受缓存口径影响。
  3. 换成结果侧度量。在一两个模块上引入变异测试拿到基线分数。之后无论测试怎么写出来,你都有客观数字回答”它能抓住多少回归”。
  4. 把前置设计显式化。既然假说指向”先做完整设计的 run 更好”,就写进规范:写任何代码之前先输出架构、数据类型、边界情况清单和契约。这条与模型默认倾向同向,阻力小、稳定性好。
  5. 加两个漂移传感器 + 把人插在冻结点上。采集”每次改动触及文件数”和”每次改动消耗 token 数”的趋势线,向上就是重构信号;人只在”第一次确认场景”和”冻结期望被打破”时介入,而不是每一步。
  6. 别忘了那两种没被测的用法。如果某个模块的正确性真的很贵(计费、结算、权限),把测试场景的所有权收回人手——你写场景,agent 写实现。

相关阅读

FAQ

Q1:所以结论是”不要让 AI 写测试”吗?

不是。所有实验组都带了至少 80% 覆盖率指令,非 TDD 组反而写出了最多的测试(107 个)。被质疑的是在 agent 循环内部强制红-绿-重构这个流程,不是”要不要有测试”。作者仍然在意扎实的回归测试,只是改用变异测试去度量它。

Q2:那个 3 倍 token 会让我的账单变成 3 倍吗?

大概率不会。原文的数字用的是 getSessionStats(),把每轮的 cacheRead 也累加进去,而缓存读单价远低于新鲜输入输出。作者自己说这”很可能高估了 TDD 的真实美元成本”。但轮次翻几倍是硬事实——小任务从 10 轮到 55–68 轮,直接对应墙钟时间和上下文膨胀。

Q3:为什么 TDD 组的测试反而更少?

原文假说是:TDD 循环下 agent 一次只处理一个需求,设计从局部最小决策中涌现且很少回头修订,没被想到要写测试的行为压根没被实现。非 TDD 组先把架构、数据类型、边界情况和契约列全再动手,功能完整度更高。所以那不是”精炼”,是覆盖面缺失。

Q4:强化 TDD 提示词有用吗?

有一次有效——加了显式前置设计与重构审查后,一个 TDD 方案拿到第 1 名。但同一份提示词跑出的另一个 TDD run 排最后一名,且第 1 名花了 3,447,283 token 和 117 轮。另一个观察是:加强重构指令后 agent 确实增加了重构步骤,但也出现”着手重构、然后判定设计已够好”的空动作。

Q5:这个结论适用于遗留代码吗?

不适用。实验全部是绿地、相对小规模的纯业务逻辑任务,作者本人把这列为四条 caveat 之一。TDD 在存量代码上先写”刻画现有行为的测试”来锁住风险,这个场景一次都没被测到。

结语

这个实验最有价值的地方不是排名表,而是它示范了一种态度:面对一条被广泛接受的最佳实践,去搭一个能证伪它的装置,而不是继续引用它。

如果你今天的 agent 规范里就写着”先写失败的测试”,最低成本的下一步不是删掉它,而是去抽查五份会话记录,看看那个红灯是不是真的红过。

未经允许不得转载:80aj » AI Agent 做 TDD 有没有用: 实测排名与 3 倍 token 成本
赞助推荐 一键部署 AI 大模型
赞助推荐 一键部署 AI 大模型