Agent 评测环境:Terminal-Bench、Harbor 与 Sandbox

Jul 2026 · Agent Eval / Terminal-Bench / Harbor / Sandbox

一个 coding / terminal agent 写完了,怎么知道它到底行不行?你需要一套能把 agent 真的塞进一个真实终端里跑起来、跑完再自动判分 的环境。这篇把这套东西拆成三层讲清楚:benchmark(任务从哪来)、harness(谁来跑、怎么接 agent)、sandbox(在哪跑、怎么隔离),并落到 Terminal-Bench、Harbor 和主流 sandbox 的具体用法。

一句话:评测一个 agent = benchmark(任务集) + harness(运行器 / adapter) + sandbox(隔离容器)。Terminal-Bench 提供任务,Harbor 是跑任务的框架,sandbox 是任务实际执行的隔离环境。三者可以自由组合。

0. 先建立三层心智模型

Agent 评测和传统 benchmark(跑一个 forward、比对 label)最大的区别是:任务是开放式、需要真实执行的——agent 要在 shell 里敲命令、改文件、编译、训练,最后由测试脚本检查容器的最终状态(outcome-driven),而不是比对某条命令轨迹。

负责什么 代表 类比
Benchmark 定义任务:指令、初始环境、判分测试、参考解 Terminal-Bench、SWE-bench 「考卷 + 标准答案」
Harness 起环境、把 agent 接进去、跑、收集轨迹、判分 Harbor、tb CLI 「监考 + 阅卷流水线」
Sandbox 真正执行 agent 命令的隔离环境 Docker、E2B、Modal、Daytona 「考场」

下面从中间的 benchmark 说起,再到 harness,最后是 sandbox。

1. Terminal-Bench:任务集

是什么。 Terminal-Bench(简称 T-Bench / TB)是一个 “benchmark for testing AI agents in real terminal environments”——从编译代码、训练模型到配服务器,评测 agent 端到端自主完成真实命令行任务的能力。它由 Stanford × Laude Institute 合作出品(Laude Institute 是 Andy Konwinski 联合创立的非营利),论文见 arXiv:2601.11868(Merrill、Shaw 等,作者上百人,含 Carlini、Muennighoff、Schmidt 等)。

它由两部分组成:一个任务数据集 + 一个把 LLM 接到终端 sandbox 的 execution harness

任务长什么样。 都是「给你一个真实 shell,做完产生一个可验证的最终状态」的任务,比如:

难度跨度很大:论文里约 48.6% 的任务专家能在 1 小时内做完,约 47.3% 要 1–24 小时,最难的接近 10 天。每个 2.0 任务都经过数小时的人工 + LM 辅助三轮 review,确保「可解、真实、描述清楚」。

版本与任务数(引用时务必说清是哪个版本):

版本 任务数 说明
1.0 / core 启动时 80(terminal-bench-core v0.1.0),legacy repo 现已累积 241 个社区任务 老 leaderboard 用 terminal-bench-core v0.1.1
2.0 89 覆盖软件工程 / ML / 安全 / 数据科学,用 Harbor 任务格式
2.1 进行中 「受 Z.ai 工作启发的改进版」
3.0 / Science 进行中 面向科学计算

任务的解剖结构(2.0 / Harbor 格式)

一个任务就是一个目录,长这样:

crack-7z-hash/
├── task.toml              # 配置 + 元数据(分节)
├── instruction.md         # 给 agent 的自然语言指令(单独成文件)
├── environment/
│   ├── Dockerfile         # 或 docker_image 引用 / docker-compose.yaml
│   └── task-deps/…        # 任务资产
├── solution/
│   └── solve.sh           # oracle 参考解(可多文件依赖)
└── tests/
    ├── test.sh            # 把 reward 写进 /logs/verifier/reward.txt
    └── test_outputs.py    # pytest 断言,检查容器最终状态

task.toml 真实样子(节选):

schema_version = "1.1"
[task]
name = "terminal-bench/crack-7z-hash"
description = "Evaluates the ability to crack a password-protected 7z archive..."
[metadata]
difficulty = "medium"
category = "security"
expert_time_estimate_min = 5.0
[verifier]
timeout_sec = 900.0
[agent]
timeout_sec = 1800.0
[environment]
docker_image = "alexgshaw/crack-7z-hash:20251031"
cpus = 1
memory_mb = 4096
gpus = 0
allow_internet = true

判分不再靠一个中心 parser,而是任务自己产出 rewardtests/test.sh 跑 pytest,成功就 echo 1 > /logs/verifier/reward.txt。这一步是关键的解耦——任何第三方 benchmark 只要会往那个文件写 0/1,就能挂进来。

顺带说,1.0 的老格式用的是 task.yaml + run-tests.sh + solution.sh,2.0 迁移成了 task.toml + instruction.md + solution/solve.sh + tests/test.sh。两种格式并存,别混。

端到端执行流程

  1. 准备环境:从 environment.docker_image 拉镜像,或用 Dockerfile 现 build(本地,或在 Daytona / Modal 这类云 sandbox 上并发 build)。
  2. 起容器:按 task.toml 的 cpus / memory / storage / gpus 和 allow_internet 施加资源与网络限制。
  3. 装 agent、跑任务:把 agent 装进容器,喂 instruction.md,它通过 bash / 文件工具迭代探索,受 [agent].timeout_sec 约束。
  4. 跑 verifier:agent 结束后,tests/test.sh 针对最终容器状态跑断言(outcome-driven,不看命令轨迹)。
  5. 判分:reward 写进 /logs/verifier/reward.txt,harness 汇总通过率并落轨迹 / 日志。特殊的 oracle agent 会直接跑 solve.sh,用来 sanity-check「这个任务确实可解」。

Leaderboard(mid-2026 快照,发表前请复核)

论文发布时(TB 2.0)「frontier models and agents resolve less than 65% of tasks」:

组合 分数
GPT-5.2 + Codex CLI 62.9%
Claude Opus 4.5 + Terminus 2 57.8%
Gemini 3 Pro + Terminus 2 56.9%

而 tbench.ai 上的 live board 随着新模型 / 新 harness 提交已经爬到 ~84%(GPT-5.5 系居多,Opus 4.7、Gemini 3.1 Pro 紧随)。这些是 mid-2026 的快照数字,会持续变化,引用前请到 live 页面复核。

2. Harbor:跑任务的框架

是什么。 Harbor 是 “a framework from the creators of Terminal-Bench for evaluating and optimizing agents and language models”——同一个 Stanford × Laude 团队把原来的 TB harness 从头重写了一遍,为的是可靠性、可观测性、可扩展性。它就是 Terminal-Bench 2.0 的官方 harness。 repo 在 harbor-framework org(和 laude-institute 互为镜像),站点 harborframework.com。

它的核心思想是把三样东西彻底解耦task(指令 + sandbox 镜像 + verifier)、agent(工具面 + loop)、sandboxdocker / e2b / daytona / gke…),从而可以自由组合——同一套任务用任意 agent 在任意 sandbox 上跑。

装 + 跑

uv tool install harbor        # 或 pip install harbor

# 先用 oracle(参考解)跑一遍,验证 Docker 环境没问题
uv run harbor run --dataset [email protected] --agent oracle --n-concurrent 4

# 用 Claude Code 跑 TB 2.0
export ANTHROPIC_API_KEY=<YOUR-KEY>
harbor run --dataset [email protected] \
   --agent claude-code \
   --model anthropic/claude-opus-4-1 \
   --n-concurrent 4

想上规模,加 --env 换到云 sandbox provider,并发直接拉到几十上百:

export DAYTONA_API_KEY=<YOUR-KEY>
harbor run -d [email protected] -a claude-code \
   -m anthropic/claude-opus-4-1 --n-concurrent 100 --env daytona

其它常用命令:

harbor init --task "<org>/<name>"                 # 脚手架一个新任务
harbor run -d [email protected] -a claude-code --include-task-name "<task>"   # 只跑单个任务
harbor run -d [email protected] --agent-import-path "path.to.agent:MyAgent"   # 挂自定义 agent
harbor datasets list                              # 列出第三方 benchmark(SWE-Bench、Aider Polyglot…)
harbor traces export <job-path>                   # 导出轨迹 / rollout

Agent / adapter 接口

开箱支持一堆真 agent:oraclenopterminus-2(TB 自带的参考 agent),加上一大排 installed agent——claude-codecodexgemini_cliaideropenhandsmini_swe_agentgoosecursor_cliopencode 等。

接自己的 agent 就实现两个基类之一:

官方给的例子就是 Claude Code adapter——ClaudeCode 类设了 SUPPORTS_ATIF = True、一个安装检查命令,以及 --max-turns / --permission-mode / --allowedTools 等 flag。

别混:Terminal-Bench vs Harbor

顺带一提 Harbor 还是一等公民地支持 RL 训练:官方接了 HuggingFace TRL(trl.experimental.harbor),用 HarborSpec 把任务集接进 GRPOTrainer--env e2b 时只有 environment.exec 跨进云 sandbox,从而大批并发 rollout。

3. Sandbox:隔离层

为什么一定要 sandbox

agent 评测跑的是模型自己生成的、不可信的 shell 命令,所以有四个硬需求:

  1. 隔离:agent 输出天然不可信,一个内核漏洞 / 配置错误就可能容器逃逸拿到宿主。sandbox 把一次 rollout 关起来,坏 agent 碰不到 harness 或别的任务。
  2. 可复现:镜像不 pin 死,分数就没法跨时间 / 跨机器比较。SWE-bench、Terminal-Bench 都为此把依赖冻进 Docker 镜像。
  3. 安全:agent 拿着真凭证、真网络,出网就是数据外泄风险,最佳实践是默认 deny 出网 + egress 过滤。容器是这套网络策略的落点。
  4. 并发:benchmark 动辄上千实例(SWE-bench full ≈ 2,300),要靠 --n-concurrent / --max_workers 大规模 fan-out。容器共享内核和镜像层,一台机器上并存几百个很便宜。

Docker:默认基线

绝大多数 benchmark 的 sandbox 就是 per-task Docker 镜像

云 / microVM sandbox providers

规模一大,本地 Docker 就不够了,于是有一批 provider(很多正是 Harbor --env 的后端)。按隔离边界从强到弱:Firecracker microVM → gVisor → 普通 Docker 容器

Provider 隔离原语 卖点
E2B Firecracker microVM 跑 LLM 生成代码 / code-interpreter,启动 <200ms,可暂停/恢复(存盘 + 内存)
Modal gVisor(runsc Sandbox 跑不可信代码,秒级启动
Daytona OCI / Docker 容器 「sub 90ms 创建」,可选 VM / GPU 档
Fly Machines Firecracker microVM 亚秒起停、REST API 单独寻址,适合临时 agent sandbox
Morph / Infinibranch 自研全 VM 栈 snapshot + branch 整个环境 <250ms(「Git for compute」)
Runloop micro-VM(VM+容器) 专为评测 coding agent 的 devbox,万级并发

外加 Harbor 文档提到的 Blaxel、Novita Sandbox,以及跑在 Kubernetes 上的 GKE。

取舍:Docker vs gVisor vs microVM vs 全 VM

维度 Docker gVisor Firecracker microVM 全 VM
隔离机制 namespaces + cgroups + seccomp,共享宿主内核 用户态 Go「应用内核」(Sentry)拦截 syscall KVM 给每个 VM 独立 guest 内核 独立内核 + 完整虚拟硬件
隔离强度 最弱(内核漏洞可逃逸) 中(比容器强、比 VM 弱) 强(要同时攻破 guest 内核和 hypervisor) 最强
启动延迟 最快(ms~数秒) 接近容器 + 少量开销 低至 ~125ms 最慢(秒~数十秒)
密度 / 成本 最高 / 最便宜 高 / 低 很高(每 microVM <5MiB 内存开销) 最低 / 最贵
快照 镜像层 + docker commit(有限) Sentry checkpoint 一等公民:序列化内存 + vCPU + 设备状态,copy-on-write 恢复 成熟但重

怎么选:benchmark 之所以标配 Docker,是因为它便宜、密度高、够快、可复现——代码虽不可信,但整个 loop 跑在你自己可丢弃的机器上,操作者掌控全局。而 gVisor / Firecracker 是面向「多租户 / 生产托管」的升级——那里一次容器逃逸就是灾难(Firecracker 正是 AWS Lambda / Fargate 用来大规模跑不可信客户代码的东西)。代价是 gVisor 的每 syscall 开销更高、少数应用兼容性下降。

几个容易过时 / 说错的点:gVisor 现在默认平台是 systrap(seccomp SIGSYS),早年的 ptrace 已弃用——别再说「gVisor 靠 ptrace」;Morph 是自研全 VM 栈,没有官方来源说它基于 Firecracker;Daytona 是否用 Kata / Sysbox 加固官方未确认。Harbor 的 star / 版本(~2.9k、v0.16.1)是抓取时的数字,引用请复核。

跑一个最小例子

在 E2B 里跑一段模型生成的(不可信)代码:

from e2b_code_interpreter import Sandbox

with Sandbox() as sandbox:
    execution = sandbox.run_code("x = 1; x += 1; x")   # 模型产出的代码
    print(execution.text)   # 2

Terminal-Bench 每任务起的容器(docker-compose.yaml 节选)就是让容器 sleep infinity 挂着,好让 harness 挂 tmux、注入 /tests

services:
  client:
    build: { dockerfile: Dockerfile }
    command: [ "sh", "-c", "sleep infinity" ]
    environment: [ TEST_DIR=${T_BENCH_TEST_DIR} ]

SWE-bench 判分则是一条命令把 docker pull → docker run → 打 patch → 跑测试 全干了:

python -m swebench.harness.run_evaluation \
    --dataset_name princeton-nlp/SWE-bench_Lite \
    --predictions_path <preds> --max_workers <n> --run_id <id>

4. 串起来:最小工作流

把三层拼一起,评一个 coding agent 大概就这四步:

uv tool install harbor                                       # 1. 装 harness
harbor run -d [email protected] -a oracle -n 4              # 2. oracle 冒烟,验证 sandbox
harbor run -d [email protected] -a claude-code \            # 3. 跑你的 agent
   -m anthropic/claude-opus-4-1 -n 4
harbor run -d [email protected] -a claude-code \            # 4. 上云 sandbox 拉并发
   -m anthropic/claude-opus-4-1 -n 100 --env daytona

要加自己的任务harbor init --task,按 task.toml + instruction.md + environment/ + tests/ + solution/ 的结构填,测试往 /logs/verifier/reward.txt 写 0/1;要加自己的 agent 就 subclass BaseInstalledAgent(照 Claude Code adapter 抄),或 --agent-import-path 直接挂。benchmark、harness、sandbox 三层各管一段,替换任意一层都不影响另外两层——这就是这套设计的价值。

参考 · Terminal-Bench:tbench.ai · leaderboard · 论文 arXiv:2601.11868 · github/laude-institute · Harbor:harborframework.com · docs · github/harbor-framework · TRL 集成 · Sandbox:SWE-bench · E2B · Modal · Daytona · Fly · gVisor · Firecracker · Morph