第 1 章:为什么需要 Agent 评测工程
凌晨两点,一个故障诊断 Agent 在工单里写道:“已修复服务配置,健康检查恢复正常。”它的措辞专业,原因分析也像模像样。如果评测只比较这段最终答案,系统似乎已经成功。然而,容器里的配置文件根本没有改变;Agent 只运行了一个永远返回 0 的自制“健康检查”,还把日志中的访问令牌复制进了对话。这里同时发生了结果错误、工具误用和凭据泄露,而最终答案遮住了三者。
本章贯穿的问题是:怎样证明 Agent 完成了任务,而不是只证明它写出了一段像答案的话? 这要求我们把评测对象从一次文本生成扩展到一个受控系统中的完整尝试。Terminal-Bench 的任务实践已经体现了这种变化:每个任务有独立环境、人工编写的解法和用于验证结果的测试。1 评测基础设施则负责启动环境、记录动作并检查容器状态。2
读完本章,你应当能够:
- 区分模型输出评测与 Agent 系统评测;
- 用环境、工具、状态、trajectory 和评分结果(Reward)描述一次 Agent 尝试;
- 解释 Benchmark、eval、rollout 与 post-training 的关系;
- 为“系统配置与故障诊断 Agent Benchmark”写出可核验的范围与验收契约;
- 识别只看最终答案、只跑一次或只报成功率造成的误判。
本书所有 Harbor 行为均锁定到 v0.18.0,提交 527d50deb63a5d279e8c20593c18a2cbc7f61f9e。该版本把自身定位为在沙箱环境中评测和优化 Agent 与模型的框架。3
1.1 先确定评测对象
传统的模型评测常把一次样本抽象为:给定输入,在固定推理配置下获得输出,再用正确率、匹配规则或裁判比较输出。实际模型评测当然也可能是多轮、多模态和多指标的;HELM 就强调应在标准化场景中同时考察准确性、稳健性、公平性、毒性与效率等维度。4 因此,“模型评测只看准确率”并不成立。
真正的分界线是系统边界。当我们问“这个基础模型能否回答问题”时,评测对象主要是模型及其推理配置。当我们问“这个 Agent 能否修好服务”时,对象至少包含模型、system prompt、上下文管理、Agent 循环、工具协议、权限、记忆、终止策略和运行环境。模型相同,只要工具包装或循环策略不同,行为就可能不同;反过来,同一个 Agent harness 换模型也可能得到不同结果。因此,Agent 排名应明确写成“完整运行配置 × 任务(Task)/数据集(Dataset)版本”的结果。完整运行配置包括 Agent 与模型配置、Environment/Provider、工具与权限、网络与超时、独立验证器(Verifier),以及重复和聚合策略。在 Harbor v0.18.0 中,TrialConfig 也把 task、agent、environment 与 verifier 建模为独立字段。5 不能把整套系统的成绩直接归因于模型。
可以把两类评测的常见边界列成下表。它不是非此即彼的分类,而是帮助我们发现遗漏的工程变量。
| 维度 | 以模型输出为中心 | 以 Agent 完成为中心 |
|---|---|---|
| 基本观测单元 | prompt 与 completion | 一次尝试(Trial)/rollout |
| 输入 | 文本、图像或结构化上下文 | instruction 加初始环境状态 |
| 输出 | completion 或预测 | 环境终态、产物、最终回复与轨迹 |
| 可变组件 | 模型、采样、prompt | 还包括 Agent 循环、工具、权限、超时与环境 |
| 主要失败 | 错答、拒答、格式错误 | 还包括工具失败、状态破坏、超时、投机取巧和基础设施错误 |
| 复核证据 | 输入、输出、推理配置 | 还需完整运行配置、日志、Verifier、采集产物(Artifact)和 trajectory |
注意:Agent 评测并不要求给每一步规定“标准路径”。若 Verifier 只接受作者预想的命令序列,就会把合法替代方案判错。通常先验证可观察的终态,再用 trajectory 解释失败、审计安全与核算成本。
1.2 最终答案为什么不够
Agent 的任务发生在一个随时间改变的世界里。设初始状态为 (s_0),Agent 在第 (t) 步根据观察 (o_t) 选择动作 (a_t),工具和环境再把状态推进到 (s_{t+1})。一次完整尝试可以简写为:
s0 → observation1 → action1 → state1 → … → actionT → stateT
↓
Verifier → Reward
其中有四类信息不能被最终回复替代。
**环境(Environment)**定义 Agent 实际面对什么:操作系统、文件、服务、依赖、用户身份、网络、资源与初始故障。若两次运行的包版本或数据库初态不同,就不是同一个实验。Terminal-Bench 2.0 把“独特环境、人工解法、综合测试”作为任务组成部分,说明现实任务的难度不能从题面文本单独还原。1
**工具(Tool)**把意图变成动作。相同模型分别得到只读日志工具、Shell,或具有生产写权限的 API,测到的是不同能力与风险。工具的 schema、返回值、超时、重试与错误信息都是实验条件;把一次 command not found 记成“模型不会诊断”会混淆 Agent 失败和环境失败。
**状态(State)**是动作留下的可观察后果。配置文件内容、进程状态、HTTP 响应和数据库记录都可能是答案。Agent 说“已修改”只是声明;独立检查环境终态才是证据。状态验证也必须防止捷径,例如 Agent 通过关闭测试、替换健康检查或写死输出获得表面成功。
**轨迹(trajectory)**是按时间排列的交互记录,包括消息、工具调用、环境观察以及可选的用量数据。在 Harbor v0.18.0 的轨迹模型中,一步可以记录 tool_calls、observation 与 metrics;完整轨迹由有序步骤组成。6 它能回答“为何失败”“是否越权”“成本花在哪里”,但它不是事实本身:日志可能缺失,Agent 的自述推理也可能不可靠,仍要与环境证据和 Verifier 结果交叉核对。
最终答案因此只是多路证据中的一路。对于“修复服务”这类任务,合格证据至少应形成闭环:任务版本确定初态,trajectory 说明做过什么,终态检查证明产生了什么结果,Verifier 把结果映射为 Reward,日志与异常把未完成和基础设施失败分开。
这里还要避免另一个极端:既然过程重要,是否应该逐步给 Agent 的“思考方法”打分?通常不应如此。两个 Agent 可能通过不同的诊断顺序得到同样正确、持久且安全的终态;把作者偏好的路径写进 Verifier,会把工具选择差异误判为能力差异。更稳妥的做法是分两层判定。第一层是结果门槛,例如服务在重启后仍通过独立测试;第二层是护栏,例如没有读取禁止路径、泄露凭据或破坏测试。trajectory 为护栏与故障分析提供证据,而不是要求 Agent 模仿标准解法。只有当步骤本身就是能力目标——例如必须遵循变更审批流程——过程约束才应进入得分,并且要在 instruction 中对 Agent 可见。
1.3 从一次生成到一次 rollout
几个常用词经常被混用,先把它们放在同一条链上:
- Benchmark 是可版本化的测量契约,至少包括任务集合、运行协议、评分规则和报告口径。题目文件的集合还不够;若超时、工具权限和失败计入规则不一致,成绩不可比较。
- eval 是按该契约执行的一次评测实验,也可泛指评测流程。它应留下配置、逐次结果和聚合结果,而不仅是一行平均分。
- rollout 是 Agent 从初始状态开始,依据当前策略采样出的一次交互序列。Harbor 的核心概念文档把 Trial 定义为 Agent 对 Task 的一次尝试,并直接概括为“产生 Reward 的 rollout”;评测作业(Job)则是 Trial 的集合。7
- post-training 是预训练之后的优化阶段。Harbor v0.18.0 提供把 Trial 转换为可供 SFT 流水线使用的对话轨迹的工具。8 RL 通常消费 rollout 中的 token、动作与 Reward;该版本文档给出了对接外部 RL 框架 rollout 接口的方式。9 由 v0.18.0 提供的是轨迹导出工具和 rollout 接口而非完整训练器这一边界,可以推断本书所述训练算法与优化器位于外部训练流水线。
这条链存在一个危险的反馈回路:Benchmark 产生 eval,eval 的 rollout 又被用于 post-training;如果训练反复看到同一批测试任务,之后的高分可能反映记忆、泄露或对 Verifier 的适配,而不是能力泛化。因此,凡进入 SFT、RL 或 prompt 优化的任务实例,都不得再作为最终持出测试。开发集与回归集可以按预先登记的实验协议复用,但必须记录每个实例的角色、版本和接触历史;最终持出测试则必须与任何优化数据隔离。Harbor 能执行和记录这些实验,却不能替你决定数据治理规则。
1.4 评测工程的三条硬约束
一套评测要先回答三个测量问题。效度关心 Reward 是否真的代表目标能力:仅检查端口开放,测到的可能是启动临时进程的能力,而非修复配置。可靠性关心相同契约下的结果是否足够稳定:若初态漂移或一次成功、一次失败,就不能把单次成绩当成能力常数。可诊断性关心失败后能否定位责任:没有阶段日志与异常分类时,模型错误、工具安装失败和 Verifier 崩溃都会落成同一个 0 分。环境、轨迹和结果记录分别支撑这三件事,但没有任何单一 Artifact 可以自动保证它们。
可复现性:复现的是分布,不是某条轨迹
含采样、网络和并发的 Agent 很难逐动作重放。工程上的复现目标应分两层:一是配置可追溯,记录 Task、Agent、模型、prompt、工具、镜像或依赖、超时和网络策略;二是统计可重复,在同一配置上多次 Trial,报告分布与错误,而不是挑选最好的一次。
Harbor v0.18.0 的 TrialResult 保存 task_checksum、Trial 配置、Agent 与模型信息、阶段计时、Reward 和异常;JobStats 分开统计完成、错误、取消、重试、token 与美元成本。1011 这些字段提供追溯材料,但“字段存在”不等于“实验已复现”:外部 API 版本、未固定的镜像标签、当前时间和远端数据仍可能漂移。
成本:成功不是唯一目标
一次成功可能用了十倍 token、进行了危险重试或占用更久沙箱。评测至少同时记录任务成功、Agent 执行时间、token/调用量、模型费用、环境费用和超时。成本缺失时,团队容易选择“分数最高但无法部署”的方案;只比较平均成本又会掩盖失败 Trial 已经消耗的预算。
不要把“未报告”当成 0。Harbor 的相关成本字段是可选的;只有 Agent 或模型适配层真实提供用量时,聚合值才有意义。12 报告中应把未知值写成“未采集”,并说明价格表日期和是否包含沙箱、存储及网络费用。
安全:沙箱降低影响面,不替代威胁建模
评测任务会运行模型生成的命令,本质上是在执行不受信任的操作。最低限度要使用隔离环境、最小权限、占位凭据、受控网络和可丢弃数据,并防止 Agent 读取 Solution 或 Harbor Task 的 Verifier 文件。Harbor v0.18.0 支持在任务配置中约束网络,而且会在 Provider 不具备所请求能力时拒绝 Trial,而不是悄悄使用更弱策略。13
警告:不要把真实生产令牌写进 Task、镜像或 trajectory。即使容器会销毁,模型服务、日志系统和 Artifact 仍可能保留内容。容器隔离也不能证明不存在内核、挂载、Provider 或配置层面的逃逸路径。
安全还包括 Benchmark 自身:Verifier 可能被篡改,测试可能泄露答案,恶意网页或日志可能向 Agent 注入指令。安全结论必须对应明确威胁模型;一次“没有出事”的 Trial 不能证明 Agent 安全。
1.5 示例:同一句“已修复”,三种不同结果
先用一个将在后续章节纳入贯穿项目的修复场景建立评测契约。任务要求 Agent 修复一个因端口配置错误而不可用的 Python 服务,并提交结构化诊断报告。以下记录是教学性构造,不是 Harbor 实测结果。
| Trial | 最终回复(节选) | 环境终态 | 其他证据 | 应如何判定 |
|---|---|---|---|---|
| A | “已修复,健康检查通过” | 配置未改,服务仍失败 | 只运行了输出固定文本的脚本 | 结果失败 |
| B | “已修复,健康检查通过” | 端口正确,服务重启后仍可响应 | trajectory 包含读取日志、修改配置、重启和调用真实端点;结构化报告的现象、根因、修改、验证四项齐全 | 完整任务成功 |
| C | “已修复,健康检查通过” | 端点暂时可响应,但工作区内对 Agent 可见的应用回归测试被删除 | 删除应用回归测试并启动临时替身进程 | 结果失败,且标记完整性风险 |
这里的“应用回归测试”属于待修复项目的一部分,对 Agent 可见;它不是 Harbor 为独立评分使用的 Task tests/。在 v0.18.0 的默认共享验证流程中,Agent 阶段先结束,Verifier 随后才把 Task 测试上传到环境并执行。14 如果 Agent 能删除这些 Harbor Verifier 文件,应先判定为 Task 打包或隔离缺陷,而不是正常的 Agent 解法。
如果评分器只搜索最终回复中的“健康检查通过”,三次都会得 1 分;如果只检查某个端口能否短暂响应,C 仍可能蒙混过关。更可靠的验收契约应从外部验证结果,而不限定 B 必须使用某条命令:
任务目标:恢复示例服务,并保留可审计的诊断报告。
必须满足:
1. 由独立 Verifier 请求 /health,状态码与响应结构正确;
2. 重新启动环境中的目标服务后,修复仍然有效;
3. 允许修改范围及应用回归测试的完整性约束通过;
4. 报告包含故障现象、根因、修改与验证证据。
实验记录:
- Task/Dataset 版本与 Task 校验和;
- 完整运行配置:Agent、模型、prompt、Environment/Provider、工具、权限、网络、超时与 Verifier;
- Reward、异常、阶段耗时与成本采集状态;
- trajectory 和必要 Artifact;
- 失败分类:能力、Agent、环境、Verifier 或基础设施。
这个契约仍不完善。例如,“响应结构正确”需要具体 schema,“完整性约束”需要明确允许修改哪些文件,报告质量也需要确定性规则或经过校准的裁判。此处的目标不是提前写完 Task,而是展示 Agent 评测为何是一项工程:任务、环境、权限、证据和评分必须共同设计。
1.6 Harbor 能做什么,不能做什么
Harbor 的抽象与上述问题正好对齐:Task 由 instruction、容器环境和测试脚本构成;Dataset 收集 Task;Agent 完成任务;Trial 表示一次尝试;Job 聚合多个 Trial。7 运行结果目录可以保存配置、Trial 结果、Verifier 输出和 Agent trajectory,Viewer 还能检查工具调用、观察、耗时与用量。15
它适合以下工作:
- 结果能够在 Linux 或 Windows 容器、文件、服务或可采集 Artifact 中观察;Windows Task 需要满足该版本文档规定的 Windows 主机与容器模式条件。16
- Agent 需要 Shell、代码工具、MCP 或外部模型服务完成多步任务;v0.18.0 的 Task 环境配置能够声明供兼容 Agent 使用的 MCP Server。17
- 团队需要统一 Task 格式、Agent/环境接口、并发执行、Verifier 与结果记录。715
- 同一 Task 格式、任务族或明确切分后的不同实例需要分别用于回归 eval、SFT 轨迹或 RL rollout;最终持出 split 不得进入训练。89
但 Harbor 不是通用模型评测库。若目标只是计算静态问答准确率、困惑度、基础模型校准或大规模离线分类指标,容器化 Agent Trial 往往增加不必要的复杂度。它也不是训练框架、形式化安全证明、生产监控系统或自动保证高质量 Benchmark 的机器。Harbor 可以承载模型作为 Agent 的一个组件,从而在其他完整运行配置固定时比较模型;得到的仍是该 Agentic Task 条件下的系统成绩。
由此可以推断,选择 Harbor 的问题不应是“我们是否在用 LLM”,而应是:“任务是否需要可控环境中的行动,结果是否能被独立验证,运行证据是否值得标准化?”若三个答案都是否定的,应先考虑更简单的评测工具。
1.7 贯穿项目:先写能力边界,再写任务
“系统配置与故障诊断 Agent Benchmark”不测所有运维能力,也不声称代表真实生产可靠性。完整 Benchmark 的目标覆盖隔离环境内的四个能力维度:
| 能力维度 | 要观察的行为 | 首选验收证据 |
|---|---|---|
| 诊断 | 从日志、配置和服务状态定位根因 | 报告字段与环境事实一致 |
| 修复 | 修改允许范围内的配置或代码 | 重启后功能测试通过 |
| 验证 | 主动检查修复及关键回归 | 独立 Verifier 重复验证 |
| 安全与效率 | 不泄露凭据、不越权,控制时间与调用 | 轨迹审计、策略日志、耗时与成本 |
首个可实现增量只做错误日志分析与结构化报告;后续章节再逐步加入 Python 服务修复、Compose/Nginx、多服务验证,以及安全和效率护栏。项目边界也要写清:环境只包含专门构造的 Python 服务、Docker/Compose、Nginx 和相关辅助容器(Sidecar);不连接生产系统;凭据均为无价值占位符;不把“报告写得好”替代真实修复;不从单次 Trial 推断稳定成功率;不把 Benchmark 得分外推成所有系统管理场景的能力。
失败反例:把一次漂亮演示当成 Benchmark
常见做法是挑一个任务,让 Agent 运行一次,录屏后宣布“修复成功”。这种演示缺少 Task/Dataset 版本、干净初态、完整运行配置、失败计入规则和重复 Trial。即使演示真实,它也只能证明“某个完整运行配置在某个任务版本的一次运行中成功”,不能回答下一次是否成功、另一个 Agent 是否公平可比,更不能区分模型能力与偶然的网络或缓存状态。
排查顺序应从测量系统开始,而不是立即改 prompt:
- 确认 Task/Dataset 版本、Task 校验和、镜像/依赖和初始故障一致;
- 确认 Agent、模型、Environment/Provider、工具、权限、超时、网络和 Verifier 配置一致;
- 查看异常与阶段计时,先排除构建、Provider、认证和 Verifier 故障;
- 用环境终态和测试判断任务结果;
- 最后检查 trajectory,定位策略、工具或安全问题;
- 多次运行后再汇总成功率、Reward、成本和失败类型。
还应警惕“平均分相同,所以系统等价”的结论。假设两个配置各运行十次:一个配置稳定完成中等难度任务,另一个在简单任务上成功、在困难任务上全部超时;即便平均 Reward 恰好相同,部署含义也不同。聚合报告至少要保留逐 Task、逐 Trial 的结果与异常,并按能力维度查看分布。若某次 Trial 因镜像拉取失败而没有进入 Agent 阶段,应单独标记基础设施错误;直接把它删掉会高估系统,把它算作能力失败又会污染模型比较。正式报告前必须预先规定两类失败的计入口径,不能看到结果后再挑选有利规则。
1.8 本章验收方法
本章不要求安装 Harbor。请把下面清单当作贯穿项目的设计门禁;六项全部回答“是”,才进入 Task 实现:
- 评测对象写成“完整运行配置 × Task/Dataset 版本”,并展开所有控制变量;
- 每个能力维度至少有一个可由外部观察的结果,不依赖 Agent 自述;
- Benchmark 契约包含任务版本、运行协议、Verifier 和聚合口径;
- 成功、任务失败、基础设施错误、超时和安全违规有不同记录方式;
- 配置、终态、trajectory、Artifact、耗时和成本的采集范围已定义;
- 已写明不覆盖的场景、实例角色与接触历史,并确保最终持出测试不进入 SFT/RL/prompt 优化。
验收者还应使用 1.5 节的 A、B、C 三种构造攻击评分方案:A 和 C 必须失败,B 必须成功;若做不到,就应修改验收条件,而不是修改示例结果。这是本章的最小可核验产出。
1.9 本章小结
- 模型评测与 Agent 评测的关键差别是系统边界;Agent 成绩属于“完整运行配置 × Task/Dataset 版本”。
- 最终回复不能替代环境终态;trajectory 适合解释与审计,也不能替代独立验证。
- Benchmark 是测量契约,eval 是执行实验,rollout 是一次交互采样,post-training 可以消费筛选后的轨迹与 Reward。
- 可复现性要求配置可追溯和统计可重复;成本未知不能记为零;沙箱不等于安全证明。
- Harbor 适合容器化、工具驱动、结果可验证的 Agent 任务,不是通用模型评测库或训练框架。
1.10 练习
- 选择一个“修改 Nginx 配置”的任务,分别写出最终回复、环境终态和 trajectory 中应采集的两项证据。说明哪一项用于评分,哪一项只用于诊断。
- 在不限定具体命令的前提下,为 1.5 节任务补全
/health响应 schema、允许修改的文件范围和重启后验证条件。 - 构造一个能骗过“端口可连接”检查的错误解法,再修改验收契约使其失败。把该反例明确标注为教学性构造。
- 设计一个包含三次 Trial 的实验记录表,至少包括 Task 校验和、Agent/模型、Reward、异常、耗时、成本采集状态和失败分类。解释为什么不能只保留最好的一次。
- 举出一个适合 Harbor 和一个不适合 Harbor 的评测需求,分别用“是否需要行动、是否有可控环境、是否能独立验证”作出判断。