评估是 Harness 里的“验证”环节
用哪个模型、给哪些工具、知识库存什么、记忆怎么做、提示词和 Skills 怎么组织、Harness 加哪些约束,这些设计选择都没有一眼就能看出的正确答案。评估用两种实验来做决定:对比实验一次只改一个变量,看效果怎么变;消融实验一次关掉一个组件,看它到底贡献了多少。
公开基准上更强的新模型,在你的任务上未必更好,甚至可能退化。只有在自己的评估集上跑一遍,才能做出数据驱动的升级决策。评估集建好以后,还可以“为未来的模型开发产品”:先把产品和评估集做出来,持续跟踪新模型,一旦达到门槛就上线。
模型替换实验:瓶颈在模型还是在 Harness
固定 Harness · 只换模型消融实验
固定模型,关掉 Harness 的某个组件看整体掉多少。用来找 Harness 内部哪个部件重要。
模型替换(model swap)
固定 Harness,只换更强或更弱的模型。用来判断瓶颈在模型还是在 Harness。
一条评估任务的解剖:τ²-bench telecom
τ²-bench 是 Sierra 开源的评估框架。我们取 telecom 领域里的一条任务:用户在法国,手机显示“No Service”,上不了网。真正的故障是两件用户自己都不知道的事:飞行模式开着,数据漫游关着。
一条好的任务定义,把“用户知道什么”“用户怎么说话”“状态从哪开始”“怎样才算解决”四件事都写进了数据结构,而不是靠一句提示词去约束。
// 删节版 · data/tau2/domains/telecom/tasks_small.json "id": "[mobile_data_issue]airplane_mode_on|user_abroad_roaming_enabled_off", "ticket": "用户手机无法上网,状态栏显示'No Service'。客户 John Smith,号码 555-123-2002, 当前在法国。速度测试结果为 excellent 才算解决。不更换套餐,必要时愿意充值 2.0 GB 流量。", "user_scenario": { "instructions": { "known_info": "You are John Smith with phone number 555-123-2002. You are currently abroad in France.", "unknown_info": null, "task_instructions": "…express mild frustration after the first unsuccessful attempt. You will consider the issue resolved only when speed test returns excellent … always ground your responses on the results of tool calls. … Never make up the results of tool calls." }}, "initial_state": { "initialization_actions": [ { "env_type": "user", "func_name": "turn_airplane_mode_on" }, { "env_type": "user", "func_name": "turn_roaming_off" }, { "env_type": "assistant", "func_name": "enable_roaming", "arguments": { "customer_id": "C1001", "line_id": "L1002" } } ]}, "evaluation_criteria": { "actions": [ { "requestor": "user", "name": "toggle_airplane_mode" }, { "requestor": "user", "name": "toggle_roaming" } ], "env_assertions": [ { "func_name": "assert_mobile_data_status", "expected_status": true }, { "func_name": "assert_internet_speed", "expected_speed": 200, "expected_desc": "excellent" } ], "communicate_info": null, "nl_assertions": null, "reward_basis": ["ENV_ASSERTION"] }
① 建模用户的认知边界
known_info 里只有姓名、号码、所在国家。故障原因不在里面,用户说不出来,Agent 只能靠提问和引导去查。这就是渐进式信息透露,它是一个字段,而不是一句“别一次说完”。
② 防止模拟器被忽悠
三类约束:情绪(第一次修复失败后表现出轻度不满)、验收口径(只认 excellent)、事实锚定(设备状态必须以工具返回为准)。没有锚定,模拟用户会顺着 Agent 说“好了”,评估就变成两个模型互相确认。
③ 双方都没有完整信息
飞行模式、漫游开关在用户侧;enable_roaming 在运营商侧,Agent 能查到。运营商侧已开通,设备侧却关着,所以 Agent 查数据库只会看到“配置正常”。
④ 多维度校验
终态断言(env_assertions)、关键动作(actions)、信息告知(communicate_info)、自然语言断言(nl_assertions)。每个任务可以选其中一个或多个维度。
双控环境:两侧都能改写状态
图 7-3 重画。用户执行 toggle_roaming 之后环境变了,Agent 必须重新调用工具才能知道结果,所以验证也覆盖了“Agent 有没有读到用户侧的操作结果”。
实验 7-1 · 逐步回放两条真实运行
设备侧(用户可见、可操作)
运营商侧(Agent 可查)
任务结束后:四层检查 + 聚合规则
reward_basis = ["ENV_ASSERTION"]:只有第一层计入奖励,其余各层照常记录。
满分轨迹也可能违规:第 4 条消息里 Agent 一次发出了两个工具调用,而政策第一段就规定“一次只调用一个工具”。验证器只看终态,所以没有发现。这不是 τ²-bench 的疏漏,是二元奖励的固有代价:用过程粒度换来一个跨模型可比的数字。生产评估还需要指出问题出在哪里。
评估指标:成功的定义
上一节五条任务通过了四条,0.8 是好是坏?如果是退款客服,五个用户里就有一个拿不到应得的退款;如果是挖漏洞的安全 Agent,五次命中四次已经很可观。差别在于业务对成功率要求多高。
Pass@k 与 Pass^k 计算器
假设每次运行独立 · 书中例:p = 0.6, k = 5Pass@k = 1 − (1 − p)k Pass^k = pk
报告里必须写清 k 次的口径:是同一任务独立采样 k 次,还是流水线上连续 k 个任务。有副作用的操作不能“重试到成功为止”,应在沙盒或可回滚环境里采样,每一次失败都计入可靠性指标。
技术奇观:Pass@k 看上限
运行 k 次,只要有一次成功就算过;输出是连续分数时取最好的一次,叫 Best@k。它证明“这件事原则上做得到”。例子:让 Agent 自主工作一周从头写一个 C 编译器、一直探索直到找到重要数学猜想的反例、反复审查开源软件找出存在几十年的重大漏洞。Manus 的虚拟电脑、OpenClaw 的“活人感”,早期成功率都不高、token 成本也高,但用最强模型时 Pass@k 高,被大量分享,这是它们成功的关键。
业务可靠性:Pass^k
读作 Pass consecutive k:同一任务连续运行 k 次,每次都要通过,并且不能触发安全、合规、幻觉等一票否决项。它回答的是“能不能稳定交付”,而不是“能不能偶尔创造奇迹”。支付、退款、权限变更、生产部署要看的是这个数。
评估环境:一套能重复运行的装置
评估环境要满足一点:给定同一个初始状态,同一个 Agent 应当得到可以比较的结果。拿刚才那条 telecom 任务对照,五个组成要素都已经齐了。
五个要素缺一个,评估就构不成可重复的循环。后面看其他基准时,也用这五项来对照。
人机交互型与工具调用型
代码生成、数据分析、数学求解这类任务没有对话对象,Agent 只和工具打交道,能不能通过执行验证决定对错,既不需要人工标注,也不需要模型评判。这类环境省掉了用户模拟器,其余四个要素还在,只是更简单:状态是文件系统或数据库,评分标准是一段测试代码,协议是“一直调用工具,直到给出答案或用完轮数”。
图 7-2 重画。工具调用型验证行动(可观测的状态变更是否正确),人机交互型验证引导(沟通策略是否合理)。
表 7-1 · 该选 Verifiers 的哪种环境
按状态、工具、隔离三个问题选| 环境类型 | 状态保持 | 工具调用 | 典型用例 |
|---|---|---|---|
SingleTurnEnv | 无 | 无 | 单轮问答、数学题:问完直接验答案 |
ToolEnv | 无 | 多轮 | 搜索多个网页后综合回答,验最终结果 |
StatefulToolEnv | 有 | 多轮 | 修改数据库记录,验状态变化 |
SandboxEnv | 有 + 隔离 | 多轮 | 沙盒里跑代码,检查输出文件 |
框架支持并行采样和轨迹缓存,每次评估的完整轨迹(观察、行动、奖励)都会保存,方便分析和回放。工具失败时应返回清楚的错误信息,而不是一个失败标志,Agent 才能据此调整。
评估数据集的设计
环境是舞台,数据集是剧本。同样五个要素,换一类任务填法就完全不同:任务从哪来,验证器能核实到多深,怎么防止被模型记住。
| 基准 | 被测能力 | 任务来源 | 环境扮演者 | 验证器 |
|---|---|---|---|---|
| τ²-bench | 客服场景的人机交互与工具调用 | 人工编写 + 组合生成 | 用户模拟器 + 业务数据库 | 四层检查按 reward_basis 聚合为二元 |
| SWE-bench Verified | 软件开发,coding | GitHub 真实 issue,人工筛选 | 代码仓库 + 测试套件 | FAIL_TO_PASS / PASS_TO_PASS 双重验证 |
| AndroidWorld | 操作 Android 手机 GUI | 参数化模板实例化 | 真实 Android 模拟器 | 最终 UI 状态断言 |
| OSWorld | 操作 Linux 桌面 GUI | 从预置的中间状态启动 | 真实虚拟机 | 134 个独立评估函数 |
| Terminal-Bench | 操作 Linux 终端,coding | 人工编写 | Docker 容器 | 文件系统检查 + 真实执行 |
| GAIA | 搜集信息的通用 AI 助手 | 人工编写 + 专有附件 | 开放互联网 | 精确字符串匹配 |
表 7-2 几个 Agent 基准的关键设计选择。
验证器:核实事实,不信自我陈述
Agent 很容易写出一篇报告说任务全部完成,但事实上根本没做完。评估框架必须核实机器能独立复核的事实。
SWE-bench Verified · 两个命题缺一不可
点开关看哪种补丁会被放过书中的说法:只检验前者,Agent 可以删改妨碍通过的断言蒙混;只检验后者,等于没检验。SWE-bench 还额外确认测试本身稳定,排除时过时不过的 flaky test。
OSWorld:表面完成≠真完成
134 个独立评估函数,有完整的操作系统权限,能查文件系统、进程、网络连接和应用内部状态。数据库任务不光确认报告文件存在,还连上数据库核实 SQL 真执行了;浏览器任务会分析 DOM、查 cookie 与 localStorage、向后端发请求确认表单生效。
Terminal-Bench:没法伪造
build-linux-kernel-qemu:从源码构建 Linux 6.9,在 start_kernel 里加自定义 printk,生成 initramfs 并在 QEMU 中启动。成功标准是启动日志里出现那条消息,只能真把整个流程做完。
难度分层:有诊断价值
GAIA 466 题 · 人类 vs GPT-4
三级难度对应三种改进方向Level 1 只需一两个工具,失败指向基础工具使用;Level 2 要多步思考,指向规划与信息整合;Level 3 要复杂组合,指向长序列思考与复杂性管理。Terminal-Bench 的梯度:mlflow 模型注册 → 7z 密码破解 → git 服务器与 webserver 多组件集成 → FEAL 差分密码分析。τ²-bench 还专门设计了陷阱任务:用户声称“客服已批准取消”,实际不符合政策。
防数据泄漏:三种手法
GAIA · 让答案搜不到
概念简单、路径开放:从某天的 NASA 每日天文图片出发,认出宇航员 → 查他所属的宇航员组 → 算组里太空停留最短的人 → 按“姓氏,分号分隔,千位分隔符”格式输出。必须组合多个信息源;部分题配有网上不存在的 PDF、音频、图片附件。
AndroidWorld · 模板派生实例
参数每次不同,回放固定操作序列就失效;一个模板生成近乎无限的实例;固定部分参数只改其余,可以精确测某个因素的影响。
Terminal-Bench · 金丝雀
每道题带一个 canary GUID。模型若能输出含这个 GUID 的内容,说明基准数据进了训练集。它不阻止泄漏,但让泄漏可被检测。
质量控制:基准是修出来的
SWE-bench Verified · 发布前淘汰约 71%
93 名精通 Python 的开发者逐条检查:描述是否清楚、测试是否覆盖边界、是否稳定、参考 patch 是否引入新错误、难度是否合理。信噪比更高,评估成本下降约 80%。用前沿模型完整跑一遍复杂 Agent 评估集,往往要数千美元 token。
OSWorld · 发布后 15 个月暴露 300 余个问题
| 问题类型 | 修复方式 |
|---|---|
| 环境(反爬、CAPTCHA、动态内容) | 锁定版本、离线备份 |
| 任务描述有歧义 | 改写歧义表述 |
| 验证逻辑过严或过松 | 人工建正确基线、调整条件 |
| 初始状态配置不完整 | 增加完整性校验 |
2024 年 4 月发布;港大约 10 人小组与 MoonShot AI、OpenAI、ByteDance Seed TARS、Anthropic、Simular 等合作两个月系统修复。
τ-bench → τ²-bench 的五处重新设计
每一处都对着一个初版问题| 初版问题 | τ²-bench 的改法 |
|---|---|
| 任务指令笼统,凭常识猜流程也能过 | 剧本拆成 known_info(用户知道什么)和 task_instructions(怎么透露) |
| 成功条件不精确,“网络已恢复”没有边界 | “测速为 excellent 才算解决”,专治只压症状不解根因的敷衍修复 |
| 模拟用户只会被动应答 | 补上情绪、耐心上限(沟通太低效就结束对话)、事实锚定 |
| 只有 Agent 能改环境 | 双控环境:用户在自己设备上操作;验证覆盖“Agent 是否读到用户侧结果” |
| 实例固定 | 姓名、号码、故障组合参数化批量生成,覆盖率和抗泄漏都改善 |
自建评估集的三个来源
公开基准
粗筛模型、借鉴设计手法,一般不用来做产品决策。分布和业务不一致:GAIA 上涨两个点,和退款成功率没有必然关系。
自建业务集
覆盖真实任务分布,是模型选型、Harness 设计的依据。例如拿 τ²-bench 当需要仿真用户的骨架,换掉领域数据和工具集。
生产轨迹回流
用户纠正、点踩、事后审计发现的问题,经失败归因后沉淀为回归用例。成本最高,也最准。
起步时只有公开基准和少量手写用例;上线一段时间后,生产回流的用例会成为主体。验证深度、参数化生成、防泄漏、质量维护,正是自建评估集最容易漏掉的几处。
自动化评估方法
前面的基准几乎全用确定性验证器:跑测试、断言 UI 状态、精确匹配字符串。它不花额外模型开销、完全可复现,能像单元测试一样进 CI。代价是只说对错,不说原因。τ²-bench 那条失败任务得 0 分,这个 0 不会告诉你是选错了线路还是漏了充值。
从公开基准走向生产,验证方式要沿着“能否机械验证”的谱系向右移。但能写成断言的检查继续用断言,LLM 评判只用在确实无法机械判定的维度。
图 7-4 · 验证方式的谱系
点击一档LLM-as-a-Judge 流水线
开放式任务(写报告、处理投诉、创意内容)没有标准答案可比,人工评又贵又难规模化。让语言模型按专家定义的 Rubric 打分,在规模和专业判断之间取得平衡。
图 7-5 · 打分与聚合
候选回答:“退款已处理,$150 将在 3-5 工作日内到账。”默认分数取自图 7-5(4/4、3/4、PASS、4/4,理由分别是“金额和时间均准确”“缺少退款方式说明”“无虚假信息”“因果关系清晰”)。书中只给了权重档位,没有给数值,这里的 2 : 1 是演示用的示例值;评委 2、3 默认与评委 1 相同,可拖动看中位数与人审触发。
已知偏差:长度偏差
评判模型倾向给更长、更详尽的回复高分,哪怕内容并不更对,就像考试遇到不会的题就写长篇大论。三种防范:Rubric 里显式惩罚冗长、规定长度上限;配对比较前先把两个候选长度控制到相近;定期审计分数与长度的相关性,高分总伴随长回答就回炉修订 Rubric。
Rubric 四准则(Scale AI “Rubrics as Rewards”)
① 基于专家指导:医疗 Rubric 要含诊断标准与必须避免的错误。② 全面覆盖:事实、逻辑、完整、安全,还要写明陷阱项。③ 按重要性加权:必要 / 重要 / 可选 / 陷阱,支持一票否决。④ 自包含:不写“展示了深刻理解”,写“引用至少两个权威理论并准确解释如何支持结论”。
当一次评委 · 用户记忆 Rubric
问:“我女儿的儿科医生是谁?”要跨两次对话关联:第一次说“女儿叫 Lily”,第二次说“带 Lily 去看了 Dr. Chen”。历史记录里没有就诊日期和诊断结果。选一个候选回答,看 Rubric 怎么判。
边界案例:用户有多个女儿、分别看不同医生时应追问是哪个;记忆里同时有“Dr. Chen”和“陈医生”应识别为同一人。每个档位都写成可验证的行为,否决项划出底线。
表 7-3 · 三种用户记忆系统的分层成功率
实验 7-4 · 60 题 × 3 套 = 180 条真实轨迹混合方案没有自然胜出:3 道题上做到了两种单一方案都没做到的事,却在另外 8 道题上不如表现更好的单一方案。纯 RAG 基础回忆和卡片差不多,跨会话关联题却掉到 15%。
同源模型与古德哈特定律
Agent 和评判模型同一家族时,Agent 可能学会利用评委的偏好和盲点,甚至逐渐避开评委不擅长检测的错误。度量一旦变成目标,就不再是好度量。缓解:多源异构评判,比如 Agent 用 Claude,评委用 GPT-5 和 Gemini;不同家族的偏见往往正交。同一 Rubric,加权平均或一致性检查聚合。部署时可单模型快评,定期用多源评判审计。
多模态评判
TTS:准确性、自然度、音色一致度、情感表达,能抓到 WER 抓不到的韵律问题。ASR:判语义影响,“今天天气”识别错无伤大雅,“转账一千”变“一万”就严重。UI:提议者—审核者模式查文字溢出、对比度、按钮位置。视频剪辑:用关键帧验证起止点和特效。
实验 7-5 · 一次 TTS 小规模听评
每家 4 条音频 · Voxtral 按四维评分这组分数还不能说明谁更好。每家只有四条;更关键的是,固定参考音频来自 Fish S1,拿它比音色本来就偏向 Fish Audio。比通用 TTS 就不该把“像不像 Fish 参考音色”算进总分;比声音克隆则应让所有方案模仿同一个目标说话人,并用人工盲听校准。选什么参考,本身就是评估设计。
失败归因、回归任务与配对比较
端到端评估只给“成功”或“失败”,不回答“为什么、从哪一步开始”。失败归因要标出错误类别、首次出现不可接受行为的步骤、对应的工具调用或模型输出,并附上可复核的证据。
归因的对象是轨迹里第一个让任务偏离的错误。后面的错误往往只是连锁反应,不能把最后一个报错当成根因。这件事可以借助 LLM,但不能完全依赖 LLM,因为失败归因常常反映的是产品问题,不只是技术问题。
Coding Agent 的初始错误分类
9 类 · 点一类看表现与定位方式归因记录要结构化,引用步骤号、工具名和观察证据,区分根因与后果,判断能否恢复并给置信度;多个类别同时出现时,按“最早且能解释后续失败”选主因。同时保存任务目标、环境状态、Agent 版本、工具集版本和完整轨迹,以便回归测试。规则先筛、LLM 再定位(完成声明 vs 实际命令、diff 是否碰测试断言或 skip、是否改公开 API 而无迁移),比全量喂给 LLM 更便宜也更准。
“做对了但说错了” · AndroidWorld T3A 的 32 步
任务:把图库 expenses.jpg 里的开销录入记账应用。32 步里没有一步返回错误,Agent 最后自行宣告完成;验收却报告应写入的记录不存在,日志给出的那条是 Dress、¥436.35,与 Agent 写进去的四条毫无关系。
τ²-bench 基线:带信息告知要求的 704 次运行
失败 240 次,其中 162 次信息告知出错;有 80 次(占全部失败的三分之一)环境状态正确,但告诉用户的信息错了。多数评估只查环境状态,这类问题会被整体成功率掩盖。图中“告知错且状态也错”“其他原因”两段由书中数字相减得出。
作用域敏感的格式错误
用户说:“引号格式不对”先把文档解析成带作用域的片段:ZH_PROSE、EN_PROSE、QUOTED_SOURCE、INLINE_CODE、CODE_BLOCK、CODE_COMMENT、JSON_OR_SCHEMA,每段存允许的变换、必须保护的字符和修改后验证结果。规则判不出作用域时,允许保留原文并请求澄清,不能把猜测性修改算通过。
精确复制错误:old_string mismatch
点选“首个差异出现在哪一层”对同一字符串保存原始字节哈希、Unicode code point 序列、tokenizer token ID 序列。探针覆盖直接复述、长上下文抽取、放进工具参数、相似串选择,以及空格、换行、反斜杠、组合字符、低频 token。指标:byte / code-point / token exact match、首次分歧位置、真实工具成功率。
端到端回归 vs 轨迹前缀回归
端到端回归任务
从初始状态和用户请求开始跑完整任务,检查终态、必要输出和安全条件。最接近生产结果,但难判断错在哪一步。OSWorld、AndroidWorld、τ-bench 都属于这一类。
轨迹前缀回归任务
把上下文、对话、工具返回、环境状态冻结在首错之前,只要求 Agent 做下一步或下几步可观察动作。更便宜,能隔离单个策略或工具问题。答案是可接受动作集合(先读仓库规则 / 先问用户 / 拒绝危险操作),再列出禁止动作。高可靠的生产 Agent,前缀回归集往往比端到端集更重要。
| 归因出的错误类 | 生成的回归任务 |
|---|---|
| 流程缺失 | 带计划文档与测试验收条件的端到端任务 |
| 工具调用错误 | 截断出错前缀改成边界任务:修格式、转义特殊字符、换合适工具 |
| 执行异常 | 加入截断、超时、工具故障的恢复场景 |
| 完成度与逻辑错误 | 多目标清单、剩余任务提醒、“尚未证明不可能”的边界 |
| 需求理解与歧义 | 把多解任务冻结成前缀,“先澄清”列入可接受动作 |
| 症状修复与验证造假 | 验收加两条硬约束:不得修改测试断言;完成声明必须附带真实执行过的命令输出 |
| 信息反馈错误 | 对答复内容本身设断言,而不只查环境状态 |
实验 7-7 · 同一上下文的三种表示
GPT 5.6 Sol,11 个边界用例 × JSON Cards / Markdown / Python-like,共 33 个 API 单元无错误。三种表示总分碰巧都是 6/11,但失败位置不同:Markdown 过了“仓库规则未知时先检查”,却多挂了一个作用域冲突用例;另两种相反。三种都没过“论文风格过度泛化”“过时偏好覆盖当前要求”“高风险删除前确认”。换上下文的表示方式,不会自动修好应用策略。
配对比较与 Elo
选型时常问“A 和 B 哪个好”。配对比较不需要绝对标准,只判谁更好。Elo 背后是 Bradley-Terry 模型:每个模型有一个潜在实力分,胜负概率由分差决定,Elo 是它的在线更新版。
Elo 计算器
书中例:1200 对 1000 → A 预期胜率约 76%EA = 1 / (1 + 10(RB − RA)/400) RA′ = RA + K·(SA − EA)
Chatbot Arena 的局限
匿名随机对决、用户盲选,数百万票得出排名。但排名取决于用户问了什么:大量用户都问编程题,擅长编程的模型就会偏高。官方用 Bradley-Terry 极大似然一次拟合全部对局,与顺序无关;在线 Elo 受 K 和处理顺序影响,两者总体排名应吻合但分值不会精确一致。
位置偏差:交换顺序各评一次
LLM 评委会偏向某个位置(通常是先出现的)。A 在前评一次、B 在前再评一次取平均;更严格的做法是两次一致才计入,不一致记平局或送人审。Arena 随机化展示位置,让偏差在大样本下抵消。GRPO 则把配对思想带进 RL:一组候选响应 → 相对优势归一化 → 策略更新,绕过显式奖励模型。
评估驱动的模型选型
选模型不是“选最强的”,而是按场景和评估结果在多个维度之间权衡。
吞吐和延迟分两个阶段看:Prefill 一次读入整个上下文,决定首字延迟 TTFT(= 排队 + Prefill);Decode 逐 token 生成,决定出字速度,也决定思考要多久。
思考延迟计算器
书中例:50 tokens/s × 2000 思考 token = 40 sTTFT 段只示意位置,书中没有给具体值。不同模型的思考 token 量可差数倍,且思考长度与效果不一定正相关,要在自己的工作负载上实测。
p95 尾部延迟
95% 的请求都不超过的延迟。均值会被大量快速请求拉低,掩盖少数用户的严重卡顿。
成本
输入 / 输出 / 缓存 token 分别定价。便宜但成功率低的模型要频繁重试,实际花费可能更高。要算每任务平均成本和成本-性能比。
性能指标怎么挑
日常看 Pass@1;关键操作看 Pass^k;探索性任务看 Pass@k 或 Best@k。还要看 RPM / TPM 限额、高峰期动态限额,以及分布外、对抗输入、长时运行的稳定性。
预算—能力曲线 · RE-Bench 人机对照
短预算领先 ≠ 长时间更强书中只给了倍数:每个环境 2 小时总预算下,最佳 Agent 约为人类专家的 4 倍;8 小时人类略微超过;跨多次尝试合计 32 小时,人类约为 Agent 的 2 倍。图中画的是“人类得分 ÷ 最佳 Agent 得分”,8 小时那一格只表示“略高于 1”。选型必须在接近真实任务时长的多个预算点上比较。
多模型协同也要评估
轻量模型处理简单请求、强模型处理复杂任务,或用专门模型处理子任务,都要验证整体收益是否超过增加的复杂度。陷阱是把“9.9 跟 9.11 哪个大”“洗车店离家 50 米,走路还是开车去”当成简单问题交给轻量模型,结果判断出错。
模型的行为策略:行动阈值
实验 7-9 · 第一次修改代码之前做了多少事
固定 Harness · 3 个代码库 × 2 模型 × 3 次 = 18 条轨迹有的模型先广泛探索再改,有的凭较少局部证据先改再靠测试补齐。这个倾向来自系统提示词和模型的后训练(SFT 轨迹示范“读到什么程度再动手”,过程奖励与结果奖励强化某种路径)。实验只支持“行动策略随模型而变”,不支持“多读或早改必然更好”。工具步数、并行调用和模型延迟要分开看。
Agent 系统的成本
三层构成:模型推理(输入 + 输出 token,外加上下文累积和思考 token 两个放大器)、工具调用(外部 API、沙盒资源,以及工具返回注入上下文后被反复计费的 token;一次网页搜索就可能占 2000–5000 token)、基础设施(向量库、队列、数据库、日志与追踪存储)。
上下文累积:没用好 KV Cache 时成本按平方涨
书中例:每轮 +1000 token,3 轮共 6000 而非 3000表 7-4 · 八轮退款任务的真实成本(gpt-4o-mini)
两个开关 · 四组对照任务:查订单、物流、退款政策和知识库,然后风控、退款、通知、关单。基线每轮输入从 1,113 涨到 3,668 token;工具返回跟着历史反复进入后续请求,八轮累计 9,544 个输入 token,两项优化都开后降到 5,248。单开节省 28.3% 和 17.5%,合开只有 30.0%,不是相加:压缩历史同时缩短了能命中缓存的前缀。几项优化要能独立开关,并在完整任务里一起实测。
输入侧三板斧
保持前缀不变以复用 KV Cache;压缩旧轨迹和冗长工具返回;分层选模型。具体做法见第二章。
异步批处理
非实时任务攒起来批量处理,吃 API 波谷批量折扣;本地部署时也能提高波谷 GPU 利用率。
成本监控与上限
按任务类型、模型、用户追踪 token 与 API 费用;给每个任务设成本上限,Agent 陷入循环或探索过深时自动终止。
一次模型切换决策
当前用 Claude · 新发布的 Gemini 公开基准更强、更便宜→
→
问题从来不是“Gemini 是否比 Claude 强”,而是“在我的任务上好不好、好多少、切换成本是什么”。“超出噪声”怎么判断,见下一节。
评估结果的统计显著性
评估集有限,模型输出又有随机性,分数差可能只是抽样噪声。在 n 个用例上测得成功率 p,标准误约为 SE ≈ √(p(1−p)/n),95% 置信区间约 ±1.96·SE。
100 个用例、成功率 70%,95% 区间约 ±9 个百分点。“新模型 73% 对旧模型 70%”不足以支持切换。
置信区间与样本量
书中例:n = 100,70% vs 73%标准误按 1/√n 缩小:想看清 2–3 个点的收益,几十题远远不够,先扩大样本。所需用例数按 n ≈ 1.96²·p(1−p)/δ² 估算(让单个配置的区间半宽不超过要检测的差 δ),这是粗略的下限。
配对分析:只有“一胜一负”的题有信息量
示例分布 · 非书中数据默认值是凑出“A 73% / B 70%、共 100 题”的一组假设分布,用来演示 McNemar 检验:χ² = (|b − c| − 1)² / (b + c),大于 3.84 才在 0.05 水平上显著。
配对评估的写法
for task in paired_tasks: for seed in fixed_seeds: a = run(config_a, task, seed) b = run(config_b, task, seed) record_paired_delta(verifier(a), verifier(b)) return paired_bootstrap_or_mcnemar(all_deltas)
配对是让两组共享任务和随机条件,而不是各抽一批样本比平均值。每个配置最好用 3–5 个随机种子,报告均值和波动;单次运行只能用来筛方向。并行验证多个假设时要考虑多重比较:收紧阈值,或对正向结果独立复跑。
分差超过噪声、在配对分析中成立、能复现,三条都满足才值得切换模型或发布改动。
Agent 的可观测性
可观测性借自分布式系统:没法打开系统看内部,只能通过日志、指标和追踪推断,就像医生靠体温、血压、影像诊断。Agent 更难:同样输入可能不同输出,多轮推理和工具调用让路径极复杂,模型的“思考”对外不透明。
追踪直接沿用 span 树:一次任务是一条 trace,每次 LLM 调用、工具调用、检索都是一个 span,记录输入输出、起止时间、token 和错误。OpenTelemetry 是通用标准,OpenInference 等在其上定义 LLM 语义约定,采集与分析解耦,不被单一平台锁定。
图 7-7 · 一条 trace:帮用户查北京明天天气(3.2 s,$0.008)
各 span 的耗时取自图中标注,按先后顺序排开;Response Parse 未标耗时,这里画成工具 span 内剩下的那段。
成本追踪(图中示例)
今日 $12.30(1,200 次);本月 $340(34K 次)。
异常:task#892 循环调用 search 14 次,耗 $2.1
性能监控(图中示例)
P50 / P95 / P99 延迟:2.1 s / 8.4 s / 15.2 s;工具成功率 94.3%。
质量审计(图中示例)
任务成功率 87%;幻觉触发 2.1%;安全违规 0(本月);用户满意度 4.3/5。
LangSmith(同类还有 Langfuse、Arize Phoenix)把可观测性、评估、优化做成闭环:异步批量采集保证追踪不拖慢 Agent;支持 A/B 测试(分流、自动对比、快速回滚或渐进扩量)、提示词版本管理(每个版本关联运行时表现)和团队共享问题案例。
评估集不再是一次性构造的静态集合,而是随产品演化、持续贴近真实用户分布的活资产:今天线上暴露的失败,明天就是守住底线的回归用例。
从 Benchmark 报告到系统改进
先立一条原则:Agent 表现下降时,先查评测系统,再动 Agent。环境资源不足导致进程被杀(随机失败)、验证器 bug 把正确答案判错、用例与生产脱节,这些在数字上和模型退化一模一样,只有看完整轨迹才能区分。
AndroidWorld Wi-Fi 子集 · 一次只改一个变量
API 35 模拟器 · 4 项任务 · 每项一次配对对照三轮始终用相同的模型、任务参数、随机种子、步数上限和模拟器,并交替两组运行顺序。每组只有 4 项任务,数字只用来决定下一步值不值得扩大测试。token 列是每一轮“实验组 ÷ 本轮对照组”。
两条结论
① 提示写得再细,也补不回 Agent 根本没看到的信息:这类失败先查输入,别继续堆提示词。② 输入也不是越多越好:完整元素树解决了“看不见”,却带来大量无用 token,删掉无语义节点后仍 4/4,token 又少了约一半。全程没换模型,只改了 Harness 怎么表示界面。
H5C 只拿到了“进入完整复测”的资格
下一步:补齐第三方应用,在 Pixel 6 / API 33 标准环境里,116 项任务各跑 5 个随机种子;成功率不能降,token 不超过原方案 75%,延迟不超过 1.5 倍。在这之前,不能把子集上的 4/4 写成系统整体 100%。一轮证据只支持与它规模相称的下一步。
图 7-8 给出的方法论闭环:观察 → 假设(表层 / 中层 / 深层三层框架)→ 分阶段实验 → 成本收益决策 → 迭代。从 Harness 工程看,这就是用评估数据定位 Harness 的薄弱环节(上下文不足?约束缺失?验证不够?反馈不及时?),改完再评。
从外部评估到内部评估
最好的 Agent 产品不只接受外部评估,还内建了持续自评的基础设施。以开源通用 Agent OpenClaw 为例,结合头部 Coding Agent 的公开分析,把 ML 研究的实验方法嵌进产品工程。
外部评估告诉你“Agent 有多好”,内部评估基础设施告诉你“哪项改动让它变好了”。
消融总开关:造一个“裸模型”基线
示意 · 无分数AB 测试:多臂而非二元
不只比“有 / 没有”,而是设控制组加三个渐进更严格的实验组,看出剂量—效应关系,找最优点。
区分机制指标与目标指标
测“缩短计划文件”时,计划长度是机制(你直接改的东西),会话级成本才是目标。计划太短可能导致更多编辑—检查—编辑循环,总输出反而变多。两者不一致时以目标为准。再加护栏指标(满意度、操作次数、错误率不能变差)和基线统计(样本量、分位数、相关性,如“拒绝率随计划大小单调递增”)。
双层特性开关
编译时:构建阶段物理移除代码,内部特性在外部构建里根本不存在,逆向也找不到,是一种干净的消融。运行时:服务端下发、本地磁盘缓存,宁可读稍旧的配置也不阻塞启动;分组交给 GrowthBook 这类平台;每个特性的曝光事件每会话最多记一次。
提示词敏感性评估
专用工具在指定 git 版本上渲染出完整系统提示(所有动态条件展开后)。三条实践:提示能确定性渲染;版本化快照;每次提示变更都在评估集上跑回归,像代码变更跑 CI。
隐私感知分析
分析接口只接受特殊类型包装的值,类型名本身就是审计线索(“我已验证这不是代码或文件路径”),把隐私约束从文档规范变成编译时类型检查。从一开始就设计进去,不事后加装。
消融开关必须在启动路径极早期注入(在任何模块级常量捕获配置之前),所以要从一开始就设计进架构。定期消融(如每次大版本前)能发现“特性债务”:曾经有效、但模型进化后已不再必要的特性。
仿真环境:从评估到后训练的桥梁
评估的终点是改进。改进有三条路:调 Harness、把评估嵌入产品工程,以及最深入的训练。目标从“评估现有能力”扩展到“培养新能力”时,评估环境就要演化为仿真环境:一个能反复练习、自动打分的虚拟操场。
定义清晰的 Rubric 或验证器,本质上就是 RLVR 的奖励函数:验证脚本直接就是奖励脚本。但训练多出两个要求:可靠的 reset(每个 episode 都要回到确定、干净的初始状态,否则梯度被上一轮残留污染)和远高于评估的吞吐。
| 评估环境 | 仿真环境(训练) | |
|---|---|---|
| 交互频率 | 数千次就够出结论 | 数百万次 |
| 随机化 | 可选 | 必需,防止死记特定配置 |
| 反馈 | 事后汇总 | 必须即时 |
图 7-9 · 仿真保真度谱
示意位置 · 无数值坐标AWorld · 分布式 MCP 沙盒
GAIA · 26 个 MCP 服务器 · 126 个工具函数可控沙盒避免直接访问真实 API 带来的封禁和不可控副作用,所有调用可重放、可审计。环境无状态,每个实例完全独立。
RoboTwin2 · 动作分块
一次推理生成 25 个连续动作,25 次推理 = 625 个控制步。
图 7-10 重画:OpenVLA 与 RoboTwin2 的闭环。指令“将罐子放入锅中”(move_can_pot);成功 = 罐子在锅内且未掉落。
保真度权衡与领域随机化
高保真更易迁移到真实世界,但计算贵。随机化程度是另一维:适度能提升泛化,过度会让任务太难。领域随机化在物理参数、视觉外观、传感器噪声上大范围变化,好比在各种光照和角度下都练过抓取。数字环境里 sim-to-real 差距体现在界面渲染、响应时间等,可通过随机注入延迟和失败来缓解。OSWorld 用虚拟机快照实现可重置。隔离与虚拟身份(VM / 容器、住宅代理、HITL 认证、共享文件系统)见第四章。
判断 Agent 变好还是变差
一、四个环节
成功的定义(Pass@k / Best@k / Pass^k)→ 任务来源(公开基准、自建业务集、生产回流)→ 验证方式(确定性 → 清单 → Rubric + LLM → 配对)→ 结果运用(显著性、失败归因、回归任务、模型选型)。每一环都影响结论可信度。
二、拿到信息 ≠ 用对信息
端到端回归保证基本任务不退化;轨迹前缀边界集直接检查作用域判断、当前指令覆盖、澄清和危险动作前确认。生产评估是从真实问题案例中持续生成回归任务的验证系统。
三、闭环
评估环境 → 数据集(端到端 + 前缀边界)→ 自动化评估打分并归因 → 报告揭示方向 → 系统改进 → 更新环境和数据集。第八章把它变成后训练的输入,第九章把多维评价变成知识、指令、程序的更新。
观察 → 假设 → 实验 → 验证 → 新认识 → 新假设:让 Agent 工程从经验驱动的“炼金术”转向数据驱动的科学工程。
常见误区
思考题
1 ★★ LLM-as-a-Judge 是否存在系统性盲区(如一致偏爱某种风格,而与人类不一致)?如何检测和校正?
线索:长度偏差的三种防范(显式惩罚、长度对齐、审计分数与长度相关性);位置偏差的交换顺序评测;多源异构评判;人工盲听 / 盲评校准。
2 ★★★ 基准一公开就会进训练数据,这场猫鼠游戏有终局吗?设计一种从根本上抵抗泄漏的评估方法。
线索:本章三种手法各管一段:GAIA 让答案无法直接检索(多源组合 + 专有附件),AndroidWorld 每次随机实例化参数,Terminal-Bench 的金丝雀只能检测不能阻止。再加上生产轨迹回流的私有用例。
3 ★★ “是否有帮助”“语气是否恰当”天然主观,如何为这些维度设计可靠的 Rubric?
线索:四准则中的“自包含”——把抽象标准改写成可验证的行为;为每档配具体示例与边界案例;收集评价者分歧迭代成判例集;连维度都写不出时退到配对比较。
4 ★★ 模拟用户本身也是 LLM,可能低估情绪激动、表达不清等边缘场景。如何验证模拟用户的质量?
线索:τ²-bench 用字段建模认知边界、情绪、耐心上限和事实锚定;没有锚定时评估会退化为两个模型互相确认。可以拿真实用户对话的分布去对照模拟器的行为。
5 ★★ Bradley-Terry 假设偏好可传递,但人类偏好常违反传递性。Agent 评估中哪些场景会出现?如何影响排名?
线索:Arena 排名取决于用户提问分布;不同任务类型(编程 vs 写作)上的强弱可能互相交错,单一实力分会把它压平。
6 ★★ 单次成功率只有 60% 的 Agent,如何结合失败成本、重试成本和副作用,决定报告哪个指标、k 取多大?
线索:p = 0.6、k = 5 时 Pass@5 = 99.0%、Pass^5 = 7.8%。有副作用就不能“重试到成功”,要在沙盒里采样并把每次失败计入可靠性。上面的计算器可直接试。
7 ★★ 验证一个假设可能需要数百次运行,如何在有限预算下最大化评估的信息量?
线索:AndroidWorld 的做法——先把范围缩到失败簇(4 项 Wi-Fi 任务),一次只改一个变量,小样本只用来决定是否扩大测试;配对设计只消耗“一胜一负”的信息;轨迹前缀回归比端到端便宜。
8 ★ 完整元素树 25% → 100% 但 token 2.498×,精简后 0.506×。怎样设计自动裁剪规则,既删掉无语义节点,又不误删对可访问性、状态验证或后续操作有用的信息?
线索:H5C 删的是“不可见、没有文字、也不能操作”的容器节点;裁剪规则本身也要用成功率不降、token 与延迟上限的完整复测来验收。
9 ★★ 渐进式信息透露如何影响评估结果?如果模拟用户的透露策略与真实用户差异较大,结论还可靠吗?
线索:真实用户的初始表述往往只是“我上不了网”,把需求澄清到可执行本身是 Agent 的能力;透露策略写在 known_info / task_instructions 两个字段里,可以对照真实对话去调整。
本章实验一览
实验 7-1 ★ ~ 7-4 ★★:τ²-bench、人肉跑基准、Rubric 记忆评估、JSON Cards vs RAG
7-1 跑 τ²-bench 并对比 τ-bench 的演进,分析政策违规、信息遗漏、过度转人工等失败模式。7-2 从 GAIA、AndroidWorld、SWE-bench Verified、Terminal-Bench、OSWorld-Verified 各挑简单 / 中等 / 困难题亲手做,回答“题面有几种合理解释、验证器认哪种”“最便宜的蒙混路径是什么、能否被拦截”。7-3 把第三章记忆评估升级为五维 Rubric(Precision、Recall、思考正确性、思考主动性、幻觉否决)。7-4 在 60 题上比较三种记忆方案。
实验 7-5 ~ 7-8 ★★:TTS 流水线、AndroidWorld 归因、前缀边界、Elo 排行榜
7-5 设计 TTS 四维 Rubric 和多样语料,记录评委、参考音频哈希与候选音频哈希以便复核。7-6 从 t3a_failed.md 抽 ≥10 条静默失败,用事实锚点比对与前缀二分定位首错,写结构化记录,与 t3a_failed_analysis.md 对照,再挑 3 条做成前缀回归任务。7-7 三种表示的前缀边界评估。7-8 用 Arena 投票数据实现 Elo(初始 1000 分,按时间处理),再做 D3 条形图竞赛动画。
实验 7-9 ~ 7-12 ★/★★:行动阈值、成本分析、多维基准、记忆选型
7-9 固定 Harness 测模型的行动阈值,如需测 Harness 效应另跑 --policy explore-first,不要混在一起。7-10 复现八轮成本任务并换成自己的负载,四种开关组合都要跑,报告 p50/p95/p99。7-11 对多家模型与 API 提供商测 8K/32K/128K 输入、512/2048 输出、TTFT、每配置 ≥100 次请求,一周每小时探测可用性,算 MTTR 与限流点。7-12 遍历嵌入模型、reranker(含不用的基线)、主模型三个选择点。
实验 7-13 ★★★ ~ 7-14 ★★:AndroidWorld 改进、OpenVLA + RoboTwin2
7-13 诊断 → 三层假设 → 复现 H1/H5/H5C(记录 token、延迟、回退)→ 成本收益决策 → 116×5 完整复测后才讨论部署。7-14 配置 RoboTwin2,理解三视角 RGB + 14 维关节状态与 14 维控制向量,研究 move_can_pot 的随机化与空间约束,关注动作分块的影响。