深入理解 AI Agent · 第 7 章图解

Agent 的评估

做出一个 Agent 不等于做对了。只有能稳定地测量结果,换模型、改 Harness、做训练才有方向。被评估的不只是模型,而是“模型 + Harness”这个组合:同一个模型换个 Harness,分数可能差很多。所以评估体系必须能分清,问题出在模型能力不足,还是 Harness 设计有缺陷。本章把“Agent 变好了还是变差了”拆成四个环节。

① 成功的定义什么算成功

Pass@k 衡量能力上限,Pass^k 衡量业务可靠性。

Pass@kPass^kBest@k
② 任务来源任务从哪来

公开基准借鉴手法、粗筛选型;自建业务集覆盖真实分布;生产轨迹回流来自失败归因。

公开基准自建业务集生产回流
③ 验证方式由谁验证

按任务能被机械验证的程度,从左到右排开。

确定性验证器检查项清单Rubric + LLM配对比较
④ 结果的运用分数怎么变成决策

统计显著性 → 失败归因 → 回归任务 → 模型选型与 Harness 迭代。

显著性首错定位回归集
↺ 回归任务沉淀为新用例,回到 ② · 支撑设施:可观测性(提供轨迹)· 内部评估基础设施(消融 / AB / 特性开关)· 仿真环境(通向第八章)
单次成功率 0.6 时 Pass@599.0%
同一 Agent 的 Pass^57.8%
100 题、70% 的 95% 置信区间±9 pp
τ²-bench 中“做对了但说错了”占失败的 1/3
Agent 行为 用户 / 用户模拟器 通过 / 可核实的事实 模型评判 / 成本 中性 / 未计入 失败 / 首个错误 / 否决
开篇

评估是 Harness 里的“验证”环节

用哪个模型、给哪些工具、知识库存什么、记忆怎么做、提示词和 Skills 怎么组织、Harness 加哪些约束,这些设计选择都没有一眼就能看出的正确答案。评估用两种实验来做决定:对比实验一次只改一个变量,看效果怎么变;消融实验一次关掉一个组件,看它到底贡献了多少。

公开基准上更强的新模型,在你的任务上未必更好,甚至可能退化。只有在自己的评估集上跑一遍,才能做出数据驱动的升级决策。评估集建好以后,还可以“为未来的模型开发产品”:先把产品和评估集做出来,持续跟踪新模型,一旦达到门槛就上线。

模型替换实验:瓶颈在模型还是在 Harness

固定 Harness · 只换模型

消融实验

固定模型,关掉 Harness 的某个组件看整体掉多少。用来找 Harness 内部哪个部件重要。

模型替换(model swap)

固定 Harness,只换更强或更弱的模型。用来判断瓶颈在模型还是在 Harness。

7.1

一条评估任务的解剖:τ²-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 的疏漏,是二元奖励的固有代价:用过程粒度换来一个跨模型可比的数字。生产评估还需要指出问题出在哪里。

7.2

评估指标:成功的定义

上一节五条任务通过了四条,0.8 是好是坏?如果是退款客服,五个用户里就有一个拿不到应得的退款;如果是挖漏洞的安全 Agent,五次命中四次已经很可观。差别在于业务对成功率要求多高。

Pass@k 与 Pass^k 计算器

假设每次运行独立 · 书中例:p = 0.6, k = 5

Pass@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 次,每次都要通过,并且不能触发安全、合规、幻觉等一票否决项。它回答的是“能不能稳定交付”,而不是“能不能偶尔创造奇迹”。支付、退款、权限变更、生产部署要看的是这个数。

7.3

评估环境:一套能重复运行的装置

评估环境要满足一点:给定同一个初始状态,同一个 Agent 应当得到可以比较的结果。拿刚才那条 telecom 任务对照,五个组成要素都已经齐了。

五个要素缺一个,评估就构不成可重复的循环。后面看其他基准时,也用这五项来对照。

人机交互型与工具调用型

代码生成、数据分析、数学求解这类任务没有对话对象,Agent 只和工具打交道,能不能通过执行验证决定对错,既不需要人工标注,也不需要模型评判。这类环境省掉了用户模拟器,其余四个要素还在,只是更简单:状态是文件系统或数据库,评分标准是一段测试代码,协议是“一直调用工具,直到给出答案或用完轮数”。

图 7-2 重画。工具调用型验证行动(可观测的状态变更是否正确),人机交互型验证引导(沟通策略是否合理)。

表 7-1 · 该选 Verifiers 的哪种环境

按状态、工具、隔离三个问题选
环境类型状态保持工具调用典型用例
SingleTurnEnv无无单轮问答、数学题:问完直接验答案
ToolEnv无多轮搜索多个网页后综合回答,验最终结果
StatefulToolEnv有多轮修改数据库记录,验状态变化
SandboxEnv有 + 隔离多轮沙盒里跑代码,检查输出文件

框架支持并行采样和轨迹缓存,每次评估的完整轨迹(观察、行动、奖励)都会保存,方便分析和回放。工具失败时应返回清楚的错误信息,而不是一个失败标志,Agent 才能据此调整。

7.4

评估数据集的设计

环境是舞台,数据集是剧本。同样五个要素,换一类任务填法就完全不同:任务从哪来,验证器能核实到多深,怎么防止被模型记住。

基准被测能力任务来源环境扮演者验证器
τ²-bench客服场景的人机交互与工具调用人工编写 + 组合生成用户模拟器 + 业务数据库四层检查按 reward_basis 聚合为二元
SWE-bench Verified软件开发,codingGitHub 真实 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 当需要仿真用户的骨架,换掉领域数据和工具集。

生产轨迹回流

用户纠正、点踩、事后审计发现的问题,经失败归因后沉淀为回归用例。成本最高,也最准。

起步时只有公开基准和少量手写用例;上线一段时间后,生产回流的用例会成为主体。验证深度、参数化生成、防泄漏、质量维护,正是自建评估集最容易漏掉的几处。

7.5

自动化评估方法

前面的基准几乎全用确定性验证器:跑测试、断言 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 条真实轨迹
Advanced JSON Cards 总体68.3%41/60
混合系统66.7%40/60
RAG48.3%29/60
幻觉否决触发28 / 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 参考音色”算进总分;比声音克隆则应让所有方案模仿同一个目标说话人,并用人工盲听校准。选什么参考,本身就是评估设计。

7.5.2 – 7.5.4

失败归因、回归任务与配对比较

端到端评估只给“成功”或“失败”,不回答“为什么、从哪一步开始”。失败归因要标出错误类别、首次出现不可接受行为的步骤、对应的工具调用或模型输出,并附上可复核的证据。

归因的对象是轨迹里第一个让任务偏离的错误。后面的错误往往只是连锁反应,不能把最后一个报错当成根因。这件事可以借助 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:一组候选响应 → 相对优势归一化 → 策略更新,绕过显式奖励模型。

7.6

评估驱动的模型选型

选模型不是“选最强的”,而是按场景和评估结果在多个维度之间权衡。

吞吐和延迟分两个阶段看:Prefill 一次读入整个上下文,决定首字延迟 TTFT(= 排队 + Prefill);Decode 逐 token 生成,决定出字速度,也决定思考要多久。

思考延迟计算器

书中例:50 tokens/s × 2000 思考 token = 40 s

TTFT 段只示意位置,书中没有给具体值。不同模型的思考 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 条轨迹
首个补丁与最终测试都是 100%
跨模块任务读文件数7.00 vs 6.67
到首次修改的时间15.01 s vs 14.48 s

有的模型先广泛探索再改,有的凭较少局部证据先改再靠测试补齐。这个倾向来自系统提示词和模型的后训练(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 公开基准更强、更便宜
在自己的评估集上跑成功率、工具调用正确率、延迟、成本
数小时内
→
发现分化简单任务更好更便宜;复杂多轮工具编排成功率 −5%
确认超出噪声
→
差异化策略简单任务迁到新模型,复杂任务保留原模型

问题从来不是“Gemini 是否比 Claude 强”,而是“在我的任务上好不好、好多少、切换成本是什么”。“超出噪声”怎么判断,见下一节。

7.7

评估结果的统计显著性

评估集有限,模型输出又有随机性,分数差可能只是抽样噪声。在 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 个随机种子,报告均值和波动;单次运行只能用来筛方向。并行验证多个假设时要考虑多重比较:收紧阈值,或对正向结果独立复跑。

分差超过噪声、在配对分析中成立、能复现,三条都满足才值得切换模型或发布改动。

7.8

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 测试(分流、自动对比、快速回滚或渐进扩量)、提示词版本管理(每个版本关联运行时表现)和团队共享问题案例。

生产轨迹筛出失败与可疑案例
→
脱敏去掉用户隐私、密钥等字段
→
评估资产新用例 + 回归测试

评估集不再是一次性构造的静态集合,而是随产品演化、持续贴近真实用户分布的活资产:今天线上暴露的失败,明天就是守住底线的回归用例。

7.9

从 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 的薄弱环节(上下文不足?约束缺失?验证不够?反馈不及时?),改完再评。

7.10

从外部评估到内部评估

最好的 Agent 产品不只接受外部评估,还内建了持续自评的基础设施。以开源通用 Agent OpenClaw 为例,结合头部 Coding Agent 的公开分析,把 ML 研究的实验方法嵌进产品工程。

外部评估告诉你“Agent 有多好”,内部评估基础设施告诉你“哪项改动让它变好了”。

消融总开关:造一个“裸模型”基线

示意 · 无分数

AB 测试:多臂而非二元

不只比“有 / 没有”,而是设控制组加三个渐进更严格的实验组,看出剂量—效应关系,找最优点。

区分机制指标与目标指标

测“缩短计划文件”时,计划长度是机制(你直接改的东西),会话级成本才是目标。计划太短可能导致更多编辑—检查—编辑循环,总输出反而变多。两者不一致时以目标为准。再加护栏指标(满意度、操作次数、错误率不能变差)和基线统计(样本量、分位数、相关性,如“拒绝率随计划大小单调递增”)。

双层特性开关

编译时:构建阶段物理移除代码,内部特性在外部构建里根本不存在,逆向也找不到,是一种干净的消融。运行时:服务端下发、本地磁盘缓存,宁可读稍旧的配置也不阻塞启动;分组交给 GrowthBook 这类平台;每个特性的曝光事件每会话最多记一次。

提示词敏感性评估

专用工具在指定 git 版本上渲染出完整系统提示(所有动态条件展开后)。三条实践:提示能确定性渲染;版本化快照;每次提示变更都在评估集上跑回归,像代码变更跑 CI。

隐私感知分析

分析接口只接受特殊类型包装的值,类型名本身就是审计线索(“我已验证这不是代码或文件路径”),把隐私约束从文档规范变成编译时类型检查。从一开始就设计进去,不事后加装。

消融开关必须在启动路径极早期注入(在任何模块级常量捕获配置之前),所以要从一开始就设计进架构。定期消融(如每次大版本前)能发现“特性债务”:曾经有效、但模型进化后已不再必要的特性。

7.11

仿真环境:从评估到后训练的桥梁

评估的终点是改进。改进有三条路:调 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 工程从经验驱动的“炼金术”转向数据驱动的科学工程。

常见误区

✗ 分数掉了,赶紧改 Agent✓ 先查评测系统:被杀的进程、有 bug 的验证器、脱节的用例都长得像模型退化。
✗ Pass@5 = 99%,可以上线退款✓ 同样 p = 0.6,Pass^5 只有 7.8%。有副作用的场景看 Pass^k。
✗ 73% 比 70% 高,换新模型✓ 100 题的区间约 ±9 pp。做配对分析、多种子、能复现再说。
✗ 环境状态对了就是做对了✓ τ²-bench 失败里有 1/3 是状态正确、告知错误,答复内容也要断言。
✗ 最后一个报错就是根因✓ 找第一个让任务偏离的步骤;它可能既不报错,也不是工具调用。
✗ 加提示词就能修好✓ H1 补提示 25% → 25%。Agent 没看到的信息,提示补不回来,先查输入通道。
✗ 两项优化各省 28% 和 18%,一起省 46%✓ 实测合开只省 30%,必须一起实测。
✗ 用同家族模型当评委最省事✓ 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 的随机化与空间约束,关注动作分块的影响。