跳转到内容

从零搭一个 Agent Eval Harness:Task、Environment、Trial、Trajectory 与 Grader ​

系列:开源模型评测

来源公众号:智能大时代

发布时间:2026-09-08 22:34

原文链接:阅读公众号原文

这里单独

上一篇 模型能力评测:从 LLM Eval 到 Agent Eval 我们讨论了:

Agent Eval 到底在评什么?

结论是,Agent Eval 测量的不只是一个 Model,而是一个完整的 Agent System。

整体流程可以表示为:

Model × Scaffold × Environment × Task × Protocol                          ↓                        Trial                          ↓             ┌────────────┴────────────┐             ↓                         ↓        Trajectory                  Outcome             │                         │             └────────────┬────────────┘                          ↓                        Grader                          ↓                        Metric                          ↓                     Evaluation

但是,怎么把这套 Evaluation 真正跑起来呢?

一个自然的想法是使用类似下面的代码实现:

for task in tasks:     result = agent.run(task)     score = evaluate(result)

几十行代码就能快速进行测试。

但是,Agent 的执行不像普通的独立测评任务,随着任务变复杂,会出现各种问题:

环境如何初始化? 不同 Agent 是否从相同状态开始? Agent 失败了,还是 API 挂了? Timeout 后如何处理? Trajectory 怎么保存? 不同模型是否使用了相同资源? 上一个任务会不会污染下一个任务?

这时候会发现:

Agent Eval 需要的不是一个 evaluation script,而是一套 Eval Harness。

什么是 Eval Harness? ​

Eval Harness 不同于 Agent Harness。

Agent Harness 是被测 Agent System 的一部分,负责:

Agent 怎么完成任务。

而 Eval Harness 负责的是:

怎么管理评测环境、给 Agent 出题、运行 Agent、记录过程、检查结果并生成评测结果。

具体包括:

Task Loading Environment Setup Protocol Control Agent Execution Trajectory Recording Outcome Collection Grading Reporting

Agent Eval 需要哪些组件? ​

一个最小的 Agent Eval 系统不需要很复杂,核心是下面几个组件:

Task Environment Agent Protocol Trial Trajectory Outcome Grader

下面对几个重要组件进行简要介绍: ​

Task ​

Task 描述:

Agent 被要求完成什么?

例如:

根据 Alice 发来的销售数据更新 Q4 forecast。

在系统中可能是这样表示:

Task(    id="forecast_001",     instruction="根据 Alice 的邮件更新 Q4 forecast",     environment="office_env_v1", )

Environment:Agent 所处的世界 ​

Environment 回答的是:

Agent 能看到什么、能做什么,以及动作会产生什么后果?

Coding Agent 的 Environment 可能包含:

Repository Filesystem Shell Python Tests

Office Agent 可能包含:

Email Calendar Spreadsheet Docs

一个 Environment 最基本需要提供 reset() 和 execute();为了评测最终结果,通常还需要通过 snapshot() 获取环境的最终状态。

其中,reset() 负责把世界恢复到 Task 的初始状态,execute(action) 负责执行 Agent 的动作并返回 Observation,snapshot() 则负责获取最终 Environment State。

Agent:Eval Harness 面向被测系统的统一接口 ​

Agent 框架很多,例如不同的 Coding Agent、Browser Agent 或自研 Agent Harness。

为了对多种 Agent 进行统一评测,Eval Harness 不应该绑定某一种 Agent Framework,而应该定义统一接口。

例如:

class Agent:    def run(self, task, environment):         ...

至于内部怎么完成任务,是 Agent Harness 自己的事情。

Eval Harness 只需要知道:

给定 Task、Environment 和 Protocol,这个 Agent 能不能完成一次 Trial。

Trial:Agent Eval 的基本单位 ​

所谓 Trial,就是:

某个 Agent 在一组确定的评测条件下,对某个 Task 的一次完整尝试。

为什么需要把 Task 和 Trial 区分开?

因为 Agent 通常具有随机性,同一个 Task 需要执行多次,以分析整体成功率,其中每一次具体尝试都是一个 Trial:

Trial 1 → Success Trial 2 → Failure Trial 3 → Success

Trial 和 Task 的关系可以这样理解:

Task A ├── Trial 1 ├── Trial 2 ├── Trial 3 └── Trial 4

这也是后面具体评测指标的基础:

Success Rate Pass@k Pass^k Variance Reliability

Trial 的生命周期 ​

Trial 是评测的基本单位,相对其他组件更为重要,我们在本节单独进行分析。一个完整 Trial 可以简化成:

Prepare    ↓ Reset    ↓ Execute    ↓ Collect    ↓ Grade    ↓ Persist    ↓ Cleanup

可以把它理解成一次受控实验的完整生命周期。

Prepare ​

加载本次 Trial 需要的:

Task Agent Configuration Environment Version Protocol

同时生成唯一的:

trial_id

Reset ​

把环境恢复到指定 initial state。

Coding Agent 可能需要:

checkout commit reset filesystem restart container clear temporary files

Office Agent 可能需要:

restore inbox restore calendar restore spreadsheet clear session

这一步非常重要。

如果 Agent B 接着 Agent A 修改后的环境继续跑,那么两个 Agent 已经不在同一个实验条件下。

Execute ​

Agent 根据 Task 开始与 Environment 交互,不断执行 Action 并接收新的 Observation,直到 Agent 主动结束,或者达到:

max_steps timeout agent_error environment_error

Collect ​

Agent 停止以后,不能只保存 final_answer,还应该收集真实 Evidence。

例如:

git diff test result final files calendar state email state tool calls token usage latency

因为:

Agent 说“我完成了”,并不等于任务真的完成了。

Agent 最终改变了什么,才是 Outcome。

Grade ​

Grader 负责具体的评分,根据 Task 和 Evidence 判断任务是否完成。

例如:

代码测试是否通过? 有没有引入 regression? 表格数据是否正确? 有没有修改不该修改的数据? 会议邀请对象是否正确?

最终返回结构化结果。此外,对于固定的结果证据,可以修改 Grader 以得到更“合理”的得分。

例如:

{  "success": true,  "constraint_violation": false }

Persist ​

保存 Trial、Evidence 和 Grade。

这一步会直接决定后面能不能做:

Failure Analysis Regression Analysis Regrading Statistics Training Data Mining

Cleanup ​

Trial 结束以后,还需要释放本次运行产生的资源,例如容器、临时文件、Session 等,避免本次 Trial 的状态影响后面的运行。

对于一个稳定的 Eval Harness 来说:

Reset 保证每次 Trial 从正确的状态开始,Cleanup 保证它不会污染下一次 Trial。

Trajectory 的意义 ​

Score 只能告诉我们 Agent 成功还是失败,却无法解释为什么失败。为了了解 Agent 究竟做了哪些事情,Eval Harness 至少应该保存可观察的 Trajectory + Outcome + Grade:Trajectory 记录 Agent 做了什么,Outcome 记录环境最终变成什么,Grade 记录我们如何评价这些证据。

同时,如果需要进行模型的后训练,也依赖 Trajectory。

记录好 Version ​

在 Agent 的持续评测过程中,Model、System Prompt、Tool、Environment、Task、Protocol、Grader 都可能导致分数变化。

为了知道一次结果变化究竟来自哪里,每次 Trial 都应该保存完整的版本和运行配置:

task_version: 3 model: model-x-2026-03-01 scaffold_version: 17 environment_version: 4 max_steps: 30 timeout: 300

这样结果变化时,我们才有可能回答:到底是什么发生了变化? 从这个角度看,Eval Harness 不只是一个 Agent Runner,同时也是一套最小的实验管理系统。

一个贯穿整个系列的 Mini Framework ​

现在,我们已经可以搭出第一版 mini framework,核心接口不需要复杂:

class Task:    id: str     instruction: str     environment: str class Environment:    def reset(self, task):         ...    def execute(self, action):         ...    def snapshot(self):         ...    def cleanup(self):         ... class Agent:    def run(self, task, env, recorder):         ... class Trial:     task_id: str     trajectory: list     outcome: dict     execution_status: str class Grader:    def grade(self, task, trial):         ... class EvalRunner:    def run(self, task, agent, env, protocol):         ...

执行流程大概是:

def run(task, agent, env, grader, protocol):     trial = Trial(task_id=task.id)    try:         env.reset(task)         agent.run(             task=task,             env=env,             recorder=trial         )         trial.execution_status = "completed"         trial.outcome = env.snapshot()    except TimeoutError:         trial.execution_status = "timeout"    except EnvironmentError:         trial.execution_status = "environment_error"    finally:         env.cleanup()     save_trial(trial)     grade = grader.grade(task, trial)     save_grade(grade)    return grade

当然,在 AI Coding 已经非常成熟的今天,实现这套 Mini Framework 本身并不是有难度的事情。上面的代码是为了读者更清楚理解 Eval Harness 的设计原理。

持续沉淀企业 AI 技术内容。