← 返回方法论

Benchmark 怎么用:搭 Agent 的人该如何使用 benchmark

benchmark 不是考卷,是答案库——读榜选型、抄判分方法、切片诊断,三步把"感觉变好了"变成"分数从 61 到 68"

  • Agent
  • Benchmark
  • 评测

问题:改了但不知道是不是更好

搭 Agent 的团队几乎都经历过这个循环:改了一版,手动试三五个 case,感觉好多了,上线。过两天用户又报了一个新 badcase,再补丁式修改,再试几个 case。循环往复,系统看起来在进步,但没人说得清它整体是变好还是变坏。

这个循环的问题不在于改得慢,在于没有坐标系:

  • 不知道这次修改让系统整体变好还是变坏——手动试的三五个 case 可能恰好都是被这版改动覆盖的,改坏的部分还没踩到。
  • 不知道问题出在链路的哪一段——用户报一个 badcase,你只能整条链路一起猜,是理解错了、检索错了,还是最终没验证好?

归结起来就是一个问题:Agent 怎么知道自己做对了?

正路:把循环倒过来

直观的做法是先改功能,再靠感觉验收。正路恰恰相反——先定义”好”是什么,再让修改对着”好”回归。

  1. 建一个小而真的评测集:每个 badcase、每类核心场景,都落成一条”输入 → 期望行为”的记录。
  2. 定一份可执行的判分标准:能说清”什么算对”,才能给每一步打 1/0 分或 0~1 分。
  3. 让每次修改回归这个评测集。

改完之后,修改的最小单位不再是”改了个功能,感觉不错”,而是**“评测分从 61 → 68,退化 0 例”**。有了这个基数,改对改错、改好改坏,一目了然。

从 benchmark 身上拿三样东西

这里的关键认知是:benchmark 不是考卷,是答案库。你不需要自己从零发明一套评测方法——SVT 的跑分文件、编程评测的验证器、对话评测的判分标准,都已经是别人踩过坑的答案,直接拿来拆、抄、改。

把 benchmark 当答案库,能从中拿到三样东西:

第一样:读榜选型——拿公开榜单做模型与方案比较

榜单是别人替你把一大票候选跑过的对照实验。选型时不要只盯”总分数”,要按你的场景挑维度:

  • 按任务类型过滤:你是做 coding 的,就别被总分最高的对话榜带跑,看 coding 分项和 retrieval 分项。
  • 看重倒退与失败模式:总分接近的两个模型,看它们各自在哪些 case 上栽——一个稳但偏保守,一个激进但偶尔翻车,你要的是跟你业务风险匹配的那一个。
  • 警惕分数饱和:榜单顶层分压在一起时,同一个 agent 换不同模型,跑你自己的小评测集往往比榜单更能分出高下。

第二样:抄判分方法——把公开 benchmark 变成自己的评测集

公开 benchmark 最有价值的部分常常不是分数,而是判分方法——它是可迁移、可复制的。抄不是照搬题目,是抄”怎么判”:

  • 抄验证方式:编程 benchmark 用测试用例判分,那你也可以给关键输出写断言;对话 benchmark 用评分模型判分,你也可以在判分环节套一层”检查清单打分”。
  • 抄判分粒度:好的 benchmark 不只有总分,还有分项分。你的评测集也要能出”理解、检索、验证各得几分”,而不是一句”通过了/没通过”。
  • 抄 case 构造:看 benchmark 是怎么把一个 base case 扩展成”有歧义版 / 缺信息版 / 需要澄清版”,用同样的手法给自己的工作堆非法输入、边界输入。

第三样:切片诊断——出问题时把执行拆成节点逐段定位

有了评测集回答”好不好”,还需要一个工具回答”坏在哪”。每次出 badcase,把单次执行拆成节点,逐段对照判分标准:

  • 拉出这次执行的节点流水(见下节),每个节点都带上输入、输出、耗时、调用的工具。
  • 二分定位:先看输出端对没对,再往前看”推理/检索/理解”哪一格已经埋了错。通常 80% 的坏 case 在往下传的时候就已经错了,后面再修也修不回来。
  • 按节点记账:每个节点单独打分。分低的那一节,才是你这次要动的”最小可验证单元”——改了它,只回退这条链路的分数,而不是整条链路一起试。

一次执行的 7 个节点

切片依赖一个稳定的坐标系。任何一个 Agent 系统,不管什么框架、什么模型、多复杂,单次请求都可以拆成下面 7 个节点。搭的时候给每个节点留钩子(记录输入输出、判分),诊断就有了抓手。

节点它在做什么典型的”坏法”
① 输入理解与澄清把用户模糊的话读成明确的意图,缺信息时先问该问不问、拿着歧义需求直接猛跑
② 检索 / 工具调用从外部拿到完成任务的资料或能力检索结果不相关、调用了错误的工具或参数
③ 上下文组装把检索结果、历史、系统约束拼成模型能看懂的上下文有用的被挤掉、无用的塞进来,上下文过长
④ 推理规划决定下一步做什么、拆成几步、按什么顺序不规划就执行、规划了但和检索到的信息对不上
⑤ 执行落库、调 API、写文件、跑工具副作用操作没有确认、拿到的结果没落回状态
⑥ 结果验证对自己产出的东西做自查,必要时返工验证缺失、把幻觉直接当答案输出
⑦ 输出把结果整理成用户要的格式交付格式不对、关键信息丢在中间过程里

拿这 7 格对照刚才的老问题:用户报”answer 不对”,别再整条猜——先看 ⑥ 验证和 ⑦ 输出是不是根本没判;往前看 ④ 规划是不是从一开始就理解偏了。每一格都能独立打分,才谈得上”定位”。

六组可直接抄的开源 benchmark:每种失败都有现成答案

七种失败模式各自怎么量化判分?最强的答案在公开 benchmark 里。这六组是覆盖面最广、判分最机械可信、最值得抄的:

组开源仓库主要考哪一节点判分方式(可信度链条)
τ²-benchsierra-research/tau2-bench① 理解澄清 + ④ 按 policy 调工具可执行终态比对
RAGASexplodinggradients/ragas② 检索与组装LLM 判分(recall/precision/faithfulness)
CRAGfacebookresearch/CRAG② 检索(含伪前提)三值打分(+1 对 / 0 老实说不知道 / −1 错)
PlanBenchkarthikv792/LLMs-Planning④ 规划可执行验证(VAL,零 LLM 判卷)
BFCLShishirPatil/gorilla④ 工具调用(含 irrelevance)AST 比对
TRAILpatronus-ai/trail-benchmark⑤⑥ 过程与验证LLM 评审(且判不准,见下)
SWE-benchprinceton-nlp/SWE-bench⑥⑦ 结果验证可执行验证(FAIL_TO_PASS + PASS_TO_PASS 双绿)

这几组背后有一条统一的判分可信度链条,抄之前先记住它:

可执行验证(测试/终态比对)> 精确匹配 > AST 结构比对 > 规则断言 > LLM-as-judge

前四种是”死代码”判分:零成本零方差,跑一万次一个结果;LLM 裁判每次心情不一样。原则是能用死代码就用死代码,LLM 只留给非它不可的语义判断。 逐个看最值得抄的设计:

  • τ²-bench(1.5k★)考”会不会问对问题、扛得住用户忽悠”。三件套:一份 policy 出错时当考纲、一个带状态的数据库(db.json)当考场、一个用户模拟器当对手戏演员——模拟器被要求渐进式披露信息,Agent 不问就不说,甚至会拿”领导已经批准了”来诱导违规。判分是乘积制 reward = DB × COMMUNICATE:DB 项把参考操作重放得到”金标终态”,与 Agent 改出的终态做 hash 比对——任何等价终态的操作序列都算对,比结果不比过程。
  • RAGAS(14.7k★)是一套现成指标定义,四个互相制衡:context recall(该进来的进来没)、context precision(进来的都有用吗)、faithfulness(答案每个断言能否被上下文支撑)、answer relevancy。前两个评 N2,后两个评 N2 到 N6 的传导。
  • CRAG(Meta)的洞察是 RAG 失败不平均分布:长尾实体 + 实时信息 + 多跳是重灾区,评测集必须显式分层才暴露短板。记分最值得抄:四档折算成三值,答错 −1、答对 +1、老实说”不知道”得 0——让诚实严格优于瞎编。它还专设 false_premise(伪前提)型,正确答案是”问题无效”——自建评测最容易漏的类别。
  • PlanBench 考的是基座模型的”排步骤”能力,不考 Agent。因为积木世界有形式化定义(PDDL),正确性用符号验证器 VAL 机械判定:把计划真执行,检查每步前置条件满足、终态达标——与金标计划一致与否无关,零 LLM 判卷。它还有换皮卷(把词全换掉、逻辑不动),专拆穿”靠眼熟得分”的假推理。业务里凡是有形式化规则的规划——审批流、调度、路径——都能照这个思路造”验证器判分”。
  • BFCL(12.9k★)函数调用领域最常被引用的榜单,分 simple / multiple / parallel / irrelevance / multi-turn 五层。两个值得抄的设计:一是 AST 比对而非字符串匹配——等价写法用”每个参数给允许值集合”解决(如 "unit": ["units", ""] 都算对);二是 irrelevance 作为一等测试类别——给用户问三角形面积、唯一可用函数却是算 BMI 的,满分答案是”一个函数都不调”。大部分团队只测”会不会调”,忘了测”会不会不调”,而”不该调硬调”恰是生产事故大户。
  • TRAIL 是 2025 年起最新、也最没标准答案的过程评测。它从 GAIA 和 SWE-bench 的真实执行轨迹里取 148 条 trace,人工在 span 级标 841 个错误,建了一套 Agent 错误分类学(推理类 / 系统执行类 / 规划协调类),然后考 LLM「读 trace 把错找全、分对类、定准位置」。但据其 README,最好的模型准确率仅 约 11%——“让 LLM 读 trace 找错”本身还不可靠,所以过程评测必须死代码打底、LLM 收尾。它附赠的错误分类词典能直接拿来标自己的 trace。
  • SWE-bench(5.3k★,编码 Agent 使用最广)从 12 个热门 Python 仓库的真实 PR 反向出题:取”issue + 修复它的 PR”对,仓库回滚到 PR 之前,让 Agent 自己改。判分不可作弊:FAIL_TO_PASS(PR 前失败、PR 后通过=真修好了)+ PASS_TO_PASS(PR 前后都通过=没改坏别的),双绿才算解决。金标 patch 是一行代码,但判分不比对文本,只看两组测试颜色——判”效果”不判”写法”,和 τ² 的终态比对同一哲学。

评测思想长在代码里:deer-flow

这些”尺子怎么造”的思想,有人直接内建进了运行时。deer-flow(字节开源,76.2k★,bytedance/deer-flow)最初是经典的多 Agent 流水线,2026 年重构成一个 lead agent + 约 30 个各管一件事的中间件。妙处在于 这 30 个中间件的文件名本身就是一份”问题清单”:

backend/packages/harness/deerflow/agents/middlewares/
├── clarification_middleware.py        # N1 澄清:中断等用户
├── dynamic_context_middleware.py      # N2 动态上下文
├── summarization_middleware.py        # N2 历史压缩
├── token_budget_middleware.py         # N5 token 预算
├── todo_middleware.py                 # N3 计划管理
├── loop_detection_middleware.py       # N5 死循环熔断
├── read_before_write_middleware.py    # N5/N4 写前必读
├── subagent_limit_middleware.py       # N5 并发上限
├── dangling_tool_call_middleware.py   # N4 悬挂调用修复
└── ...(共约 30 个)

最值得看的是它的 goal loop(runtime/goal.py):每跑完一轮,由另一个独立的 LLM 评估器固定审查一个问题——「真完成了吗?」评估器提示词是防自欺的教科书写法:

“You are a strict completion evaluator … Decide whether the active goal is fully satisfied using ONLY the visible conversation evidence. Do not assume files, commands, tests, or external state changed unless the conversation explicitly shows it. If the visible evidence is too weak to prove progress, fail closed with blocker missing_evidence.”

两个关键词:strict(严判)和 fail closed(证据不足判失败而不是放行)。而”无进展”怎么判它不问 LLM——LLM 每次措辞都不一样,比对不可靠——改为由代码对最近一条用户可见产出算指纹,两轮指纹相同 = 无进展。LLM 判断语义,代码判断事实,各干各的。

拉远看:同一批 benchmark 在不同阶段扮演不同角色

  • ① 选型阶段·读榜:基座模型 release notes 必带 SWE-bench Verified、工具调用类分数,用来排除明显不行的模型(也选裁判模型)。只能用于排除、不能用于预测——榜单环境与你的工具集、业务分布都不同。
  • ② 设计阶段·评测先于构建:Sierra(τ-bench 出品方)先把”客服 Agent 什么叫好”定义成 benchmark 再迭代产品;TRAIL 是 Patronus 把自家 trace 标注方法论开了源。构思题意会反哺架构——看过 irrelevance 就会给”不调用工具”留路径;看过终态判分,就会把可验证状态设计进工具返回。
  • ③ 迭代阶段·工程实证:OpenHands(84k★,OpenHands/OpenHands,配套评测仓库 OpenHands/benchmarks)把评测拆成独立仓库,README 开宗明义”为各类真实世界任务的 Agent 能力测试提供标准化评测流水线”。两个含金量的工程细节:Agent SDK 用 git submodule 钉死 commit——练次评测结果对应一个可复现的代码版本;跑分与版本强绑定——没有来历不明的分数。
  • ④ 成熟阶段·公共尺子对外锚定:自建评测接管日常回归后,公开 benchmark 只剩一个角色——换基座、重构 harness 时横向锚定,供外界对齐。UI-TARS(字节 GUI Agent)每代发布拿 OSWorld、AndroidWorld 分数做版本间比较。

一个完整的落地例子

把上面串起来,跑通一次”用 benchmark 改进”的闭环:

  1. 上线当日,用户报一个 badcase:问”今天杭州去上海的高铁”,agent 直接给出了买票链接而没有先确认车次。
  2. 沉淀进评测集:新增一条 {"输入": "今天杭州去上海的高铁", "期望行为": "先澄清:起讫车站、出发时段、是否含当天全部车次"}。
  3. 对照 7 节点判分:假设本节在 ① 输入理解被记了 0 分——该澄清没澄清。
  4. 只改这一段的最小单元:在理解阶段加一条”起点终点不明时需要澄清”的约束,而不是重排整条链路。
  5. 回归评测集:这条从 0 → 1,同时跑既有 60 条,“总 61 → 63,退化 0 例”。确认没把别的 case 改坏,才上线。

一次迭代变成了一个可复现、可回滚、可归因的动作。这个闭环跑熟了,累积下来的评测集就是你团队最贵的资产——它录的是”什么算对”的共识,比任何一个模型版本都活得久。

实践体会

  • 评测集不是一次建完的:每发现一个 badcase,就沉淀一条;它跟着系统一起长大,而不是上线前拍一次脑袋。
  • 判分标准要可执行:能说清”什么算对”,修改才有方向;说不清”对”,改多少次都只能靠手感。
  • benchmark 是答案库不是考卷:先学会用别人的,再抄判分方法建自己的,别从零发明轮子。
  • 没有坐标系的迭代,只是看起来在进步——给人感觉忙忙碌碌,其实是在原地打转。