mini-swe-agent 实战指南:在 SWE-bench 基准上批量运行与单实例调试
mini-swe-agent 实战指南:在 SWE-bench 基准上批量运行与单实例调试
导读
本指南以 mini-swe-agent 仓库提供的两个官方脚本(swebench 批量模式与 swebench-single 单实例调试模式)为核心,完整讲解如何加载 SWE-bench 数据集、选择子集与切片、并行运行 Agent、收集 preds.json 预测结果,并通过云端 sb-cli 或本地 SWE-bench harness 完成评估。读完本文,你将掌握一套可复制、可扩展的 SWE-bench 评测流水线,并理解其底层实现原理(镜像选择、实例筛选、断点续跑、进度报告与异常处理)。
背景:两个脚本的分工
mini-swe-agent 针对 SWE-bench 基准提供了两个入口脚本,二者互补:
mini-extra swebench(批量模式):自动遍历所有任务实例(task instance),以多线程并行方式运行 Agent,产出可供评估的preds.json文件,适合正式跑分与批量实验。mini-extra swebench-single(单实例模式):在单个任务实例上以交互方式运行,便于调试提示词、观察 Agent 行为;由于带有交互性,它不会生成preds.json文件。
两个脚本都位于 src/minisweagent/run/benchmarks/ 目录下,其中 swebench_single.py 通过复用 swebench.py 中的 DATASET_MAPPING 与 get_sb_environment 等公共函数来保持行为一致。如果你要构建自己的批量处理流水线,直接阅读这两个脚本的源码是最佳起点。
快速开始:批量模式(swebench)
查看帮助与最小示例
mini-extra swebench --help
# 等价于直接调用 Python 模块:
python src/minisweagent/run/benchmarks/swebench.py --help
一个典型的最小批量运行命令如下(以 verified 子集、test 分片为例):
mini-extra swebench \
--model anthropic/claude-sonnet-4-5-20250929 \
--subset verified \
--split test \
--workers 4
⚠️ 架构注意:SWE-bench 的 Docker 容器面向 x86 Linux 架构构建,在其他 CPU 架构上可能无法运行。运行前请确认你的宿主机满足该前提。
批量模式参数全解
| 分组 | 参数 | 说明 | 默认值 |
|---|---|---|---|
| 基础 | -o, --output |
输出目录(存放 preds.json、轨迹与日志) |
空(当前目录) |
| 基础 | -m, --model |
使用的模型名称 | 由配置决定 |
| 基础 | -c, --config |
配置文件路径;一旦指定,默认配置文件不再生效,需显式带上 swebench.yaml |
config 目录下的 swebench.yaml |
| 基础 | -w, --workers |
并行工作线程数 | 1 |
| 数据选择 | --subset |
SWE-bench 子集名或自定义数据集路径 | lite |
| 数据选择 | --split |
数据集分片 | dev |
| 数据选择 | --slice |
切片规格,如 '0:5' 表示只取前 5 个实例 |
空(不切片) |
| 数据选择 | --filter |
按正则表达式过滤实例 ID | 空(不过滤) |
| 数据选择 | --shuffle |
是否打乱实例顺序 | False |
| 数据选择 | --redo-existing |
是否重新运行已有结果的实例 | False |
| 高级 | --environment-class |
环境类型(推荐 docker 或 singularity) |
docker |
| 高级 | --model-class |
模型类(如 'anthropic' 或完整导入路径) |
由配置决定 |
-c 的合并语义
-c 接受一个列表,多个配置会被递归合并(对应源码 swebench.py 中的 recursive_merge)。但注意:一旦你使用了 -c,内置默认配置就不会被加载,因此常用写法是先显式指定基准配置文件,再叠加自己的覆盖项:
mini-extra swebench \
-c swebench.yaml \
-c model.model_kwargs.temperature=0.5 \
-c agent.step_limit=100
命令行传入的 -m/--model、--environment-class 等选项最终也会作为一份配置参与合并,因此优先级语义一致。
内置子集与数据集映射
源码 swebench.py 中的 DATASET_MAPPING 定义了可直接使用的子集名:
| 子集名 | 对应 Hugging Face 数据集 |
|---|---|
full |
princeton-nlp/SWE-Bench |
verified |
princeton-nlp/SWE-Bench_Verified |
lite |
princeton-nlp/SWE-Bench_Lite |
multimodal |
princeton-nlp/SWE-Bench_Multimodal |
multilingual |
swe-bench/SWE-Bench_Multilingual |
smith |
SWE-bench/SWE-smith |
_test |
klieret/swe-bench-dummy-test-dataset(用于测试) |
rebench |
nebius/SWE-rebench |
凡不在映射表中的值都会被直接当作数据集路径或名称传给 datasets.load_dataset(dataset_path, split=split)(见 swebench.py),这正好对应 FAQ 中"如何运行自定义数据集"的机制。
实例筛选、切片与打乱
批量脚本在加载数据集后,会调用 filter_instances 完成三步预处理,顺序为:打乱 → 正则过滤 → 切片:
- 打乱使用固定随机种子
42(保证可复现),源码为random.seed(42); --filter用re.match匹配instance_id,例如--filter 'django__.*'只保留 Django 相关实例;--slice支持完整的 Python 切片语法(0:5、3:、:2),作用于过滤后的列表。
测试用例 tests/run/test_swebench.py 覆盖了 filter 与 slice 的各种组合,包括"先过滤后切片"的执行顺序以及打乱的确定性。
断点续跑与重跑
脚本具备天然的"断点续跑"能力:
- 默认(
--redo-existing False)下,若输出目录中已存在preds.json,脚本会读取其中已记录的实例 ID 并跳过(见 swebench.py); - 若你想强制重跑,加
--redo-existing即可。
对应测试见 tests/run/test_swebench.py(test_redo_existing_false_skips_existing 与 test_redo_existing_true_overwrites_existing)。
单实例模式:面向调试(swebench-single)
mini-extra swebench-single --help
# 等价于:
python src/minisweagent/run/benchmarks/swebench_single.py --help
按实例 ID 运行单个任务:
mini-extra swebench-single \
--subset verified \
--split test \
--model anthropic/claude-sonnet-4-5-20250929 \
-i sympy__sympy-15599
也可以按索引运行(例如第 0 个实例):
mini-extra swebench-single \
--subset verified \
--split test \
-m anthropic/claude-sonnet-4-5-20250929 \
-i 0 # instance index
提示:若希望脚本在 Agent 完成任务后不弹出确认提示直接退出,加上
--exit-immediately标志(或命令行等价项-y/--yolo)。
单实例模式参数
| 分组 | 参数 | 说明 | 默认值 |
|---|---|---|---|
| 基础 | -m, --model |
使用的模型 | 由配置决定 |
| 基础 | -c, --config |
配置文件路径(语义同批量模式) | config 目录下的 swebench.yaml |
| 基础 | -o, --output |
输出轨迹文件路径 | 全局配置目录下的 last_swebench_single_run.traj.json |
| 数据选择 | --subset |
子集名或数据集路径 | lite |
| 数据选择 | --split |
数据集分片 | dev |
| 数据选择 | -i, --instance |
SWE-bench 实例 ID 或实例索引 | 0 |
| 高级 | --environment-class |
环境类(如 docker) |
docker |
| 高级 | --exit-immediately |
Agent 想结束时立即退出而非询问 | False |
| 高级 | --model-class / --agent-class |
自定义模型类 / Agent 类(支持完整导入路径) | 由配置决定 |
| 高级 | -l, --cost-limit |
成本上限(设为 0 禁用) |
由配置决定 |
从源码 swebench_single.py 可以看到,-i 参数会先判断是否为纯数字:若是,则把数据集按实例 ID 排序后取对应索引;否则直接按实例 ID 查找。随后脚本使用默认的 interactive Agent 类型(default_type="interactive")运行该实例的 problem_statement,因此整个调试过程是交互式的。
评估:云端 sb-cli 与本地 harness
跑完 SWE-bench 后需要评估 preds.json,官方提供两种途径:
方案一:云端评估(免费、快速)
使用 SWE-bench 官方的 sb-cli,安装并获取 token 后:
sb-cli submit swe-bench_verified test --predictions_path preds.json --run_id some-id-for-your-run
通常约 20 分钟内出结果。需要注意:耗时不受实例数量影响,而取决于 SWE-bench 中评估最慢的那个实例。
方案二:本地评估
安装 SWE-bench 包后,使用其 harness 在本地跑:
python -m swebench.harness.run_evaluation \
--dataset_name princeton-nlp/SWE-bench_Verified \
--predictions_path preds.jsonl \
--max_workers <num_workers> \
--run_id <run_id>
本地评估适合需要完全掌控运行环境、或不便上传数据的场景;注意其 --predictions_path 接受的是 preds.jsonl,而批量脚本默认输出 preds.json,两者格式需自行对齐。
输出产物与进度管理
输出目录结构
批量模式运行后,输出目录中包含:
preds.json:评估所需的核心产物。每个实例对应一条记录,格式为{instance_id: {"model_name_or_path": ..., "instance_id": ..., "model_patch": ...}},由 update_preds_file 以线程安全(threading.Lock)方式增量写入;<instance_id>/<instance_id>.traj.json:每个实例的完整轨迹文件,包含exit_status、submission、异常信息(如有)以及全部对话消息;exit_statuses_<timestamp>.yaml:各实例退出状态的汇总报告(由RunBatchProgressManager维护);minisweagent.log:运行日志(通过add_file_handler写入)。
实时进度面板
批量模式使用 rich 的 Live 渲染双进度条(见 batch_progress.py):主进度条显示整体完成数、已花费成本(累计 GLOBAL_MODEL_STATS.cost)与 ETA;每个实例对应一个子任务,状态文本由 ProgressTrackingAgent 在每个 step 更新为 Step N ($cost)。因此你在终端能同时看到"总进度 + 每个实例当前走到第几步 + 退出状态统计表"。
默认配置剖析
批量与单实例模式的默认配置均指向 src/minisweagent/config/benchmarks/swebench.yaml,它定义了 Agent 行为、环境与模型三大部分:
agent:提示词与限制
system_template/instance_template:Jinja2 模板,把每个 SWE-bench 实例的problem_statement渲染进<pr_description>,并给出完整任务指令(工作目录/testbed、禁止修改测试文件、最终必须通过echo COMPLETE_TASK_AND_SUBMIT_FINAL_OUTPUT && cat patch.txt提交补丁等);step_limit: 250:单实例最大推理步数;cost_limit: 3.:单实例成本上限(美元)。
environment:运行沙箱
cwd: "/testbed":SWE-bench 标准工作目录;timeout: 60:单条命令超时(秒);interpreter: ["bash", "-c"]:命令执行解释器;env:设置PAGER/MANPAGER=cat、LESS=-R、关闭进度条噪音,并通过BASH_ENV=/root/.bashrc确保conda activate testbed生效;environment_class: docker:默认容器后端。
model:观测与回退模板
observation_template:把命令输出包装成<returncode>/<output>;当输出超过 10000 字符时自动截断,仅保留前 5000 与后 5000 字符并提示 elided 数量;format_error_template:针对输出 token 耗尽(finish_reason == "length")与工具调用错误给出纠正提示;model_name: "anthropic/claude-sonnet-4-5-20250929",并开启drop_params与parallel_tool_calls。
底层原理:从实例到容器
镜像名推导
每个 SWE-bench 实例都运行在独立容器中。若数据集未提供 image_name 或 docker_image 字段,get_swebench_docker_image_name 会按规则构造镜像名:因为 Docker 不允许镜像名中出现双下划线,源码把实例 ID 中的 __ 替换为魔法 token _1776_,生成形如 docker.io/swebench/sweb.eval.x86_64.<repo>_1776_<repo>_1776_<version>:latest 的镜像名。相关单测见 tests/run/test_swebench.py。
环境装配与启动命令
get_sb_environment 负责把配置与实例结合出真实环境:
- 复制配置中的
environment段(不修改共享配置,避免多线程竞争,有专门测试验证); - 按环境类设置镜像:
docker/swerex_modal直接用裸镜像名,singularity/contree则加上docker://前缀; - 若配置了
run.env_startup_command,会先用 Jinja2(StrictUndefined模式)以实例字段为模板变量渲染,再在容器内执行,失败则抛出RuntimeError。
并发、异常与中断
批量模式通过 concurrent.futures.ThreadPoolExecutor(max_workers=workers) 并行调度实例(swebench.py)。每个实例的执行被包在 try/except 中:任何异常都会以异常类名作为 exit_status 记录进轨迹与 preds.json(model_patch 为空字符串)。测试 tests/run/test_swebench.py 验证了 RuntimeError/ValueError/ConnectionError 等异常都会被正确记录并通知进度管理器。
若你按下 Ctrl+C(KeyboardInterrupt),脚本会先取消尚未启动的任务,等待已运行任务收尾,再次 Ctrl+C 才强制退出。
FAQ 与常见问题排查
能否设置全局成本上限?
可以。通过环境变量/全局配置中的 MSWEA_GLOBAL_CALL_LIMIT(全局模型调用次数上限,0 表示不限)与 MSWEA_GLOBAL_COST_LIMIT(全局成本上限,美元,0 表示不限)实现,详见 docs/advanced/global_configuration.md。
用 Ctrl+C 中断后,未完成的任务怎么办?
轨迹只在任务完成时才保存,因此多数情况下直接重新运行脚本即可续跑未完成任务(preds.json 中已完成的实例会被自动跳过)。但个别已保存的任务可能以 KeyboardInterrupt 作为 exit_status,重跑前建议检查 preds.json。
删除了轨迹文件,某些任务仍然卡住不跑?
"已完成"的判定依据是 preds.json,而非轨迹文件。请把对应实例从 preds.json 中删除。
如何运行自定义数据集?
只要数据遵循 SWE-bench 格式,且能被 datasets.load_dataset(path, split=split) 加载,就可以通过 --subset /path/to/your/dataset 直接指定。--split 同样生效。
部分任务长时间卡在 "initializing task" 甚至超时?
这通常是因为正在拉取 Docker 镜像,第二次运行会立即开始。若是 docker pull 超时,可调大环境配置中的 environment.pull_timeout(默认 120 秒)。
遇到 Docker 问题怎么排查?
脚本会在控制台打印将要执行的 Docker 命令,可以手动复制执行观察报错;用 docker ps 确认容器在跑,再用 docker exec -it <container-id> ls 验证容器可交互。
HPC 集群上没有 Docker?
改用 Singularity/Apptainer 后端:在 Agent 配置文件中设置 environment.environment_class: singularity(参见 docs/advanced/yaml_configuration.md),或直接命令行加 --environment-class singularity。
能否在环境里先执行启动命令?
可以,配置 run.env_startup_command,命令会以 Jinja2 模板渲染实例字段后执行。例如:
run:
env_startup_command: "apt-get update && apt-get install -y python3-pip"
利用实例变量做初始化尤其适合轻量环境,例如:
run:
env_startup_command: "git clone {{ repo_url }} . --force"
该能力在配合 docs/reference/environments/bubblewrap.md 这类无预置代码的沙箱时非常实用。
SWE-bench 可以使用哪些环境后端?
docker(默认,经 docker exec 执行)、singularity(HPC 友好)、swerex_docker/swerex_modal(经 SWE-ReX 的本地/云端执行)、bubblewrap(Linux 无特权沙箱,实验性)、contree(ConTree 安全执行沙箱)等。各后端的取舍与配置详见 docs/advanced/environments.md。
延伸阅读
- 批量脚本源码:src/minisweagent/run/benchmarks/swebench.py
- 单实例脚本源码:src/minisweagent/run/benchmarks/swebench_single.py
- 默认基准配置:src/minisweagent/config/benchmarks/swebench.yaml
- 进度管理实现:src/minisweagent/run/benchmarks/utils/batch_progress.py
- 批量模式端到端测试:tests/run/test_swebench.py
- 单实例模式测试:tests/run/test_swebench_single.py
- 脚本 API 参考:docs/reference/run/swebench.md、docs/reference/run/swebench_single.md