温度计与恒温器:让 eval 真正改变下一步的那一层

Yaqin Hei··10分钟阅读
中文EN
温度计与恒温器:让 eval 真正改变下一步的那一层

本文编译自 X 作者 @Argona0x 2026 年 7 月 28 日的长帖《Eval Engineering: the step that turns a $200 model into a $200,000 system》(原文)。作者身份未公开,我核不到他的从业背景——所以这篇的分量不在「他是谁」,而在于它把一件正在发生的事串成了可执行的顺序。这不是全文直译,是编译:保留全部可操作的骨架,换上我自己核到的一手数据,并标出原文哪几处站不住。编译、核实、配图:Yaqin Hei(非原创,已保留原文出处)。

译者的话:我为什么编译它,而不是直译它

我原本打算直译。核完事实之后改主意了——因为核实的过程本身,比原文更值得给你。

先说好的那一半:这篇讲的工具链是真的,我一条条核过。 LangChain 确实发了一个 eval-engineering skill,产物确实是 Harbor 格式的可执行 eval,流程确实是「先访谈用户再生成」而不是一把梭;langsmith-skills 是配套用来捞生产 trace 的另一个仓库;AWS 的 Agent-EvalKit 是真的,Apache 2.0,真的是六个阶段,原文给的那条 uv tool install evalkit --from git+… 命令一字不差。换句话说,「装个 skill 就能开始做评测」这件事,在 2026 年 7 月确实成立了——这不是画饼。

但最硬的那组数字,原文的用法是选择性的。 原文拿一个「盲测」当核心论据:100 条真实生产 trace、人工标注 39 个 failure、把标签藏起来让各家评测系统自己找。这个研究是真的(Parlance Labs 做的),我把完整结果捞回来了,就在下面那张表里。原文引用时做了三件事:

  • 它说「通用 coding agent 排在两家专业评测平台之上」。原研究的结论是「单看发现质量,coding agent 和专业平台大致打平」——而且榜首 Braintrust Loop 的召回率是压着 Codex 的。原文自己下一句引的「你用 coding agent 能拿到类似结果」才是原意,它前后矛盾了。
  • 删掉了两行:Claude Code 和 Factory Droid 的成绩没进榜单,留下的恰好都是对它论点有利的。
  • 完全没提原研究最重要的那个限制:所有系统都漏掉了依赖上下文的失败——异议处理、平台特有问题、该转人工却没转——这些只有人工分析才挖得出来。原研究的落点是「人仍然不可替代」,而原文的调子是「装上就行」。这两个方向是反的。

这件事改了我读这类文章的顺序。 以前我读到一篇结构漂亮、每个论点都挂着一个数字的方法论长文,默认它的数字是它的地基,先照着骨架去落地。现在我会先干一件事:把最关键的那个数字追回一手来源,然后看原文有没有把不利的那几行删掉。 这篇的骨架我照用,但它教我的最实在的一课,恰好是它自己示范的——一套「答得漂亮但没依据」的说法,读者只看行文是抓不出来的。 这正是它整篇在讲的那个毛病,讲的人自己也踩了。

所以对你我最直接的用处有两层。骨架那层:六条「判决 → 结构性动作」的路由、25 条 trace 怎么挖出第一条 eval、自动合并的四个信号、本周先建哪五条 eval——这些是真能照着做的,下面都在。判断那层:你给 agent 建的那个裁判,第一条要测的不是「答得好不好」,而是「这个答案有没有依据」——因为前者你的眼睛能看出来,后者看不出来。这也是我核这篇的方法,跟给 agent 建 eval 是同一件事。

以下是正文

温度计与恒温器

原文的核心比喻只有一句,但它值这一句:温度计告诉你屋里冷,恒温器把暖气打开。

大多数拿 AI 做东西的团队,手里最多只有一支温度计——一块看板、一种感觉,或者周五下午有人翻一翻输出,说「好像比上周差点」。

从读数到炉子之间那根线,就是 eval 工程(eval engineering)。

温度计只给读数,恒温器把判决送回图里、改变下一步执行——两者的差别只在右边那根回流箭头

全部差别在右边那根回流箭头:判决回到 graph 里,改变接下来跑什么

原文把这层能力放在一个演进顺序的末位,这个排序我认为是对的:先有 loop,再有 graph,最后才是 eval。

先是单个 agent 跑在循环里,于是它能试一次、看看回来什么、再试一次。然后是多个 agent 铺成一张图,于是本来互不依赖的活儿可以并排跑,不用排队。graph 是最后一个让你变快的升级;而裁判决定这份「快」值不值得要

原文有一句话点得很准:二十个 agent 同时跑、全都向同一个冻住不动的裁判汇报,等于二十倍数量的地方可以让一个错答案看起来像是完工了。

这也是整套系统里唯一一个「你跑得越久它越值钱」的部件。模型是租来的,每年换两轮;裁判是你自己的,你喂给它的每一次失败都永久留在里面。

第一步:评测引擎你其实已经有了

大多数人从没建起这一层,是因为默认它得从一个平台开始——合同、按座位付费、一个季度的接入期才见到第一个有用的数字。

这个默认前提在 2026 年 7 月已经不成立了。

那个盲测:100 条 trace,39 个人工标注的 failure。 两位研究者从一个跑在生产里的租房 AI(apartment-leasing,短信 + 电话真实客户对话)取了 100 条 trace,请领域专家手工标出每一个失败,建成 39 条标注,然后把标签藏起来,把同一堆 trace 交给市面上每一个评测系统,让它们自己找。

以下是我从一手来源核回来的完整结果——原文只登了其中四行

系统召回率 Recall精确率 Precision
Braintrust Loop87.2%79.1%
Codex (GPT-5.5)84.6%82.8%
Factory Droid (GPT-5.5)84.6%83.3%
LangSmith79.5%77.5%
Claude Code (Opus 4.8)79.5%77.4%
Arize AX Alyx74.4%91.0%

盲测的完整六行与原文引用的四行:删掉的两行、被改写的结论、被省掉的限制

榜首是专业平台而非 coding agent 本身;原研究的结论是「大致打平」,且明确指出所有系统都漏掉了依赖上下文的失败

三点值得你自己看清楚:

  • 榜首是专业平台(Braintrust Loop 87.2%),并不是 coding agent 本身。原文「coding agent 排在专业平台之上」的说法不成立。
  • 但「大致打平」这个结论确实成立,而这已经足够改变你的决策:一个你本来就在付钱的通用 coding agent 就能把 84.6% 的人工标注失败找回来,和专业平台在同一个量级。这意味着你今天下午就能开始,不用等采购。
  • 所有系统都漏掉了同一类东西:依赖上下文才能判断的失败。什么算失败,在新领域里仍然得由人先定义出来。这条是原研究的落点,也是你别把这套当自动挡的理由。

然后平台们做了件比输更值得注意的事:它们搬了进来。四周之内,多家评测厂商把自己的专长做成了「装进别人 coding agent 里的 skill」——LangChain(7 月 22 日)、Galileo、AWS(Apache 2.0 开源),Arize 则把它的 trace 抽取做成了 skill,用它自己的话说,装进「你最喜欢的那个 coding agent」。

这是一个品类把自己拆开,塞进你早就开着的那个终端。

装上裁判

原文给的安装是三行:

npx skills add langchain-ai/langchain-skills --skill '*' --yes --global
npx skills add langchain-ai/langsmith-skills --skill '*' --yes --global
uv tool install evalkit --from git+https://github.com/awslabs/Agent-EvalKit.git

在 Claude Code 里,同样的东西以 plugin 形式装:

/plugin marketplace add langchain-ai/langchain-skills
/plugin install langchain-skills@langchain-skills

命令之外,有两个细节比命令本身值钱:

  • 两个仓库,两件事:langchain-skills 负责建 eval,langsmith-skills 负责捞出真实生产运行来作为建 eval 的原料。几乎所有人只装第一个,然后开始纳闷素材从哪来。
  • 这不是 Claude Code 专属:这些 skill 遵循开放的 skills 规范,同一份文件也能装进 Codex、Cursor、Windsurf、Goose。

AWS 那套跑在六个命令上,每个命令是一个阶段,写进一个 eval/ 文件夹供下一个阶段读:

evalkit init my-agent-evaluation
# 然后,在你的 coding agent 里:
/evalkit.plan Evaluate my agent at ./my_agent for grounding and tool accuracy
/evalkit.data
/evalkit.trace
/evalkit.run_agent
/evalkit.eval
/evalkit.report

最后那条命令是整套装配里最值的一条:/evalkit.report 返回的是带优先级的改进建议,并指向你代码里的具体位置

第二步:让分数改变下一条边

你会建好第一个 eval、拿到一个数字、盯着它,然后感觉什么也没发生。

这个感觉是对的。报告里的一个数字,没有一条路通回它所测的那次运行。

原文引了一句话,我认为是整篇最有用的一句:

一个从不改变行为的分数,是分析(analytics)。一条能改变下一条边的 eval,才是工程(engineering)。

配套的接线是六条规则。每一条拿到一个判决,就对正在进行中的这次运行做一件结构性的事:

context recall 过低    → 拒绝这次 handoff
工具用错             → 重试,或换掉这个节点
出现 hallucination   → 隔离这条分支
schema 不合          → 封掉这条边
有合规风险            → 转人工复核
完成已被验证          → 结束这次运行

六条判决对应六个结构性动作:拒绝交接、换节点、隔离分支、封边、转人工、结束运行

每一条都是 graph 真的会执行的路由决策——eval 在飞行中改航向,一条边一条边地改

这六条的共同点:它们全都不是「记录下来周会讨论」,而是 graph 当场执行的路由。

裁判自己也要讲卫生

这部分几乎没人配置对,但它决定你后面所有分数算不算数:

  • 让另一个家族的模型当裁判。模型认得出自己的文风,认出来之后打分会手软。有团队故意用 Sonnet 给 Haiku 的产出打分。同族生成、同族打分,盲区是共享的。
  • rubric 写成一句话。可用的形式就是「Pass iff〔那个可以独立观察到的成功结果〕」。一个主判决,绝不是一堆代理指标打包。
  • 按种类分工。语义判断交给裁判,客观判断交给普通代码——测试过了没、文件存不存在、状态变了没。
  • 绝不奖励答案的「形状」。skill 里明文禁止按这些打分:回答长度、关键词、引用条数、精确措辞、工具调用次数、与参考答案的相似度。你奖励形状,agent 就学会形状。
  • 把裁判钉死版本,并记录版本号。一个偷偷升级的裁判,会让升级前后的每一个分数都不可比,而你一个月都不会发现。这条是最常被跳过的一条,也是事后让一个月的分数变成废纸的那一条。

一句话收口:对着一个裁判优化足够久,agent 学会的是「看起来对」,不是「真的对」。

第三步:把一次失败的 run 变成一条 eval

你在工位上凭想象编出来的测试,只能保护你免于你已经想到过的失败。 真正花钱的那些,此刻就躺在你的日志里,还带着时间戳。

整个循环只有五步:

挖 trace → 定位一个 failure → 建一条 eval → 改进 agent → 重跑

第一步承担了全部重量。原文提到,专业做这件事的 skill 会指定该捞哪些运行,而且起点是25 条完整 trace,不要更多——挑选原则是让好行为和坏行为挨着放:

  • 一个正常完成的请求:你的基线,「正常工作」长什么样。
  • 一个用户明确确认过的请求:难得的、你知道答案是好的那条。
  • 一个用户纠正或重新表述过的请求:那句纠正就是标签,免费送的。
  • 一次工具调用失败、返回空、或重复的运行:重复意味着死循环,返回空意味着接下来会出现一个编造的答案
  • 一次外部失败的运行:超时或限流。这里唯一被测的是——当外界说「不行」时,你的 agent 怎么表现。

每条写成四行,这个模板值得直接抄走:

Observed behavior  观察到的行为:用户问了什么,agent 实际做了什么
Comparison         对比:什么起作用了,什么没有
Attribution        归因:agent 的行为 / 依赖方的行为 / 不明
Eval candidate     eval 候选:要保住或要改进的那个能力

归因(attribution)是新手会栽一周的地方。 同一次查询、同样的参数被调了两次,那是你 agent 里的一个循环。回来一个 429,那是别人的限流——它只有在「你的 agent 本该从中恢复」时,才变成你的 eval。

从「发现」到「文件夹」

发现随后变成一个文件夹,而文件夹就是工具链能跑的格式:

evals/<task-id>/
├── task.toml
├── instruction.md
├── environment/
└── tests/

一个文件夹一个能力。instruction 和 environment 对被测 agent 是可见的;预期结果、rubric 和裁判的凭据不可见——这个隔离是分数有意义的唯一原因。

三条铁律,挡住那些让人放弃的失败:

  • 绝不把记录下来的答案当真相。trace 告诉你 agent 做了什么,永远不告诉你它本该做什么。答案要从测试、源始记录、政策、已知状态或者一个人那里取。
  • 信任验证器之前先测它。手工递给它两个假结果:一个明显正确,一个看着像但是错的。任何一个判反了,是 rubric 坏了,不是 agent 坏了。
  • 盯住「环境把答案漏出去」。如果 setup 在 agent 还没走到那个该用的工具之前就把结果递过去了,这个任务会永远通过,而且什么也没测。

任何花钱的、或者会写生产的动作,都用模拟代替真调用——这样这套 suite 你想跑多少次跑多少次,不产生账单。

一条指令就能在你已经开着的 agent 里启动全部:

Use the eval-engineering skill.

Map this repository's agent: entrypoint, tools, backing data, and what a good
result looks like. Then read the 25 traces in ./traces and propose two or three
eval candidates grounded in what actually failed there.

Recommend one. Do not implement until I choose.
Build it as a Harbor task under evals/, keep the rubric and expected outcome
hidden from the target, and test the verifier on one passing and one plausible
wrong result before the real run.

中间那个「先访谈、我不选你别动手」的步骤是故意的。写这个 skill 的团队发现,访谈用户每次都打得过一把梭生成——理由很朴素:「什么算对」这件事住在你脑子里,模型里一个字都没有。

跑几轮之后,每一次失败都不再是一次事故,而变成一条永久的测试。

第四步:让这张图自己合并自己的活儿

agent 开的每一个 PR 最后都落在同一个地方:人的队列。你成了你自己那套自动化的瓶颈,你造的这支舰队,跑在一个累了的 reviewer 的速度上。

出路完全不是「更信任模型」。当 agent 开出一个 PR 时,有四个信号当场就在,置信分(confidence score)由它们现算:

  • Guardrails 结果:对那些阻塞性标准做确定性的过 / 不过。不涉及模型。
  • 近期 eval 走势:这个 agent 的这个确切版本最近考得怎么样。
  • 历史回滚率:这个 agent、在这个仓库、在这类改动上,以前被回滚过多少次。
  • 沙箱结果:它到底跑起来了没有。

四个信号算出一个置信分:过线自动合并,不过线转人工并直接点出是哪个信号不合格

四个信号里三个是历史与确定性检查,只有一个碰到模型——转人工时带着「哪个信号挂了」,复核从问题处开始,不从第一行开始

过线就自己合并。不过线交给人,而且带着那个不合格的信号的名字——于是复核从问题开始,不从第一行开始。

四个信号里,三个是历史和确定性检查,恰好只有一个碰到模型。 所以原文那句判断是准的:对一个 agent 的信任,是一次精算。 你在建的是一份带价格的履历,跟保险公司建履历是同一回事,而且不管模型有没有变强,它每周都更锋利一点。

跑起来是什么样——以下数字来自原文引述的匿名公司与个人,我核不到一手来源,请当作案例听,不要当基准:原文称在那家「只改了 evals」的公司,全自动 agent 上每 20 个 PR 有 19 个无人介入就合并;头部几个 agent 里约四分之三的已合并工作没经过一次人工编辑,回滚率停在个位数低位,光 Guardrails 一项就在人看到之前弹掉五分之一的 PR。另有一位在自己仓库上跑这套模式的人说,90 天里他批准并合并了约 1500 个 PR,一行代码都没看——他给的理由值得记下来:

我一点也不信任它们。我也不信任我自己 code review 它们的能力。但我确实信任我约束它们工作的能力。

约束本身就是产品。

而比公式更值钱的是一条警告,来自一个跑了 285 轮自我改进迭代的团队(同样未经我核实):38 个绿色测试,和一个彻底坏掉的产品,是可以同时存在的。

一套 suite 可以全绿,而它守护的产品正在崩塌。所以这个循环必须收敛到 spec 上,不是收敛到分数上。

小心地把它打开:

  • 先跑影子模式:闸门给每个 PR 打分,但一个也不放行,至少跑满 4 小时真实流量。
  • 设 2% 的偏差阈值:自动判决和人工判决分歧超过这个数,闸门就保持关闭。
  • trace 采样 1% 到 5%:全量捕获是一笔你不必背的成本。

一个两人小店,如果每一个 agent 写的改动都要等那一个 reviewer,那它能接的活儿就只有那个人读得完的量。把闸门在风险切片上关着、在无聊的那 80% 上打开,同样这两个人开始给以前只能推掉的合同报价。 模型账单一分钱没变,别的全变了。

第五步:本周就能建起来的那几条

太慢或者太含糊的 suite,最后一定没人跑。 所以这部分是要存下来的。

从三个测量开始,不是十二个。任何会调工具的 agent,这三个是能用的默认值:

  • Faithfulness(忠实度):答案是否扎根在工具真实返回的东西上。这是那个在看板上其他数字都好看时、独自趴在低位的指标。
  • Tool parameter accuracy(工具参数准确率):对的工具,对的参数。
  • Response quality(回答质量):输出对提问的人是否连贯、有用。

三者的关系是这篇最该带走的东西:回答质量是你眼睛能看出来的,忠实度是看不出来的。 一个 agent 完全可以写得漂亮、条理清晰、数字精确到小数点后一位——而那个数字是它在搜索工具返回空之后自己填上的。只看行文,你永远抓不出来。

如果你的 agent 产出的是代码,那就给「改动」打分。生产里对每个 PR 用的五个维度:意图与决策、执行与产物、完整性与有用性、指令与边界、效率。

故意挑对 dataset 类型。有四种:final_response(只看最终答案)、single_step(孤立看一个决策)、trajectory(看 agent 走过的整条路)、RAG(看检索质量)。

只给最终回答打分,正是「agent 通过一条坏掉的步骤序列到达了一个正确答案,而没人发现」的成因。

规模上要让它活得下去:留出 300 到 800 个用例,并保证其中 500 个在 5 分钟内跑完一套比一次咖啡休息还长的 suite,会停止被运行。

头五条 eval,按顺序:

  • 工具返回空:工具什么也没返回,agent 必须说出这件事,而不是把数字编出来。
  • 重复调用:同一次查询、同样的参数,调了两次。那是循环,这条 eval 判它不过。
  • 边界拒绝:被要求做权限之外的事,agent 干净地拒绝,而不是去找绕过去的路。
  • handoff 完整性:上一个节点产出的东西,就是下一个节点读到的东西,中间没有任何东西被编造出来。
  • 完成已验证:「做完了」意味着有一个真实信号说做完了,绝不是 agent 自己这么说。

本周的清单:三个测量、一种 dataset 类型、五条 eval——一个下午的工作量

三个测量、一种 dataset 类型、五条 eval:一个下午的工作量,而此后每一周它都比上一周更值钱

我的收口

模型从来不是有意思的那部分。它是租来的,对每个人都一样,而且到年底之前还会被换掉两轮。

每次换代都活下来的,是你围着它建起来的那个裁判:你变成了永久测试的那些失败、能让一个判决改变下一条边的那些规则、能让机器合并自己工作的那份履历。

原文最后收在三句话上,这三句我照原样带过来,因为它们确实立得住:

  • 测 agent 走过的路径,永远不要只测它落在哪个答案上。
  • 一个不改变下一条边的判决,只是一份报告。
  • 任何你没有变成永久测试的失败,你都会再遇到它一次。

我要加第四句,是核这篇文章核出来的: 别只给你的 agent 建裁判——给你读到的方法论也建一个。 这篇文章漂亮、结构清晰、每个论点都挂着一个数字,而它最关键的那个数字,是从一份真实研究里选择性引用出来的:删掉了两行不利数据,改写了结论,省掉了「人仍然不可替代」这个落点。

这跟一个 agent 在搜索返回空之后编出一个精确到小数点后一位的汇率,是同一种失败——答得漂亮,但没有依据。 抓它的办法也是同一个:不看行文,去追它的来源。

装一个 skill。捞 25 条 trace。今天建一条 eval,然后每次坏掉一样东西就再加一条。

本文由 Yaqin Hei 编译、核实并配图。原文作者 @Argona0x,原文链接。盲测完整数据来自 Parlance Labs《Do Automated Evals Work?》,来源,核实于 2026 年 7 月 29 日。

Subscribe for updates

Get the latest AI engineering posts delivered to your inbox.

评论