1. 为什么同一模型换个 Harness 分数能差 27 个百分点
如果你最近在看 SWE-bench 排行榜,可能会发现一个奇怪现象:同一个模型,A 团队报 73%,B 团队报 46%,两边都声称自己用的是标准评测流程。问题不在模型,而在 Harness。
Harness 这个词在 Agent 评测语境里,指的是包裹在模型外面的那一整套脚手架:Agent 循环怎么转、工具接口长什么样、工作区怎么隔离、什么时候判定任务结束、超时和重试策略怎么设。模型只负责生成 token,Harness 决定这些 token 怎么变成可执行的代码修改、怎么被评分管线接受。
我试过用同一套 SWE-bench 题目跑两个不同的 Agent 框架,底层模型完全一样,resolved rate 差了将近 20 个百分点。后来拆开看日志才发现,差距主要来自三个地方:一是 patch 提取逻辑,有的框架会把会话文件、缓存目录一起塞进 git diff,评分器直接判 apply 失败;二是停止策略,有的框架在模型说"我改完了"就停,有的会再跑一轮测试确认;三是工具接口设计,文件读写是原子操作还是批量提交,直接影响模型能不能正确理解当前仓库状态。
这就是为什么 Claw-SWE-Bench 这类基准要把模型轴和 Harness 轴拆开做交叉实验。固定题库、固定提示词、固定运行预算、固定评分流程,只让 Harness 和模型各自变,才能看清每个变量到底贡献了多少分。
对做评测的人来说,这意味着两件事:第一,横向比较分数之前必须确认 Harness 版本;第二,如果你想复现别人的结果,光有模型和题目不够,还得把 Harness 配置一起复现。下面我就用 TaoToken 搭一套可复现的评测通道,把 config.toml 和 settings.json 的骨架给出来,让你能自己跑通基准、对比不同 Harness 的结果。
2. TaoToken 在评测链路里的位置:统一 Key 和 API 通道
做 Agent 评测最烦的事情之一,是每换一个模型就要改一遍 API 配置。SWE-bench 的评测脚本通常要调多个模型做对比,如果每个模型走不同的 endpoint、不同的 key 管理方式,光是环境变量就能把人搞疯。
TaoToken 在这里的角色是统一入口。它提供兼容 OpenAI 风格的 API 通道,你可以用同一个 key 访问多个模型,评测脚本里只需要改 model 字段,不用动 base_url 和认证逻辑。官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。
具体到 SWE-bench Agent 评测,TaoToken 解决的是这几个问题:
第一,Key 统一管理。评测环境里通常要跑多个 Harness × 多个模型的组合,如果每个组合都配一套 key,很容易出现某个 key 额度用完导致整组实验失败。用 TaoToken 的 API Keys 页面可以集中管理,跑之前先确认额度。
第二,通道统一。不同 Harness 对 API 的调用方式不一样,有的用 OpenAI SDK,有的用 Anthropic SDK,有的直接发 HTTP 请求。TaoToken 的兼容层让这些调用都能落到同一个 base_url 上,减少适配器层面的变量。
第三,成本可追踪。前面提到 Harness 维度的成本差异能到两个数量级,很大一部分来自缓存命中率。统一通道之后,你可以在一个地方看到每个组合的 token 消耗和缓存情况,方便做成本诊断。
需要先拿 Key 的话,去 https://taotoken.net/api-keys 创建,然后按下面的配置骨架接入评测工具。
3. 可复制的 config.toml 与 settings.json 配置骨架
SWE-bench 评测工具链里,常见的配置入口有两个:一个是 Harness 自身的 config.toml,用来定义 Agent 循环、工具集、超时策略;另一个是评测编排层的 settings.json,用来定义模型列表、API 通道、任务集路径。
下面这套骨架是我实测下来比较通用的结构,你可以直接复制改。
3.1 config.toml:Harness 侧配置
# config.toml - Harness 运行配置骨架 [agent] name = "swe-agent" max_iterations = 30 timeout_seconds = 600 stop_on_test_pass = true workspace_root = "/testbed" [agent.tools] file_read = true file_write = true shell_exec = true git_diff = true [agent.patch] extract_mode = "git_diff" exclude_patterns = [ "*.log", ".cache/**", "session_*.json", "__pycache__/**" ] apply_check = true [llm] provider = "openai_compatible" base_url = "https://taotoken.net/api" api_key_env = "TAOTOKEN_API_KEY" model = "gpt-5.5" temperature = 0.0 max_tokens = 8192 [llm.retry] max_retries = 3 backoff_seconds = 2 [evaluation] dataset = "claw-swe-bench-lite" task_count = 80 languages = ["python", "java", "go", "rust", "javascript", "typescript", "c", "cpp", "ruby", "php"]几个关键点说明。exclude_patterns是防止 patch 污染的核心,Harness 运行过程中产生的会话文件、缓存目录必须排除,否则 git diff 里会混入非解决方案内容,评分器直接判 apply 失败。stop_on_test_pass控制停止策略,设成 true 表示测试通过就停,设成 false 会继续跑到 max_iterations,两种策略对最终分数影响很大,做 Harness 对比实验时这个字段必须固定。
base_url指向 TaoToken 的 API 入口,api_key_env指定从环境变量读取 key,不要把 key 硬编码进配置文件。
3.2 settings.json:评测编排侧配置
{ "api_channel": { "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "timeout_seconds": 120 }, "models": [ { "name": "gpt-5.5", "model_id": "gpt-5.5", "max_tokens": 8192 }, { "name": "claude-opus-4.7", "model_id": "claude-opus-4.7", "max_tokens": 8192 }, { "name": "deepseek-v4-flash", "model_id": "deepseek-v4-flash", "max_tokens": 8192 } ], "harnesses": [ { "name": "openclaw", "config_path": "./harnesses/openclaw/config.toml" }, { "name": "nanobot", "config_path": "./harnesses/nanobot/config.toml" } ], "dataset": { "name": "claw-swe-bench-lite", "path": "./datasets/claw-swe-bench-lite", "task_count": 80 }, "output": { "result_dir": "./results", "save_patch": true, "save_logs": true } }这个 settings.json 定义的是实验矩阵:models 列表 × harnesses 列表,编排器会为每个组合生成一次运行。api_channel统一指向 TaoToken,所有模型走同一个通道。dataset指向 Lite 版本,80 题,适合调试阶段反复跑。
如果你要跑全量 350 题,把task_count改成 350,dataset.name改成全量数据集路径就行。但建议先用 Lite 把适配器和配置调通,再上全量。
3.3 环境变量设置
export TAOTOKEN_API_KEY="你的key" export SWE_BENCH_WORKSPACE="/tmp/swe-bench-workspace" export DOCKER_HOST="unix:///var/run/docker.sock"环境变量在运行评测脚本之前设置好,Harness 和编排器都从这里读 key。
4. 跑通基准:从单题验证到 Lite 全量
配置写完之后,不要一上来就跑 80 题。先用单题验证链路通不通,再逐步放大。
4.1 单题冒烟测试
python -m swe_bench.run \ --config ./settings.json \ --harness openclaw \ --model gpt-5.5 \ --task-id python__django__12345 \ --dry-run false这一步会拉起 Docker 容器,把仓库 checkout 到基准提交,让 Harness 跑一轮 Agent 循环,最后提取 patch 并尝试 apply。如果 apply 成功,说明 patch 提取逻辑没问题;如果失败,去看results/目录下的日志,重点检查 git diff 里有没有混入非解决方案文件。
4.2 Lite 全量运行
单题通过之后,跑 Lite 的 80 题:
python -m swe_bench.run \ --config ./settings.json \ --harness openclaw \ --model gpt-5.5 \ --dataset claw-swe-bench-lite \ --parallel 4--parallel 4表示同时跑 4 个任务,具体并发数看你机器的 Docker 资源。跑完之后结果会写到results/openclaw_gpt-5.5_lite.json,里面包含每题的 resolved 状态、token 消耗、缓存命中率、挂钟时间。
4.3 对比不同 Harness
要对比 Harness 的影响,固定模型,换 harness 参数再跑一次:
python -m swe_bench.run \ --config ./settings.json \ --harness nanobot \ --model gpt-5.5 \ --dataset claw-swe-bench-lite \ --parallel 4两次结果都出来之后,用编排器自带的对比脚本:
python -m swe_bench.compare \ --results ./results/openclaw_gpt-5.5_lite.json \ --results ./results/nanobot_gpt-5.5_lite.json \ --output ./results/compare_harness.json对比报告会给出两个 Harness 在同一模型下的 Pass@1 差异、平均 token 消耗差异、缓存命中率差异。如果差异超过 5 个百分点,基本可以确认 Harness 设计对结果有实质性影响。
5. 本篇常见错排查
跑评测的过程中,下面这几个错误出现频率最高。
patch apply 失败率偏高。最常见的原因是exclude_patterns没配全。Harness 运行时会生成会话文件、日志、缓存,这些如果进了 git diff,评分器 apply 的时候就会冲突。检查方法:跑完单题之后,手动看一下提取出来的 patch 文件,确认里面只有源码修改。另外apply_check = true要打开,让 Harness 在提交前先自己试一次 apply。
模型返回空响应或超时。先确认TAOTOKEN_API_KEY环境变量有没有正确设置,然后检查base_url是不是https://taotoken.net/api。如果 key 没问题但还是超时,把timeout_seconds从 120 调到 300 试试,有些复杂题目的推理链比较长。还不行的话,去 API Keys 页面确认一下额度。
不同 Harness 的缓存命中率差异大。这个不一定是 bug,可能是适配器行为不同导致的。有的 Harness 会把完整对话历史每轮都发一遍,缓存命中率就高;有的只发增量,缓存命中率就低。做成本对比的时候要把这个因素考虑进去,不能只看 token 单价。
Lite 和全量结果偏差超过 5 个百分点。正常情况下 Lite 和全量的平均差异在 2 个百分点以内。如果偏差过大,检查一下 Lite 的题目集有没有被意外修改,或者 Harness 配置在两次运行之间有没有变动。做对比实验的时候,除了要对比的变量,其他配置必须完全一致。
Docker 容器启动失败。确认 Docker daemon 在运行,DOCKER_HOST环境变量指向正确的 socket。SWE-bench 的评测镜像比较大,第一次拉取会花一些时间,确保磁盘空间充足。
6. 把评测通道固定下来,再谈分数对比
跑完上面这套流程,你应该能得到一组可复现的结果:固定题库、固定提示词、固定预算、固定评分流程,只让 Harness 和模型各自变。这时候再看分数,就能分清哪些差距来自模型能力,哪些来自 Harness 设计。
如果你要长期做 Agent 评测或者编码 Agent 的选型对比,建议把 TaoToken 的 API 通道固定下来,用同一套 key 和 base_url 跑所有组合。模型对话功能可以在 https://taotoken.net/models 直接试,快速验证某个模型在你的任务集上表现如何。需要长期跑编码 Agent 评测或者搭自动化回归流水线的话,Coding Plan 页面 https://taotoken.net/coding-plan 有更详细的额度方案。接入文档在 https://taotoken.net/doc ,里面有完整的 API 参数说明和错误码对照。
评测这件事,最怕的就是变量没控住。Harness 是那个最容易被忽略、但影响最大的变量。把它固定住,分数才有比较的意义。