OOOMETA/OS
← 返回洞察

2026 年 9 月 · 11 分钟阅读

自建智能体基准:合并过的改动就是考题

自建智能体基准:合并过的改动就是考题

关键定义

编码智能体基准 用自己仓库里已合并的真实改动当考题、用现有测试当判分器,衡量一套模型与壳的组合在你的代码上花多少钱、通过多少任务。

壳(harness) 模型外面那一圈做决定的代码:每轮把哪些内容放进上下文、何时压缩历史、工具结果怎么截断、失败后重试几次。它决定每轮上下文量与轮数。

Databricks 的工程师要回答一个采购问题:下周默认把哪套编码智能体发给团队用。公共榜单能给的答案是模型名次的排序。而他们要知道的是,在自己那套几百万行、跨十几种语言的代码库上,哪套组合能更省地把活干完。于是他们拿自家已合并的历史改动造了一套内部基准,跑完之后,团队里两个默认的假设没有站住。换句话说,决定账单的并不是他们一直在比的那个东西。

这篇文章要讲的不是 Databricks 后来买了什么,而是它测出来的几组数字合起来改变了一件事:编码智能体的成本该按什么单位来算。单位一换,采购谈判、选型流程和验收标准都要跟着换。

单价便宜 1.7 倍的模型,每个任务反而更贵

第一个没站住的假设是「单价便宜就等于便宜」。Sonnet 5 的每 token 价格大约比 Opus 4.8 低 1.7 倍,按价格表看它应该更划算。但在 Databricks 的任务集上,Sonnet 每个任务花掉 2.09 美元,Opus 是 1.94 美元,同时完成率低了 6 个百分点,81% 对 87%。

差额不是运气造成的。为了把事做完,Sonnet 读得更多、跑得更久,token 消耗量是对方的 1.9 倍。单价在账单里是一个乘数,被乘的那个数由模型的工作方式决定,一个更啰嗦的模型即使单价更低,总账单也会更高。

换成采购的说法:价格表能告诉你乘数,被乘的那个数只有你自己的任务能告诉你。问题是,这个数从来不出现在价格表上,它只出现在你自己的仓库里。问题是,同一批任务两次运行之间的差异,有时候比两个模型档位之间的差异更大。

同一个模型换一层壳,成本差两倍以上

第二个假设更接近工程直觉:成本由模型决定。他们做了一组更干净的对照,同一个模型、同样的思考强度,分别从两套不同的壳(Claude Code/Codex 与 Pi)里跑一遍。同一个任务的成本差了 2 倍以上。而质量没有可测的差别。

差别落在每轮往模型里喂多少上下文。Pi 每轮喂进去的上下文大约少 3 倍。它把工作集收得更紧,完成同一批任务用的轮次更少。 「壳」在这里不是比喻。它指的是模型外面那一圈做决定的代码:每一轮把哪些内容放进上下文、什么时候压缩历史、工具调用的结果截断到什么程度、失败了重试几次。这四个动作每一个都在改账单的最终数字。

Databricks 在这段结论里留了一句很克制的话:不是某一层壳永远更便宜,原生壳也并不一定更差。他们为此专门做了一个让模型与壳可以互换的中间层,理由很实际,一个组合被焊死之后,连比较的机会都没有了。这意味着,可换性本身就是一项资产,比暂时便宜几个百分点值钱。

公共基准答不了这个问题,原因有两条

第一条是题目公开。SWE-Bench 与 Terminal-Bench 这类基准的题目在网上放了很久,解法会随时间渗进训练数据,于是分数越来越好看,也越来越难说明你现在买到的能力到底是多少。

第二条更值得企业注意:任务形状对不上。Databricks 那套代码跨 10 种以上语言,Scala、Go、Rust、Java、Python 都在,构建体系是 Bazel 与 Protobuf,服务边界是自己长出来的。公开榜单测的是通用能力。而你要买的,是你这套形状上的成本。

任何一家有几年历史的公司,仓库里都有外人没有的东西:命名习惯、内部框架、脚手架、没人写清楚但所有人都遵守的约定。这些恰好是决定一个智能体要读多少内容、要试几次才成功的东西。

自建基准还有一个不花钱的副产品。进入基准的任务都是已合并的改动。而合并本身就意味着有人确认过这个解法可以进主干,标签已经在版本历史里,不需要再雇人标一遍数据。

我们的判断:算成本的单位选错了

这几组数字合起来只说明一件事:编码智能体的成本大致等于「每轮上下文量 × 轮数 × 单价」,前两项由壳与任务形状决定,只有第三项印在公开价格表上。按单价谈判,谈的是三个变量里最不重要的那一个;按排行榜选型,选的又不是你的工作负载。这意味着,选型文件的第一行不该是模型名字,而是这批任务由谁判分。换句话说,你比较的不该是模型名字,而是壳与任务形状。

我们更愿意把这件事落到一个可以被核对的数上:每个通过评审的任务的成本。这个数买不到,只能自己测。好消息是测它需要的原料,一批有确定正确答案的真实任务,大多数团队早就放在仓库里了。

这也是很多团队第一次看到账单时才发现成本结构的原因:在此之前,他们能看到的只有单价。

四步,一周把基准跑起来

  • 取样。从过去两三个月的已合并改动里挑 30 到 50 个任务,覆盖你最常见的几类工作,改配置、修缺陷、加字段、重构都要有。不要只挑最难的,基准要能代表日常。
  • 归因。把「已合并」当作正确答案,把你已有的测试当作判分器。换句话说,你要先有一批能被自动判分的任务,之后才谈得上按任务算钱。判分器必须是自动的,否则第二次就没有人愿意跑了。
  • 锁变量。先固定壳、只换模型跑一轮,再固定模型、只换壳跑一轮。两轮分开做,混在一起得出的结论无法归因。这正是把壳的成本差误记到模型头上的常见原因。
  • 重复。每个任务跑三次取通过率,而不是跑一次定胜负。人工分析机构的编码智能体指数就是这么做的,每个任务在三个基准上取三次通过率的平均值。

记账口径要一起记:每个任务的 token 总量、轮数,以及每轮喂进去的上下文量。只记单价,你会得到前面那个 1.7 倍的反例。

什么情况下这套方法不成立

任务必须能被自动判分。老系统重写、修已知缺陷、补测试这类活有标准答案,适合放进基准;绿地开发和设计探索没有确定答案,只能靠人评,规模上不去,也不该拿它得出的比例去向业务承诺。

样本量决定分辨能力。30 到 50 个任务足以分出「差两倍」这样的量级,分不出 5% 的差别。要比较两条接近的路线,样本要往几百个走。

结论只对你自己成立。自己的基准不能拿去做通用的选型宣言。不过可以拿去谈价格,因为它是你自己的数据,对方没法用别人的测试来反驳。

还有一条容易被忽略:不要把处在预览期的工具写进长期基准。预览期的默认行为和计费口径都在动。这个月测出来的数字,下个月就不成立了。

把基准放进合同附件,而不是只放在心里

有了基准,验收标准就能从「交付了多少个功能」换成「在固定任务集上的通过率与单任务成本」。这件事过去做不到,因为没有人能自动判定任务是不是真的被做完了;现在判分器是你自己的测试。

合同里值得加的是一条定期重跑:每季度用同一批任务重跑一次,把模型换代或壳升级带来的成本变化留在可见范围内。否则下一次账单出现异常,归因又要从零开始。反过来,如果你的仓库里连一条 5 分钟能跑完的验证路径都没有,先补这一条,再谈基准。

最后留给买方一个问题:你现在用的是谁的任务集在决定默认工具?如果答不出这个名字,那这个决定大概率是由厂商的排行榜替你做的。我们建议你在下一次选型会上,先把这个名字问出来。

同类的独立测量,测的是同一件事

Databricks 不是唯一在做这件事的一方。人工分析机构的编码智能体指数把 20 个「智能体 × 模型」组合放在三个基准上跑,DeepSWE 113 个任务、Terminal-Bench 66 个任务、SWE-Atlas-QnA 124 个任务,每个任务的通过率取三次尝试的平均值,最后排出一张逐任务的 API 成本表。它与 Databricks 那套基准有两处不同,任务公开、形状通用。不过方法上的共识比结论更值得抄:都以单个任务为计数单位,都不接受「跑一次看运气」,都要求把上下文消耗量记下来。

两份测量指向同一个方向。同一批任务在不同组合下的成本差得很开。而这个差别在单价表上完全看不出来。这意味着,同一个任务在两种壳里的成本可以差到 2 倍以上,你自己的账单会告诉你具体差多少。

把口径算一遍,比记住结论有用

举一个只为说明口径的例子。假设某个任务需要 20 轮交互,每轮平均向模型发送 4 万 token 的输入。在每百万输入 token 三美元的价位上。这个任务光是输入就接近 2.4 美元。而这个数字完全由「每轮发多少」乘「跑多少轮」决定,与任务本身写了多少行代码无关。把每轮输入压到四分之一,同一个任务的输入成本降到 0.6 美元。这比换一个单价打三折的模型省得更多。

真实账单里还有输出 token、缓存命中、工具调用的往返开销,上面这个算式不该被当成报价去用。真正的问题是,判分器一旦需要人来看,第三次就没人愿意跑了。它要说明的是为什么单价会成为第一个被推翻的假设:单价只是三个变量里的一个,另外两个在采购文件里通常不出现。

别漏掉复核那一侧的成本

完成率低 6 个百分点,在账单上只表现为多花了几毛钱,真正的代价落在团队这一侧:交付出去的东西要有人复核,没通过的活要有人重做,注意力被占用的时间不会出现在 API 账单里。这也是我们主张把「通过评审」写进计数单位的原因——合并没有发生,成本就已经发生了。说白了,你要买的不是模型,是一个可以被复核的数字。

基准要连着记三样东西,否则半年后无法解释

  • 模型与壳的版本号,以及每次运行的日期。模型可能在不通知你的情况下被换成新版本,分数动了却找不到原因。
  • 每个任务的上下文量与轮数。只记总成本,你无法判断账单变化是因为任务变难了,还是因为壳变啰嗦了。
  • 取样分布。如果连续两个季度都只挑最难的活,通过率自然会降。这个下降和工具好坏没有关系。结果是,基准的维护成本和它的建设成本一样重要。关键在于,任务集要能被自动判分,否则 50 个样本也维持不下去。

我们自己的做法

OOMeta 内部跑着一套自己的智能体流水线,任务来自运营数据而不是演示脚本。所以我们对「让模型把同一批文件读第二遍」这类浪费很敏感。我们的做法是把确定性的步骤从模型手里拿走,交给脚本执行:判重、取数、拼接路径、写文件这些动作不需要模型参与,也就不需要把上一轮的输出再发一遍,模型只负责需要判断的那一步。这个划分不是为了省事,我们算过它的口径,每轮上下文越小,下一次换模型时账单反弹的幅度也越小。我们因此把这条划分写进了内部流程,确定性的事不交给模型。我们建议把这三样记录写在同一份文件里:版本号、轮数、每轮上下文量,并且每 90 天重跑一次,样本不动。

这套做法为什么现在才跑得起来

三年前,把「已合并的改动」变成考题这件事做不成。要跑通它,你需要能重现当时的代码状态、能自动执行当时的测试、能把一次真实改动拆成不含答案的题面。这些能力在过去两年才在主流工具链里普及。判分器也一样,现在大多数仓库里都有一条几分钟能跑完的测试子集。这正是把「通没通过」变成自动数字的前提。

所以自建基准的门槛不在方法。而在你的仓库里有没有一条能在几分钟内跑完的验证路径。没有这条路径的团队,先把这条路径补出来。它同时也是把改动交给智能体之前本来就需要的东西。这意味着,工具选型在这里会从市场动作变成工程动作,我们看到的大多数团队还停在第一种。

谈判桌上的三个动作

  • 把任务集与判分方式写进合同附件,注明取样时间窗与任务数量,避免供应商只对通过率负责、不对口径负责。
  • 要求每季度提供一次逐任务成本明细,包含 token 总量与轮数,而不是一份月度总账单。
  • 把「换模型」当成默认会发生的动作。模型换代以季度计,任何需要重写集成才能更换的方案,都会在第二次换代时被放弃。

参考来源

常见问题

为什么单价便宜的模型总成本反而更高?+

因为账单是单价乘消耗量。Sonnet 5 每 token 比 Opus 4.8 便宜约 1.7 倍。不过为了把任务做完读得更多,token 消耗是对方的 1.9 倍。结果每个任务 2.09 美元对 1.94 美元,完成率还低 6 个百分点。

同一个模型换一层壳,为什么会差两倍成本?+

差别在每轮往模型里喂多少上下文。Databricks 的对照里,Pi 每轮喂的上下文大约少 3 倍,工作集更紧、完成任务的轮次更少,成本因此差了 2 倍以上。而质量没有可测的差别。

公共基准为什么不够用?+

两个原因:题目公开,解法会随时间渗进训练数据;任务形状和你的代码库差得远。Databricks 那套代码跨十几种语言、构建用 Bazel 与 Protobuf,公开榜单测不出这个形状上的成本。

搭一套自己的基准要多少工作量?+

四步:取 30 到 50 个已合并任务、把现有测试当判分器、分开做「固定壳换模型」与「固定模型换壳」两轮对照、每个任务跑三次取通过率。原料已经在版本历史里。

样本要多大才有意义?+

30 到 50 个任务能分出「差两倍」这种量级,分不出 5% 的差别;要比较两条接近的路线,样本要往几百个走。

什么样的任务不适合放进基准?+

没有确定答案的活,比如绿地开发和设计探索,只能靠人评,规模上不去。老系统重写、修已知缺陷、补测试这类有标准答案的才适合放进去。

测出来的基准能拿来做什么?+

把验收标准从「交付了多少功能」换成「在固定任务集上的通过率与单任务成本」,并写进合同附件、每季度重跑一次,让模型换代带来的成本变化留在可见范围内。