研究提案 已修订

Agent Benchmark 执行框架综合调研:从 SWE-bench 到 Agentless,13 个 Harness 的架构解剖与设计取舍

系统调研 13 个主流 Agent Benchmark 的配套执行框架(Harness),包括 SWE-bench/SWE-agent、OpenHands、Agentless、BrowserGym、OSWorld、APEX、AppWorld、τ-Bench、MLAgentBench、DevBench 等,从环境隔离、动作空间、评分机制、可扩展性四个维度进行横向对比,给出 Agent 评估体系设计建议。

agent benchmark evaluation harness execution-framework survey

TL;DR

几乎所有主流 Agent Benchmark 都自带配套执行框架——这不是巧合,而是必然。因为评估结果的可信度取决于 Harness 而非模型本身。本文解剖 13 个框架的内部结构,从 SWE-bench 的 Docker + ACI 到 OpenHands 的 CodeAct 双通道,从 Agentless 的”反 Agent”三阶段流水线到 APEX 的 MCP Gateway,再到 AppWorld 的多应用 API 协作和 MLAgentBench 的科研实验迭代,梳理它们在环境隔离、动作空间、评分机制上的设计取舍,最终给出 Agent 评估体系的设计建议。


一、为什么每个 Benchmark 都要造自己的 Harness

Agent 评估与传统模型评估的根本区别:Agent 需要与环境交互。这意味着:

  1. 环境必须可复现——同一任务跑两次,初始状态必须一致
  2. 动作必须有边界——Agent 能做什么、不能做什么,需要明确定义
  3. 评判必须客观——不能只看最终答案,还要看过程是否安全

2026 年 4 月发表的综述论文 Agent Harness for Large Language Model Agents: A Survey 将 Harness 形式化为六组件框架 H=(E, T, C, S, L, V):

组件含义必要性
E执行循环(观察-思考-行动)必须
T工具注册表必须
C上下文管理推荐
S状态持久化视任务而定
L生命周期钩子(日志/审计)生产环境必须
V评估接口Benchmark 必须

关键实证:xAI Grok 仅改变编辑工具格式(Harness 层变化),SWE-bench 成绩从 6.7% 跃升到 68.3%——10 倍提升来自 Harness 而非模型。


二、八大框架逐一解剖

2.1 SWE-bench + SWE-agent

定位:代码修复(GitHub Issue → Patch)

环境架构:Docker 容器化。每个任务实例对应一个独立容器,基于目标项目的特定 commit 构建镜像。x86_64 架构,建议 120GB 磁盘 + 16GB RAM。

执行流程:

Issue 描述 + 代码仓库快照
        ↓
SWE-agent 启动交互循环
        ↓
Agent 通过 ACI 执行:搜索/浏览/编辑/bash
        ↓
生成 unified diff 格式的 patch
        ↓
Docker 容器内 apply patch
        ↓
运行项目原有测试套件
        ↓
判定:FAIL_TO_PASS ✓ 且 PASS_TO_PASS ✓ = Resolved

动作空间(ACI = Agent-Computer Interface):

这是 SWE-agent 的核心创新。关键设计决策:

ACI 工具对比原始终端设计理由
专用文件查看器(100行/页)替代 cat防止大文件淹没上下文窗口
带 linter 的编辑器替代 sed/vim语法错误时拒绝提交编辑
精简搜索(只列文件名)替代 grep过多上下文反而让模型困惑
空输出显式提示原始终端无反馈消除 Agent 不确定性

评分机制:二元判定——所有 FAIL_TO_PASS 测试通过 + 无回归 = Resolved。核心指标 % Resolved。

设计哲学:“不要让 LM 用为人类设计的终端工具”——ACI 是为 LM 认知特点量身定制的命令接口。

端到端交互实例:

下面用一个真实 SWE-bench 任务,完整展示”给模型什么 → 模型输出什么 → 框架怎么执行 → 结果怎么回传”的全链路。

Step 0:框架构造系统提示词(模型看到的第一条消息)

SETTING:
You are an autonomous programmer. Your task is to solve the GitHub issue
described below. You have access to a special interface (ACI) with the
following commands:

COMMANDS:
open <path> [<line_number>]
  Opens the file at the given path in the file viewer.
  Shows 100 lines at a time.

scroll_up / scroll_down
  Scrolls the file viewer by 100 lines.

edit <start_line>:<end_line>
<replacement_text>
end_of_edit
  Replaces lines start_line to end_line with replacement_text.
  Your edit will be REJECTED if the linter detects syntax errors.

search_dir <search_term> [<dir>]
  Searches for search_term in all files. Only shows matching file names.

search_file <search_term> [<file>]
  Searches for search_term in the given file.

find_file <file_name> [<dir>]
  Finds all files with the given name.

submit
  Submits your current changes as the final patch.

RESPONSE FORMAT:
Always respond with a THOUGHT (your reasoning) followed by an ACTION
(exactly one command). Example:
THOUGHT:
I need to find where the bug is.
ACTION:
search_dir "parse_config" src/

IMPORTANT:
- Your edit command will be checked by a linter. If there are syntax errors,
  the edit will NOT be applied, and you will see an error message.
- If a command has no output, you will see:
  "Your command ran successfully and did not produce any output."

注意几个关键点:

  1. 工具以纯文本命令描述的形式注入 system prompt,不是 API function calling schema
  2. 强制 THOUGHT + ACTION 的输出格式(类 ReAct)
  3. 明确告知 linter 会拦截错误编辑——这改变了模型的行为策略

Step 1:注入任务(User 消息)

ISSUE:
TypeError in parse_config when config file is empty.
Traceback: File "src/config/parser.py", line 42, in parse_config
    if data = None:
              ^
SyntaxError: invalid syntax

REPOSITORY: myproject (commit abc1234)
You are now in the /repo directory.

Step 2:模型生成第一轮响应

模型输出(原始文本):

THOUGHT:
The traceback points to src/config/parser.py line 42. Let me open that file
to see the context around the bug.

ACTION:
open src/config/parser.py 35

Step 3:框架解析并执行

SWE-agent 框架做了三件事:

  1. 正则解析:从模型输出中提取 ACTION: 后面的命令 → open src/config/parser.py 35
  2. 命令路由:open 是内置 ACI 命令 → 调用文件查看器(不是 shell 的 cat)
  3. 在 Docker 容器内执行:读取文件内容,截取第 35-134 行(100 行窗口)

框架生成 Observation,追加到对话历史:

OBSERVATION:
[File: /repo/src/config/parser.py (200 lines total)]
(showing lines 35-134)
 35: class ConfigLoader:
 36:     """Load and parse configuration files."""
 37:
 38:     def parse_config(self, path):
 39:         """Parse a config file and return dict."""
 40:         data = self._load_file(path)
 41:         # validate data before processing
 42:         if data = None:
 43:             return {}
 44:         return self._process(data)
 45:
...

Step 4:模型生成第二轮响应

THOUGHT:
Found the bug on line 42: assignment operator `=` instead of comparison
`==`. I also notice it should use `is None` for Python best practices.
Let me fix it.

ACTION:
edit 42:42
        if data is None:
end_of_edit

Step 5:框架执行编辑 + Linter 检查

框架的处理流程:

  1. 解析 edit 42:42 + 替换文本
  2. 在临时副本上应用编辑
  3. 运行 linter(flake8 / pylint)→ 检查通过
  4. 写入实际文件
  5. 返回结果
OBSERVATION:
[File: /repo/src/config/parser.py (200 lines total)]
(showing lines 38-48 after edit)
 38:     def parse_config(self, path):
 39:         """Parse a config file and return dict."""
 40:         data = self._load_file(path)
 41:         # validate data before processing
 42:         if data is None:
 43:             return {}
 44:         return self._process(data)

如果 linter 失败(比如模型写了 if data is None 但缩进错误),观测会是:

OBSERVATION:
Your edit was rejected. The linter found the following error:
  Line 42: IndentationError: unexpected indent
The file has NOT been modified. Please fix the error and try again.

Step 6:模型提交

THOUGHT:
The fix has been applied and the linter passed. I'm confident this
resolves the TypeError. Let me submit.

ACTION:
submit

Step 7:框架收尾

框架执行 git diff 提取 patch → 在 Docker 容器内 git apply → 运行项目测试套件 → 判定结果。

完整对话在 API 层面的消息序列:

messages = [
  {"role": "system", "content": "SETTING: You are an autonomous..."},
  {"role": "user",   "content": "ISSUE: TypeError in parse_config..."},
  {"role": "assistant", "content": "THOUGHT: ...\nACTION: open ..."},
  {"role": "user",   "content": "OBSERVATION: [File: ...]"},
  {"role": "assistant", "content": "THOUGHT: ...\nACTION: edit ..."},
  {"role": "user",   "content": "OBSERVATION: [File: ...after edit]"},
  {"role": "assistant", "content": "THOUGHT: ...\nACTION: submit"},
]

每一轮的 OBSERVATION 都作为 user 消息追加——框架充当了”模型与环境之间的翻译层”。


2.2 BrowserGym(WebArena/VisualWebArena/WorkArena 等)

定位:Web 浏览器操作(导航、填表、信息提取)

环境架构:标准 Gymnasium API + Playwright(Chromium)。真实浏览器,非模拟。

执行流程:

env = gym.make("browsergym/webarena", task_kwargs={...})
obs, info = env.reset()         ← 加载目标网页,注入元素标记(bid)
while not done:
    action = agent(obs)         ← Agent 根据 DOM/截图/AXTree 决策
    obs, reward, done, _, info = env.step(action)  ← Playwright 执行
env.close()

动作空间:

动作说明
click(bid)点击指定元素
fill(bid, text)填入文本
scroll(direction)滚动
goto(url)导航
hover(bid)悬停
send_msg_to_user(text)返回答案
noop等待

动作以 Python 代码字符串提交,BrowserGym core 层解析执行。

观测空间(多模态):

  • DOM / AXTree(结构化)
  • 截图(像素级,支持 VLM)
  • 文本标注(带 bid 标识)
  • Chat 消息历史

评分机制:每个 Benchmark 独立评分逻辑。WebArena 基于预定义验证脚本(URL 匹配、页面内容检查、数据库状态),MiniWoB 基于精确匹配,WorkArena 基于 ServiceNow 平台操作结果。

生态价值:一套框架统一了 9 个 Web 类 Benchmark(MiniWoB、WebArena、VisualWebArena、WorkArena、AssistantBench、WebLINX、OpenApps、TimeWarp 等),Agent 切换 Benchmark 只需换任务 ID。

端到端交互实例:

以 WebArena 任务”在 Reddit 上搜索 BrowserGym 相关帖子”为例。

Step 0:env.reset()——框架初始化环境

框架启动 Playwright Chromium,导航到目标网站,为所有可交互元素注入 bid 标识。返回 observation 字典。

Step 1:Agent 收到的 Observation(模型实际看到的内容)

Agent 可以选择消费多种表示。最常用的是 AXTree(无障碍树),每个可交互元素带唯一 bid:

Goal: Search for posts about "BrowserGym" on the forum.

[bid=4] RootWebArea 'Reddit-like Forum', url='http://forum.test:9090/'
  [bid=8] banner ''
    [bid=12] link 'Home'
    [bid=15] link 'Popular'
    [bid=21] textbox 'Search posts', focused
    [bid=25] button 'Search'
  [bid=30] main ''
    [bid=32] heading 'Hot Posts'
    [bid=35] link 'Welcome to the forum!'
    [bid=38] link 'New features this week'
  [bid=80] contentinfo ''
    [bid=82] link 'About'

Last action: None
Last action error: None

关键:bid 是 BrowserGym 通过 JavaScript 注入到 DOM 中的唯一标识符,不是页面原有属性。模型用 bid 来定位要操作的元素。

如果是多模态 Agent(VLM),还会收到 screenshot_som——页面截图上叠加了 bid 编号标注。

Step 2:Agent(LLM)输出 Action

模型输出是一段 Python 函数调用字符串:

fill(bid="21", value="BrowserGym")
press(bid="21", key="Enter")

注意:不是自然语言指令,不是 JSON,而是可解析的 Python 代码。BrowserGym 支持单步或多步复合 action。

Step 3:框架解析并执行(env.step 内部)

收到 action 字符串
    ↓
解析为函数调用:fill(bid="21", value="BrowserGym") + press(bid="21", key="Enter")
    ↓
BID 定位:document.querySelector('[bid="21"]') → 找到搜索输入框
    ↓
Playwright 执行:
  locator.fill("BrowserGym")  → 清空并输入文本
  locator.press("Enter")      → 触发搜索
    ↓
等待页面稳定(网络请求完成、DOM 更新)
    ↓
重新注入 BID(页面 DOM 变化后需要更新标识)
    ↓
构建新的 Observation
    ↓
运行 task.validate() 检查任务是否完成

Step 4:新的 Observation 回传给 Agent

[bid=4] RootWebArea 'Search results for "BrowserGym"',
        url='http://forum.test:9090/search?q=BrowserGym'
  [bid=8] banner ''
    [bid=12] link 'Home'
    [bid=21] textbox 'Search posts', value='BrowserGym'
    [bid=25] button 'Search'
  [bid=30] main ''
    [bid=32] heading 'Search Results (3)'
    [bid=35] link '[Research] BrowserGym: A Gym Environment for Web Tasks'
      [bid=36] StaticText '12 comments · Posted 2 days ago'
    [bid=40] link 'How to build agents with BrowserGym?'
      [bid=41] StaticText '5 comments · Posted 1 week ago'
    [bid=45] link 'BrowserGym vs Selenium for testing'
      [bid=46] StaticText '8 comments · Posted 3 weeks ago'

Last action: fill(bid="21", value="BrowserGym"); press(bid="21", key="Enter")
Last action error: None

Step 5:Agent 判断任务完成并返回

send_msg_to_user(text="Found 3 posts about BrowserGym. The most relevant is '[Research] BrowserGym: A Gym Environment for Web Tasks' with 12 comments.")

在代码层面的完整循环:

env = gym.make("browsergym/webarena.312")
obs, info = env.reset()

while True:
    # 1. 将 obs 格式化后送入 LLM
    prompt = format_obs_for_llm(obs["axtree_txt"], obs["goal"])
    action = llm.generate(prompt)  # → "fill(bid=\"21\", ...)"

    # 2. 框架执行 action 并返回新 obs
    obs, reward, terminated, truncated, info = env.step(action)

    # 3. 终止判断
    if terminated or truncated:
        break

env.close()
# reward = 1.0 表示任务完成

与 SWE-agent 的关键区别:SWE-agent 用纯文本命令 + 正则解析,BrowserGym 用 Python 函数调用字符串 + 代码解析。两者都把”模型输出 → 环境执行”的翻译逻辑封装在框架内部。


2.3 OSWorld

定位:桌面操作系统全任务(办公软件、浏览器、终端、多应用协作)

环境架构:真实虚拟机(VMware/VirtualBox/Docker/AWS),运行完整 Ubuntu/Windows 桌面。

执行流程:

Host 机器运行 Agent 代码
        ↓
DesktopEnv 抽象层连接 VM
        ↓
初始化:下载配置文件、启动目标应用、设置初始状态
        ↓
循环(最多 max_steps=15 步):
  ① 截图 / accessibility tree → obs
  ② Agent (VLM) 分析状态,生成 PyAutoGUI 代码
  ③ 在 VM 内执行鼠标/键盘操作
  ④ 等待 3 秒界面响应
        ↓
自动化评估脚本比对最终状态

动作空间(PyAutoGUI):

Agent 输出的是可执行的 Python 代码,直接在 VM 内通过 PyAutoGUI 执行:

  • 鼠标:click、double_click、right_click、drag、move、scroll
  • 键盘:typewrite、hotkey、press/release
  • 系统:screenshot、sleep

评分机制:基于任务特定的评估脚本,比对执行后的系统状态(文件内容、应用状态、数据库等)。支持 AWS 大规模并行(评估时间可缩短至 1 小时内)。

设计特点:OSWorld 是最”重”的环境——完整 VM 意味着最高的真实性,但也意味着最高的计算成本和最低的评估吞吐量。


2.4 APEX-Agents + Archipelago

定位:专业服务任务(投行分析、管理咨询、公司法务)

环境架构:容器化三层架构(Agents Runner → Environment Sandbox → Grading),组件间 HTTP API 解耦。

执行流程(7 步):

① trajectory_id → 获取 Agent 配置
        ↓
② 生成 Environment 沙盒容器 → 健康检查 /health
        ↓
③ POST /data/populate → S3 下载初始世界快照填充环境
        ↓
④ POST /apps → 配置 MCP 服务器(热插拔工具注册)
        ↓
⑤ Agent 连接 /mcp/ 端点 → 循环执行推理+工具调用
        ↓
⑥ POST /data/snapshot → 创建最终状态快照上传 S3
        ↓
⑦ Webhook 报告结果 → 输出 trajectory.json

动作空间(MCP 协议):

这是与其他框架的关键差异——动作空间不是硬编码的,而是通过 MCP 协议动态配置:

# 热插拔工具注册
config = {
    "mcpServers": {
        "filesystem_server": {
            "transport": "stdio",
            "command": "python",
            "args": ["main.py"],
            "cwd": "./mcp_servers/filesystem_server"
        }
    }
}
requests.post("http://localhost:8080/apps", json=config)

评分机制(正向+负向双维度):

维度说明
正向 judge_grade任务完成度(pass/fail)
负向 negative_grade有害副作用检测(如删除/损坏数据)
权重加总多个 verifier 加权汇总,universal_penalty_cap=0.2

核心评估方式:before/after 快照 diff + 视觉伪影提取(从 PDF/文档/表格中提取图表)+ LLM-as-Judge。

设计特点:MCP 热插拔 + 快照 diff + 双维度评判,最适合长周期、跨应用的知识工作任务。当前最强模型 Pass@1 不足 25%,难度极高。

MCP 工具调用链路示例:

与前面三种方式不同,APEX 的动作空间运行时动态配置——Agent 连接到 MCP 端点后,通过协议发现可用工具:

① Agent 向 /mcp/ 发送 tools/list 请求
    ↓
② 收到可用工具列表:
   - filesystem.read_file(path)
   - filesystem.write_file(path, content)
   - spreadsheet.read_cells(file, range)
   - spreadsheet.write_cells(file, range, values)
   - pdf.extract_text(file)
    ↓
③ Agent 发起工具调用(MCP tool call):
   {"method": "tools/call",
    "params": {
      "name": "spreadsheet.read_cells",
      "arguments": {"file": "financials.xlsx", "range": "A1:D10"}
    }}
    ↓
④ MCP Server 在沙盒内执行,返回结构化结果
    ↓
⑤ 结果回传给 Agent,继续推理

关键差异:SWE-agent/BrowserGym/τ-Bench 的工具集在任务开始前就固定了;APEX 的工具集在运行时通过 MCP 协议按需注册和发现。


2.5 τ-Bench(τ²/τ³-Bench)

定位:客户服务对话(工具-Agent-用户三方交互)

环境架构:仿真框架,核心是用户模拟器(LLM 驱动)+ Agent + 工具集的三方交互。

执行流程:

User Simulator (LLM)  ←→  Agent (被评估)  ←→  Tools (API/数据库)
         │                       │                    │
    用户画像/任务            领域策略(Policy)        领域规则约束
tau2 run --domain airline --agent-llm gpt-4.1 --user-llm gpt-4.1 \
  --num-trials 1 --num-tasks 5

动作空间:Agent 通过结构化函数调用(function calling)与工具交互。工具是领域特定的 API(查询订单、修改航班、处理退款等)。

评分机制(双重控制):

评估要素说明
期望动作任务定义了正确的工具调用序列
策略合规性是否遵循领域 Policy(退款政策、身份验证等)
任务完成度用户目标是否被满足
状态正确性执行后数据库状态是否与预期一致

设计特点:

  • 唯一一个评估多轮对话中的策略合规性的框架
  • 支持文本半双工(回合制)和语音全双工
  • 提供 Gymnasium 兼容 RL 接口,可直接用于训练
  • τ³ 版本新增知识检索(RAG)管道评估

端到端交互实例:

以航空客服场景”用户要求改签航班”为例。τ-Bench 的交互机制与前两者完全不同:使用标准 API function calling(与 OpenAI/Anthropic 的 tool use 接口一致)。

Step 0:框架初始化(三方结构)

用户模拟器(LLM 驱动,有预设画像和目标)
    ↕ 自然语言对话
Agent(被评估的模型)
    ↕ function calling
工具集(航空公司 API:查航班、改签、退款等)

框架向 Agent 提供的 tools schema(标准 JSON Schema,与 function calling 规范一致):

[
  {
    "name": "search_flights",
    "description": "Search available flights between two airports",
    "parameters": {
      "type": "object",
      "properties": {
        "origin": {"type": "string", "description": "Origin airport code"},
        "destination": {"type": "string", "description": "Dest airport code"},
        "date": {"type": "string", "description": "YYYY-MM-DD"}
      },
      "required": ["origin", "destination", "date"]
    }
  },
  {
    "name": "get_booking",
    "description": "Get booking details by confirmation code",
    "parameters": {
      "type": "object",
      "properties": {
        "confirmation_code": {"type": "string"}
      },
      "required": ["confirmation_code"]
    }
  },
  {
    "name": "change_flight",
    "description": "Change an existing booking to a new flight",
    "parameters": {
      "type": "object",
      "properties": {
        "confirmation_code": {"type": "string"},
        "new_flight_id": {"type": "string"}
      },
      "required": ["confirmation_code", "new_flight_id"]
    }
  }
]

同时注入 领域策略(Policy):

POLICY:
- Before making any changes, you MUST verify the customer's identity
  by asking for their confirmation code and last name.
- Flight changes are free within 24 hours of original booking.
- After 24 hours, a $150 change fee applies for economy tickets.
- Business/First class tickets can be changed for free anytime.

Step 1:用户模拟器发起对话

用户模拟器(LLM 扮演,有预设画像)生成:

"Hi, I booked a flight last week and I need to change it to a
different date. Can you help?"

Step 2:Agent 回复(应先验证身份——策略要求)

Agent 的 API 响应(标准 assistant message):

{
  "role": "assistant",
  "content": "Of course! I'd be happy to help you change your flight.
Could you please provide me with your confirmation code and the last
name on the booking?"
}

注意:这里 Agent 没有直接调用工具,而是先对话——因为 Policy 要求先验证身份。如果模型跳过这步直接查订单,会在策略合规性评估中扣分。

Step 3:用户模拟器回复身份信息

"Sure, the confirmation code is ABC123 and the last name is Zhang."

Step 4:Agent 调用工具(标准 function calling)

Agent 的 API 响应中包含 tool_use:

{
  "role": "assistant",
  "content": null,
  "tool_calls": [
    {
      "id": "call_001",
      "type": "function",
      "function": {
        "name": "get_booking",
        "arguments": "{\"confirmation_code\": \"ABC123\"}"
      }
    }
  ]
}

Step 5:框架执行工具调用

τ-Bench 框架拦截 tool_calls,在模拟数据库中执行:

{
  "role": "tool",
  "tool_call_id": "call_001",
  "content": "{\"confirmation_code\": \"ABC123\", \"last_name\": \"Zhang\",
\"flight\": \"CA1234\", \"origin\": \"PEK\", \"destination\": \"SHA\",
\"date\": \"2026-04-25\", \"class\": \"economy\", \"booked_at\":
\"2026-04-10T14:30:00Z\", \"status\": \"confirmed\"}"
}

这个 tool result 作为新消息追加到对话历史,再次调用 Agent。

Step 6-8:后续对话 + 搜索新航班 + 执行改签

(省略中间对话轮次——Agent 确认用户需求后搜索航班、告知费用、执行改签)

评估机制:任务结束后,框架同时检查四个维度:

✓ 期望动作序列:get_booking → search_flights → change_flight(顺序正确)
✓ 策略合规性:先验证身份才操作(通过)
✓ 任务完成度:用户目标"改签"已满足
✓ 状态正确性:数据库中 ABC123 的航班已更新

与前两者的核心区别:

维度SWE-agentBrowserGymτ-Bench
工具定义方式文本命令描述写在 system promptPython 函数名+参数标准 JSON Schema(function calling)
模型输出格式THOUGHT:\n...\nACTION:\ncommandPython 代码字符串API 原生 tool_calls 字段
框架解析方式正则提取 ACTION 文本Python AST 解析API 响应直接包含结构化调用
执行环境Docker 容器内 shellPlaywright 浏览器模拟 API/数据库
观测回传格式文本追加为 user 消息Observation 字典(多模态)tool result 消息

2.6 GAIA

定位:通用 AI 助手任务(多步推理 + 工具使用 + Web 搜索)

环境架构:相对轻量——没有专门的沙盒,Agent 在宿主环境中运行,通过 Web 搜索、代码执行、文件处理等工具完成任务。

执行流程:

自然语言问题 + 可选附件
        ↓
Agent 自主规划:分解子问题
        ↓
多步工具使用(Web 搜索、计算器、代码执行、文件读取等)
        ↓
输出最终答案(简短文本)
        ↓
精确匹配评分

动作空间:没有预定义的固定动作集。Agent 可以使用任意工具组合(Web 搜索、Python 执行、文件操作等),动作空间是开放的。

评分机制:精确匹配——答案要么对要么错。三个难度级别(Level 1/2/3),从简单的单步到需要多步推理和专业知识的复杂问题。

设计特点:GAIA 的极简设计反映了一种立场——通用助手的评估不需要复杂的沙箱环境,关键是任务本身的设计质量。但这也意味着可复现性较低(Web 搜索结果会变化)。


2.7 HAL Harness

定位:不是 Benchmark,而是跨 Benchmark 的统一评估层

架构理念:零约束——对 Agent 实现不施加任何框架约束,同时为 12+ 个 Benchmark 提供统一的运行接口。

执行流程:

hal-eval --benchmark swebench_verified --agent_dir ./my_agent \
         --agent_function main.run --agent_name "MyAgent (gpt-4.1)"
        ↓
参数路由:-A → Agent, -B → Benchmark, -I → Inspect AI
        ↓
执行引擎选择:本地(conda) / Docker / Azure VM
        ↓
并行调度(max_concurrent N)
        ↓
Weave 日志 + 成本追踪 + 加密上传 HuggingFace

Agent 接口:

def run(task_id, **agent_args):
    # 任意实现,零框架约束
    return {task_id: {"history": [...], "cost": 0.0}}

支持的 Benchmark:SWE-bench、USACO、AppWorld、τ-bench、SciCode、CORE-bench、ScienceAgentBench、CollaborativeAgentBench、AssistantBench 等 12+。

核心差异化:成本感知评估。源于论文 “AI Agents That Matter”——“准确率高 1% 但贵 10 倍意味着什么?“。集成 Weave 自动追踪 token 使用和 API 调用成本。

设计特点:HAL 证明了”meta-harness”是可行的——用一层抽象统一多个 Benchmark 的评估流程,同时保持对具体 Agent 实现的零侵入。


2.8 AgentBench

定位:跨场景综合评估(操作系统、数据库、知识图谱、网购、家居等 8 个场景)

环境架构:统一的 Client-Worker 架构,每个场景是一个独立的 Worker 进程。

执行流程:

Agent (Client) ←→ Worker (场景环境)
                     │
        ┌────────────┼────────────┐
        OS Shell   DB Query   Web Browse   ...

动作空间:因场景而异——OS 场景是 bash 命令,DB 场景是 SQL 查询,Web 场景是浏览器操作。统一接口,但底层动作类型完全不同。

评分机制:每个场景有独立的自动评分逻辑(命令输出匹配、SQL 结果比对、状态检查等)。汇总为综合分数。


二-B、补充框架:对照组与新锐

前 8 个框架覆盖了”代码修复 / Web 操作 / 桌面 / 对话 / 通用推理 / 专业服务 / 跨场景”的主要赛道,但仍有几个在执行框架设计上有独特取舍的系统值得加入。以下 5 个框架各自填补了一个空白位置。

2.9 OpenHands(CodeAct)

定位:代码修复 + 通用软件工程(与 SWE-agent 同场景,但设计哲学相反)

环境架构:Docker 沙盒化容器,事件驱动(EventStream)。Agent 发出 Action → EventStream 路由 → Sandbox 执行 → Observation 回传。

┌─────────────┐   Action    ┌──────────────┐   Execution   ┌───────────┐
│  LLM Agent  │ ──────────► │  EventStream │ ────────────► │  Docker   │
│  (CodeAct)  │             │  (消息历史)   │               │  Sandbox  │
│             │ ◄────────── │              │ ◄──────────── │           │
└─────────────┘ Observation └──────────────┘    Result     └───────────┘

动作空间(“一切皆代码”):

这是与 SWE-agent 的核心分歧。SWE-agent 为 LM 设计了专用 ACI 命令;OpenHands 反其道——给 LM 标准工具,而非专用工具:

工具功能对比 SWE-agent ACI
execute_bash任意 Linux bash 命令(支持后台/超时)SWE-agent 限制为特定 ACI 命令
execute_ipython_cellIPython 代码执行(变量隔离、支持 pip)SWE-agent 不提供交互式 Python 环境
str_replace_editor精确字符串匹配编辑(跨调用持久化)类似 SWE-agent 的 edit,但基于字符串匹配而非行号
browserPlaywright 浏览器交互SWE-agent 无浏览器工具

动作通过标准 function calling 接口(ChatCompletionToolParam)传递,不是 SWE-agent 的纯文本命令 + 正则解析。

评分机制:与 SWE-bench 相同——测试套件通过率(FAIL_TO_PASS + PASS_TO_PASS)。OpenHands 不自带 benchmark,而是作为 Agent 框架接入 SWE-bench、HumanEval 等已有基准评估。

与 SWE-agent 的正面对比:

维度SWE-agentOpenHands
设计哲学为 LM 定制专用命令(ACI)给 LM 通用标准工具
动作空间封闭:预定义 ACI 命令集开放:bash + IPython + 浏览器
接口协议文本命令 + 正则解析function calling API
编辑方式行号范围替换(edit 42:42)字符串匹配替换(str_replace)
代码执行仅 bash(ACI 封装)bash + IPython 双通道
SWE-bench Verified~23%(mini-SWE-agent 基线)CodeAct 2.1 达 69.3%

核心启示:SWE-agent 证明了”为 LM 设计专用工具”能大幅提升单任务性能(ACI 的 linter 拒绝机制尤其有效);OpenHands 则证明了”给 LM 通用能力”在跨场景泛化性上更优。两者不是谁对谁错,而是专用 vs 通用的经典取舍。


2.10 Agentless

定位:反 Agent 范式——不交互、不循环、三阶段线性流水线

环境架构:无沙盒、无交互循环。纯 LLM 调用,不让模型自行决策下一步,每一步的输入输出完全由流水线预定义。

执行流程(三阶段):

Issue 描述 + 代码仓库结构
        ↓
阶段一:Localization(层次化定位)
  文件级 → 类/函数级 → 代码行级
        ↓
阶段二:Repair(多候选修复)
  基于定位结果 → 采样 N 个 diff 补丁
        ↓
阶段三:Patch Validation(验证筛选)
  回归测试 + 复现测试 → 多数投票 → 选出最优补丁

动作空间:不存在——这正是 Agentless 的核心设计点。LLM 在每个阶段只做一次生成(定位或修复),不进入”观察-思考-行动”循环。没有工具调用、没有环境交互、没有反馈迭代。

评分机制:与 SWE-bench 相同(测试套件通过率),因为 Agentless 的目标场景就是 SWE-bench。

性能与成本:

指标Agentless (Claude 3.5 Sonnet)SWE-agentOpenHands
SWE-bench Lite40.7%~22%~50%+
SWE-bench Verified50.8%~23%~69%
每个 Issue 成本~$0.34~$1-3~$2-5
交互轮次0(无循环)5-20 轮5-30 轮

为什么加入本文:Agentless 是整篇文章 8 个 Agent 框架的反面教材——它证明了:

  1. 复杂 Harness 不是必要的:三阶段流水线以极低成本达到可比性能
  2. Agent 交互循环的边际收益存疑:Agentless 用 0 轮交互就能解决 50%+ 的问题
  3. 为 Harness 复杂度提供了合理性论证的基线——如果 Agentless 就够用,那 Agent Harness 需要证明额外复杂度换来了什么

2.11 AppWorld

定位:多应用 API 协作(9 个日常 App,457 个 API,模拟真实用户数字生活)

环境架构:AppWorld Engine(6 万行代码),模拟 9 个日常应用:

应用类别覆盖场景
笔记/待办Notes、Todoist 类
通讯Messaging、Email
购物Shopping、Grocery
日历/音乐Calendar、Spotify 类
文件管理File Storage

填充了约 100 个虚构用户的真实数字活动数据(订单历史、聊天记录、日程等),任务需要跨多个 App 协作完成。

执行流程:

自然语言任务描述(如"为一家四口订购本周食材")
        ↓
Agent 生成 Python 代码,通过 API 与多个 App 交互
        ↓
迭代执行:代码 → API 调用 → 观察结果 → 修正代码
        ↓
评估:数据库状态验证 + 附带损害检测

动作空间:Agent 输出可执行的 Python 代码,通过 457 个 API 操作 9 个 App。与 BrowserGym 的 Python 代码动作类似,但操作对象是 API 而非浏览器元素。

评分机制(状态验证 + 附带损害):

维度说明
数据库状态验证检查执行后系统状态是否与预期一致(不是匹配 API 调用序列)
多路径支持不同的 API 调用路径,只要最终状态正确就算通过
附带损害检测检查是否产生意外副作用(类似 APEX 的负向评分)

当前最强表现:GPT-4o 在 Normal 任务约 49%,Challenge 约 30%。

与已有框架的差异:τ-Bench 也评估 API 交互,但限于单领域(航空/零售);APEX 是专业服务场景;AppWorld 填补了日常多应用协作这个最贴近普通用户的位置,且评估方式(数据库状态验证而非 API 序列匹配)更接近真实世界的”对不对”判断。


2.12 MLAgentBench

定位:ML 实验全流程(读数据 → 写代码 → 训练 → 分析结果 → 迭代改进)

环境架构:交互式文件系统环境。每个任务提供 starter code + 数据集 + 评估器,Agent 在文件系统工作区中读写文件、执行脚本、迭代实验。

执行流程:

任务描述 + Starter Code + 数据集
        ↓
循环(最多 50 步 / 5 小时):
  ① Agent 推理(Reflection → Plan → Fact Check → Thought)
  ② Agent 选择动作(12 种可选)
  ③ 环境执行动作,返回观测
  ④ Agent 更新记忆
        ↓
Final Answer → 评估器检查工作区快照

动作空间(12 种动作):

基础动作 9 种 + 复合动作 3 种:

类别动作说明
基础List Files / Read File / Inspect Script Lines信息获取
基础Write File / Append File / Copy File文件操作
基础Execute Script运行 Python 脚本(训练/推理)
基础Undo Edit Script撤销上次编辑
基础Final Answer提交最终答案
复合Understand FileLM 辅助文件摘要
复合Edit Script / Edit Script SegmentLM 辅助代码编辑

13 个任务(5 类):CIFAR-10 / IMDB / ogbn-arxiv(经典)、house-price / spaceship-titanic(入门 Kaggle)、parkinsons-disease / fathomnet 等(新竞赛)、CLRS / BabyLM(前沿研究)、llama-inference / vectorization(代码加速)。

评分机制:

指标说明
成功率性能指标相比 baseline 改进 >10% 的比例
平均改进幅度指标的百分比提升均值
效率token 消耗 + 挂钟时间

当前最强表现:Claude v3 Opus 平均成功率 37.5%,GPT-4-turbo 26%。每轮约 600 万 token / $60。

独特价值:这是唯一评估 Agent 科研实验迭代能力的框架——不是修 bug、不是完成任务,而是”能不能通过实验迭代提升模型性能”。这对训练 RL Agent 的数据收集尤其有参考价值:成功轨迹就是”从 baseline → 改进”的完整实验过程。


2.13 DevBench

定位:软件开发全生命周期(需求 → 设计 → 环境搭建 → 编码 → 测试),不是修 bug 而是从零开发

环境架构:Docker 容器化,按瀑布模型拆分 5 个阶段,每个阶段使用参考输入(而非前阶段模型输出)独立评估。

执行流程(5 阶段流水线):

产品需求文档(PRD)
        ↓
① 软件设计:生成 UML 类图 + 序列图 + 架构
        ↓
② 环境搭建:生成 requirements.txt / build.gradle 等
        ↓
③ 代码实现:按文件依赖 DAG 逐文件生成完整仓库
        ↓
④ 验收测试:生成验收测试代码
        ↓
⑤ 单元测试:生成单元测试 + 测量覆盖率

动作空间:每个阶段是单次或少量 LLM 调用(类似 Agentless 的非交互模式),不是 Agent 循环。输入是结构化的 PRD + 设计文档,输出是代码/配置文件。

多语言多领域覆盖:

语言仓库数平均代码行测试覆盖率
Python1027691.8%
C/C++549595.0%
Java552464.9%
JavaScript2617—

评分机制:

阶段评估方式客观性
软件设计LLM-as-Judge(成对比较)★★★
环境搭建执行示例代码通过率★★★★★
代码实现运行参考测试套件通过率★★★★★
验收测试Oracle Test(用生成测试检验参考实现)★★★★
单元测试Oracle Test + 语句覆盖率★★★★

当前最强表现:GPT-4-Turbo 在代码实现阶段通过率不足 10%。

与 SWE-bench 的关键差异:SWE-bench 是”给你一个成熟仓库 + 一个 bug,修它”;DevBench 是”给你一份需求文档,从零构建完整项目”。前者测修复能力,后者测创造能力。DevBench 的极低通过率表明,当前 LLM 在”从零开发”上的能力远落后于”修复已有代码”。


三、横向对比

3.1 环境隔离策略

框架隔离方式真实性启动成本并行性
SWE-benchDocker 容器★★★★中★★★★
OpenHandsDocker 沙盒 + EventStream★★★★中★★★★
Agentless无隔离、无循环★★极低★★★★★
BrowserGymPlaywright 进程★★★★低★★★★★
OSWorld完整 VM★★★★★高★★★(AWS 可加速)
APEXDocker + S3 快照★★★★中高★★★
AppWorld模拟 App Engine(进程内)★★★低★★★★
τ-Bench纯 Python 仿真★★★极低★★★★★
MLAgentBench文件系统工作区(进程内)★★★低★★★★
DevBenchDocker 容器★★★★中★★★★
GAIA无隔离★★无★★★★★
HAL视 Benchmark 而定继承继承★★★★
AgentBenchWorker 进程★★★低★★★★

趋势:Docker 容器仍是主流平衡点。Agentless 证明了”零隔离零交互”也能达到可比性能——这为 Harness 的复杂度提供了”需要证明必要性”的基线。

3.2 动作空间设计谱系

框架抽象层级动作类型开放性
SWE-agent中层(ACI)为 LM 定制的结构化命令封闭(预定义命令集)
OpenHands中-低层(CodeAct)bash + IPython + 浏览器 + 编辑器开放(任意代码执行)
Agentless无动作空间单次 LLM 生成(不交互)N/A
BrowserGym中层语义化浏览器操作半封闭(固定动作类型)
OSWorld低层PyAutoGUI 代码(像素级操作)开放(任意鼠标键盘)
APEX高层(MCP)热插拔工具协议动态(运行时可配置)
AppWorld高层(API)Python 代码调用 457 个 App API半开放(API 固定,调用方式自由)
τ-Bench高层结构化函数调用封闭(领域固定工具集)
MLAgentBench中层12 种预定义动作(含 LM 辅助)半封闭(预定义但可组合)
DevBench无动作空间单次/少量 LLM 生成N/A
GAIA无限制任意工具组合完全开放

关键取舍:

  • 低层动作(如 PyAutoGUI):最接近人类操作,但学习难度高、episode 长、评估慢
  • 中层动作(如 ACI / CodeAct):为 LM 优化过的命令接口,是当前效果最好的折衷。ACI 走专用路线(封闭命令集),CodeAct 走通用路线(开放代码执行),各有优势
  • 高层动作(如 MCP/function calling/API):抽象程度高,AppWorld 的 457 API 覆盖了复杂的跨应用场景,但可能遗漏真实场景的底层复杂性
  • 无动作空间(如 Agentless/DevBench):证明部分任务不需要交互循环——Agentless 的三阶段流水线以极低成本达到可比性能
  • 完全开放:评估灵活性最高,但可复现性最差

3.3 评分机制对比

框架评分方式客观性可解释性
SWE-bench测试套件通过率★★★★★★★★★★
OpenHands继承 SWE-bench(测试套件)★★★★★★★★★★
Agentless继承 SWE-bench(测试套件)★★★★★★★★★★
BrowserGym验证脚本(URL/内容/DB 状态)★★★★★★★★
OSWorld状态比对脚本★★★★★★★
APEXLLM-as-Judge + 快照 diff★★★★★★★
AppWorld数据库状态验证 + 附带损害检测★★★★★★★★
τ-Bench期望动作序列 + 状态正确性★★★★★★★★
MLAgentBench性能指标改进幅度(>10% 算成功)★★★★★★★★
DevBench测试通过率 + LLM-as-Judge + 覆盖率★★★★★★★
GAIA精确匹配★★★★★★★
HAL继承各 Benchmark继承★★★★(统一成本追踪)

关键洞察:

  • 测试套件(SWE-bench/OpenHands/Agentless)是最客观的评分方式,但只适用于有明确测试的代码场景
  • 数据库状态验证(AppWorld)是 API 场景的最佳折衷——不绑定具体调用路径,只检查最终结果,且检测附带损害
  • 性能指标改进(MLAgentBench)适合实验类任务——不关心过程,只看结果提升幅度
  • LLM-as-Judge(APEX、DevBench 设计阶段)灵活性最高,但引入了评判模型自身的偏差
  • 精确匹配(GAIA)最简单,但无法区分”差一点”和”完全跑偏”
  • 多维混合评估(DevBench 的 5 阶段各用不同方式)是全生命周期评估的必然选择

3.4 可扩展性对比

框架新增任务新增 Agent新增工具
SWE-bench需构建 Docker 镜像需实现 patch 生成接口修改 ACI 配置
OpenHands继承 Benchmark 要求实现 function calling 接口标准工具定义(ChatCompletionToolParam)
Agentless继承 SWE-bench 镜像修改流水线脚本N/A(无工具概念)
BrowserGym继承 AbstractBrowserTask标准 Gym 接口浏览器内置
OSWorld编写评估脚本 + VM 快照实现 obs→action 函数PyAutoGUI 内置
APEX编写 World + Rubric注册到 Agent RegistryMCP Server 热插拔
AppWorld扩展 App Engine(新 App/API)标准 Python 代码接口新增 API endpoint
τ-Bench定义 Domain(Policy+Tools+Tasks)实现 function calling定义新工具函数
MLAgentBench编写 starter code + 评估器实现 12 种动作接口扩展动作枚举
DevBench编写 PRD + 参考实现 + 测试标准代码生成接口N/A
HAL编写 Benchmark 模块run(task_id) 一个函数视 Benchmark 而定

APEX 的 MCP 热插拔、HAL 的零约束 Agent 接口、OpenHands 的标准 function calling 是扩展性最好的三个设计。DevBench 的新增任务成本最高——需要完整的 PRD + 参考实现 + 多语言测试套件。


四、核心发现与设计建议

4.1 三个核心发现

发现一:Harness 是性能的绑定约束(Binding Constraint)

Agent Harness Survey 论文的核心论点,多个独立研究验证:

案例仅改变 Harness性能变化
xAI Grok(SWE-bench)编辑工具格式6.7% → 68.3%(~10×)
LangChain DeepAgents系统提示+上下文注入52.8% → 66.5%(+26%)
Vercel移除 80% 工具超过任何模型升级
Meta-Harness自动化 harness 搜索达 76.4%(超手工 74.7%)

发现二:动作空间粒度决定训练迁移性

  • 低层动作(PyAutoGUI)学到的是”点像素坐标”——换个屏幕分辨率就失效
  • 中层动作(ACI)学到的是”编辑第 42 行”——跨项目可迁移
  • 高层动作(function calling)学到的是”调用退款 API”——跨领域不可迁移

SWE-agent 的 ACI 之所以效果好,正是因为找到了最佳抽象粒度:比 bash 高一层,比 API 调用低一层。

发现三:统一 Harness 层是可行且必要的

HAL 证明了一个”meta-harness”可以统一 12+ 个 Benchmark 的评估流程,同时保持零侵入。这意味着:

  • Agent 开发者只需实现一次 run(task_id) 接口
  • Benchmark 维护者只需实现评分逻辑
  • 成本追踪和可观测性在 Harness 层统一解决

发现四:Agent 交互不是唯一路径

Agentless 的三阶段线性流水线以 ~$0.34/issue 的成本达到了 SWE-bench Verified 50.8% 的解决率——与许多 Agent 方案可比。DevBench 的 5 阶段流水线同样不依赖 Agent 循环。这说明:

  • Harness 复杂度需要合理性论证:如果线性流水线就能解决一半问题,Agent 循环需要证明额外复杂度换来了什么
  • “定位-修复-验证”的分治思想比”让 Agent 自己想办法”更可控、更可解释
  • 但 Agent 循环在需要多步探索、环境反馈驱动决策的场景(如 OSWorld、BrowserGym)仍不可替代

发现五:任务场景决定了 Harness 的必要复杂度

13 个框架覆盖的场景从”纯 LLM 生成”(Agentless)到”完整虚拟机交互”(OSWorld)——复杂度跨越 3 个数量级。关键规律:

任务特征需要的 Harness 复杂度代表框架
有明确输入→输出映射极低(流水线即可)Agentless、DevBench
需要环境反馈但环境可模拟中(进程内仿真)τ-Bench、AppWorld、MLAgentBench
需要与真实环境交互高(容器/VM 隔离)SWE-bench、OSWorld、BrowserGym
需要跨应用/跨工具协作高(MCP/多 Worker)APEX、AgentBench

4.2 Agent 评估体系设计建议

建议一:分层评估,不要追求一个 Benchmark 覆盖所有能力

评估层推荐 Benchmark测的是什么
代码修复SWE-bench Verified真实 Issue 修复
代码修复(基线)Agentless非 Agent 基线,成本对照
从零开发DevBench全生命周期软件工程
Web 操作WebArena / VisualWebArena网页导航与信息处理
桌面操作OSWorld多应用协作
对话工具τ-Bench策略合规 + 多轮对话
多应用 APIAppWorld跨 App 数据协作
科研实验MLAgentBench实验设计与迭代改进
通用推理GAIA多步推理 + 工具组合
专业服务APEX-Agents长周期知识工作

建议二:投资 Harness 工程,而非只投资模型能力

  • 优先优化 ACI(动作空间)设计——实验表明回报率远超模型升级
  • 统一使用 HAL 等标准化框架,确保结果可对比
  • 集成成本追踪——“准确率高 1% 但贵 10 倍”是伪进步

建议三:设计自定义 Benchmark 时的框架选型

场景特征推荐参考理由
有明确测试套件SWE-bench harness测试驱动评估最客观
需要非 Agent 基线Agentless成本极低,验证 Agent 必要性
Web/浏览器场景BrowserGymGymnasium 标准接口 + 真实浏览器
需要多种外部工具Archipelago(MCP 热插拔)动作空间动态可配置
多 App API 协作AppWorld Engine数据库状态验证 + 附带损害检测
多轮对话 + 策略合规τ-Bench用户模拟器 + 双重控制
科研实验迭代MLAgentBench12 种动作 + 性能指标评估
全生命周期开发DevBench5 阶段独立评估 + 多语言
跨多个场景对比HAL统一评估层 + 成本追踪

建议四:评分机制选择矩阵

任务类型推荐评分方式避免
有正确答案的精确匹配 / 测试套件LLM-as-Judge(没必要)
开放性输出的LLM-as-Judge + Rubric纯精确匹配(覆盖不了)
有状态变更的Before/After 快照 diff只看最终答案(遗漏副作用)
安全相关的正向+负向双维度评判只有正向评分(忽略有害行为)

五、总结:执行框架设计的五条铁律

  1. 隔离是底线——至少 Docker 级别,否则评估不可复现
  2. 动作空间要为 Agent 设计,不是为人设计——SWE-agent 的 ACI 和 OpenHands 的 CodeAct 是两条经过验证的路线
  3. 评分必须包含负向维度——Agent 能做对事很重要,不搞破坏同样重要(AppWorld 的附带损害检测、APEX 的 negative_grade)
  4. 成本必须纳入评估——没有成本追踪的 Benchmark 结果只说了一半的故事
  5. 必须设立非 Agent 基线——Agentless 证明了线性流水线能解决相当比例的问题,Agent Harness 的额外复杂度需要用超越基线的性能来证明

参考资料