From f3c836036a5f8f785de3147ac8a00b388a1f9673 Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:39:21 +0800 Subject: [PATCH 1/9] update docs of agent runtime --- .../extended_benchmark/agent/harbor_bench.md | 105 ++++++++++-------- .../extended_benchmark/agent/swe_bench.md | 42 +++++++ .../extended_benchmark/agent/swe_bench_pro.md | 56 ++++++++++ 3 files changed, 159 insertions(+), 44 deletions(-) diff --git a/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md b/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md index 113d55f9..46b97099 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md +++ b/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md @@ -44,8 +44,20 @@ 确保本地或云端部署了遵循 OpenAI chat/completions API 规范且支持 tool call 的被测推理服务。 -### 2. 安装 AISBench 测评工具 & Harbor 依赖 -#### 2.1 源码安装 +### 2. 准备AISBench修改过的Terminal-Bench-2数据集和对应镜像 +AISBench修改的数据集获取链接:https://github.com/AISBench/terminal-bench-2 +> 👉注意: AISBench没有改用例内容,只是将所有环境的准备全部集中到Dockerfile中,避免反复执行还需要反复构建环境和安装依赖 + +Terminal-Bench-2 预制打包镜像信息: +| 镜像名称 | 获取链接 |cpu架构| 打包压缩包大小 | +| -------- | -------- | ------- |-------- | +|`terminal-bench-2-prepared-images_aarch64.tar`| https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_aarch64.tar | aarch64 | 48.50 GB | +|`terminal-bench-2-prepared-images_x86_64.tar`| https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_x86_64.tar | x86_64 | 71.43GB | + +> 🌟提示:如果不想准备所有case的镜像,可以从[terminal-bench-2-offline-mini](https://modelers.cn/datasets/AISBench/terminal-bench-2-offline-mini)获取基于terminal-bench-2.0小规模采样的数据集及对应打包镜像 + +### 3. 安装 AISBench 测评工具 & Harbor 依赖 +#### 3.1 源码安装 > ⚠️环境限制: 确保环境docker 版本 >= 20.10.0,docker compose 版本 >= 2.0.0(docker compose可能需要额外安装)。同时需要准备一个python 3.12的运行环境 1. 在python 3.12的运行环境内,参考 [AISBench 安装文档](../../get_started/install.md) 安装 AISBench 测评工具。 2. python 3.12的运行环境内安装 Harbor: @@ -54,54 +66,59 @@ ``` > ⚠️注意:安装harbor会将datasets库的版本升级到4.0.0以上的版本,这会导致安装后报datasets库的依赖冲突,对于执行harbor测试terminal-bench相关数据集没有影响,但是如果你需要测试其他数据集,需要降低datasets库的版本。 -#### 2.2 在docker容器中安装 -1. 参考[镜像概览](https://github.com/AISBench/benchmark/blob/master/docker/OVERVIEW.zh.md)的“运行 Agent / 沙箱类测评(在容器内使用 Docker)”章节启动基于**python3.12及以上版本镜像(2026.7.1之后发布的镜像才支持)**的容器。 -2. 在容器内执行以下命令安装 Harbor: - ```bash - pip install harbor==0.6.1 --break-system-packages - ``` -3. 编辑harbor中的docker compose配置文件`/usr/local/lib/python3.12/dist-packages/harbor/environments/docker/docker-compose-base.yaml` -```yaml -services: - main: - network_mode: host # 共享主机网络,必须配置 - security_opt: # 模式 B 启动的容器需要配置 - - seccomp=unconfined - volumes: - - type: bind - source: ${HOST_VERIFIER_LOGS_PATH} - target: ${ENV_VERIFIER_LOGS_PATH} - - type: bind - source: ${HOST_AGENT_LOGS_PATH} - target: ${ENV_AGENT_LOGS_PATH} - - type: bind - source: ${HOST_ARTIFACTS_PATH} - target: ${ENV_ARTIFACTS_PATH} - deploy: - resources: - limits: - cpus: ${CPUS} - memory: ${MEMORY} +> ⚠️注意:源码安装方式下,[2. 准备数据集和对应镜像](##-2-准备aisbench修改过的terminal-bench-2数据集和对应镜像) 章节下载的 case 镜像 tar 需要在**物理机**上执行 `docker load -i xxxxxxx.tar` 加载到本地 docker daemon 后再跑测评。 + +#### 3.2 一键准备方案(推荐) + +如果不想手动处理依赖冲突 / DinD 配置,推荐使用 **AISBench Agent Runtime 一键准备方案**。同一脚本同时覆盖**快速入门(在线)**与**离线场景(内网/隔离环境)**,通过 `--runtime-tar` / `--case-tar` / `--datasets` 自由组合,无需切换不同流程。 + +```bash +# 1. 物理机上一键起 runtime 容器(自动选 DinD/Socket 模式,自动挂载数据集,自动把 case 镜像 tar 拷进容器内部 docker load 完) +# 在线场景:省略 --runtime-tar,runtime 镜像自动从 ghcr.io 拉取 +# 离线场景:通过 --runtime-tar 跳过外网拉取 +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /path/to/terminal-bench-2-offline-mini/terminal-bench-2-offline-selected_0.10/ \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --case-tar /path/to/terminal-bench-2-offline-prepared-images-selected-0.10.tar \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --datasets 指向的目录结构需与 terminal-bench-2-offline-mini 仓库的 terminal-bench-2-offline-selected_0.10/ 子目录结构一致 +# --runtime-tar (可选)提前准备的测评镜像,不传则自动拉取最新 +# --case-tar 指向的 tar 结构需与对应 agent 测评文档的 case 镜像 tar 结构一致(可多次传,也可传目录) +# --host-path 指向的目录需为空目录,容器内会自动创建同名目录挂载数据集和 case 镜像 +# --container-name 指向的容器名需唯一,否则会覆盖旧容器 + +# 2. 进入容器(case 镜像已在内部,直接可用) +docker exec -it test_agent_run bash + +# 3. (无需改 path)原生配置 path 自动从 AISBENCH_AGENT_DATASET_PATH 读 +# 仅需 vim 改 model_names / api_base +vim ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py + +# 4. 验证 runtime 就绪 +ais_bench_agent_doctor.sh harbor + +# 5. 跑测评 +agent_env harbor +ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug ``` -> ⚠️注意:安装harbor会将datasets库的版本升级到4.0.0以上的版本,这会导致安装后报datasets库的依赖冲突,对于执行harbor测试terminal-bench相关数据集没有影响,但是如果你需要测试其他数据集,需要降低datasets库的版本。 +切到其它数据集(mini-0.14 / mini-0.20 / full):销毁旧容器 → 重新 `bash ... --datasets <新路径> --case-tar <新tar>` 起容器。 -### 3. 准备AISBench修改过的Terminal-Bench-2数据集和对应镜像 -AISBench修改的数据集获取链接:https://github.com/AISBench/terminal-bench-2 -> 👉注意: AISBench没有改用例内容,只是将所有环境的准备全部集中到Dockerfile中,避免反复执行还需要反复构建环境和安装依赖 +`--runtime-tar` / `--case-tar` / `--datasets` 三者完全独立,可任意组合。三个都不会触发任何 `docker pull` 或 `curl` 到外网的操作;在快速入门(在线)场景中省略 `--runtime-tar`,脚本会自动从网络拉取 runtime 镜像。 -Terminal-Bench-2 预制打包镜像信息: -| 镜像名称 | 获取链接 |cpu架构| 打包压缩包大小 | -| -------- | -------- | ------- |-------- | -|`terminal-bench-2-prepared-images_aarch64.tar`| https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_aarch64.tar | aarch64 | 48.50 GB | -|`terminal-bench-2-prepared-images_x86_64.tar`| https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_x86_64.tar | x86_64 | 71.43GB | +`--case-tar` 在 A/B 两种模式下都生效:脚本会 `docker cp` 把 tar 拷进 runtime 容器,再在容器内 `docker load` 加载到该容器的 docker daemon。 -> 🌟提示:如果不想准备所有case的镜像,可以从[terminal-bench-2-offline-mini](https://modelers.cn/datasets/AISBench/terminal-bench-2-offline-mini)获取基于terminal-bench-2.0小规模采样的数据集及对应打包镜像 +该方案解决了以下痛点: +- **依赖冲突**:harbor==0.6.1 强制升级 datasets 到 4.0+ 会污染主环境,runtime 镜像用独立 venv 隔离 +- **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp 自动处理 +- **数据集版本频繁**:数据集与 case 镜像均不烤入 runtime 镜像,由用户在物理机准备后通过 `--datasets` 挂载 / `--case-tar` 加载,避免镜像频繁过期 +- **case 镜像管理**:通过 `--case-tar` 在 bootstrap 时一次性加载到容器内,容器内无需手动 `docker pull` / `docker load` +- **环境无验证**:`doctor.sh` 在跑测评前验证 runtime 就绪,失败时给精确修复指引 +- **离线部署**:支持 `--runtime-tar ` 跳过 runtime 镜像的网络获取;支持 `--case-tar ` 加载 case 镜像到容器内(可多次,可传目录)。内网隔离环境可全程零外网请求 -> ⚠️注意: -> 如果通过源码安装 AISBench 测评工具 & Harbor 依赖这种方式安装依赖的情况下,部署Terminal-Bench-2的镜像需要在**物理机**上执行`docker load -i xxxxxxx.tar` -> 如果通过模式 A(真 docker in docker)启动AISBench容器,部署Terminal-Bench-2的镜像需要在**容器内**上执行`docker load -i xxxxxxx.tar` -> 如果提供给模式 B(Socket 代理)启动AISBench容器,部署Terminal-Bench-2的镜像需要在**物理机**上执行`docker load -i xxxxxxx.tar` +方案原理与脚本实现见 [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md)。 ### 4. 配置 Harbor 任务的自定义配置文件 diff --git a/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md b/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md index 731113de..bfd3e836 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md +++ b/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md @@ -2,6 +2,48 @@ SWE-bench是一个基准测试,用于评估大语言模型在从GitHub收集的现实世界软件问题上的表现。给定一个代码库和一个问题,语言模型的任务是生成一个补丁来解决所描述的问题。 +## 快速上手(推荐) + +如果你是第一次跑 Agent 测评,或不想手动处理依赖冲突 / DinD 配置 / mini-swe-agent fork 选择,推荐使用 **AISBench Agent Runtime 一键准备方案**: + +```bash +# 1. 物理机上一键起 runtime 容器 +# --datasets 挂载数据集 + 注入 env var(原生配置 path 自动从此 env var 读,无需 vim 改) +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- --datasets /data/datasets/swebench + +# 2. 进入容器 +docker exec -it ais_bench_agent bash + +# 3. 准备 case 镜像(HF 上 princeton-nlp/SWE-Bench_* 的 docker 镜像,或 docker load tar) +# 数据集由原生配置自动从 HF 下载,无需用户准备 +docker pull swebench/sweb.eval.x86_64.: +# 详见各实例对应的 docker image tag + +# 4. 验证 runtime 就绪 +ais_bench_agent_doctor.sh swebench + +# 5. 改原生配置中的 model_names / api_base(path 由 env var 自动给) +vim ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py + +# 6. 激活 swebench venv(AISBench fork 的 mini-swe-agent) +agent_env swebench + +# 7. 跑测评 +ais_bench ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py --debug +``` + +切到其它数据集(verified / full / multilingual 等):改原生配置文件的 `datasets[0].name` 字段,重新跑。 + +该方案解决了以下痛点: +- **mini-swe-agent fork 冲突**:AISBench fork 与 scaleapi fork 同包名互相覆盖,runtime 用独立 venv 隔离两个 fork +- **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp 自动处理 +- **离线部署**:`--runtime-tar` 跳过 runtime 镜像的网络获取;`--case-tar` 加载 case 镜像到容器内(可多次,可传目录) + +方案原理与脚本实现见 [`docker/agent_runtime/`](../../../docker/agent_runtime/README.md)。 + +> 下文为完整的 SWE-bench 测评原理与手动配置方式,适用于不使用一键方案、或需要深入定制的场景。 + ## 1. 功能概览 当前在 `ais_bench` 已接入以下 SWEbench 能力: diff --git a/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md b/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md index 853d6b77..7f7bfd88 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md +++ b/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md @@ -4,6 +4,62 @@ SWE-Bench Pro 是一个用于评估大语言模型在长时域软件工程任务 > **注意**:由于官方提供的 Docker 镜像均为 x86 架构,SWE-bench Pro 目前仅支持在 x86 环境上评测,暂不支持 ARM 环境。 +## 快速上手(推荐) + +如果你是第一次跑 Agent 测评,或不想手动处理依赖冲突 / DinD 配置 / mini-swe-agent fork 选择,推荐使用 **AISBench Agent Runtime 一键准备方案**: + +```bash +# 1. 物理机上准备 mini 数据集(已有可跳过) +# SWE-bench Pro 的 mini 数据集**必须**本地准备,无在线版 +# 从 modelers 下载到任意目录,目录结构由用户自行规划 +mkdir -p /data/datasets/swebench_pro +# 下载地址:https://modelers.cn/datasets/AISBench/SWE-Bench_Pro_mini +# 优先 parquet 格式;下载后解压到 /data/datasets/swebench_pro/ 即可 + +# 2. 物理机上一键起 runtime 容器 +# --datasets 挂载数据集 + 注入 env var(原生配置 path 自动从此 env var 读) +# 运行时已 clone 好 /opt/src/SWE-bench_Pro-os,swebp_scripts_dir / swebp_docker_dir 直接指向它 +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- --datasets /data/datasets/swebench_pro + +# 3. 进入容器 +docker exec -it ais_bench_agent bash + +# 4. 验证 runtime 就绪 +ais_bench_agent_doctor.sh swebench_pro + +# 5. 改原生配置: +# - model_names / api_base +# - path 自动从 AISBENCH_AGENT_DATASET_PATH 读(mini 数据集本地路径) +# - SWEBP_SCRIPT_PATH_ABS / SWEBP_DOCKER_PATH_ABS 指向运行时已 clone 的 SWE-bench_Pro-os +vim ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py + +# 6. 激活 swebench_pro venv(scaleapi fork 的 mini-swe-agent) +agent_env swebench_pro + +# 7. 跑测评 +ais_bench ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py --debug +``` + +切到 full 数据集:先确认 HF 可达,然后改原生配置文件中 `SWEBP_SCRIPT_PATH_ABS` / `SWEBP_DOCKER_PATH_ABS` / `path` / `name='mini'` → `name='full'`,重新跑。 + +**SWE-bench Pro 与 SWE-bench 的差异**(影响快速上手的几处): + +- **mini-swe-agent fork**:SWE-bench Pro 必须用 scaleapi fork,不能用 AISBench fork;runtime 用独立 `swebench_pro` venv 隔离两个 fork +- **mini 数据集**:SWE-bench Pro 的 mini 数据集没有在线版,必须从 modelers 下载本地 parquet;full 数据集可 HF 在线 +- **评测参数**:`SWEBP_SCRIPT_PATH_ABS` 和 `SWEBP_DOCKER_PATH_ABS` 必须指向 SWE-Bench_Pro-os 仓库的 `run_scripts/` 和 `dockerfiles/`;runtime 镜像已 clone 到 `/opt/src/SWE-bench_Pro-os/`,直接填这个路径即可 +- **case 镜像**:scaleapi 官方 x86 docker 镜像,按 instance 拉取;具体 tag 与拉取方式详见 [SWE-bench Pro 官方仓库](https://github.com/scaleapi/SWE-bench_Pro-os) 与 [scaleapi/mini-swe-agent](https://github.com/scaleapi/mini-swe-agent) + +该方案解决了以下痛点: + +- **mini-swe-agent fork 冲突**:AISBench fork 与 scaleapi fork 同包名互相覆盖,runtime 用独立 venv 隔离两个 fork +- **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp 自动处理 +- **离线部署**:`--runtime-tar` 跳过 runtime 镜像的网络获取;`--case-tar` 加载 case 镜像到容器内(可多次,可传目录) + +方案原理与脚本实现见 [`docker/agent_runtime/`](../../../docker/agent_runtime/README.md)。 + +> 下文为完整的 SWE-bench Pro 测评原理与手动配置方式,适用于不使用一键方案、或需要深入定制的场景。 + ## 1. 功能概览 当前在 `ais_bench` 已接入以下 SWE-Bench Pro 能力: From a4afa46dd8bbe55d7bc3b554c718c6c03f13ab2a Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:39:53 +0800 Subject: [PATCH 2/9] update configs of agent runtime --- .../harbor_terminal_bench_2_task.py | 24 ++++++++++++++++++- .../mini_swe_agent_swe_bench_full.py | 18 +++++++++++++- .../mini_swe_agent_swe_bench_lite.py | 20 ++++++++++++++-- .../mini_swe_agent_swe_bench_multilingual.py | 18 +++++++++++++- ...i_swe_agent_swe_bench_multilingual_mini.py | 19 ++++++++++++++- .../mini_swe_agent_swe_bench_verified.py | 18 +++++++++++++- .../mini_swe_agent_swe_bench_verified_mini.py | 18 +++++++++++++- .../mini_swe_agent_swe_bench_pro_full.py | 18 +++++++++++++- .../mini_swe_agent_swe_bench_pro_mini.py | 19 ++++++++++++++- 9 files changed, 162 insertions(+), 10 deletions(-) diff --git a/ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py b/ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py index ace9d81b..700a7132 100644 --- a/ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py +++ b/ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py @@ -6,6 +6,27 @@ with read_base(): from ais_bench.benchmark.configs.summarizers.example import summarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10 +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 切到其它 tier 时只改 bootstrap.sh --datasets 参数即可(4 套常用路径): +# full: /data/datasets/harbor/full/terminal-bench-2 (89 case) +# mini-0.10: /data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10 (7 case, 默认) +# mini-0.14: /data/datasets/harbor/mini-0.14/terminal-bench-2-offline-selected_0.14 (10 case) +# mini-0.20: /data/datasets/harbor/mini-0.20/terminal-bench-2-offline-selected_0.20 (14 case) +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时使用下方 DEFAULT_DATASET_FALLBACK 兜底。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:/data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10}}' + models = [ dict( abbr="terminus-2", @@ -59,7 +80,8 @@ environment_type="docker", # -e/--env: 环境类型 (docker, daytona, e2b, modal) environment_force_build=False, # --force-build/--no-force-build: 是否强制重建环境 environment_delete=False, # --delete/--no-delete: 完成后是否删除环境 - path="/path/to/terminal-bench-2/", # -p/--path: 本地数据集路径 + path=DEFAULT_DATASET_PATH, # -p/--path: 本地数据集路径(需与 bootstrap.sh --datasets 传入路径对齐) + # 切换 tier:把上面 DEFAULT_DATASET_PATH 改成 full / mini-0.14 / mini-0.20 对应路径 dataset_name_version=None, # -d/--dataset: 远程数据集名称@版本 task_names=None, # --include-task-name: 包含的任务名称(支持glob模式)例如 ["task_name1", "task_name2"] exclude_task_names=None, # --exclude-task-name: 排除的任务名称 diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_full.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_full.py index e3efa693..cf409a3b 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_full.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_full.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -31,7 +46,8 @@ type=SWEBenchDataset, abbr="swebench_full", # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing dir -> HF snapshot_download - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="full", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py index d218d61d..93a548a7 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -30,8 +45,9 @@ dict( type=SWEBenchDataset, abbr="swebench_lite", - # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing -> HF download - path="", + # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing dir -> HF snapshot_download + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="lite", split="test", filter_spec="", diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual.py index 3f3cd5a4..a48f82ab 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -31,7 +46,8 @@ type=SWEBenchDataset, abbr="swebench_multilingual", # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing -> HF download - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="multilingual", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual_mini.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual_mini.py index 0bed2c06..942499e9 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual_mini.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_multilingual_mini.py @@ -4,6 +4,22 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → HF 在线下载会失败)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: 下载 mini 数据集并准备目录(HF 无该数据集) +# https://modelers.cn/datasets/AISBench/SWE-Bench_Multilingual_mini +# 2. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/ +# 3. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -31,7 +47,8 @@ type=SWEBenchDataset, abbr="swebench_multilingual_mini", # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing -> HF download - path="", # Set local path to the mini dataset. Download from https://modelers.cn/datasets/AISBench/SWE-Bench_Multilingual_mini + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;mini 数据集 HF 无,必须 env var 注入本地路径 + path=DEFAULT_DATASET_PATH, name="multilingual", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified.py index 2287c917..aebd0349 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -31,7 +46,8 @@ type=SWEBenchDataset, abbr="swebench_verified", # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing -> HF download - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="verified", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified_mini.py b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified_mini.py index fe424766..d4f96153 100644 --- a/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified_mini.py +++ b/ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_verified_mini.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchInferTask, SWEBenchEvalTask from ais_bench.benchmark.summarizers import SWEBenchSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 200 models = [ @@ -31,7 +46,8 @@ type=SWEBenchDataset, abbr="swebench_verified_mini", # Relative to AIS_BENCH_DATASETS_CACHE (default: project root); missing -> HF download - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="verified_mini", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py index a5f58992..c77200b2 100644 --- a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py +++ b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py @@ -4,6 +4,21 @@ from ais_bench.benchmark.tasks import SWEBenchProInferTask, SWEBenchProEvalTask from ais_bench.benchmark.summarizers import SWEBenchProSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → 沿用 HF 在线下载)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench_pro/<...> +# 2. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可; +# 不 export 时回落到 HF 在线下载(默认行为)。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 250 models = [ @@ -33,7 +48,8 @@ dict( type=SWEBenchProDataset, abbr="swebench_pro_full_data", - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;不设置时为空,沿用 HF 在线下载 + path=DEFAULT_DATASET_PATH, name="full", split="test", step_limit=STEP_LIMIT, diff --git a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py index 3af1b043..d1f48ba6 100644 --- a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py +++ b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py @@ -4,6 +4,22 @@ from ais_bench.benchmark.tasks import SWEBenchProInferTask, SWEBenchProEvalTask from ais_bench.benchmark.summarizers import SWEBenchProSummarizer +# 数据集路径:用 mmengine 的 {{$VAR:default}} 占位符从环境变量读取。 +# mmengine 在执行本文件前,会先用 os.environ['VAR'] 的值替换整个 {{$VAR:default}} +# 占位符;如果环境变量未设置,则替换为 default 部分(此处为空 → mini 无 HF 源会失败)。 +# +# 这里 AISBENCH_AGENT_DATASET_PATH 的值就是 bootstrap.sh --datasets 传入的完整路径, +# 由 bootstrap.sh 自动注入到容器环境变量中,无需 import sys / import os 任何库。 +# +# 使用流程: +# 1. 物理机: 下载 mini 数据集并准备目录 +# https://modelers.cn/datasets/AISBench/SWE-Bench_Pro_mini +# 2. 物理机: bash bootstrap.sh --datasets /data/datasets/swebench_pro/ +# 3. 容器内: ais_bench <此配置> --debug # path 自动从 env var 读 +# +# 不使用 agent_runtime 容器方案时:直接 export AISBENCH_AGENT_DATASET_PATH= 即可。 +DEFAULT_DATASET_PATH = '{{$AISBENCH_AGENT_DATASET_PATH:}}' + STEP_LIMIT = 250 models = [ @@ -33,7 +49,8 @@ dict( type=SWEBenchProDataset, abbr="swebench_pro_mini_data", - path="", + # 本字段通过环境变量 AISBENCH_AGENT_DATASET_PATH 注入;mini 数据集 HF 无,必须 env var 注入本地路径 + path=DEFAULT_DATASET_PATH, name="mini", split="test", step_limit=STEP_LIMIT, From 74f154ee080adc1b26472e47c93ede0f7a280bed Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:40:40 +0800 Subject: [PATCH 3/9] update docker doc of agent runtime --- docker/OVERVIEW.zh.md | 133 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/docker/OVERVIEW.zh.md b/docker/OVERVIEW.zh.md index ccc26dba..0db6f6b7 100644 --- a/docker/OVERVIEW.zh.md +++ b/docker/OVERVIEW.zh.md @@ -171,6 +171,55 @@ docker build \ 镜像预装了 Docker Engine(≥ 20.0)与 Docker Compose v2(≥ 2.0.0)。在容器内启动 Docker 有两种模式,请根据宿主 Docker 版本与隔离需求二选一。 ### 模式 A:Docker-in-Docker(推荐,真嵌套容器,要求宿主 Docker ≥ 20.10 + cgroup v2) +<<<<<<< HEAD +```bash +┌────────────────────────── 宿主机 (Host) ──────────────────────────┐ +│ │ +│ ┌──────────────────┐ ┌──────────────────────────┐ │ +│ │ Host Kernel │ │ Host dockerd │ │ +│ │ (cgroup v2) │◀───────▶│ /var/run/docker.sock │ │ +│ └──────────────────┘ │ 管理宿主自身的容器 │ │ +│ └──────────────────────────┘ │ +│ │ +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ +│ ┃ AISBench Container (--privileged --cgroupns=host) ┃ │ +│ ┃ ┃ │ +│ ┃ ┌──────────────────────┐ ┌──────────────────────┐ ┃ │ +│ ┃ │ Docker CLI │────▶│ Inner dockerd │ ┃ │ +│ ┃ │ (用户执行) │ │ (容器内独立进程) │ ┃ │ +│ ┃ └──────────────────────┘ │ daemon.json: │ ┃ │ +│ ┃ │ native.cgroupdriver │ ┃ │ +│ ┃ │ =cgroupfs │ ┃ │ +│ ┃ │ storage=vfs │ ┃ │ +│ ┃ └──────────┬───────────┘ ┃ │ +│ ┃ │ spawn ┃ │ +│ ┃ ▼ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ containerd │ ┃ │ +│ ┃ │ (内嵌在 inner d) │ ┃ │ +│ ┃ └──────────┬───────────┘ ┃ │ +│ ┃ │ ┃ │ +│ ┃ ▼ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ 嵌套子容器 │ ┃ │ +│ ┃ │ (真隔离命名空间) │ ┃ │ +│ ┃ │ ┌────────────────┐ │ ┃ │ +│ ┃ │ │ Agent 进程 │ │ ┃ │ +│ ┃ │ │ OpenBLAS │ │ ┃ │ +│ ┃ │ │ Python deps │ │ ┃ │ +│ ┃ │ └────────────────┘ │ ┃ │ +│ ┃ └──────────────────────┘ ┃ │ +│ ┃ ┃ │ +│ ┃ —— 隔离边界:独立 PID/IPC/Net/Mount/User 命名空间 —— ┃ │ +│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ +│ │ +│ ✦ 嵌套子容器不出现在宿主 `docker ps` 中 │ +│ ✦ 子容器继承 Docker 官方默认 seccomp profile(无 clone3 拦截) │ +│ ✦ 宿主 dockerd 重启不会影响 inner dockerd │ +└──────────────────────────────────────────────────────────────────┘ +``` +======= +>>>>>>> master_center 容器内自起一个独立的 `dockerd`,子容器与宿主机完全隔离。这是 agent 测评的**首选模式**:子容器继承的是 Docker 官方默认 seccomp profile,不会触发 openEuler / RHEL 加固 profile 导致的 `pthread_create` / `clone3` 拦截问题;也不存在宿主 dockerd 重启后 socket 句柄失效的问题。 @@ -236,6 +285,50 @@ docker compose version - 对于长时间运行的 DinD 场景,建议在 `/etc/docker/daemon.json` 中加入 `"default-runtime": "runc"`、`"log-driver": "json-file"`、`"data-root"` 等调优项。 ### 模式 B:Socket 代理(兼容任意 Docker 版本 ≥ 1.0) +<<<<<<< HEAD +```bash +┌────────────────────────── 宿主机 (Host) ──────────────────────────┐ +│ │ +│ ┌──────────────────┐ │ +│ │ Host Kernel │ │ +│ └──────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────┐ bind mount │ +│ │ Host dockerd │ /var/run/docker │ +│ │ /var/run/docker.sock ──────────────────────────┐ │ +│ │ (管理宿主自身的容器) │ │ │ +│ └────────────┬─────────────────────────────┘ │ │ +│ │ │ │ +│ │ 实际创建/管理 │ │ +│ ▼ │ │ +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┓ │ +│ ┃ AISBench Container (--privileged, 与宿主共享 PID/IPC) ┃ │ +│ ┃ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ Docker CLI │──── HTTP/Unix socket 调用 ─────┘ ┃ │ +│ ┃ │ (用户执行) │ 容器内无 dockerd 进程 ┃ │ +│ ┃ └──────────────────────┘ ┃ │ +│ ┃ ┃ │ +│ ┃ —— 与宿主共享内核、PID、IPC 命名空间 —— ┃ │ +│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ +│ │ +│ ┌──────────────────────────────────────────┐ │ +│ │ 子容器 (实为宿主上的容器) │ │ +│ │ ┌────────────────┐ │ │ +│ │ │ Agent 进程 │ ← 由 Host dockerd │ │ +│ │ │ OpenBLAS │ 直接创建/回收 │ │ +│ │ │ Python deps │ │ │ +│ │ └────────────────┘ │ │ +│ └──────────────────────────────────────────┘ │ +│ │ +│ ✦ 嵌套子容器出现在宿主 `docker ps` 中 │ +│ ✦ 子容器继承宿主 dockerd 的 seccomp profile │ +│ (openEuler/RHEL 加固 profile → 触发 clone3 拦截) │ +│ ✦ 宿主 dockerd 重启 → socket inode 失效 → 需 `docker restart` │ +└──────────────────────────────────────────────────────────────────┘ +``` +======= +>>>>>>> master_center 挂载宿主的 Docker socket,使容器内的 `docker run` 实际上在**宿主机** daemon 上创建容器。仅当宿主 Docker 版本低于 20.10、或不支持 cgroup v2 无法使用模式 A 时再选用本模式。 @@ -354,6 +447,46 @@ docker compose -f /tmp/docker-compose.yml up - [Sysbox](https://github.com/nestybox/sysbox)——支持嵌套容器而无需 `--privileged`,代价是要在宿主机装自定义运行时。 - Rootless Docker——以非 root 用户运行 `dockerd`,但有限制(多数发行版不支持 `overlay2`、网络限制等)。 +<<<<<<< HEAD +## Agent 测评一键环境准备 + +针对 Harbor Terminal-Bench、SWE-bench、SWE-bench Pro 等 agent 测评,本仓库在 [`docker/agent_runtime/`](agent_runtime/README.md) 提供了一键环境准备方案,将上文"运行 Agent / 沙箱类测评"章节的模式 A/B 选择、`daemon.json` 配置、`--cgroupns=host`、seccomp 处理等步骤收敛为一个脚本,并额外解决了: + +- **依赖冲突**:多个 agent 测评的依赖互相冲突(如 harbor 强制升级 datasets 到 4.0+、两个 `mini-swe-agent` fork 同包名互相覆盖),通过 runtime 镜像内的多 venv 隔离 +- **case 镜像庞大**:SWE-bench full ~1TB 不能整体打包,**不**预置到 runtime 镜像,由用户自行 docker pull / load +- **数据集版本频繁**:agent 数据集版本变化快,**不**预置到 runtime 镜像,由用户在物理机准备好,通过 `bootstrap.sh --datasets ` 挂载进容器(容器内路径 = 宿主路径) +- **环境无验证**:`doctor.sh` 在跑测评前验证 runtime 配置(L1 静态)+ case 镜像存在性扫描(warning),失败时给精确修复指引 + +**用户使用**(三个 pack 都用同一条流程,按 benchmark 选 `--datasets` 和 `agent_env`): + +```bash +# 物理机:准备数据集目录 + 一键起 runtime 容器(把数据集目录挂载进容器) +# Harbor: +mkdir -p /data/datasets/harbor/mini-0.10 +# 准备数据集(见 harbor_bench.md)+ case 镜像(可用 bootstrap --case-tar 离线加载) +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10 \ + --case-tar /data/cases/case-tb2-mini-0.10.tar.gz +docker exec -it ais_bench_agent bash +# 容器内: +ais_bench_agent_doctor.sh harbor +agent_env harbor +ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug + +# SWE-bench / SWE-bench Pro 同理: +# --datasets +# agent_env swebench | swebench_pro +# ais_bench ais_bench/configs/swe_bench[_pro]_examples/... --debug +# 数据集与 case 镜像获取详见各 benchmark 文档 +``` + +方案设计与各脚本参数详见 [`docker/agent_runtime/README.md`](agent_runtime/README.md)。各 agent 测评文档([harbor_bench.md](../docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md)、[swe_bench.md](../docs/source_zh_cn/extended_benchmark/agent/swe_bench.md)、[swe_bench_pro.md](../docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md))开头也已加入"快速上手"引导段。 + +> 本节是"运行 Agent / 沙箱类测评"章节的可执行化封装。理解原理仍建议阅读上文模式 A/B 章节;快速上手直接用本节脚本即可。 + +======= +>>>>>>> master_center ## 许可证 / 免责声明 本项目镜像及其构建脚本按仓库根目录的 [LICENSE 文件](https://github.com/AISBench/benchmark/blob/master/LICENSE) 授权。 From 1a7980641ec10a65fce6a404adb56a6a53985bae Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:41:38 +0800 Subject: [PATCH 4/9] add docs and dep of agent runtime --- docker/agent_runtime/README.md | 268 ++++++++++++++++++ docker/agent_runtime/packs/harbor.yaml | 12 + docker/agent_runtime/packs/swebench.yaml | 12 + docker/agent_runtime/packs/swebench_pro.yaml | 15 + .../patches/harbor_compose_patch.py | 44 +++ 5 files changed, 351 insertions(+) create mode 100644 docker/agent_runtime/README.md create mode 100644 docker/agent_runtime/packs/harbor.yaml create mode 100644 docker/agent_runtime/packs/swebench.yaml create mode 100644 docker/agent_runtime/packs/swebench_pro.yaml create mode 100644 docker/agent_runtime/patches/harbor_compose_patch.py diff --git a/docker/agent_runtime/README.md b/docker/agent_runtime/README.md new file mode 100644 index 00000000..755fb0ba --- /dev/null +++ b/docker/agent_runtime/README.md @@ -0,0 +1,268 @@ +# AISBench Agent Runtime + +为 AISBench Agent 测评(Harbor Terminal-Bench、SWE-bench、SWE-bench Pro 等)提供运行环境容器的镜像与脚本。 + +> 本仓库目录是 AISBench/benchmark 的社区运行时补充,不属于 benchmark 核心评测逻辑。用户使用本目录的脚本和镜像准备好 runtime 容器后,仍用原生 `ais_bench` 命令执行测评,原理与各 benchmark 文档完全一致。 + +## 解决什么问题 + +Agent 测评的环境准备存在三大痛点: + +1. **依赖冲突**:harbor 强制升级 datasets 到 4.0+;SWE-bench 与 SWE-bench Pro 各需要一个不同 fork 的 `mini-swe-agent`,同包名互相覆盖。 +2. **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp,任一步漏配都会在跑测评时才报错。 +3. **数据集 / case 镜像版本变化频繁**:数据集和 case 镜像都有大量版本,烤入 runtime 镜像会很快过期。 + +本包通过分层解决这些问题: + +| 层 | 内容 | 解决 | +|---|---|---| +| `Dockerfile.agent-runtime` | 在 `aisbench_benchmark` 基镜之上追加 3 个 venv 隔离层(harbor / swebench / swebench_pro) | 依赖冲突 | +| `bootstrap.sh` | 一键起 runtime 容器,自动选 DinD/Socket 模式 + 挂载数据集 + 加载 case tar | 容器配置易错 + 数据集接入 | +| `doctor.sh` | 静态自检(L1,秒级)— 校验 docker / venv / pack / 资源 | 跑前验证 runtime 配置 | +| `packs/.yaml` | 各 benchmark 的元数据(venv 名 / 原生配置 / 文档) | 工具链与 benchmark 解耦 | + +## 数据集 / case 镜像由谁负责 + +**刻意不做的事**:本方案**不**预置 agent benchmark 的数据集和 case 沙箱镜像到 runtime 镜像中。原因是这两者版本变化频繁,烤入镜像后: + +- 数据集每次更新都要重新构建 runtime 镜像,对维护者负担大、对用户下载体积大 +- case 沙箱镜像一个 full 集 ~71GB,不能烤进基础镜像 + +**谁负责什么**: + +| 项 | 谁准备 | 怎么接入 runtime 容器 | +|---|---|---| +| runtime 镜像 | AISBench 维护者 | `docker pull ghcr.io/aisbench/agent-runtime:latest-...`(或 `--runtime-tar` 离线) | +| 数据集(task.toml 等) | 用户在物理机上准备好 | `bootstrap.sh --datasets <完整数据集路径>`(挂载到容器内同路径 + 注入 env var) | +| case 沙箱镜像 | 用户在物理机上准备好 tar | `bootstrap.sh --case-tar `(自动 `docker cp` 进容器 + `docker load`) | +| 模型调用参数 (api_base / model_names) | 用户改原生配置 | 容器内 `vim ais_bench/configs/agent_example/...` | + +## 快速入门(以 Harbor Terminal-Bench 为例 aarch64) +快速入门针对物理机20.0.0以下版本docker环境,其他环境请参考对应agent测评文档。 + +```bash +# 1. 物理机上准备数据集与镜像 tar(已有可跳过) + +git clone https://modelers.cn/AISBench/terminal-bench-2-offline-mini.git # 数据集准备 +wget https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-aarch64.tar.gz # 测评镜像准备(可选,不准备则自动获取最新) +wget https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-offline-prepared-images-selected-0.10_aarch64.tar # case 镜像准备,按需从对应agent测评文档获取链接 +mkdir /path/to/test_wkp/ # 物理机创建一个空的工作目录 + +# 2. 物理机上一键起 runtime 容器(自动选 DinD/Socket 模式,自动挂载数据集,如果执行环境不通外网,可以先从其他环境获取ais_bench_agent_bootstrap.sh再bash执行 +# 自动把 case 镜像 tar 拷进容器内部 docker load 完) +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /path/to/terminal-bench-2-offline-mini/terminal-bench-2-offline-selected_0.10/ \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-aarch64.tar.gz \ + --case-tar /path/to/terminal-bench-2-offline-prepared-images-selected-0.10.tar \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --datasets 指向的目录结构需与 terminal-bench-2-offline-mini 仓库的 terminal-bench-2-offline-selected_0.10/ 子目录结构一致 +# --runtime-tar (可选)提前准备的测评镜像 +# --case-tar 指向的 tar 结构需与对应 agent 测评文档的 case 镜像 tar 结构一致 +# --host-path 指向的目录需为空目录,容器内会自动创建同名目录挂载数据集和 case 镜像 +# --container-name 指向的容器名需唯一,否则会覆盖旧容器 + +# 3. 进入容器(case 镜像已在内部,直接可用) +docker exec -it test_agent_run bash + +# 4. (无需 vim)原生配置 path 自动从 AISBENCH_AGENT_DATASET_PATH 读 +# 仅需 vim 改 model_names / api_base +vim ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py + +# 5. 验证 runtime 就绪 +ais_bench_agent_doctor.sh harbor + +# 6. 跑测评 +agent_env harbor +ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug +``` + +切换数据集:销毁旧容器 + 重启 bootstrap(数据集路径 / case tar 一起更新): + +```bash +docker rm -f test_agent_run +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets/harbor/full/terminal-bench-2 \ + --case-tar /data/cases/terminal-bench-2-prepared-images_x86_64.tar.gz +``` + +## 目录结构 + +``` +agent_runtime/ +├── README.md # 本文件 +├── Dockerfile.agent-runtime # runtime 镜像构建文件(BASE_IMAGE 通过 --build-arg 传入,不写死) +├── build_image_agent_runtime.sh # 构建脚本(支持 --base-tag/--push/--upload/--multi-arch) +├── ais_bench_agent_bootstrap.sh # 一键起 runtime 容器(用户侧入口,需上传到 OBS) +├── doctor.sh # runtime 就绪验证(容器内,仅校验 docker/venv/config 不校验数据集/cases) +├── packs/ # 各 benchmark 的清单(name/runtime_venv/native_config/native_doc) +│ ├── harbor.yaml # Harbor Terminal-Bench +│ ├── swebench.yaml # SWE-bench(mini_swe_agent + SWE-bench harness) +│ └── swebench_pro.yaml # SWE-bench Pro(scaleapi 适配版) +└── patches/ # 构建期 / 启动期用的补丁脚本 + └── harbor_compose_patch.py # 给 harbor 的 docker-compose-base.yaml 加 seccomp=unconfined + network_mode=host +``` + +## ais_bench_agent_bootstrap.sh 用法 + +```bash +# 最简调用:挂载一个数据集目录 +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets + +# 挂载多个目录 +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --datasets /data/extra + +# 强制模式 A/B +bash ais_bench_agent_bootstrap.sh --mode A --datasets /data/datasets + +# 自定义容器名(一台机器同时跑多个 runtime 时区分) +bash ais_bench_agent_bootstrap.sh --container-name my_eval_1 --datasets /data/datasets + +# 自定义 runtime 镜像(推荐显式传 tag,保证可复现性) +bash ais_bench_agent_bootstrap.sh \ + --runtime-image ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 \ + --datasets /data/datasets + +# 模式 B + 自定义 /benchmark 提取目标(仅 /opt 不可写时用) +bash ais_bench_agent_bootstrap.sh --mode B --host-path /data/ais_bench_host --datasets /data/datasets + +# 离线模式(内网/隔离环境):用宿主上已下载好的 tar 包加载 runtime 镜像 +# 完全跳过 docker pull / OBS 下载 +# 适用:内网部署机无法访问 ghcr.io,也无法访问外网 OBS +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --runtime-tar /opt/aisbench/agent-runtime-ubuntu24-py312-x86_64.tar.gz + +# 完全离线:runtime tar + case 镜像 tar 一起传入 +# 容器启动后会自动把 case tar 拷进容器并 docker load +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /opt/aisbench/agent-runtime.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.10.tar.gz + +# 一次加载多个 case 镜像(可多次 --case-tar,也可传一个目录) +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /opt/aisbench/agent-runtime.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.10.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.14.tar.gz \ + --case-tar /opt/aisbench/case-tars/ # 目录下所有 .tar/.tar.gz/.tgz 都会被加载 +``` + +`--datasets` / `--host-path` / `--runtime-tar` / `--case-tar` 必须是**绝对路径**,且在**物理机上必须存在**(脚本会校验)。容器内路径与宿主路径相同。 + +`--datasets` 传入的完整路径会原封不动注入为容器内环境变量 `AISBENCH_AGENT_DATASET_PATH`,原生 ais_bench 配置(如 `harbor_terminal_bench_2_task.py`)直接把这个 env var 作为数据集 `path` 字段使用——**不拼接、不转换、完全一致**。所以: + +- **推荐**:把 `--datasets` 传成你准备好的 harbor benchmark 数据集完整路径(如 `/data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10`),这样配置无需 vim 改 path +- **多目录**:可多次传 `--datasets`,但 env var 只用首个;用户可手动 `export AISBENCH_AGENT_DATASET_PATH=...` 覆盖 + +### 命令行参数一览 + +| 参数 | 默认值 | 说明 | +|---|---|---| +| `--datasets ` | 无(不挂载) | 数据集目录,可多次 | +| `--runtime-tar ` | 无(走 pull) | runtime 镜像 tar,离线场景用 | +| `--case-tar ` | 无(容器内手动准备) | case 镜像 tar,文件或目录,可多次 | +| `--mode A\|B` | 自动判断 | 强制 DinD (A) 或 Socket 代理 (B) | +| `--container-name ` | `ais_bench_agent` | runtime 容器名 | +| `--runtime-image ` | `ghcr.io/aisbench/agent-runtime:latest-ubuntu24.04-py312-${ARCH}` | runtime 镜像 tag | +| `--host-path ` | `/opt/ais_bench_agent` | 模式 B 时 `/benchmark` 提取目标 | + +### 环境变量 + +仅保留一个 env 变量(其它配置请用 CLI 参数): + +| env | 默认值 | 说明 | +|---|---|---| +| `OBS_RUNTIME_TAR_BASE` | `https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/runtime` | OBS runtime tar 下载基址(一般无需改) | + +### 离线场景 + +内网/隔离环境的部署机无法访问 `ghcr.io/aisbench/agent-runtime` 或 OBS,但已通过 U 盘、内网代理等方式拿到了 runtime tar 包和 case 镜像 tar: + +1. **获取 tar 包**(任选其一): + - 让维护者跑 `build_image_agent_runtime.sh --upload 1` 上传到 OBS,内网用户从 OBS 下载 + - 在能访问外网的机器上 `docker save ghcr.io/aisbench/agent-runtime: -o agent-runtime.tar.gz` 后拷贝进来 +2. **部署机执行**: + ```bash + # 最小:只传 runtime tar(case 镜像仍需在容器内手动 pull / load) + bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --runtime-tar /path/to/agent-runtime.tar.gz + + # 完全离线:runtime + case tar 都传 + bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /path/to/agent-runtime.tar.gz \ + --case-tar /path/to/case-tb2-mini-0.10.tar.gz + ``` +3. **行为**: + - `--runtime-tar`:完全跳过 `docker pull` 与 OBS 的 `curl` 下载;`docker load -i ` 后自动检测 tag(grep `agent-runtime`),优先匹配 `RUNTIME_IMAGE`;检测失败给精确错误 + - `--case-tar `:支持传单个 tar 或一个目录(目录会递归加载所有 `.tar` / `.tar.gz` / `.tgz`)。脚本会 `docker cp` 进容器,再用 `docker load -i` 加载。**支持 A/B 两种模式**(A 模式加载到容器内 DinD;B 模式加载到容器内,但因 socket 与宿主共享实际也加载到了宿主),模式A|B的具体介绍参考[OVERVIEW.zh.md](../OVERVIEW.zh.md#运行-agent--沙箱类测评在容器内使用-docker) + - 可多次 `--case-tar` + +模式 B(Socket 代理)默认会把 `/benchmark` 提取到宿主 `/opt/ais_bench_agent`。若你的环境 `/opt` 不可写(如某些只读根容器/沙箱),用 `--host-path` 改写到可写路径: + +```bash +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --host-path /data/ais_bench_host +``` + +正常物理机无需设置该变量。其余可配置环境变量见 `bootstrap.sh` 头部注释。 + +## 镜像构建 + +runtime 镜像基于 `aisbench_benchmark` 基镜构建,基镜像 tag 通过参数传入,不写死: + +```bash +# 基础构建(本地,当前架构) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master + +# 指定 OS/Python(默认 ubuntu24.04 + py312) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --os ubuntu24.04 --py-version py312 + +# 构建并推送到远程仓库 +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --push 1 + +# 多架构构建并推送 +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --multi-arch 1 --push 1 + +# 构建、推送、并上传离线包到 OBS(供 ais_bench_agent_bootstrap.sh 回退下载) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --push 1 --upload 1 +``` + +构建脚本会自动校验(4 项): +1. ais_bench 可用 +2. 3 个 venv(harbor / swebench / swebench_pro)都完整 + 3 个 venv 内都有 ais_bench wrapper + 两个 swebench venv 能 import minisweagent +3. doctor.sh / packs 就位 +4. harbor compose 模板已 patch `seccomp=unconfined` + +## 已支持的 pack + +| pack 名 | runtime_venv | 文档 | 说明 | +|---|---|---|---| +| `harbor` | harbor | [harbor_bench.md](../../docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md) | Harbor Terminal-Bench 2.0 | +| `swebench` | swebench | [swe_bench.md](../../docs/source_zh_cn/extended_benchmark/agent/swe_bench.md) | SWE-bench(lite/verified/full/multilingual 等) | +| `swebench_pro` | swebench_pro | [swe_bench_pro.md](../../docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md) | SWE-bench Pro(仅 x86) | + +pack.yaml 不声明数据集路径、不声明 case 镜像获取方式——这些完全交给用户掌控: +- 数据集路径:用户 `bootstrap.sh --datasets <完整数据集路径>` 时显式指定(要哪个就跑哪个) +- case 镜像:用户按 pack.yaml 的 `native_doc` 指向的文档自行 `docker pull` 或 `docker load` + +如果以后接更多 benchmark,每加一个 `packs/.yaml` 即可。 + +> 常用的 harbor 数据集目录名(仅供参考,与工具无关): +> - `/data/datasets/harbor/full/terminal-bench-2`(89 case,含少量外网任务) +> - `/data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10`(7 case) +> - `/data/datasets/harbor/mini-0.14/terminal-bench-2-offline-selected_0.14`(10 case) +> - `/data/datasets/harbor/mini-0.20/terminal-bench-2-offline-selected_0.20`(14 case) +> +> 用户在 `bootstrap.sh --datasets` 传入哪个路径,就由 env var `AISBENCH_AGENT_DATASET_PATH` 把哪个路径注入容器。 +> mini-* 系列基于 `terminal-bench-2-offline`(剔除外网任务后的 70 个 case)做 K-means 采样,完全离线可跑。 +> +> SWE-bench 数据集说明见 [swe_bench.md](../../docs/source_zh_cn/extended_benchmark/agent/swe_bench.md)(HF 下载);SWE-bench Pro 见 [swe_bench_pro.md](../../docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md)。 + +## 详细方案 + +完整设计与各脚本参数说明见各脚本头部注释。 \ No newline at end of file diff --git a/docker/agent_runtime/packs/harbor.yaml b/docker/agent_runtime/packs/harbor.yaml new file mode 100644 index 00000000..42ad4d0a --- /dev/null +++ b/docker/agent_runtime/packs/harbor.yaml @@ -0,0 +1,12 @@ +# Harbor Terminal-Bench 2.0 pack 元数据 +# 供 ais_bench_agent_doctor.sh 读取,验证该 pack 的 runtime 是否就绪 +# +# 字段用途: +# name pack 唯一标识 +# runtime_venv doctor L1 验证 /opt/venvs/ 存在 + python 可执行 +# native_config doctor L1 验证原生 ais_bench 配置文件存在 +# native_doc 跑完 doctor 后指引用户看哪份文档 +name: harbor-terminal-bench-2 +runtime_venv: harbor +native_config: ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py +native_doc: docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md diff --git a/docker/agent_runtime/packs/swebench.yaml b/docker/agent_runtime/packs/swebench.yaml new file mode 100644 index 00000000..ce60129d --- /dev/null +++ b/docker/agent_runtime/packs/swebench.yaml @@ -0,0 +1,12 @@ +# SWE-bench pack 元数据 +# 供 ais_bench_agent_doctor.sh 读取,验证该 pack 的 runtime 是否就绪 +# +# 字段用途: +# name pack 唯一标识 +# runtime_venv doctor L1 验证 /opt/venvs/ 存在 + python 可执行 +# native_config doctor L1 验证原生 ais_bench 配置文件存在 +# native_doc 跑完 doctor 后指引用户看哪份文档 +name: swebench +runtime_venv: swebench +native_config: ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py +native_doc: docs/source_zh_cn/extended_benchmark/agent/swe_bench.md \ No newline at end of file diff --git a/docker/agent_runtime/packs/swebench_pro.yaml b/docker/agent_runtime/packs/swebench_pro.yaml new file mode 100644 index 00000000..a99e9a15 --- /dev/null +++ b/docker/agent_runtime/packs/swebench_pro.yaml @@ -0,0 +1,15 @@ +# SWE-bench Pro pack 元数据 +# 供 ais_bench_agent_doctor.sh 读取,验证该 pack 的 runtime 是否就绪 +# +# 字段用途: +# name pack 唯一标识 +# runtime_venv doctor L1 验证 /opt/venvs/ 存在 + python 可执行 +# native_config doctor L1 验证原生 ais_bench 配置文件存在 +# native_doc 跑完 doctor 后指引用户看哪份文档 +# +# 注意:SWE-bench Pro 官方 docker 镜像均为 x86 架构,ARM 环境只能装 runtime, +# 跑测评时报 case 镜像架构不兼容。 +name: swebench_pro +runtime_venv: swebench_pro +native_config: ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py +native_doc: docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md \ No newline at end of file diff --git a/docker/agent_runtime/patches/harbor_compose_patch.py b/docker/agent_runtime/patches/harbor_compose_patch.py new file mode 100644 index 00000000..ac82f6f2 --- /dev/null +++ b/docker/agent_runtime/patches/harbor_compose_patch.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# Patch harbor 0.6.1 的 docker-compose-base.yaml: +# 1. 给 main service 追加 security_opt: ["seccomp=unconfined"] +# 2. 把 main service 的 network_mode 设为 "host" +# 两个改动都是 harbor_bench.md 第 2.2 节所要求的 agent-side patch。 +# +# 用法:harbor_compose_patch.py +# +# 与 Dockerfile.agent-runtime 的 RUN 段配合:从 build context COPY 进镜像后调用。 +# 用独立脚本而不是 RUN 内联 heredoc,是为了绕开 BuildKit 对 RUN 内嵌多行引号字符串的 +# 解析限制(Dockerfile 1.0 起就不支持引号内裸换行 + 续行符的混合写法)。 + +import sys +import yaml + + +def main() -> int: + if len(sys.argv) != 2: + print("usage: harbor_compose_patch.py ", + file=sys.stderr) + return 2 + + path = sys.argv[1] + + with open(path, "r", encoding="utf-8") as f: + cfg = yaml.safe_load(f) or {} + + svc = cfg.setdefault("services", {}).setdefault("main", {}) + opts = svc.setdefault("security_opt", []) + if "seccomp=unconfined" not in opts: + opts.append("seccomp=unconfined") + + # harbor_bench.md 第 2.2 节:agent 测评需要 main 直连宿主网络 + svc["network_mode"] = "host" + + with open(path, "w", encoding="utf-8") as f: + yaml.safe_dump(cfg, f, sort_keys=False, allow_unicode=True) + + print("patched:", path) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From fb425d327c2428b168bfaa4cc6a84cb531efa247 Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:42:17 +0800 Subject: [PATCH 5/9] add agent runtime build --- docker/agent_runtime/Dockerfile.agent-runtime | 279 ++++++++++ .../build_image_agent_runtime.sh | 482 ++++++++++++++++++ 2 files changed, 761 insertions(+) create mode 100644 docker/agent_runtime/Dockerfile.agent-runtime create mode 100644 docker/agent_runtime/build_image_agent_runtime.sh diff --git a/docker/agent_runtime/Dockerfile.agent-runtime b/docker/agent_runtime/Dockerfile.agent-runtime new file mode 100644 index 00000000..55d60b01 --- /dev/null +++ b/docker/agent_runtime/Dockerfile.agent-runtime @@ -0,0 +1,279 @@ +# AISBench Agent Runtime Dockerfile +# +# 在现有 aisbench_benchmark 基础镜像(已含 docker engine + compose + ais_bench)之上, +# 追加多 venv 隔离层,解决 agent 测评之间的依赖冲突: +# - harbor venv:隔离 harbor==0.6.1 强制升级的 datasets 4.0+,不污染主环境 +# + harbor_task.py 用 subprocess 启动 venv python,所以 venv 内还 +# 放了一个 ais_bench wrapper(shebang 指向 venv python), +# 让用户 `agent_env harbor` 后 which ais_bench 指向 venv 内 +# - swebench venv:装 AISBench fork 的 mini-swe-agent + SWE-bench harness +# - swebench_pro venv:装 scaleapi fork 的 mini-swe-agent + SWE-bench_Pro-os +# +# 三个 venv 都使用 --system-site-packages --copies: +# --system-site-packages: 让 venv 看到系统已装的 ais_bench_benchmark(共用基镜像, +# 不重复装 torch / datasets / tiktoken 等大依赖) +# --copies: 强制 python 二进制是真实副本(不是 symlink),否则 subprocess 启动时会 +# 丢 venv 身份(找不到 venv local 的包) +# +# 构建方式(推荐使用 build_image_agent_runtime.sh): +# bash docker/agent_runtime/build_image_agent_runtime.sh \ +# --base-tag v3.1-20260522-master --os ubuntu24.04 --py-version py312 +# +# 或直接 docker build: +# docker build \ +# --network host \ +# -f docker/agent_runtime/Dockerfile.agent-runtime \ +# -t ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 \ +# --build-arg BASE_IMAGE=ghcr.io/aisbench/aisbench_benchmark:v3.1-20260522-master-ubuntu24.04-py312-x86_64 \ +# . +# +# BASE_IMAGE 必须通过 --build-arg 传入,无默认值,避免基镜像 tag 写死导致过期。 + +ARG BASE_IMAGE +FROM ${BASE_IMAGE} + +ENV DEBIAN_FRONTEND=noninteractive +ENV PYTHONUNBUFFERED=1 + +# agent runtime 相关路径 +ENV AGENT_VENVS_ROOT=/opt/venvs +ENV AGENT_PACKS_ROOT=/opt/agent-resources/packs + +RUN mkdir -p ${AGENT_VENVS_ROOT} \ + ${AGENT_PACKS_ROOT} \ + /opt/src + +# ============================================================ +# venv: harbor +# harbor==0.6.1 会把 datasets 升到 4.0+,必须隔离在独立 venv +# 否则会污染 ais_bench 主环境,导致其他数据集依赖冲突 +# +# --system-site-packages: 让 venv 能看到基镜像里已经装好的 ais_bench_benchmark +# - ais_bench_benchmark 装在基镜像 /usr/local/lib/.../dist-packages/, +# 是 ais_bench 框架本体(benchmark / configs / datasets / tasks / ...) +# - venv 默认不读系统 site-packages,会导致 harbor_task.py 跑时找不到 ais_bench 包 +# - harbor 升级的 datasets 4.0+ 仍只装在 venv local site-packages, +# 不会污染系统环境(Python venv 优先用 local 包覆盖 system 包) +# +# --copies: 强制拷贝 python 二进制到 venv 内(默认是 symlink 到系统 python3.12) +# - harbor_task.py 通过 subprocess.Popen 以绝对路径启动 venv 的 python +# - 若 venv python 是 symlink,python 启动时通过 symlink 解析到 /usr/bin/python3.12, +# 丢失 venv 身份(不再读 venv 的 pyvenv.cfg),找不到 venv local 的 harbor 包 +# - 用 --copies 后 venv python 是真实二进制,python 通过真实路径识别 venv 身份, +# 正确加载 venv local site-packages +# ============================================================ +RUN python3.12 -m venv ${AGENT_VENVS_ROOT}/harbor --system-site-packages --copies && \ + ${AGENT_VENVS_ROOT}/harbor/bin/pip install --no-cache-dir --upgrade pip \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 && \ + ${AGENT_VENVS_ROOT}/harbor/bin/pip install --no-cache-dir \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 \ + harbor==0.6.1 + +# ============================================================ +# harbor venv 内放置 ais_bench 命令(关键) +# +# 问题链路(已修过的两层坑): +# 1. venv 默认不读系统 site-packages → 加 --system-site-packages ✓ +# 2. venv python 是 symlink 时丢身份 → 加 --copies ✓ +# 3. **主进程 sys.executable 是系统 python**(ais_bench 命令装在系统不在 venv) +# → harbor_task.py:44 python = sys.executable 拿到 /usr/bin/python3.12 +# → subprocess 启动系统 python(不是 venv python) +# → 系统 python 找不到 venv local 的 harbor 包 +# +# 修复:把 ais_bench wrapper 放到 harbor venv/bin 下,shebang 指向 venv python +# - 用户 agent_env harbor 后,PATH 中 venv/bin 在前 +# - which ais_bench → /opt/venvs/harbor/bin/ais_bench(venv 内) +# - shell 解析 shebang 用 venv python 启动 ais_bench +# - 主进程 sys.executable = venv python +# - harbor_task.py:44 拿到的也是 venv python +# - subprocess 启动 venv python → 找到 venv local site-packages → import harbor OK +# +# 注意:不依赖基镜像 /usr/local/bin/ais_bench 的具体实现,直接 import 调用 main() +# ========================================================= +RUN cat > ${AGENT_VENVS_ROOT}/harbor/bin/ais_bench <<'PYEOF' +#!/opt/venvs/harbor/bin/python +# -*- coding: utf-8 -*- +"""harbor venv 内置 ais_bench wrapper +启动时使用 harbor venv 的 python,让 subprocess.Popen 启动 harbor venv 的 python, +从而能正确加载 venv local site-packages(harbor 0.6.1 在此)。 +""" +import re +import sys +try: + from ais_bench.benchmark.cli.main import main +except ImportError as e: + sys.stderr.write(f"[error] failed to import ais_bench: {e}\n") + sys.stderr.write("[hint] 检查 harbor venv 是否启用 --system-site-packages(需看到系统 ais_bench)\n") + sys.exit(2) +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(main()) +PYEOF +RUN chmod +x ${AGENT_VENVS_ROOT}/harbor/bin/ais_bench + +# ============================================================ +# Patch harbor 的 docker-compose-base.yaml +# 模式 B(Socket 代理)下子容器由宿主 dockerd 创建,会继承宿主 seccomp +# profile。openEuler/RHEL 的默认 profile 比 Docker 官方严格,会拦截 +# OpenBLAS/NumPy 初始化线程时使用的 clone3 调用,表现为: +# OpenBLAS blas_thread_init: pthread_create failed: Operation not permitted +# 详见 docker/OVERVIEW.zh.md 模式 B 常见问题 +# +# harbor 0.6.1 的 compose 模板路径(python3.12 site-packages): +# harbor/environments/docker/docker-compose-base.yaml +# 在其中给 main service 补上 security_opt: [seccomp=unconfined] +# 模式 A(DinD)下此 patch 无副作用(子容器本就用 Docker 官方默认 profile) +# ============================================================ +COPY docker/agent_runtime/patches/harbor_compose_patch.py /tmp/harbor_compose_patch.py +RUN HARBOR_SITEPKG=$(${AGENT_VENVS_ROOT}/harbor/bin/python -c "import harbor, os; print(os.path.dirname(harbor.__file__))") && \ + COMPOSE_FILE="${HARBOR_SITEPKG}/environments/docker/docker-compose-base.yaml" && \ + if [ -f "$COMPOSE_FILE" ]; then \ + cp "$COMPOSE_FILE" "$COMPOSE_FILE.bak" && \ + python3.12 /tmp/harbor_compose_patch.py "${COMPOSE_FILE}"; \ + else \ + echo "[warn] harbor compose 模板未找到: $COMPOSE_FILE,跳过 patch"; \ + fi + +# ============================================================ +# venv: swebench +# SWE-bench / SWE-bench Pro 两个 benchmark 各需要一个 mini-swe-agent fork, +# 同包名 minisweagent 互相覆盖,必须在两个独立 venv 内安装。 +# +# 仓库选择: +# - AISBench fork (https://github.com/AISBench/mini-swe-agent) 用于 SWE-bench +# - scaleapi fork (https://github.com/scaleapi/mini-swe-agent) 用于 SWE-bench Pro +# +# 需要 ais_bench wrapper(与 harbor 同机理): +# - system /usr/local/bin/ais_bench 的 shebang 指向 system python3.12,不会自动切到 venv python +# - 用户 agent_env swebench 后,PATH 首位是 /opt/venvs/swebench/bin, +# 但 swebench/bin/ 下若没有 ais_bench,shell 仍落到 /usr/local/bin/ais_bench +# - task 代码 (swebench_infer.py) 在主进程 import minisweagent, +# system python 看不到 venv-local 的 minisweagent → ModuleNotFoundError +# - 在 swebench/bin/ 放一个 ais_bench wrapper(shebang 指向 venv python), +# PATH 命中它后启动 venv python → 正确加载 venv-local 的 minisweagent +# - 同时通过 --system-site-packages 仍能看到系统的 ais_bench / datasets / tasks +# ============================================================ +RUN python3.12 -m venv ${AGENT_VENVS_ROOT}/swebench --system-site-packages --copies && \ + ${AGENT_VENVS_ROOT}/swebench/bin/pip install --no-cache-dir --upgrade pip \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 && \ + git clone --depth 1 https://gh-proxy.com/https://github.com/AISBench/mini-swe-agent.git \ + /opt/src/mini-swe-agent-aisbench && \ + ${AGENT_VENVS_ROOT}/swebench/bin/pip install --no-cache-dir \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 \ + -e /opt/src/mini-swe-agent-aisbench && \ + git clone --depth 1 https://gh-proxy.com/https://github.com/SWE-bench/SWE-bench.git \ + /opt/src/SWE-bench && \ + ${AGENT_VENVS_ROOT}/swebench/bin/pip install --no-cache-dir \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 \ + -e /opt/src/SWE-bench + +# ais_bench wrapper for swebench venv(让主进程加载 venv-local 的 minisweagent) +RUN cat > ${AGENT_VENVS_ROOT}/swebench/bin/ais_bench <<'PYEOF' +#!/opt/venvs/swebench/bin/python +# -*- coding: utf-8 -*- +"""swebench venv 内置 ais_bench wrapper +启动时使用 swebench venv 的 python,让 task 代码 (swebench_infer.py) +在主进程 import minisweagent 时加载 venv-local 的 mini-swe-agent (AISBench fork)。 +""" +import re +import sys +try: + from ais_bench.benchmark.cli.main import main +except ImportError as e: + sys.stderr.write(f"[error] failed to import ais_bench: {e}\n") + sys.stderr.write("[hint] 检查 swebench venv 是否启用 --system-site-packages(需看到系统 ais_bench)\n") + sys.exit(2) +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(main()) +PYEOF +RUN chmod +x ${AGENT_VENVS_ROOT}/swebench/bin/ais_bench + +# ============================================================ +# venv: swebench_pro +# SWE-bench Pro 需用 scaleapi 适配的 mini-swe-agent 和官方 SWE-Bench_Pro-os +# 单独 venv 避免与 swebench venv 内的 mini-swe-agent fork 冲突 +# +# 同样需要 ais_bench wrapper(原因同上):主进程要加载 scaleapi fork 的 minisweagent +# +# ARM 限制:官方 docker 镜像均为 x86 架构,ARM 跑不动(runtime 仍可启动) +# ============================================================ +RUN python3.12 -m venv ${AGENT_VENVS_ROOT}/swebench_pro --system-site-packages --copies && \ + ${AGENT_VENVS_ROOT}/swebench_pro/bin/pip install --no-cache-dir --upgrade pip \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 && \ + git clone --depth 1 https://gh-proxy.com/https://github.com/scaleapi/mini-swe-agent.git \ + /opt/src/mini-swe-agent-scaleapi && \ + ${AGENT_VENVS_ROOT}/swebench_pro/bin/pip install --no-cache-dir \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 \ + -e /opt/src/mini-swe-agent-scaleapi && \ + git clone --depth 1 https://gh-proxy.com/https://github.com/scaleapi/SWE-bench_Pro-os.git \ + /opt/src/SWE-bench_Pro-os && \ + ${AGENT_VENVS_ROOT}/swebench_pro/bin/pip install --no-cache-dir \ + -i https://repo.huaweicloud.com/repository/pypi/simple \ + --trusted-host repo.huaweicloud.com \ + --default-timeout=120 --retries=5 \ + -r /opt/src/SWE-bench_Pro-os/requirements.txt + +# ais_bench wrapper for swebench_pro venv(让主进程加载 venv-local 的 minisweagent) +RUN cat > ${AGENT_VENVS_ROOT}/swebench_pro/bin/ais_bench <<'PYEOF' +#!/opt/venvs/swebench_pro/bin/python +# -*- coding: utf-8 -*- +"""swebench_pro venv 内置 ais_bench wrapper +启动时使用 swebench_pro venv 的 python,让 task 代码 (swebench_pro_infer.py) +在主进程 import minisweagent 时加载 venv-local 的 mini-swe-agent (scaleapi fork)。 +""" +import re +import sys +try: + from ais_bench.benchmark.cli.main import main +except ImportError as e: + sys.stderr.write(f"[error] failed to import ais_bench: {e}\n") + sys.stderr.write("[hint] 检查 swebench_pro venv 是否启用 --system-site-packages(需看到系统 ais_bench)\n") + sys.exit(2) +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(main()) +PYEOF +RUN chmod +x ${AGENT_VENVS_ROOT}/swebench_pro/bin/ais_bench + +# ============================================================ +# 脚本 + pack 清单 +# ============================================================ +COPY docker/agent_runtime/doctor.sh /usr/local/bin/ais_bench_agent_doctor.sh +RUN chmod +x /usr/local/bin/ais_bench_agent_doctor.sh + +COPY docker/agent_runtime/packs/ ${AGENT_PACKS_ROOT}/ + +# ============================================================ +# 便捷函数:激活对应 venv +# 用户在容器内 `agent_env harbor` 即可激活 harbor venv, +# 然后照常执行原生 ais_bench 命令 +# ============================================================ +RUN cat >> /etc/bash.bashrc <<'EOF' + +# AISBench Agent venv 激活便捷函数 +agent_env() { + case "$1" in + harbor) source /opt/venvs/harbor/bin/activate ;; + swebench) source /opt/venvs/swebench/bin/activate 2>/dev/null || echo "venv swebench 未安装" ;; + swebench_pro) source /opt/venvs/swebench_pro/bin/activate 2>/dev/null || echo "venv swebench_pro 未安装" ;; + *) echo "usage: agent_env " ;; + esac +} +EOF + +WORKDIR /benchmark diff --git a/docker/agent_runtime/build_image_agent_runtime.sh b/docker/agent_runtime/build_image_agent_runtime.sh new file mode 100644 index 00000000..d873bc7b --- /dev/null +++ b/docker/agent_runtime/build_image_agent_runtime.sh @@ -0,0 +1,482 @@ +#!/bin/bash +# +# 构建 AISBench Agent Runtime 镜像 +# +# 在 aisbench_benchmark 基础镜像之上追加多 venv 隔离层, +# 用于 agent 测评(Harbor Terminal-Bench 等)的环境准备。 +# +# 用法: +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag [选项] +# +# 必填参数: +# --base-tag 基镜像(aisbench_benchmark)的 TAG,例如 v3.1-20260522-master +# 会自动拼接为 :--- +# +# 可选参数: +# --os 操作系统,默认 ubuntu24.04 +# --py-version Python 版本,默认 py312(agent runtime 必须用 py312) +# --hub-repo 基镜像仓库地址,默认 ghcr.io/aisbench/aisbench_benchmark +# --target-hub-repo 目标镜像仓库地址(agent-runtime 镜像推到哪),默认 ghcr.io/aisbench/agent-runtime +# --image-output-dir 离线包输出目录,默认 /home/ais_bench_ci/release_images +# --obs-path OBS 工具路径,默认 /home/ais_bench_ci/obsutil_linux_arm64_5.7.9/ +# --push <0|1> 是否推送到远程仓库,默认 0 +# --upload <0|1> 是否上传离线包到 OBS,默认 0 +# --use-cache <0|1> 是否使用缓存构建,默认 0 +# --multi-arch <0|1> 是否构建多架构镜像(amd64+arm64),默认 0 +# -h, --help 显示帮助 +# +# 示例: +# # 基础构建(本地,x86_64 或 aarch64 视当前机器) +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag v3.1-20260522-master +# +# # 指定 OS/Python 版本 +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag v3.1-20260522-master \ +# --os ubuntu24.04 --py-version py312 +# +# # 构建并推送 +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag v3.1-20260522-master --push 1 +# +# # 多架构构建并推送(需在各自架构机器上分别执行 + manifest 合并) +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag v3.1-20260522-master \ +# --multi-arch 1 --push 1 +# +# # 构建、推送、并上传离线包到 OBS +# bash docker/agent_runtime/build_image_agent_runtime.sh --base-tag v3.1-20260522-master \ +# --push 1 --upload 1 + +set -e + +usage() { + echo "用法: $0 --base-tag [选项]" + echo "" + echo "必填参数:" + echo " --base-tag 基镜像(aisbench_benchmark)的 TAG,例如 v3.1-20260522-master" + echo "" + echo "可选参数:" + echo " --os 操作系统,默认: ubuntu24.04" + echo " --py-version Python 版本,默认: py312(agent runtime 推荐 py312)" + echo " --hub-repo 基镜像仓库地址,默认: ghcr.io/aisbench/aisbench_benchmark" + echo " --target-hub-repo 目标镜像仓库,默认: ghcr.io/aisbench/agent-runtime" + echo " --image-output-dir 离线包输出目录,默认: /home/ais_bench_ci/release_images" + echo " --obs-path OBS 工具路径,默认: /home/ais_bench_ci/obsutil_linux_arm64_5.7.9/" + echo " --push <0|1> 是否推送到远程仓库,默认: 0" + echo " --upload <0|1> 是否上传离线包到 OBS,默认: 0" + echo " --use-cache <0|1> 是否使用缓存构建,默认: 0" + echo " --multi-arch <0|1> 是否构建多架构镜像(amd64+arm64),默认: 0" + echo " -h, --help 显示本帮助" + echo "" + echo "示例:" + echo " $0 --base-tag v3.1-20260522-master" + echo " $0 --base-tag v3.1-20260522-master --push 1 --upload 1" + echo " $0 --base-tag v3.1-20260522-master --multi-arch 1 --push 1" + exit 1 +} + +# ============ 默认配置 ============ +BASE_TAG="" +OS="ubuntu24.04" +py_version="py312" +hub_repo="ghcr.io/aisbench/aisbench_benchmark" +target_hub_repo="ghcr.io/aisbench/agent-runtime" +image_output_dir="/home/ais_bench_ci/release_images" +obsutils_path="/home/ais_bench_ci/obsutil_linux_arm64_5.7.9/" +push=0 +upload=0 +use_cache=0 +multi_arch=0 + +# ============ 参数解析 ============ +while [[ $# -gt 0 ]]; do + case $1 in + --base-tag) + BASE_TAG="$2" + shift 2 + ;; + --os) + OS="$2" + shift 2 + ;; + --py-version) + py_version="$2" + shift 2 + ;; + --hub-repo) + hub_repo="$2" + shift 2 + ;; + --target-hub-repo) + target_hub_repo="$2" + shift 2 + ;; + --image-output-dir) + image_output_dir="$2" + shift 2 + ;; + --obs-path) + obsutils_path="$2" + shift 2 + ;; + --push) + push="$2" + shift 2 + ;; + --upload) + upload="$2" + shift 2 + ;; + --use-cache) + use_cache="$2" + shift 2 + ;; + --multi-arch) + multi_arch="$2" + shift 2 + ;; + -h|--help) + usage + ;; + *) + echo "错误:未知参数 $1" + usage + ;; + esac +done + +# ============ 校验必填参数 ============ +if [ -z "$BASE_TAG" ]; then + echo "错误:缺少必需参数 --base-tag" + echo "提示:--base-tag 是 aisbench_benchmark 基镜像的 TAG,例如 v3.1-20260522-master" + usage +fi + +# agent runtime 依赖 python3.12 的 venv,若用其他 py_version 给出警告 +if [ "$py_version" != "py312" ]; then + echo "警告:agent runtime 推荐 py312,当前指定 ${py_version},可能因缺 python3.12 导致 venv 创建失败" +fi + +# ============ 计算镜像名 ============ +arch=$(uname -m) + +# 基镜像全名: :--- +base_image="${hub_repo}:${BASE_TAG}-${OS}-${py_version}-${arch}" + +# 目标镜像全名: :--- +# 用 base-tag 作为 agent-runtime 的 tag,便于追溯基镜像版本 +image_name="${target_hub_repo}:${BASE_TAG}-${OS}-${py_version}-${arch}" + +# 多架构 manifest 名(不带 arch 后缀) +manifest_image_name="${target_hub_repo}:${BASE_TAG}-${OS}-${py_version}" + +# 离线包名 +offline_pkg_name="agent_runtime_image_${BASE_TAG}-${OS}-${py_version}-${arch}.tar.gz" +offline_pkg_full_path="${image_output_dir}/${offline_pkg_name}" + +# Dockerfile 路径 +dockerfile_path="$(dirname "$0")/Dockerfile.agent-runtime" + +if [ ! -f "${dockerfile_path}" ]; then + echo "错误:Dockerfile 不存在:${dockerfile_path}" + exit 1 +fi + +echo "============================================================" +echo " 构建 AISBench Agent Runtime 镜像" +echo "============================================================" +echo " 基镜像: ${base_image}" +echo " 目标镜像: ${image_name}" +echo " Dockerfile: ${dockerfile_path}" +echo " arch: ${arch}" +echo " push: ${push}" +echo " upload: ${upload}" +echo " use_cache: ${use_cache}" +echo " multi_arch: ${multi_arch}" +echo "============================================================" + +# ============ 检查基镜像是否存在(本地或远程) ============ +echo "检查基镜像 ${base_image} ..." +if ! docker image inspect "${base_image}" >/dev/null 2>&1; then + echo " 本地不存在,尝试 pull ..." + if ! docker pull "${base_image}" 2>/dev/null; then + echo "错误:基镜像拉取失败:${base_image}" + echo "提示:请确认 --base-tag / --os / --py-version / --hub-repo 参数正确" + exit 1 + fi +fi +echo " ✓ 基镜像就绪" + +# ============ 清理本地旧资源 ============ +echo "清理本地旧资源..." +if docker images -q "${image_name}" >/dev/null 2>&1; then + docker rmi -f "${image_name}" >/dev/null 2>&1 || true + echo " 已删除本地旧镜像:${image_name}" +fi +if [ -f "${offline_pkg_full_path}" ]; then + rm -f "${offline_pkg_full_path}" || true + echo " 已删除本地旧离线包:${offline_pkg_full_path}" +fi + +# ============ 构建镜像 ============ +BUILD_ARGS="--build-arg BASE_IMAGE=${base_image}" + +if [ "$use_cache" == "1" ]; then + echo "开始构建(使用缓存)..." + docker build \ + --network host \ + ${BUILD_ARGS} \ + -f "${dockerfile_path}" \ + -t "${image_name}" \ + "$(dirname "$0")/../../" +else + echo "开始构建(强制不使用缓存)..." + docker build \ + --no-cache \ + --network host \ + ${BUILD_ARGS} \ + -f "${dockerfile_path}" \ + -t "${image_name}" \ + "$(dirname "$0")/../../" +fi + +if [ $? -ne 0 ]; then + echo "错误:镜像构建失败" + exit 1 +fi +echo "✓ 镜像构建成功:${image_name}" + +# ============ 验证镜像 ============ +echo "开始验证镜像..." + +# 1. ais_bench 可用 +echo " [1/4] ais_bench 可用性..." +# ais_bench CLI 不支持 --version,用 --help 第一行即可 +validation_output=$(docker run --rm "${image_name}" ais_bench --help 2>&1 | head -1) || { + echo "错误:ais_bench 不可用" + echo "${validation_output}" + exit 1 +} +echo " ✓ ais_bench: ${validation_output}" + +# 2. venv 完整性 +echo " [2/4] venv 完整性..." +# 单独运行 venv 检查,每项独立 + set +e + 单独捕获 stderr, +# 让具体哪一项失败、错误信息是什么都能完整打印,方便排障 +docker run --rm "${image_name}" bash -c ' + set +e # 单个子命令失败不中止整体 + failures=() + + # 2.1 三个 venv 目录 + python 可执行 + for v in harbor swebench swebench_pro; do + if [ -d /opt/venvs/$v ] && [ -x /opt/venvs/$v/bin/python ]; then + ver=$(/opt/venvs/$v/bin/python --version 2>&1) + echo " ✓ $v venv: ${ver}" + else + echo " ✗ $v venv: 缺失或 python 不可执行" + failures+=("$v venv 缺失或 python 不可执行") + fi + done + + # 2.2 三个 venv 都需有 ais_bench wrapper + # harbor 的 wrapper 让 subprocess 启动 harbor venv 的 python; + # swebench / swebench_pro 的 wrapper 让主进程 import venv-local 的 minisweagent + for v in harbor swebench swebench_pro; do + if [ -x /opt/venvs/$v/bin/ais_bench ]; then + echo " ✓ $v-ais_bench-wrapper: OK" + else + echo " ✗ $v-ais_bench-wrapper: 缺失" + failures+=("$v-ais_bench-wrapper 缺失") + fi + done + + # 2.3 swebench / swebench_pro 各自能 import 对应 fork 的 mini-swe-agent + # PyPI 包名 mini-swe-agent(带横杠),但 Python 模块名是 minisweagent(连写无下划线) + # 单独捕获 stderr,方便看到 ModuleNotFoundError / 内部 ImportError 等真实错误 + for v in swebench swebench_pro; do + out=$(/opt/venvs/$v/bin/python -c "import minisweagent; print(minisweagent.__file__)" 2>&1) + rc=$? + if [ $rc -eq 0 ]; then + echo " ✓ $v minisweagent: ${out}" + else + echo " ✗ $v minisweagent: import 失败(python exit=$rc)" + echo " 错误信息:" + echo "$out" | sed "s/^/ /" + failures+=("$v minisweagent import 失败") + fi + done + + echo "" + if [ ${#failures[@]} -gt 0 ]; then + echo " 失败项汇总 (${#failures[@]}):" + for f in "${failures[@]}"; do + echo " - $f" + done + echo "" + echo " 排查建议:" + echo " 1. 进入镜像手动检查:" + echo " docker run --rm -it ${image_name} bash" + echo " ls -la /opt/venvs/" + echo " /opt/venvs/swebench/bin/python --version" + echo " /opt/venvs/swebench/bin/python -c \"import minisweagent\"" + echo " 2. 若 import 报 ModuleNotFoundError:Dockerfile 步骤 8/9 的 pip install 未生效;" + echo " 检查 gh-proxy.com / 华为云 pypi 镜像可达性;可加 --no-cache 强制重建步骤 8/9。" + echo " 3. 若 import 报内部 ImportError:minisweagent 自身依赖在当前 venv 内不可见;" + echo " 检查 mini-swe-agent setup.py 的 install_requires 在 venv 内是否齐全。" + exit 1 + fi +' || { + echo "错误:venv 检查失败(详见上方失败项汇总与排查建议)" + exit 1 +} +echo " ✓ harbor / swebench / swebench_pro venv 都完整" + +# 3. doctor.sh / packs 就位 +echo " [3/4] 脚本就位..." +scripts_output=$(docker run --rm "${image_name}" bash -c ' + [ -x /usr/local/bin/ais_bench_agent_doctor.sh ] && echo "doctor.sh: OK" || echo "doctor.sh: 缺失" + ls /opt/agent-resources/packs/*.yaml 2>/dev/null | while read f; do + echo "pack: $(basename $f .yaml)" + done +') || { + echo "错误:脚本检查失败" + exit 1 +} +echo "${scripts_output}" | sed 's/^/ /' + +# 4. harbor 的 docker-compose-base.yaml 已 patch +echo " [4/4] harbor compose 模板 patch 校验..." +patch_output=$(docker run --rm "${image_name}" bash -c ' + /opt/venvs/harbor/bin/python -c " +import harbor, os, yaml +p = os.path.dirname(harbor.__file__) + \"/environments/docker/docker-compose-base.yaml\" +cfg = yaml.safe_load(open(p)) +svc = cfg.get(\"services\", {}).get(\"main\", {}) +opts = svc.get(\"security_opt\", []) +print(\"seccomp=unconfined:\", \"seccomp=unconfined\" in opts) +print(\"network_mode=host:\", svc.get(\"network_mode\") == \"host\") +" 2>&1 +') || { + echo "错误:harbor compose 模板校验失败" + echo "${patch_output}" + exit 1 +} +echo "${patch_output}" | sed 's/^/ /' +if ! echo "${patch_output}" | grep -q "seccomp=unconfined: True"; then + echo "错误:harbor compose 模板未正确 patch seccomp" + exit 1 +fi +echo " ✓ harbor compose patch OK" + +echo "✓ 镜像验证通过" + +# ============ 推送镜像 ============ +if [ "$push" == "1" ]; then + echo "推送镜像到远程仓库..." + docker push "${image_name}" + if [ $? -ne 0 ]; then + echo "错误:镜像推送失败" + exit 1 + fi + echo "✓ 已推送:${image_name}" + + # 同时打 latest tag 并推送,供 bootstrap.sh 默认拉取 + latest_image_name="${target_hub_repo}:latest-${OS}-${py_version}-${arch}" + echo " 打 latest tag: ${latest_image_name}" + docker tag "${image_name}" "${latest_image_name}" + docker push "${latest_image_name}" + if [ $? -ne 0 ]; then + echo "错误:latest tag 推送失败" + exit 1 + fi + echo "✓ 已推送 latest:${latest_image_name}" +fi + +# ============ 多架构 manifest 合并 ============ +if [ "$multi_arch" == "1" ]; then + if [ "$push" != "1" ]; then + echo "提示:多架构模式下未开启推送,manifest 合并需要已推送的镜像。跳过 manifest 合并。" + else + arch_image_amd64="${target_hub_repo}:${BASE_TAG}-${OS}-${py_version}-x86_64" + arch_image_arm64="${target_hub_repo}:${BASE_TAG}-${OS}-${py_version}-aarch64" + latest_arch_image_amd64="${target_hub_repo}:latest-${OS}-${py_version}-x86_64" + latest_arch_image_arm64="${target_hub_repo}:latest-${OS}-${py_version}-aarch64" + latest_manifest_image_name="${target_hub_repo}:latest-${OS}-${py_version}" + + echo "创建多架构 manifest list:${manifest_image_name}" + echo " - ${arch_image_amd64}" + echo " - ${arch_image_arm64}" + + docker buildx imagetools create \ + -t "${manifest_image_name}" \ + "${arch_image_amd64}" \ + "${arch_image_arm64}" + + if [ $? -ne 0 ]; then + echo "错误:多架构 manifest 创建失败" + exit 1 + fi + echo "✓ 多架构 manifest list 已更新:${manifest_image_name}" + + echo "创建 latest 多架构 manifest list:${latest_manifest_image_name}" + echo " - ${latest_arch_image_amd64}" + echo " - ${latest_arch_image_arm64}" + + docker buildx imagetools create \ + -t "${latest_manifest_image_name}" \ + "${latest_arch_image_amd64}" \ + "${latest_arch_image_arm64}" + + if [ $? -ne 0 ]; then + echo "错误:latest 多架构 manifest 创建失败" + exit 1 + fi + echo "✓ latest 多架构 manifest list 已更新:${latest_manifest_image_name}" + echo " docker buildx imagetools inspect ${manifest_image_name}" + echo " docker buildx imagetools inspect ${latest_manifest_image_name}" + fi +fi + +# ============ 打包离线包并上传 OBS ============ +if [ "$upload" == "1" ]; then + echo "打包离线包..." + mkdir -p "${image_output_dir}" + docker save "${image_name}" | gzip -9 > "${offline_pkg_full_path}" + echo " 离线包已生成:${offline_pkg_full_path}" + chmod 640 "${offline_pkg_full_path}" + + echo "上传离线包到 OBS 桶..." + if [ ! -d "${obsutils_path}" ] || [ ! -x "${obsutils_path}/obsutil" ]; then + echo "错误:obsutil 路径不存在或不可执行:${obsutils_path}" + exit 1 + fi + + cd "${obsutils_path}" + ./obsutil cp "${offline_pkg_full_path}" "obs://aisbench/images/agent/runtime/${offline_pkg_name}" -f + + if [ $? -eq 0 ]; then + echo "✓ 离线包已上传:obs://aisbench/images/agent/runtime/${offline_pkg_name}" + else + echo "错误:OBS 桶上传失败" + exit 1 + fi +fi + +# ============ 完成 ============ +echo "" +echo "============================================================" +echo "✓ 构建完成" +echo "============================================================" +echo " 镜像: ${image_name}" +if [ "$push" == "1" ]; then + echo " latest: ${target_hub_repo}:latest-${OS}-${py_version}-${arch}" +fi +if [ "$multi_arch" == "1" ] && [ "$push" == "1" ]; then + echo " manifest: ${manifest_image_name}" + echo " latest manifest: ${target_hub_repo}:latest-${OS}-${py_version}" +fi +if [ "$upload" == "1" ]; then + echo " 离线包: obs://aisbench/images/agent/runtime/${offline_pkg_name}" +fi +echo "" +echo "用户使用:" +echo " curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh | bash" +echo " # 或本地测试:" +echo " bash docker/agent_runtime/bootstrap.sh --mode A" From 60ba29e16600d0224a17381aabedeed9fa66fe62 Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 14:42:45 +0800 Subject: [PATCH 6/9] add auto scripts --- .../ais_bench_agent_bootstrap.sh | 526 ++++++++++++++++++ docker/agent_runtime/doctor.sh | 169 ++++++ 2 files changed, 695 insertions(+) create mode 100644 docker/agent_runtime/ais_bench_agent_bootstrap.sh create mode 100644 docker/agent_runtime/doctor.sh diff --git a/docker/agent_runtime/ais_bench_agent_bootstrap.sh b/docker/agent_runtime/ais_bench_agent_bootstrap.sh new file mode 100644 index 00000000..4def7964 --- /dev/null +++ b/docker/agent_runtime/ais_bench_agent_bootstrap.sh @@ -0,0 +1,526 @@ +#!/bin/bash +# ais_bench_agent_bootstrap.sh +# +# 一键准备 AISBench Agent 测评运行环境(runtime 容器) +# +# 本脚本在物理机上执行,完成: +# 1. 探测宿主 docker / cgroup / arch +# 2. 自动选择 DinD(模式 A)或 Socket 代理(模式 B) +# 3. 拉取 agent-runtime 镜像(dockerhub 优先,OBS tar 回退) +# 4. 启动 runtime 容器(自动带 --privileged / --cgroupns=host / daemon.json) +# 5. 容器内启动 dockerd(模式 A)或重链 ais_bench(模式 B) +# 6. (可选)把宿主的数据集目录挂载进容器(--datasets ) +# 7. 自检并打印下一步(doctor → 原生 ais_bench) +# +# 本脚本不接管测评执行,也不预置数据集 / case 镜像: +# - 数据集由用户在物理机上准备好,通过 --datasets 挂载到容器内同路径 +# - case 沙箱镜像由用户自行 docker pull / docker load 后再跑测评 +# 环境就绪后,用户用原生 ais_bench 命令跑测评,原理与各 benchmark 文档完全一致。 +# +# 用法: +# curl -fsSL /ais_bench_agent_bootstrap.sh | bash -s -- --datasets /data/datasets +# bash ais_bench_agent_bootstrap.sh --datasets /data/datasets +# +# 环境变量(仅 OBS_RUNTIME_TAR_BASE 保留为 env,其他配置请用 CLI 参数): +# OBS_RUNTIME_TAR_BASE OBS runtime tar 下载基址(一般无需改,正常物理机无需设置) +# +# 命令行参数: +# --datasets 把宿主 挂载到容器内的相同路径 +# 同时把首个 --datasets 路径作为环境变量 +# AISBENCH_AGENT_DATASET_PATH 注入容器(这就是 +# 原生配置 path 的值,不在容器内做任何拼接)。 +# +# 直接传 harbor benchmark 数据集完整目录即可: +# --datasets /data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10 +# 或 full: +# --datasets /data/datasets/harbor/full/terminal-bench-2 +# 原生配置(如 harbor_terminal_bench_2_task.py)从 +# env var 直接读 path,无需 vim 修改。 +# +# 可多次指定挂载多个目录,但只有首个路径会注入 env var。 +# 多目录场景下用户可手动 export AISBENCH_AGENT_DATASET_PATH +# 覆盖。 +# --runtime-tar 离线模式:用宿主上已下载好的 tar 包加载 runtime 镜像, +# 完全跳过 docker pull / OBS 下载。 +# 适用场景:内网/隔离环境部署机无法访问 registry。 +# tar 可通过以下方式获取: +# - 维护者用 build_image_agent_runtime.sh --upload 1 上传 OBS 后下载 +# - 拷贝到 U 盘/内网代理服务器后再 wget +# - 镜像构建产物(docker save)直接拷贝 +# tar 内镜像 tag 默认从 tar 内检测(grep agent-runtime), +# 若 RUNTIME_IMAGE 已在宿主机存在则优先匹配。 +# 例: --runtime-tar /opt/aisbench/agent-runtime-ubuntu24-py312-x86_64.tar.gz +# --case-tar 离线场景:把宿主上已下载好的 case 沙箱镜像 tar 加载进 runtime 容器内 +# 的 docker daemon。路径可以是单个 tar 文件,也可以是一个文件夹 +# (脚本会递归加载其中所有 .tar / .tar.gz / .tgz 文件)。 +# 适用于 case 镜像提前下载到本地、内网无法 pull 的场景。 +# 加载完成后镜像就在 runtime 容器内可见,可直接跑测评。 +# (可多次指定) +# 例: --case-tar /opt/aisbench/case-tb2-mini-0.10.tar.gz +# --case-tar /opt/aisbench/case-tars/ +# --mode A|B 强制指定 DinD (A) 或 Socket 代理 (B)。不传则按 +# docker 版本 + cgroup 类型自动判断。 +# --container-name runtime 容器名(默认 ais_bench_agent)。用于一台机器上 +# 同时跑多个独立 runtime 容器时区分。 +# --runtime-image 指定 runtime 镜像 tag(默认 latest-ubuntu24.04-py312-${ARCH})。 +# 推荐显式传具体 commit tag 以保证可复现性: +# --runtime-image ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 +# --host-path 仅模式 B 生效。/benchmark 的提取目标目录, +# 默认 /opt/ais_bench_agent。仅 /opt 不可写的受限环境需要改。 + +set -e + +# ============ 默认配置 ============ +# runtime 镜像 tag 格式: :--- +# 例如 ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 +# +# 默认用 "latest" tag(CI 构建时打 latest,指向最新版本),用户推荐显式传 --runtime-image +# 指定具体版本,以保证可复现性: +# bash bootstrap.sh --runtime-image ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 --datasets /data/datasets +# +# 构建脚本(build_image_agent_runtime.sh)产出的 tag 形如 +# ghcr.io/aisbench/agent-runtime:--- +# 推送时若同时打了 latest---,本脚本默认拉 latest。 +ARCH=$(uname -m) + +# 仅保留的 env 变量(CLI 参数已替代其他所有 env 配置) +OBS_RUNTIME_TAR_BASE="${OBS_RUNTIME_TAR_BASE:-https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/runtime}" + +# CLI 参数暂存变量(由 --xxx 填充;后续 [应用默认值] 段统一给最终值) +MODE_FORCE="" +CONTAINER_NAME_CLI="" +RUNTIME_IMAGE_CLI="" +HOST_PATH_CLI="" + +# 用户要挂载进容器的宿主数据集路径(可多个) +DATASET_MOUNTS=() +# 离线模式:用户提供的 runtime tar 包路径(绝对路径) +RUNTIME_TAR="" +# 离线模式:用户提供的 case 沙箱镜像 tar(文件或目录,可多个) +CASE_TAR_PATHS=() + +# ============ 参数解析 ============ +while [[ $# -gt 0 ]]; do + case "$1" in + --datasets) + [ -z "${2:-}" ] && { echo "[错误] --datasets 需要一个绝对路径" >&2; exit 1; } + [[ "$2" != /* ]] && { echo "[错误] --datasets 必须是绝对路径: $2" >&2; exit 1; } + [ ! -d "$2" ] && { echo "[错误] --datasets 路径在宿主上不存在: $2" >&2; exit 1; } + DATASET_MOUNTS+=("$2") + shift 2 + ;; + --runtime-tar) + [ -z "${2:-}" ] && { echo "[错误] --runtime-tar 需要一个绝对路径" >&2; exit 1; } + [[ "$2" != /* ]] && { echo "[错误] --runtime-tar 必须是绝对路径: $2" >&2; exit 1; } + [ ! -f "$2" ] && { echo "[错误] --runtime-tar 文件在宿主上不存在: $2" >&2; exit 1; } + RUNTIME_TAR="$2" + shift 2 + ;; + --case-tar) + [ -z "${2:-}" ] && { echo "[错误] --case-tar 需要一个绝对路径" >&2; exit 1; } + [[ "$2" != /* ]] && { echo "[错误] --case-tar 必须是绝对路径: $2" >&2; exit 1; } + [ ! -e "$2" ] && { echo "[错误] --case-tar 路径在宿主上不存在: $2" >&2; exit 1; } + CASE_TAR_PATHS+=("$2") + shift 2 + ;; + --mode) + [ -z "${2:-}" ] && { echo "[错误] --mode 需要 A 或 B" >&2; exit 1; } + case "$2" in + A|B) MODE_FORCE="$2" ;; + *) echo "[错误] --mode 必须是 A 或 B,收到: $2" >&2; exit 1 ;; + esac + shift 2 + ;; + --container-name) + [ -z "${2:-}" ] && { echo "[错误] --container-name 不能为空" >&2; exit 1; } + CONTAINER_NAME_CLI="$2" + shift 2 + ;; + --runtime-image) + [ -z "${2:-}" ] && { echo "[错误] --runtime-image 不能为空" >&2; exit 1; } + RUNTIME_IMAGE_CLI="$2" + shift 2 + ;; + --host-path) + [ -z "${2:-}" ] && { echo "[错误] --host-path 需要一个绝对路径" >&2; exit 1; } + [[ "$2" != /* ]] && { echo "[错误] --host-path 必须是绝对路径: $2" >&2; exit 1; } + HOST_PATH_CLI="$2" + shift 2 + ;; + -h|--help) + sed -n '2,80p' "$0" | sed 's/^# *//' + exit 0 + ;; + *) echo "[错误] 未知参数: $1" >&2; exit 1 ;; + esac +done + +# ============ 应用默认值 ============ +# 仅 CLI 参数与 hardcoded 默认,不读 env + +# --mode:默认空(自动判断) +MODE="${MODE_FORCE:-}" + +# --container-name(默认 ais_bench_agent) +CONTAINER_NAME="${CONTAINER_NAME_CLI:-ais_bench_agent}" + +# --runtime-image(默认 latest-${OS}-${PY}-${ARCH}) +RUNTIME_IMAGE="${RUNTIME_IMAGE_CLI:-ghcr.io/aisbench/agent-runtime:latest-ubuntu24.04-py312-${ARCH}}" + +# --host-path(仅模式 B,默认 /opt/ais_bench_agent) +HOST_PATH="${HOST_PATH_CLI:-/opt/ais_bench_agent}" + +# ============ 工具函数 ============ +log() { echo "[$(date +%H:%M:%S)] $*"; } +fail() { echo "[错误] $*" >&2; exit 1; } + +# ============ [1/6] 探测宿主环境 ============ +log "=== [1/6] 探测宿主环境 ===" + +command -v docker >/dev/null 2>&1 || fail "宿主未安装 docker,请先安装 docker(>= 20.10)" + +DOCKER_VER=$(docker version --format '{{.Server.Version}}' 2>/dev/null | head -1) +[ -z "$DOCKER_VER" ] && fail "无法获取 docker 版本,请确认 docker daemon 已启动" +DOCKER_MAJOR=$(echo "$DOCKER_VER" | cut -d. -f1) + +CGROUP_TYPE=$(stat -fc %T /sys/fs/cgroup 2>/dev/null || echo "unknown") + +log " Docker: ${DOCKER_VER} (major=${DOCKER_MAJOR})" +log " cgroup: ${CGROUP_TYPE}" +log " arch: ${ARCH}" +if [ "${#DATASET_MOUNTS[@]}" -gt 0 ]; then + log " datasets挂载(${#DATASET_MOUNTS[@]} 个):" + for p in "${DATASET_MOUNTS[@]}"; do + log " - 宿主 ${p} → 容器内 ${p}" + done + log " 环境变量 AISBENCH_AGENT_DATASET_PATH=${DATASET_MOUNTS[0]}(容器内可读)" +else + log " datasets挂载: 无(用户未传 --datasets;配置中 path 字段需自行保证可用)" +fi +if [ -n "${RUNTIME_TAR}" ]; then + SIZE=$(du -h "${RUNTIME_TAR}" 2>/dev/null | cut -f1) + log " runtime来源: 离线 tar ${RUNTIME_TAR} (${SIZE})" +else + log " runtime来源: registry pull / OBS 回退(默认行为)" +fi +if [ "${#CASE_TAR_PATHS[@]}" -gt 0 ]; then + log " case镜像来源(${#CASE_TAR_PATHS[@]} 个,运行时加载进容器 docker daemon):" + for p in "${CASE_TAR_PATHS[@]}"; do + log " - ${p} ($(if [ -d "$p" ]; then echo dir; else echo "file $(du -h "$p" 2>/dev/null | cut -f1)"; fi))" + done +else + log " case镜像来源: 容器内手动 docker pull / load(默认行为)" +fi + +# ============ [2/6] 选择 DinD/Socket 模式 ============ +log "=== [2/6] 选择 DinD/Socket 模式 ===" + +if [ -n "${MODE:-}" ]; then + log " → 强制模式 ${MODE}(--mode)" +else + # 模式 A 推荐:docker >= 20.10 + cgroup v2 + # 模式 B 兼容:任意 docker 版本 + # 详见 docker/OVERVIEW.zh.md "运行 Agent / 沙箱类测评" + if [ "${DOCKER_MAJOR}" -ge 20 ] && [ "${CGROUP_TYPE}" = "cgroup2fs" ]; then + MODE="A" + log " → 模式 A (Docker-in-Docker,推荐,子容器隔离)" + else + MODE="B" + log " → 模式 B (Socket 代理,兼容任意 docker 版本)" + log " 原因: docker_major=${DOCKER_MAJOR} (<20) 或 cgroup=${CGROUP_TYPE} (!=cgroup2fs)" + fi +fi + +# ============ [3/6] 拉取 agent-runtime 镜像 ============ +log "=== [3/6] 拉取 agent-runtime 镜像 ===" + +if [ -n "${RUNTIME_TAR}" ]; then + # ---------- 离线模式:用户提供的 tar ---------- + log " 离线模式:跳过 docker pull / OBS 下载" + log " docker load -i ${RUNTIME_TAR}" + docker load -i "${RUNTIME_TAR}" || fail "docker load 失败: ${RUNTIME_TAR}" + # 检测 tar 加载后的镜像 tag + if docker image inspect "${RUNTIME_IMAGE}" >/dev/null 2>&1; then + log " ✓ 使用 RUNTIME_IMAGE 指定的 tag: ${RUNTIME_IMAGE}" + else + DETECTED=$(docker images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -i 'agent-runtime' | head -1 || true) + if [ -z "${DETECTED}" ]; then + fail "tar 加载完成但未发现 agent-runtime 镜像;tar 内容或 RUNTIME_IMAGE 可能不匹配" + fi + log " ✓ tar 中检测到镜像: ${DETECTED}" + RUNTIME_IMAGE="${DETECTED}" + fi +elif docker image inspect "${RUNTIME_IMAGE}" >/dev/null 2>&1; then + log " ✓ runtime 镜像已存在本地: ${RUNTIME_IMAGE}" +else + log " 尝试 docker pull ${RUNTIME_IMAGE} ..." + if docker pull "${RUNTIME_IMAGE}" 2>/dev/null; then + log " ✓ docker pull 成功" + else + log " docker pull 失败,回退 OBS tar" + TAR_URL="${OBS_RUNTIME_TAR_BASE}/agent-runtime-ubuntu24-py312-${ARCH}.tar.gz" + log " 下载: ${TAR_URL}" + curl -fsSL "${TAR_URL}" -o /tmp/agent-runtime.tar.gz || fail "OBS 下载失败: ${TAR_URL}" + log " docker load ..." + docker load -i /tmp/agent-runtime.tar.gz || fail "docker load 失败" + rm -f /tmp/agent-runtime.tar.gz + log " ✓ OBS tar 加载成功" + fi +fi + +# ============ [4/6] 启动容器 ============ +log "=== [4/6] 启动容器(模式 ${MODE})===" + +# 清理同名旧容器 +if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log " 清理同名旧容器: ${CONTAINER_NAME}" + docker rm -f "${CONTAINER_NAME}" >/dev/null +fi + +# 拼装数据集挂载参数 +MOUNT_ARGS="" +for p in "${DATASET_MOUNTS[@]+"${DATASET_MOUNTS[@]}"}"; do + MOUNT_ARGS="$MOUNT_ARGS -v ${p}:${p}" +done + +# 把首个 --datasets 路径持久化为容器内环境变量 +# 原生配置(如 harbor_terminal_bench_2_task.py)通过读取此变量得到数据集路径, +# 无需用户在容器内额外配置,符合"一键准备"的设计目标。 +# 多 --datasets 时仅首个生效,其余需用户自行改 DEFAULT_DATASET_PATH。 +DATASET_ENV="" +if [ "${#DATASET_MOUNTS[@]}" -gt 0 ]; then + DATASET_ENV="-e AISBENCH_AGENT_DATASET_PATH=${DATASET_MOUNTS[0]}" +fi + +if [ "${MODE}" = "A" ]; then + # 模式 A:Docker-in-Docker + # cgroup v2 宿主机 --privileged + --cgroupns=host 必须同时使用 + # 缺少 --cgroupns=host 会报 "cannot enter cgroupv2 ... invalid state" + # 详见 docker/OVERVIEW.zh.md 模式 A + docker run --name "${CONTAINER_NAME}" -it -d \ + --net=host --ipc=host \ + --privileged --cgroupns=host \ + -w /benchmark \ + ${MOUNT_ARGS} \ + ${DATASET_ENV} \ + "${RUNTIME_IMAGE}" bash +else + # 模式 B:Socket 代理 + # 挂载宿主 docker socket,子容器由宿主 daemon 创建 + # 需要把 /benchmark 拷贝到宿主路径再挂回去(避免 docker cp 语义) + # 详见 docker/OVERVIEW.zh.md 模式 B + # HOST_PATH 已在前面 [应用默认值] 段统一计算 + log " 模式 B 准备 HOST_PATH: ${HOST_PATH}" + mkdir -p "${HOST_PATH}" + + # 从 runtime 镜像拷贝 /benchmark 内容到 HOST_PATH + log " 提取 /benchmark 到 ${HOST_PATH} ..." + docker run -d --name tmp_extract "${RUNTIME_IMAGE}" bash >/dev/null + docker cp tmp_extract:/benchmark/. "${HOST_PATH}/" || { docker rm -f tmp_extract; fail "docker cp 失败"; } + docker rm -f tmp_extract >/dev/null + + docker run --name "${CONTAINER_NAME}" -it -d \ + --net=host --privileged \ + -w "${HOST_PATH}" \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "${HOST_PATH}":"${HOST_PATH}" \ + ${MOUNT_ARGS} \ + ${DATASET_ENV} \ + "${RUNTIME_IMAGE}" bash +fi + +log " ✓ 容器已启动: ${CONTAINER_NAME}" + +# ============ [5/6] 容器内配置 docker ============ +log "=== [5/6] 容器内配置 docker ===" + +if [ "${MODE}" = "A" ]; then + # 模式 A:容器内启动 dockerd + # 必须写 daemon.json: + # - cgroupfs driver:DinD 在 cgroup v2 宿主上的必需配置(docker 27.x 默认 systemd,容器内无 systemd) + # - vfs 存储驱动:DinD 通用性最高;若宿主内核与容器根fs支持,overlay2 性能更好 + # 详见 docker/OVERVIEW.zh.md 模式 A 步骤二 + docker exec "${CONTAINER_NAME}" bash -c ' + set -e + mkdir -p /etc/docker + cat > /etc/docker/daemon.json < /tmp/dockerd.log 2>&1 & + for i in $(seq 1 30); do + [ -S /var/run/docker.sock ] && break + sleep 1 + done + if ! docker info >/dev/null 2>&1; then + echo "[错误] 容器内 dockerd 启动失败,日志:" + tail -30 /tmp/dockerd.log + exit 1 + fi + echo " ✓ 容器内 dockerd ready" + ' || fail "模式 A dockerd 启动失败" +else + # 模式 B:socket 已挂载,重链 ais_bench + # 因为 WORKDIR 改到了 HOST_PATH,需要在该路径重新以 editable 模式安装 ais_bench + # 只链接不改依赖(--no-deps) + # 详见 docker/OVERVIEW.zh.md 模式 B 步骤二 + docker exec "${CONTAINER_NAME}" bash -c ' + pip3 install -e ./ --use-pep517 --no-deps --no-build-isolation --break-system-packages >/dev/null 2>&1 \ + && echo " ✓ ais_bench relinked" \ + || echo " ⚠ ais_bench relink 失败(可忽略,若 ais_bench 命令可用即可)" + ' +fi + +# ============ [6/7] 加载 case 镜像(可选) ============ +log "=== [6/7] 加载 case 镜像(可选)===" + +if [ "${#CASE_TAR_PATHS[@]}" -gt 0 ]; then + # 把 --case-tar 展开成具体的 tar 文件列表 + log " 收集 case tar 文件..." + CASE_TAR_FILES=() + for p in "${CASE_TAR_PATHS[@]}"; do + if [ -f "$p" ]; then + # 单个文件 + case "$p" in + *.tar|*.tar.gz|*.tgz) CASE_TAR_FILES+=("$p") ;; + *) log " [跳过] 不是 docker tar: $p"; ;; + esac + elif [ -d "$p" ]; then + # 目录:递归收集所有 .tar/.tar.gz/.tgz + while IFS= read -r -d '' f; do + CASE_TAR_FILES+=("$f") + done < <(find "$p" -type f \( -name "*.tar" -o -name "*.tar.gz" -o -name "*.tgz" \) -print0 2>/dev/null) + fi + done + + if [ "${#CASE_TAR_FILES[@]}" -eq 0 ]; then + log " ⚠ --case-tar 路径下未发现 .tar/.tar.gz/.tgz 文件,跳过加载" + else + log " 共 ${#CASE_TAR_FILES[@]} 个 case tar 待加载" + + # 在容器内建暂存目录 + docker exec "${CONTAINER_NAME}" mkdir -p /tmp/case-tars + + # 用 docker cp 把每个 tar 拷进容器 + i=0 + for f in "${CASE_TAR_FILES[@]}"; do + i=$((i+1)) + BN=$(basename "$f") + SIZE=$(du -h "$f" 2>/dev/null | cut -f1) + log " [${i}/${#CASE_TAR_FILES[@]}] docker cp ${f} (${SIZE})" + docker cp "$f" "${CONTAINER_NAME}:/tmp/case-tars/${BN}" || { + log " ✗ docker cp 失败,跳过该文件" + continue + } + done + + # 容器内 docker load 每一个 + log " 容器内 docker load ..." + docker exec "${CONTAINER_NAME}" bash -c ' + cd /tmp/case-tars + loaded=0 + failed=0 + for tf in *.tar *.tar.gz *.tgz; do + [ -f "$tf" ] || continue + sz=$(du -h "$tf" | cut -f1) + echo " loading $tf ($sz) ..." + if out=$(docker load -i "$tf" 2>&1); then + loaded=$((loaded+1)) + echo " ✓ $(echo "$out" | tail -1)" + else + failed=$((failed+1)) + echo " ✗ docker load 失败: $out" + fi + done + echo " docker load 完成: ${loaded} 个成功, ${failed} 个失败" + rm -rf /tmp/case-tars + ' || log " ⚠ 容器内 docker load 阶段出错(请人工 docker exec 进容器检查)" + fi +else + log " 未传 --case-tar,跳过(容器内用户手动 docker pull / docker load)" +fi + +# ============ [7/7] 自检 + 打印下一步 ============ +log "=== [7/7] 自检 ===" + +docker exec "${CONTAINER_NAME}" bash -c ' + echo " docker: $(docker --version 2>/dev/null || echo 不可用)" + echo " compose: $(docker compose version 2>/dev/null | head -1 || echo 不可用)" + echo " ais_bench: $(ais_bench --version 2>/dev/null || echo unknown)" + echo " venvs:" + for v in harbor swebench swebench_pro; do + [ -d /opt/venvs/$v ] && echo " ✓ $v" || echo " ✗ $v 缺失" + done + echo " packs:" + ls /opt/agent-resources/packs/*.yaml 2>/dev/null | while read f; do + echo " ✓ $(basename $f .yaml)" + done + echo " 用户挂载目录(容器内可见性自检):" +' + +# 自检:用户传入的挂载路径在容器内是否可见 +if [ "${#DATASET_MOUNTS[@]}" -gt 0 ]; then + for p in "${DATASET_MOUNTS[@]}"; do + if docker exec "${CONTAINER_NAME}" bash -c "[ -d '$p' ]" >/dev/null 2>&1; then + SIZE=$(docker exec "${CONTAINER_NAME}" bash -c "du -sh '$p' 2>/dev/null | cut -f1") + log " ✓ ${p} (${SIZE})" + else + log " ✗ ${p} 在容器内不可见(挂载失败)" + fi + done +fi + +echo "" +echo "============================================================" +echo "✓ Agent 测评运行环境容器已就绪(模式 ${MODE})" +echo "============================================================" +cat <: # 注册表与 tag 见各 benchmark 文档 + 离线: 从 OBS 下载 tar 后 docker load -i +EOF +fi +cat < +# +# 参数: +# pack pack 名称,如 harbor +# -h, --help 显示帮助 +# +# 验证内容(一次性 L1 静态检查,秒级): +# - docker daemon 可用 +# - venv 完整性(pack.runtime_venv 对应路径存在 + python 可执行) +# - pack.yaml 一致性(pack.native_config 存在) +# - 磁盘/内存余量 + +set -e + +# ============ 默认配置 ============ +PACKS_ROOT="${AGENT_PACKS_ROOT:-/opt/agent-resources/packs}" +PACK="" + +# ============ 工具函数 ============ +log() { echo "[$(date +%H:%M:%S)] $*"; } +fail() { echo "[错误] $*" >&2; exit 1; } + +yq() { + python3.12 -c " +import yaml, sys +try: + c = yaml.safe_load(open('$PACK_FILE')) +except FileNotFoundError: + sys.exit('pack 文件不存在: $PACK_FILE') +$1 +" +} + +usage() { + cat < + + pack pack 名称,如 harbor + +验证内容(一次性 L1 静态检查,秒级): + - docker daemon / venv 完整性 / pack.yaml 一致性 / 磁盘内存 + +可用 pack: +$(ls "${PACKS_ROOT}"/*.yaml 2>/dev/null | xargs -I{} basename {} .yaml | sed 's/^/ /') + +示例: + ais_bench_agent_doctor.sh harbor +EOF + exit 1 +} + +# ============ 参数解析 ============ +[ $# -lt 1 ] && usage +PACK="$1"; shift +[ "$PACK" = "-h" ] || [ "$PACK" = "--help" ] && usage +[ $# -gt 0 ] && { echo "未知参数: $1" >&2; usage; } + +PACK_FILE="${PACKS_ROOT}/${PACK}.yaml" +[ ! -f "$PACK_FILE" ] && fail "pack 不存在: ${PACK}(查找路径 ${PACKS_ROOT})" + +VENV=$(yq "print(c.get('runtime_venv',''))") +NATIVE_CONFIG=$(yq "print(c.get('native_config',''))") +NATIVE_DOC=$(yq "print(c.get('native_doc',''))") + +echo "============================================================" +echo " AISBench Agent runtime 验证: ${PACK}" +echo "============================================================" + +# ============ L1 静态自检 ============ +echo "" +echo "[L1] 静态自检" +L1_FAIL=0 + +echo " [1/3] docker daemon..." +if docker info >/dev/null 2>&1; then + echo " ✓ $(docker --version)" +else + echo " ✗ docker daemon 不可用" + L1_FAIL=1 +fi + +echo " [2/3] venv 完整性: ${VENV}" +VENV_PATH="/opt/venvs/${VENV}" +if [ -n "$VENV" ] && [ -d "$VENV_PATH" ] && [ -x "$VENV_PATH/bin/python" ]; then + echo " ✓ ${VENV} python: $($VENV_PATH/bin/python --version 2>&1)" +else + echo " ✗ venv 不存在: $VENV_PATH" + L1_FAIL=1 +fi + +echo " [3/3] pack.yaml 一致性..." +if [ -n "$NATIVE_CONFIG" ] && [ -f "$NATIVE_CONFIG" ]; then + echo " ✓ native_config: $NATIVE_CONFIG" +else + echo " ✗ native_config 不存在: ${NATIVE_CONFIG:-<空>}" + L1_FAIL=1 +fi + +echo "" +echo " [资源] 磁盘/内存余量..." +AVAIL_GB=$(df -BG /var/lib/docker 2>/dev/null | awk 'NR==2{print $4}' | tr -d G || echo 0) +if [ "$AVAIL_GB" -gt 20 ] 2>/dev/null; then + echo " ✓ docker 数据盘剩余 ${AVAIL_GB}GB" +else + echo " ⚠ docker 数据盘仅剩 ${AVAIL_GB}GB(建议 ≥20GB)" +fi +MEM_GB=$(free -g 2>/dev/null | awk '/Mem:/{print $7}' || echo 0) +if [ "$MEM_GB" -gt 4 ] 2>/dev/null; then + echo " ✓ 可用内存 ${MEM_GB}GB" +else + echo " ⚠ 可用内存 ${MEM_GB}GB(建议 ≥4GB)" +fi + +# ============ 总结 ============ +echo "" +echo "============================================================" +if [ "$L1_FAIL" = "1" ]; then + echo " ✗ ${PACK} runtime 验证未通过" + echo "============================================================" + echo "" + echo "修复指引:" + echo " - docker daemon 不可用: 检查容器内 dockerd 是否启动(模式 A);或宿主 docker.sock 是否挂载(模式 B)" + echo " - venv 缺失: runtime 镜像损坏,重新拉取或重建容器" + echo " docker pull ghcr.io/aisbench/agent-runtime:latest-ubuntu24.04-py312-\${ARCH}" + echo " - native_config 不存在: 检查 /benchmark 路径下是否有 ais_bench 仓库" + exit 1 +fi +echo " ✓ ${PACK} runtime 就绪" +echo "============================================================" +cat <} + 3. 修改原生配置中的 model_names / api_base + 4. 跑真实测评 + + agent_env ${VENV} + vim ${NATIVE_CONFIG} # 仅改 model_names / api_base;path 已自动 + ais_bench ${NATIVE_CONFIG} --debug + +断点续跑: + ais_bench ${NATIVE_CONFIG} --debug --reuse + +切换不同的数据集 / case 集: + 物理机(销毁旧容器 + 重新起): + docker rm -f ais_bench_agent + bash bootstrap.sh --datasets <新数据集路径> --case-tar <新 case tar> + 容器内:不再跑 doctor,直接跑 ais_bench +EOF From 5d4231780ed3e41d3896ddaff08bad593a6f86bb Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 16:00:49 +0800 Subject: [PATCH 7/9] swe bench docs update --- .../mini_swe_agent_swe_bench_pro_full.py | 4 +- .../mini_swe_agent_swe_bench_pro_mini.py | 4 +- .../extended_benchmark/agent/harbor_bench.md | 9 +- .../extended_benchmark/agent/swe_bench.md | 88 +++++++------------ 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py index c77200b2..42ee1bc6 100644 --- a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py +++ b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_full.py @@ -41,8 +41,8 @@ ) ] -SWEBP_SCRIPT_PATH_ABS = "" -SWEBP_DOCKER_PATH_ABS = "" +SWEBP_SCRIPT_PATH_ABS = "/opt/src/SWE-bench_Pro-os/run_scripts" +SWEBP_DOCKER_PATH_ABS = "/opt/src/SWE-bench_Pro-os/dockerfiles" datasets = [ dict( diff --git a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py index d1f48ba6..f22afcbc 100644 --- a/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py +++ b/ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py @@ -42,8 +42,8 @@ ) ] -SWEBP_SCRIPT_PATH_ABS = "" -SWEBP_DOCKER_PATH_ABS = "" +SWEBP_SCRIPT_PATH_ABS = "/opt/src/SWE-bench_Pro-os/run_scripts" +SWEBP_DOCKER_PATH_ABS = "/opt/src/SWE-bench_Pro-os/dockerfiles" datasets = [ dict( diff --git a/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md b/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md index 46b97099..d5497161 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md +++ b/docs/source_zh_cn/extended_benchmark/agent/harbor_bench.md @@ -70,12 +70,12 @@ Terminal-Bench-2 预制打包镜像信息: #### 3.2 一键准备方案(推荐) -如果不想手动处理依赖冲突 / DinD 配置,推荐使用 **AISBench Agent Runtime 一键准备方案**。同一脚本同时覆盖**快速入门(在线)**与**离线场景(内网/隔离环境)**,通过 `--runtime-tar` / `--case-tar` / `--datasets` 自由组合,无需切换不同流程。 +如果不想手动准备环境,推荐使用 **AISBench Agent Runtime 一键准备方案**。同一脚本同时覆盖**快速入门(在线)**与**离线场景(内网/隔离环境)**,通过 `--runtime-tar` / `--case-tar` / `--datasets` 自由组合,无需切换不同流程。 ```bash # 1. 物理机上一键起 runtime 容器(自动选 DinD/Socket 模式,自动挂载数据集,自动把 case 镜像 tar 拷进容器内部 docker load 完) -# 在线场景:省略 --runtime-tar,runtime 镜像自动从 ghcr.io 拉取 -# 离线场景:通过 --runtime-tar 跳过外网拉取 +# 在线场景:在线场景:省略 --runtime-tar,runtime 镜像自动从 ghcr.io 拉取最新的 +# 离线场景:通过 --runtime-tar 跳过外网拉取,可以从最新的release信息中提前获取 curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ | bash -s -- \ --datasets /path/to/terminal-bench-2-offline-mini/terminal-bench-2-offline-selected_0.10/ \ @@ -99,9 +99,8 @@ vim ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py # 4. 验证 runtime 就绪 ais_bench_agent_doctor.sh harbor -# 5. 跑测评 +# 5. 进入测评环境 agent_env harbor -ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug ``` 切到其它数据集(mini-0.14 / mini-0.20 / full):销毁旧容器 → 重新 `bash ... --datasets <新路径> --case-tar <新tar>` 起容器。 diff --git a/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md b/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md index bfd3e836..f580fa37 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md +++ b/docs/source_zh_cn/extended_benchmark/agent/swe_bench.md @@ -2,48 +2,6 @@ SWE-bench是一个基准测试,用于评估大语言模型在从GitHub收集的现实世界软件问题上的表现。给定一个代码库和一个问题,语言模型的任务是生成一个补丁来解决所描述的问题。 -## 快速上手(推荐) - -如果你是第一次跑 Agent 测评,或不想手动处理依赖冲突 / DinD 配置 / mini-swe-agent fork 选择,推荐使用 **AISBench Agent Runtime 一键准备方案**: - -```bash -# 1. 物理机上一键起 runtime 容器 -# --datasets 挂载数据集 + 注入 env var(原生配置 path 自动从此 env var 读,无需 vim 改) -curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ - | bash -s -- --datasets /data/datasets/swebench - -# 2. 进入容器 -docker exec -it ais_bench_agent bash - -# 3. 准备 case 镜像(HF 上 princeton-nlp/SWE-Bench_* 的 docker 镜像,或 docker load tar) -# 数据集由原生配置自动从 HF 下载,无需用户准备 -docker pull swebench/sweb.eval.x86_64.: -# 详见各实例对应的 docker image tag - -# 4. 验证 runtime 就绪 -ais_bench_agent_doctor.sh swebench - -# 5. 改原生配置中的 model_names / api_base(path 由 env var 自动给) -vim ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py - -# 6. 激活 swebench venv(AISBench fork 的 mini-swe-agent) -agent_env swebench - -# 7. 跑测评 -ais_bench ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py --debug -``` - -切到其它数据集(verified / full / multilingual 等):改原生配置文件的 `datasets[0].name` 字段,重新跑。 - -该方案解决了以下痛点: -- **mini-swe-agent fork 冲突**:AISBench fork 与 scaleapi fork 同包名互相覆盖,runtime 用独立 venv 隔离两个 fork -- **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp 自动处理 -- **离线部署**:`--runtime-tar` 跳过 runtime 镜像的网络获取;`--case-tar` 加载 case 镜像到容器内(可多次,可传目录) - -方案原理与脚本实现见 [`docker/agent_runtime/`](../../../docker/agent_runtime/README.md)。 - -> 下文为完整的 SWE-bench 测评原理与手动配置方式,适用于不使用一键方案、或需要深入定制的场景。 - ## 1. 功能概览 当前在 `ais_bench` 已接入以下 SWEbench 能力: @@ -64,13 +22,11 @@ ais_bench ais_bench/configs/swe_bench_examples/mini_swe_agent_swe_bench_lite.py - `mini_swe_agent_swe_bench_multilingual_mini.py`:SWE-bench Multilingual Mini(**15**/**30**/**60** 条),AISBench官方构造的 Multilingual 子集,用于显著降低评测成本;子集筛选/构造方式见数据集卡与构造仓库:`https://modelers.cn/datasets/AISBench/SWE-Bench_Multilingual_mini`、`https://github.com/AISBench/datasets/tree/main/mini_datasets/swe_bench_multiligual_mini`。 - -## 2. 前置依赖 - -运行前请确保以下依赖可用: - -1) 安装 `mini-swe-agent`(infer 依赖) - +## 2. 运行环境安装 +### 3.1 源码安装 +1. 确认docker版本满足要求,执行`docker version`,确保docker版本为20.10.0及以上, docker API版本为 1.42及以上 +2. 参考[工具安装&卸载](../../get_started/install.html)源码安装AISBench测评工具 +3. 安装 `mini-swe-agent`(infer 依赖) ```bash git clone https://github.com/AISBench/mini-swe-agent.git cd mini-swe-agent @@ -78,7 +34,7 @@ pip install -e . cd - ``` -2) 安装 SWE-bench harness(eval 依赖) +4. 安装 SWE-bench harness(eval 依赖) ```bash git clone https://github.com/SWE-bench/SWE-bench.git @@ -87,17 +43,39 @@ pip install -e . cd - ``` -3) Docker 可用(infer/eval 都依赖容器环境) +5. ARM 环境下需要开启 docker 的 x86 支持,执行以下命令: ```bash -docker --version -docker ps +docker run --rm --privileged tonistiigi/binfmt --install all ``` -4) ARM 环境下需要开启 docker 的 x86 支持,执行以下命令: + +### 3.2 一键准备方案(推荐) +如果你不想源码安装依赖,或者docker版本较低(docker version < 20.10.0),推荐使用 **AISBench Agent Runtime 一键准备方案**: ```bash -docker run --rm --privileged tonistiigi/binfmt --install all +# 1. 物理机上一键起 runtime 容器(自动选 DinD/Socket 模式,自动挂载数据集,自动把 case 镜像 tar 拷进容器内部 docker load 完) +# 在线场景:省略 --runtime-tar,runtime 镜像自动从 ghcr.io 拉取最新 +# 离线场景:通过 --runtime-tar 跳过外网拉取,可以从最新的release信息中手动获取 +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --runtime-tar (可选)提前准备的测评镜像,不传则自动拉取最新 +# --host-path 指向的目录需为空目录,容器内会自动创建同名目录挂载数据集和 case 镜像 +# --container-name 指向的容器名需唯一,否则会覆盖旧容器 + +# 2. 进入容器 +docker exec -it test_agent_run bash + +# 3. 验证 runtime 就绪 +ais_bench_agent_doctor.sh swebench + +# 4. 激活 swebench venv(AISBench fork 的 mini-swe-agent) +agent_env swebench + ``` +> 该一键准备方案的方案原理与脚本实现和更详细的介绍见 [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md)。 ## 3. 最小配置(先跑通再调优) From 9240c5cc7588d0610afdeedb9faec40b0ca16d8d Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 16:30:31 +0800 Subject: [PATCH 8/9] swe bench pro docs update --- .../extended_benchmark/agent/swe_bench_pro.md | 146 +++++++----------- 1 file changed, 53 insertions(+), 93 deletions(-) diff --git a/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md b/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md index 7f7bfd88..b33e8cae 100644 --- a/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md +++ b/docs/source_zh_cn/extended_benchmark/agent/swe_bench_pro.md @@ -4,62 +4,6 @@ SWE-Bench Pro 是一个用于评估大语言模型在长时域软件工程任务 > **注意**:由于官方提供的 Docker 镜像均为 x86 架构,SWE-bench Pro 目前仅支持在 x86 环境上评测,暂不支持 ARM 环境。 -## 快速上手(推荐) - -如果你是第一次跑 Agent 测评,或不想手动处理依赖冲突 / DinD 配置 / mini-swe-agent fork 选择,推荐使用 **AISBench Agent Runtime 一键准备方案**: - -```bash -# 1. 物理机上准备 mini 数据集(已有可跳过) -# SWE-bench Pro 的 mini 数据集**必须**本地准备,无在线版 -# 从 modelers 下载到任意目录,目录结构由用户自行规划 -mkdir -p /data/datasets/swebench_pro -# 下载地址:https://modelers.cn/datasets/AISBench/SWE-Bench_Pro_mini -# 优先 parquet 格式;下载后解压到 /data/datasets/swebench_pro/ 即可 - -# 2. 物理机上一键起 runtime 容器 -# --datasets 挂载数据集 + 注入 env var(原生配置 path 自动从此 env var 读) -# 运行时已 clone 好 /opt/src/SWE-bench_Pro-os,swebp_scripts_dir / swebp_docker_dir 直接指向它 -curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ - | bash -s -- --datasets /data/datasets/swebench_pro - -# 3. 进入容器 -docker exec -it ais_bench_agent bash - -# 4. 验证 runtime 就绪 -ais_bench_agent_doctor.sh swebench_pro - -# 5. 改原生配置: -# - model_names / api_base -# - path 自动从 AISBENCH_AGENT_DATASET_PATH 读(mini 数据集本地路径) -# - SWEBP_SCRIPT_PATH_ABS / SWEBP_DOCKER_PATH_ABS 指向运行时已 clone 的 SWE-bench_Pro-os -vim ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py - -# 6. 激活 swebench_pro venv(scaleapi fork 的 mini-swe-agent) -agent_env swebench_pro - -# 7. 跑测评 -ais_bench ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_mini.py --debug -``` - -切到 full 数据集:先确认 HF 可达,然后改原生配置文件中 `SWEBP_SCRIPT_PATH_ABS` / `SWEBP_DOCKER_PATH_ABS` / `path` / `name='mini'` → `name='full'`,重新跑。 - -**SWE-bench Pro 与 SWE-bench 的差异**(影响快速上手的几处): - -- **mini-swe-agent fork**:SWE-bench Pro 必须用 scaleapi fork,不能用 AISBench fork;runtime 用独立 `swebench_pro` venv 隔离两个 fork -- **mini 数据集**:SWE-bench Pro 的 mini 数据集没有在线版,必须从 modelers 下载本地 parquet;full 数据集可 HF 在线 -- **评测参数**:`SWEBP_SCRIPT_PATH_ABS` 和 `SWEBP_DOCKER_PATH_ABS` 必须指向 SWE-Bench_Pro-os 仓库的 `run_scripts/` 和 `dockerfiles/`;runtime 镜像已 clone 到 `/opt/src/SWE-bench_Pro-os/`,直接填这个路径即可 -- **case 镜像**:scaleapi 官方 x86 docker 镜像,按 instance 拉取;具体 tag 与拉取方式详见 [SWE-bench Pro 官方仓库](https://github.com/scaleapi/SWE-bench_Pro-os) 与 [scaleapi/mini-swe-agent](https://github.com/scaleapi/mini-swe-agent) - -该方案解决了以下痛点: - -- **mini-swe-agent fork 冲突**:AISBench fork 与 scaleapi fork 同包名互相覆盖,runtime 用独立 venv 隔离两个 fork -- **容器配置易错**:DinD 模式 A/B、`--cgroupns=host`、`daemon.json`、seccomp 自动处理 -- **离线部署**:`--runtime-tar` 跳过 runtime 镜像的网络获取;`--case-tar` 加载 case 镜像到容器内(可多次,可传目录) - -方案原理与脚本实现见 [`docker/agent_runtime/`](../../../docker/agent_runtime/README.md)。 - -> 下文为完整的 SWE-bench Pro 测评原理与手动配置方式,适用于不使用一键方案、或需要深入定制的场景。 - ## 1. 功能概览 当前在 `ais_bench` 已接入以下 SWE-Bench Pro 能力: @@ -75,50 +19,80 @@ ais_bench ais_bench/configs/swe_bench_pro_examples/mini_swe_agent_swe_bench_pro_ - `mini_swe_agent_swe_bench_pro_mini.py`:SWE-bench Pro Mini,适合先跑通流程/快速迭代。 - `mini_swe_agent_swe_bench_pro_full.py`:SWE-bench Pro Full,完整测试集。 -## 2. 前置依赖 - -运行前请确保以下依赖可用: +## 2. 运行环境安装 -1) 安装 `mini-swe-agent`(infer 依赖) +### 2.1 源码安装 +1. 确认docker版本满足要求,执行`docker version`,确保docker版本为20.10.0及以上, docker API版本为 1.42及以上 +2. 参考[工具安装&卸载](../../get_started/install.html)源码安装AISBench测评工具 +3. 安装 `mini-swe-agent`(infer 依赖) > **注意**:SWE-Bench Pro 官方组织 scaleapi 对 mini-swe-agent 做了适配,需从 scaleapi 的仓库下载适配版本。 ```bash -# 克隆 mini-swe-agent 代码 git clone https://github.com/scaleapi/mini-swe-agent.git - -# 进入项目目录 -cd mini-swe-agent/ - -# 下载运行依赖 +cd mini-swe-agent pip install -e . - -# 返回上级目录 cd - ``` -2) 安装 `SWE-Bench_Pro`(infer 和 eval 依赖) +4. 安装 `SWE-Bench_Pro`(infer 和 eval 依赖) ```bash -# 克隆 SWE-Bench_Pro 代码 git clone https://github.com/scaleapi/SWE-bench_Pro-os.git +cd SWE-bench_Pro-os +pip install -r requirements.txt +cd - +``` -# 进入项目目录 -cd SWE-bench_Pro-os/ +5. SWEBP 脚本与 Docker 目录配置 -# 下载运行依赖 -pip install -r requirements.txt +SWE-Bench Pro 评测**必须**指定以下两个路径,无默认处理动作: -# 返回上级目录 -cd - +- `swebp_scripts_dir`:SWE-bench Pro 官方仓库的 `run_scripts` 目录绝对路径 +- `swebp_docker_dir`:SWE-bench Pro 官方仓库的 `dockerfiles` 目录绝对路径 + +```python +SWEBP_SCRIPT_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/run_scripts" # 必须指定 +SWEBP_DOCKER_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/dockerfiles" # 必须指定 ``` -3) Docker 可用(infer/eval 都依赖容器环境) +> **注意**:需提前克隆 SWE-bench Pro 官方仓库:`git clone https://github.com/scaleapi/SWE-bench_Pro-os.git` + + + +### 2.2 一键准备方案(推荐) +如果你不想源码安装依赖,或者docker版本较低(docker version < 20.10.0),推荐使用 **AISBench Agent Runtime 一键准备方案**: ```bash -docker --version -docker ps +# 1. 物理机上准备 mini 数据集(已有可跳过) +# SWE-bench Pro 的 mini 数据集**必须**本地准备,无在线版 +mkdir -p /data/datasets/swebench_pro +# 下载地址:https://modelers.cn/datasets/AISBench/SWE-Bench_Pro_mini +# 优先 parquet 格式;下载后解压到 /data/datasets/swebench_pro/ 即可 + +# 2. 物理机上一键起 runtime 容器(自动选 DinD/Socket 模式,自动挂载数据集,自动把 case 镜像 tar 拷进容器内部 docker load 完) +# 在线场景:省略 --runtime-tar,runtime 镜像自动从 ghcr.io 拉取最新 +# 离线场景:通过 --runtime-tar 跳过外网拉取,可以从最新的release信息中提前获取 +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --datasets /data/datasets/swebench_pro \ + --container-name ais_bench_agent +# --runtime-tar (可选)提前准备的测评镜像,不传则自动拉取最新 +# --datasets 指向本地数据集目录,容器内会自动创建同名目录挂载数据集 +# --container-name 指向的容器名需唯一,否则会覆盖旧容器 + +# 3. 进入容器 +docker exec -it ais_bench_agent bash + +# 4. 验证 runtime 就绪 +ais_bench_agent_doctor.sh swebench_pro + +# 5. 激活 swebench_pro venv(scaleapi fork 的 mini-swe-agent) +agent_env swebench_pro + ``` +> 该一键准备方案的方案原理与脚本实现和更详细的介绍见 [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md)。 ## 3. 最小配置(先跑通再调优) @@ -158,20 +132,6 @@ models = [ - 优先推荐的数据格式为 parquet - 将 `path` 指向本地下载的 parquet 文件或目录 -### SWEBP 脚本与 Docker 目录配置 - -SWE-Bench Pro 评测**必须**指定以下两个路径,无默认处理动作: - -- `swebp_scripts_dir`:SWE-bench Pro 官方仓库的 `run_scripts` 目录绝对路径 -- `swebp_docker_dir`:SWE-bench Pro 官方仓库的 `dockerfiles` 目录绝对路径 - -```python -SWEBP_SCRIPT_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/run_scripts" # 必须指定 -SWEBP_DOCKER_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/dockerfiles" # 必须指定 -``` - -> **注意**:需提前克隆 SWE-bench Pro 官方仓库:`git clone https://github.com/scaleapi/SWE-bench_Pro-os.git` - ### 首跑建议 - 数据集先用 `mini` From 01b3d2eab62d1c0ceb95f24838e840bdfc72ec29 Mon Sep 17 00:00:00 2001 From: SJTUyh Date: Thu, 23 Jul 2026 16:48:03 +0800 Subject: [PATCH 9/9] commit -m update en doc --- docker/OVERVIEW.en.md | 132 +++++++++ docker/agent_runtime/README_en.md | 268 ++++++++++++++++++ .../extended_benchmark/agent/harbor_bench.md | 105 ++++--- .../extended_benchmark/agent/swe_bench.md | 43 ++- .../extended_benchmark/agent/swe_bench_pro.md | 90 +++--- 5 files changed, 545 insertions(+), 93 deletions(-) create mode 100644 docker/agent_runtime/README_en.md diff --git a/docker/OVERVIEW.en.md b/docker/OVERVIEW.en.md index a781e171..a5849be3 100644 --- a/docker/OVERVIEW.en.md +++ b/docker/OVERVIEW.en.md @@ -185,6 +185,59 @@ docker build \ The image ships with Docker Engine (≥ 20.0) and Docker Compose v2 (≥ 2.0.0). There are two modes for running Docker inside the container — pick one based on your host Docker version and isolation needs. ### Mode A — Docker-in-Docker (recommended, true nested containers, requires host Docker ≥ 20.10 + cgroup v2) +```bash +┌────────────────────────── Host ──────────────────────────┐ +│ │ +│ ┌──────────────────┐ ┌──────────────────────────┐ │ +│ │ Host Kernel │ │ Host dockerd │ │ +│ │ (cgroup v2) │◀───────▶│ /var/run/docker.sock │ │ +│ └──────────────────┘ │ manages host's own │ │ +│ │ containers │ │ +│ └──────────────────────────┘ │ +│ │ +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │ +│ ┃ AISBench Container (--privileged --cgroupns=host) ┃ │ +│ ┃ ┃ │ +│ ┃ ┌──────────────────────┐ ┌──────────────────────┐ ┃ │ +│ ┃ │ Docker CLI │────▶│ Inner dockerd │ ┃ │ +│ ┃ │ (user runs) │ │ (independent proc │ ┃ │ +│ ┃ └──────────────────────┘ │ inside container) │ ┃ │ +│ ┃ │ daemon.json: │ ┃ │ +│ ┃ │ native.cgroupdriver │ ┃ │ +│ ┃ │ =cgroupfs │ ┃ │ +│ ┃ │ storage=vfs │ ┃ │ +│ ┃ └──────────┬───────────┘ ┃ │ +│ ┃ │ spawn ┃ │ +│ ┃ ▼ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ containerd │ ┃ │ +│ ┃ │ (embedded in │ ┃ │ +│ ┃ │ inner dockerd) │ ┃ │ +│ ┃ └──────────┬───────────┘ ┃ │ +│ ┃ │ ┃ │ +│ ┃ ▼ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ Nested child │ ┃ │ +│ ┃ │ container │ ┃ │ +│ ┃ │ (truly isolated │ ┃ │ +│ ┃ │ namespaces) │ ┃ │ +│ ┃ │ ┌────────────────┐ │ ┃ │ +│ ┃ │ │ Agent process │ │ ┃ │ +│ ┃ │ │ OpenBLAS │ │ ┃ │ +│ ┃ │ │ Python deps │ │ ┃ │ +│ ┃ │ └────────────────┘ │ ┃ │ +│ ┃ └──────────────────────┘ ┃ │ +│ ┃ ┃ │ +│ ┃ —— Isolation boundary: independent PID/IPC/Net/Mount/User ┃ │ +│ ┃ namespaces —— ┃ │ +│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ +│ │ +│ ✦ Nested child containers do NOT appear in host `docker ps` │ +│ ✦ Child containers inherit Docker's official default seccomp │ +│ profile (no clone3 blocking) │ +│ ✦ Host dockerd restart does NOT affect inner dockerd │ +└──────────────────────────────────────────────────────────────────┘ +``` A standalone `dockerd` is started inside the container, so child containers are fully isolated from the host. This is the **preferred mode** for agent benchmarks: child containers inherit Docker's official default seccomp profile, so the `pthread_create` / `clone3` block triggered by openEuler / RHEL hardened profiles does not occur; and there is no stale-socket issue when the host's `dockerd` restarts. @@ -250,6 +303,47 @@ docker compose version - For very long-running DinD workloads, consider adding `"default-runtime": "runc"`, `"log-driver": "json-file"`, and `"data-root"` overrides to `/etc/docker/daemon.json`. ### Mode B — Socket Passthrough (works with any Docker version ≥ 1.0) +```bash +┌────────────────────────── Host ──────────────────────────┐ +│ │ +│ ┌──────────────────┐ │ +│ │ Host Kernel │ │ +│ └──────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────┐ bind mount │ +│ │ Host dockerd │ /var/run/docker │ +│ │ /var/run/docker.sock ──────────────────────────┐ │ +│ │ (manages host's own containers) │ │ │ +│ └────────────┬─────────────────────────────┘ │ │ +│ │ │ │ +│ │ actually creates/manages │ │ +│ ▼ │ │ +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┓ │ +│ ┃ AISBench Container (--privileged, shares PID/IPC w/ host)┃ │ +│ ┃ ┃ │ +│ ┃ ┌──────────────────────┐ ┃ │ +│ ┃ │ Docker CLI │── HTTP/Unix socket call ──────┘ ┃ │ +│ ┃ │ (user runs) │ no dockerd process inside ┃ │ +│ ┃ └──────────────────────┘ ┃ │ +│ ┃ ┃ │ +│ ┃ —— Shares kernel, PID, IPC namespaces with host —— ┃ │ +│ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ │ +│ │ +│ ┌──────────────────────────────────────────┐ │ +│ │ Child container (actually on the host) │ │ +│ │ ┌────────────────┐ │ │ +│ │ │ Agent process │ ← created/collected │ │ +│ │ │ OpenBLAS │ by host dockerd │ │ +│ │ │ Python deps │ │ │ +│ │ └────────────────┘ │ │ +│ └──────────────────────────────────────────┘ │ +│ │ +│ ✦ Child containers appear in host `docker ps` │ +│ ✦ Child containers inherit host dockerd's seccomp profile │ +│ (openEuler/RHEL hardened profile → clone3 blocking) │ +│ ✦ Host dockerd restart → socket inode stale → `docker restart`│ +└──────────────────────────────────────────────────────────────────┘ +``` Mount the host's Docker socket so that `docker run` inside the container actually creates containers on the **host** daemon. Use this mode only when the host Docker is older than 20.10, or when cgroup v2 is unavailable and Mode A cannot be used. @@ -369,6 +463,44 @@ docker compose -f /tmp/docker-compose.yml up - [Sysbox](https://github.com/nestybox/sysbox) — a container runtime that supports nested containers without `--privileged`, at the cost of installing a custom runtime on the host. - Rootless Docker — runs `dockerd` as a non-root user; has its own limitations (no `overlay2` on most distros, network restrictions, etc.). +## Agent Evaluation One-Click Environment Preparation + +For agent benchmarks such as Harbor Terminal-Bench, SWE-bench, and SWE-bench Pro, this repository provides a one-click environment preparation solution in [`docker/agent_runtime/`](agent_runtime/README.md). It consolidates the Mode A/B selection, `daemon.json` configuration, `--cgroupns=host`, and seccomp handling from the "Running Agent / Sandbox Benchmarks" section above into a single script, and additionally solves: + +- **Dependency conflicts**: Dependencies of multiple agent benchmarks conflict with each other (e.g., harbor forces upgrading `datasets` to 4.0+, and two `mini-swe-agent` forks override each other with the same package name). Solved via multi-venv isolation inside the runtime image. +- **Huge case images**: SWE-bench full (~1TB) cannot be packaged as a whole, so it is **not** baked into the runtime image. Users `docker pull` / `docker load` themselves. +- **Frequent dataset versions**: Agent dataset versions change quickly, so they are **not** baked into the runtime image. Users prepare them on the host and mount them into the container via `bootstrap.sh --datasets ` (container path = host path). +- **No environment verification**: `doctor.sh` verifies the runtime configuration (L1 static) before running the benchmark + scans for case image presence (warning), and gives precise fix guidance on failure. + +**Usage** (all three packs use the same workflow; choose `--datasets` and `agent_env` per benchmark): + +```bash +# Host: prepare the dataset directory + start the runtime container with one click +# (mounts the dataset directory into the container) +# Harbor: +mkdir -p /data/datasets/harbor/mini-0.10 +# Prepare dataset (see harbor_bench.md) + case image (can be loaded offline via bootstrap --case-tar) +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10 \ + --case-tar /data/cases/case-tb2-mini-0.10.tar.gz +docker exec -it ais_bench_agent bash +# Inside the container: +ais_bench_agent_doctor.sh harbor +agent_env harbor +ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug + +# SWE-bench / SWE-bench Pro work the same way: +# --datasets +# agent_env swebench | swebench_pro +# ais_bench ais_bench/configs/swe_bench[_pro]_examples/... --debug +# For dataset and case image acquisition, see each benchmark's documentation. +``` + +For the solution design and per-script parameters, see [`docker/agent_runtime/README.md`](agent_runtime/README.md). Each agent benchmark doc ([harbor_bench.md](../docs/source_en/extended_benchmark/agent/harbor_bench.md), [swe_bench.md](../docs/source_en/extended_benchmark/agent/swe_bench.md), [swe_bench_pro.md](../docs/source_en/extended_benchmark/agent/swe_bench_pro.md)) also has a "Quick Start" section at the top. + +> This section is the executable packaging of the "Running Agent / Sandbox Benchmarks" section. To understand the principles, still read the Mode A/B sections above; for quick start, just use the script in this section. + ## License / Disclaimer This project's images and build scripts are licensed under the [LICENSE file](https://github.com/AISBench/benchmark/blob/master/LICENSE) in the repository root. diff --git a/docker/agent_runtime/README_en.md b/docker/agent_runtime/README_en.md new file mode 100644 index 00000000..1af0ee4f --- /dev/null +++ b/docker/agent_runtime/README_en.md @@ -0,0 +1,268 @@ +# AISBench Agent Runtime + +Provides images and scripts for the runtime container used by AISBench Agent evaluations (Harbor Terminal-Bench, SWE-bench, SWE-bench Pro, etc.). + +> This repository directory is a community runtime supplement to AISBench/benchmark and is not part of the core benchmark evaluation logic. After preparing the runtime container with the scripts and images in this directory, users still run evaluations with the native `ais_bench` command; the principles are identical to those in each benchmark's documentation. + +## What Problem Does It Solve + +Environment preparation for agent evaluation has three major pain points: + +1. **Dependency conflicts**: harbor forces datasets to upgrade to 4.0+; SWE-bench and SWE-bench Pro each need a different fork of `mini-swe-agent`, with the same package name overwriting each other. +2. **Error-prone container configuration**: DinD modes A/B, `--cgroupns=host`, `daemon.json`, seccomp — any missed step only surfaces as an error at evaluation time. +3. **Frequent dataset / case image version changes**: datasets and case images have many versions; baking them into the runtime image causes rapid expiration. + +This package solves these problems in layers: + +| Layer | Content | Solves | +|---|---|---| +| `Dockerfile.agent-runtime` | Adds 3 isolated venv layers on top of the `aisbench_benchmark` base image (harbor / swebench / swebench_pro) | Dependency conflicts | +| `bootstrap.sh` | One-click runtime container start: auto-selects DinD/Socket mode + mounts datasets + loads case tar | Error-prone container config + dataset injection | +| `doctor.sh` | Static self-check (L1, seconds) — validates docker / venv / pack / resources | Pre-run runtime validation | +| `packs/.yaml` | Metadata for each benchmark (venv name / native config / docs) | Decouples toolchain from benchmarks | + +## Who Prepares Datasets / Case Images + +**What is deliberately not done**: This solution does **not** pre-bake agent benchmark datasets and case sandbox images into the runtime image. The reason is that both change versions frequently, and baking them in means: + +- Every dataset update requires rebuilding the runtime image — a maintenance burden and a large download for users +- A full case sandbox image set is ~71GB and cannot be baked into a base image + +**Who is responsible for what**: + +| Item | Who prepares | How to integrate into the runtime container | +|---|---|---| +| runtime image | AISBench maintainers | `docker pull ghcr.io/aisbench/agent-runtime:latest-...` (or `--runtime-tar` offline) | +| Dataset (task.toml, etc.) | User prepares on the host | `bootstrap.sh --datasets ` (mounted at the same path inside the container + injected as env var) | +| case sandbox image | User prepares tar on the host | `bootstrap.sh --case-tar ` (auto `docker cp` into container + `docker load`) | +| Model call parameters (api_base / model_names) | User edits native config | Inside the container: `vim ais_bench/configs/agent_example/...` | + +## Quick Start (Harbor Terminal-Bench as example, aarch64) +The quick start targets host machines with Docker version below 20.0.0. For other environments, refer to the corresponding agent evaluation documentation. + +```bash +# 1. Prepare dataset and image tar on the host (skip if already present) + +git clone https://modelers.cn/AISBench/terminal-bench-2-offline-mini.git # Dataset preparation +wget https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-aarch64.tar.gz # Runtime image preparation (optional; if omitted, the latest is fetched automatically) +wget https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-offline-prepared-images-selected-0.10_aarch64.tar # Case image preparation; get the link from the corresponding agent evaluation doc as needed +mkdir /path/to/test_wkp/ # Create an empty working directory on the host + +# 2. Start the runtime container with one click on the host (auto-selects DinD/Socket mode, auto-mounts datasets; if the environment has no external network, fetch ais_bench_agent_bootstrap.sh elsewhere first and run with bash) +# Auto-copies case image tar into the container and runs docker load +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /path/to/terminal-bench-2-offline-mini/terminal-bench-2-offline-selected_0.10/ \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-aarch64.tar.gz \ + --case-tar /path/to/terminal-bench-2-offline-prepared-images-selected-0.10.tar \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --datasets must point to a directory structure consistent with the terminal-bench-2-offline-selected_0.10/ subdirectory of the terminal-bench-2-offline-mini repo +# --runtime-tar (optional) pre-downloaded runtime image +# --case-tar must point to a tar structure consistent with the case image tar described in the corresponding agent evaluation doc +# --host-path must be an empty directory; a same-named directory will be created inside the container to mount datasets and case images +# --container-name must be unique; otherwise the old container will be overwritten + +# 3. Enter the container (case images are already loaded and ready to use) +docker exec -it test_agent_run bash + +# 4. (No vim needed) The native config path is read automatically from AISBENCH_AGENT_DATASET_PATH +# Only vim model_names / api_base +vim ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py + +# 5. Verify runtime is ready +ais_bench_agent_doctor.sh harbor + +# 6. Run evaluation +agent_env harbor +ais_bench ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py --debug +``` + +Switch datasets: destroy the old container + restart bootstrap (update dataset path / case tar together): + +```bash +docker rm -f test_agent_run +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets/harbor/full/terminal-bench-2 \ + --case-tar /data/cases/terminal-bench-2-prepared-images_x86_64.tar.gz +``` + +## Directory Structure + +``` +agent_runtime/ +├── README.md # This file +├── Dockerfile.agent-runtime # runtime image build file (BASE_IMAGE passed via --build-arg, not hardcoded) +├── build_image_agent_runtime.sh # build script (supports --base-tag/--push/--upload/--multi-arch) +├── ais_bench_agent_bootstrap.sh # one-click runtime container start (user-side entry point, must be uploaded to OBS) +├── doctor.sh # runtime readiness verification (inside the container; only validates docker/venv/config, not datasets/cases) +├── packs/ # per-benchmark manifests (name/runtime_venv/native_config/native_doc) +│ ├── harbor.yaml # Harbor Terminal-Bench +│ ├── swebench.yaml # SWE-bench (mini_swe_agent + SWE-bench harness) +│ └── swebench_pro.yaml # SWE-bench Pro (scaleapi adapted version) +└── patches/ # patch scripts used at build / startup time + └── harbor_compose_patch.py # adds seccomp=unconfined + network_mode=host to harbor's docker-compose-base.yaml +``` + +## ais_bench_agent_bootstrap.sh Usage + +```bash +# Minimal call: mount a single dataset directory +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets + +# Mount multiple directories +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --datasets /data/extra + +# Force mode A/B +bash ais_bench_agent_bootstrap.sh --mode A --datasets /data/datasets + +# Custom container name (to distinguish when running multiple runtimes on one machine) +bash ais_bench_agent_bootstrap.sh --container-name my_eval_1 --datasets /data/datasets + +# Custom runtime image (recommended: pass an explicit tag for reproducibility) +bash ais_bench_agent_bootstrap.sh \ + --runtime-image ghcr.io/aisbench/agent-runtime:v3.1-20260522-master-ubuntu24.04-py312-x86_64 \ + --datasets /data/datasets + +# Mode B + custom /benchmark extraction target (use only when /opt is not writable) +bash ais_bench_agent_bootstrap.sh --mode B --host-path /data/ais_bench_host --datasets /data/datasets + +# Offline mode (intranet/isolated environment): load runtime image from a tar already downloaded on the host +# Completely skips docker pull / OBS download +# Use case: intranet deployment machines that cannot reach ghcr.io or external OBS +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --runtime-tar /opt/aisbench/agent-runtime-ubuntu24-py312-x86_64.tar.gz + +# Fully offline: runtime tar + case image tar passed together +# After container start, case tar is auto-copied into the container and docker loaded +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /opt/aisbench/agent-runtime.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.10.tar.gz + +# Load multiple case images at once (--case-tar can be repeated, or a directory can be passed) +bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /opt/aisbench/agent-runtime.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.10.tar.gz \ + --case-tar /opt/aisbench/case-tb2-mini-0.14.tar.gz \ + --case-tar /opt/aisbench/case-tars/ # all .tar/.tar.gz/.tgz under the directory will be loaded +``` + +`--datasets` / `--host-path` / `--runtime-tar` / `--case-tar` must be **absolute paths** and **must exist on the host** (the script validates them). The in-container path is the same as the host path. + +The full path passed to `--datasets` is injected verbatim into the container as the environment variable `AISBENCH_AGENT_DATASET_PATH`, and native ais_bench configs (e.g. `harbor_terminal_bench_2_task.py`) use this env var directly as the dataset `path` field — **no concatenation, no conversion, completely identical**. Therefore: + +- **Recommended**: pass `--datasets` as the full path of your prepared harbor benchmark dataset (e.g. `/data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10`); the config then needs no vim for path +- **Multiple directories**: `--datasets` can be passed multiple times, but the env var uses only the first; users can manually `export AISBENCH_AGENT_DATASET_PATH=...` to override + +### Command-Line Parameter Reference + +| Parameter | Default | Description | +|---|---|---| +| `--datasets ` | None (not mounted) | Dataset directory; can be passed multiple times | +| `--runtime-tar ` | None (pull) | runtime image tar; for offline scenarios | +| `--case-tar ` | None (prepare manually in container) | case image tar; file or directory; can be passed multiple times | +| `--mode A\|B` | Auto-detected | Force DinD (A) or Socket passthrough (B) | +| `--container-name ` | `ais_bench_agent` | runtime container name | +| `--runtime-image ` | `ghcr.io/aisbench/agent-runtime:latest-ubuntu24.04-py312-${ARCH}` | runtime image tag | +| `--host-path ` | `/opt/ais_bench_agent` | Extraction target for `/benchmark` in mode B | + +### Environment Variables + +Only one env variable is kept (use CLI parameters for other configs): + +| env | Default | Description | +|---|---|---| +| `OBS_RUNTIME_TAR_BASE` | `https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/runtime` | OBS runtime tar download base URL (usually no need to change) | + +### Offline Scenarios + +Deployment machines in intranet/isolated environments cannot reach `ghcr.io/aisbench/agent-runtime` or OBS, but have obtained the runtime tar package and case image tar via USB stick, intranet proxy, etc.: + +1. **Obtain tar package** (either): + - Ask a maintainer to run `build_image_agent_runtime.sh --upload 1` to upload to OBS; intranet users download from OBS + - On a machine with internet access, run `docker save ghcr.io/aisbench/agent-runtime: -o agent-runtime.tar.gz` and copy it in +2. **Run on the deployment machine**: + ```bash + # Minimal: pass only the runtime tar (case images still need manual pull / load inside the container) + bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --runtime-tar /path/to/agent-runtime.tar.gz + + # Fully offline: pass both runtime + case tar + bash ais_bench_agent_bootstrap.sh \ + --datasets /data/datasets \ + --runtime-tar /path/to/agent-runtime.tar.gz \ + --case-tar /path/to/case-tb2-mini-0.10.tar.gz + ``` +3. **Behavior**: + - `--runtime-tar`: completely skips `docker pull` and OBS `curl` download; runs `docker load -i ` and auto-detects the tag (grep `agent-runtime`), preferring `RUNTIME_IMAGE`; gives a precise error on detection failure + - `--case-tar `: supports a single tar or a directory (a directory recursively loads all `.tar` / `.tar.gz` / `.tgz`). The script `docker cp`s it into the container, then runs `docker load -i`. **Supports both A/B modes** (mode A loads into the in-container DinD; mode B loads into the container, but since the socket is shared with the host, it is effectively loaded onto the host as well). For details on modes A/B, see [OVERVIEW.en.md](../OVERVIEW.en.md#running-agent--sandbox-benchmarks-docker-inside-the-container) + - `--case-tar` can be repeated + +Mode B (Socket passthrough) by default extracts `/benchmark` to the host's `/opt/ais_bench_agent`. If your environment's `/opt` is not writable (e.g. some read-only root containers/sandboxes), use `--host-path` to redirect to a writable path: + +```bash +bash ais_bench_agent_bootstrap.sh --datasets /data/datasets --host-path /data/ais_bench_host +``` + +Normal host machines do not need to set this variable. For other configurable environment variables, see the header comments of `bootstrap.sh`. + +## Image Build + +The runtime image is built on top of the `aisbench_benchmark` base image; the base image tag is passed via a parameter, not hardcoded: + +```bash +# Basic build (local, current architecture) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master + +# Specify OS/Python (default ubuntu24.04 + py312) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --os ubuntu24.04 --py-version py312 + +# Build and push to a remote registry +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --push 1 + +# Multi-arch build and push +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --multi-arch 1 --push 1 + +# Build, push, and upload offline package to OBS (for ais_bench_agent_bootstrap.sh fallback download) +bash docker/agent_runtime/build_image_agent_runtime.sh \ + --base-tag v3.1-20260522-master --push 1 --upload 1 +``` + +The build script automatically validates (4 items): +1. ais_bench is available +2. All 3 venvs (harbor / swebench / swebench_pro) are complete + all 3 venvs contain the ais_bench wrapper + both swebench venvs can import minisweagent +3. doctor.sh / packs are in place +4. The harbor compose template has been patched with `seccomp=unconfined` + +## Supported Packs + +| pack name | runtime_venv | Documentation | Description | +|---|---|---|---| +| `harbor` | harbor | [harbor_bench.md](../../docs/source_en/extended_benchmark/agent/harbor_bench.md) | Harbor Terminal-Bench 2.0 | +| `swebench` | swebench | [swe_bench.md](../../docs/source_en/extended_benchmark/agent/swe_bench.md) | SWE-bench (lite/verified/full/multilingual, etc.) | +| `swebench_pro` | swebench_pro | [swe_bench_pro.md](../../docs/source_en/extended_benchmark/agent/swe_bench_pro.md) | SWE-bench Pro (x86 only) | + +pack.yaml does not declare dataset paths or case image acquisition methods — these are entirely under user control: +- Dataset path: explicitly specified by the user via `bootstrap.sh --datasets ` (run whichever you want) +- Case image: the user performs `docker pull` or `docker load` according to the document pointed to by pack.yaml's `native_doc` + +If you want to support more benchmarks in the future, just add a `packs/.yaml`. + +> Common harbor dataset directory names (for reference only, unrelated to the tool): +> - `/data/datasets/harbor/full/terminal-bench-2` (89 cases, including a few external-network tasks) +> - `/data/datasets/harbor/mini-0.10/terminal-bench-2-offline-selected_0.10` (7 cases) +> - `/data/datasets/harbor/mini-0.14/terminal-bench-2-offline-selected_0.14` (10 cases) +> - `/data/datasets/harbor/mini-0.20/terminal-bench-2-offline-selected_0.20` (14 cases) +> +> Whichever path the user passes to `bootstrap.sh --datasets` is injected into the container by the env var `AISBENCH_AGENT_DATASET_PATH`. +> The mini-* series is K-means sampled from `terminal-bench-2-offline` (70 cases after removing external-network tasks) and runs fully offline. +> +> For SWE-bench dataset notes, see [swe_bench.md](../../docs/source_en/extended_benchmark/agent/swe_bench.md) (HF download); for SWE-bench Pro, see [swe_bench_pro.md](../../docs/source_en/extended_benchmark/agent/swe_bench_pro.md). + +## Detailed Solution + +For the full design and parameter descriptions of each script, see the header comments of each script. diff --git a/docs/source_en/extended_benchmark/agent/harbor_bench.md b/docs/source_en/extended_benchmark/agent/harbor_bench.md index d2e95308..81d3f74f 100644 --- a/docs/source_en/extended_benchmark/agent/harbor_bench.md +++ b/docs/source_en/extended_benchmark/agent/harbor_bench.md @@ -44,9 +44,23 @@ Official repository: [https://github.com/harbor-framework/harbor](https://github Ensure deployment of tested inference services following OpenAI chat/completions API specification with tool call support. -### 2. Install AISBench Evaluation Tool & Harbor Dependencies +### 2. Prepare AISBench-modified Terminal-Bench-2 Dataset and Images -#### 2.1 Install from Source +AISBench modified dataset repository: [https://github.com/AISBench/terminal-bench-2](https://github.com/AISBench/terminal-bench-2) + +> Note: AISBench only centralized all environment preparation into the Dockerfile without changing the case content, avoiding repeated environment building and dependency installation. + +Terminal-Bench-2 pre-packaged images: +| Image Name | Download Link | CPU Architecture | Compressed Size | +| --------- | ------------ | ---------------- | -------------- | +| `terminal-bench-2-prepared-images_aarch64.tar` | [Link](https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_aarch64.tar) | aarch64 | 48.50 GB | +| `terminal-bench-2-prepared-images_x86_64.tar` | [Link](https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_x86_64.tar) | x86_64 | 71.43 GB | + +> Tip: If you don't want to prepare images for all cases, you can get the terminal-bench-2-offline-mini sampled dataset from [terminal-bench-2-offline-mini](https://modelers.cn/datasets/AISBench/terminal-bench-2-offline-mini). + +### 3. Install AISBench Evaluation Tool & Harbor Dependencies + +#### 3.1 Install from Source > ⚠️ Environment requirements: Ensure Docker version >= 20.10.0 and Docker Compose version >= 2.0.0 (docker compose may need to be installed separately). Also prepare a Python 3.12 runtime environment. 1. In the Python 3.12 environment, refer to [AISBench Installation Documentation](../../get_started/install.md) to install AISBench evaluation tool. 2. In the Python 3.12 environment, install Harbor: @@ -55,56 +69,57 @@ Ensure deployment of tested inference services following OpenAI chat/completions ``` > ⚠️ Note: Installing Harbor will upgrade the datasets library to version 4.0.0 or higher, which will cause dependency conflicts for the datasets library after installation. This does not affect tests for Terminal-Bench datasets using Harbor. However, if you need to test other datasets, you will need to downgrade the datasets library. -#### 2.2 Install Inside a Docker Container -1. Refer to the "Running Agent / Sandbox Benchmarks (Docker Inside the Container)" section in the [Image Overview](https://github.com/AISBench/benchmark/blob/master/docker/OVERVIEW.en.md) to start a container based on a **Python 3.12 or above image (only images published after 2026.7.1 are supported)**. -2. Inside the container, run the following command to install Harbor: - ```bash - pip install harbor==0.6.1 --break-system-packages - ``` -3. Edit Harbor's docker compose configuration file `/usr/local/lib/python3.12/dist-packages/harbor/environments/docker/docker-compose-base.yaml`: -```yaml -services: - main: - network_mode: host # Share host network, required - security_opt: # Required when starting the container with Mode B (Socket Passthrough) - - seccomp=unconfined - volumes: - - type: bind - source: ${HOST_VERIFIER_LOGS_PATH} - target: ${ENV_VERIFIER_LOGS_PATH} - - type: bind - source: ${HOST_AGENT_LOGS_PATH} - target: ${ENV_AGENT_LOGS_PATH} - - type: bind - source: ${HOST_ARTIFACTS_PATH} - target: ${ENV_ARTIFACTS_PATH} - deploy: - resources: - limits: - cpus: ${CPUS} - memory: ${MEMORY} -``` -> ⚠️ Note: Installing Harbor will upgrade the datasets library to version 4.0.0 or higher, which will cause dependency conflicts for the datasets library after installation. This does not affect tests for Terminal-Bench datasets using Harbor. However, if you need to test other datasets, you will need to downgrade the datasets library. +> ⚠️ Note: When installing from source, the case image tar downloaded in the [2. Prepare Dataset and Images](#2-prepare-aisbench-modified-terminal-bench-2-dataset-and-images) section must be loaded into the local docker daemon on the **host machine** by running `docker load -i xxxxxxx.tar` before running the evaluation. +#### 3.2 One-Click Preparation (Recommended) +If you don't want to prepare the environment manually, it is recommended to use the **AISBench Agent Runtime one-click preparation solution**. The same script covers both **Quick Start (online)** and **Offline (intranet/isolated environment)** scenarios, and can be freely combined via `--runtime-tar` / `--case-tar` / `--datasets` without switching between different flows. -### 3. Prepare AISBench-modified Terminal-Bench-2 Dataset and Images +```bash +# 1. Start the runtime container on the host with one click (automatically select DinD/Socket mode, auto-mount datasets, and auto copy case image tar into the container for docker load) +# Online scenario: omit --runtime-tar, runtime image will be automatically pulled from ghcr.io +# Offline scenario: skip external network pull via --runtime-tar, which can be obtained from the latest release information in advance +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --datasets /path/to/terminal-bench-2-offline-mini/terminal-bench-2-offline-selected_0.10/ \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --case-tar /path/to/terminal-bench-2-offline-prepared-images-selected-0.10.tar \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --datasets must point to a directory structure consistent with the terminal-bench-2-offline-selected_0.10/ subdirectory of the terminal-bench-2-offline-mini repo +# --runtime-tar (optional) pre-downloaded runtime image; if omitted, the latest is pulled automatically +# --case-tar must point to a tar structure consistent with the case image tar described in the corresponding agent evaluation document (can be passed multiple times, or as a directory) +# --host-path must be an empty directory; a same-named directory will be created inside the container to mount datasets and case images +# --container-name must be unique; otherwise the old container will be overwritten + +# 2. Enter the container (case images are already loaded inside and ready to use) +docker exec -it test_agent_run bash + +# 3. (No need to change path) The native config path is read automatically from AISBENCH_AGENT_DATASET_PATH +# Only vim model_names / api_base +vim ais_bench/configs/agent_example/harbor_terminal_bench_2_task.py + +# 4. Verify runtime is ready +ais_bench_agent_doctor.sh harbor + +# 5. Enter the evaluation environment +agent_env harbor +``` -AISBench modified dataset repository: [https://github.com/AISBench/terminal-bench-2](https://github.com/AISBench/terminal-bench-2) +To switch to another dataset (mini-0.14 / mini-0.20 / full): destroy the old container → restart bootstrap with `bash ... --datasets --case-tar `. -> Note: AISBench only centralized all environment preparation into the Dockerfile without changing the case content, avoiding repeated environment building and dependency installation. +`--runtime-tar` / `--case-tar` / `--datasets` are fully independent and can be combined freely. None of them trigger any `docker pull` or `curl` to external networks; in the Quick Start (online) scenario, omit `--runtime-tar` and the script will pull the runtime image from the network automatically. -Terminal-Bench-2 pre-packaged images: -| Image Name | Download Link | CPU Architecture | Compressed Size | -| --------- | ------------ | ---------------- | -------------- | -| `terminal-bench-2-prepared-images_aarch64.tar` | [Link](https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_aarch64.tar) | aarch64 | 48.50 GB | -| `terminal-bench-2-prepared-images_x86_64.tar` | [Link](https://aisbench.obs.cn-north-4.myhuaweicloud.com/terminal-bench-2-images/terminal-bench-2-prepared-images_x86_64.tar) | x86_64 | 71.43 GB | +`--case-tar` works in both A/B modes: the script `docker cp`s the tar into the runtime container, then runs `docker load` inside the container to load it into that container's docker daemon. -> Tip: If you don't want to prepare images for all cases, you can get the terminal-bench-2-offline-mini sampled dataset from [terminal-bench-2-offline-mini](https://modelers.cn/datasets/AISBench/terminal-bench-2-offline-mini). +This solution addresses the following pain points: +- **Dependency conflicts**: harbor==0.6.1 forces datasets to be upgraded to 4.0+, which would pollute the main environment; the runtime image uses an isolated venv +- **Error-prone container configuration**: DinD mode A/B, `--cgroupns=host`, `daemon.json`, and seccomp are handled automatically +- **Frequent dataset version changes**: datasets and case images are not baked into the runtime image; users prepare them on the host and mount via `--datasets` / load via `--case-tar`, avoiding frequent image expiration +- **Case image management**: `--case-tar` loads case images into the container in one shot during bootstrap; no manual `docker pull` / `docker load` inside the container +- **No environment validation**: `doctor.sh` validates runtime readiness before running evaluations and gives precise fix guidance on failure +- **Offline deployment**: `--runtime-tar ` skips network fetching of the runtime image; `--case-tar ` loads case images into the container (can be used multiple times, or with a directory). Intranet-isolated environments can run with zero external network requests throughout -> ⚠️ Note: -> If you installed AISBench & Harbor dependencies from source, deploy the Terminal-Bench-2 images on the **host machine** by running `docker load -i xxxxxxx.tar`. -> If you started the AISBench container using Mode A (true Docker-in-Docker), deploy the Terminal-Bench-2 images **inside the container** by running `docker load -i xxxxxxx.tar`. -> If you started the AISBench container using Mode B (Socket Passthrough), deploy the Terminal-Bench-2 images on the **host machine** by running `docker load -i xxxxxxx.tar`. +For the solution principles and script implementation, see [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md). ### 4. Configure Custom Configuration File for Harbor Tasks diff --git a/docs/source_en/extended_benchmark/agent/swe_bench.md b/docs/source_en/extended_benchmark/agent/swe_bench.md index 59e4865e..42e37481 100644 --- a/docs/source_en/extended_benchmark/agent/swe_bench.md +++ b/docs/source_en/extended_benchmark/agent/swe_bench.md @@ -21,12 +21,12 @@ Directory `ais_bench/configs/swe_bench_examples/` provides the following example - `mini_swe_agent_swe_bench_multilingual.py`: SWE-bench Multilingual (`SWE-bench/SWE-bench_Multilingual`) — multilingual issue statements. - `mini_swe_agent_swe_bench_multilingual_mini.py`: SWE-bench Multilingual Mini (**15**/**30**/**60** instances) — an AISBench-constructed Multilingual subset designed to significantly reduce evaluation cost; see the dataset card and construction repository: `https://modelers.cn/datasets/AISBench/SWE-Bench_Multilingual_mini` and `https://github.com/AISBench/datasets/tree/main/mini_datasets/swe_bench_multiligual_mini`. -## 2. Prerequisites - -Before running, make sure the following dependencies are available: - -1) Install `mini-swe-agent` (required for infer) +## 2. Runtime Environment Installation +### 2.1 Install from Source +1. Verify Docker version meets requirements: run `docker version` and ensure Docker version is 20.10.0 or above, Docker API version is 1.42 or above +2. Refer to [Tool Installation & Uninstallation](../../get_started/install.html) to install AISBench evaluation tool from source +3. Install `mini-swe-agent` (required for infer) ```bash git clone https://github.com/AISBench/mini-swe-agent.git cd mini-swe-agent @@ -34,7 +34,7 @@ pip install -e . cd - ``` -2) Install the SWE-bench harness (required for eval) +4. Install SWE-bench harness (required for eval) ```bash git clone https://github.com/SWE-bench/SWE-bench.git @@ -43,18 +43,39 @@ pip install -e . cd - ``` -3) Docker is available (both infer and eval depend on containerized environments) +5. On ARM hosts, enable Docker x86 emulation (binfmt): ```bash -docker --version -docker ps +docker run --rm --privileged tonistiigi/binfmt --install all ``` -4) On ARM hosts, enable Docker x86 emulation (binfmt): +### 2.2 One-Click Preparation (Recommended) +If you don't want to install dependencies from source, or if Docker version is low (docker version < 20.10.0), it is recommended to use the **AISBench Agent Runtime one-click preparation solution**: ```bash -docker run --rm --privileged tonistiigi/binfmt --install all +# 1. Start the runtime container on the host with one click (automatically select DinD/Socket mode, auto-mount datasets, and auto copy case image tar into the container for docker load) +# Online scenario: omit --runtime-tar, runtime image will be automatically pulled from ghcr.io +# Offline scenario: skip external network pull via --runtime-tar, which can be obtained from the latest release information in advance +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --host-path /path/to/test_wkp/ \ + --container-name test_agent_run +# --runtime-tar (optional) pre-downloaded runtime image; if omitted, the latest is pulled automatically +# --host-path must be an empty directory; a same-named directory will be created inside the container to mount datasets and case images +# --container-name must be unique; otherwise the old container will be overwritten + +# 2. Enter the container +docker exec -it test_agent_run bash + +# 3. Verify runtime is ready +ais_bench_agent_doctor.sh swebench + +# 4. Activate the swebench venv (AISBench fork of mini-swe-agent) +agent_env swebench + ``` +> For the solution principles and script implementation, see [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md). ## 3. Minimal Configuration (Run First, Tune Later) diff --git a/docs/source_en/extended_benchmark/agent/swe_bench_pro.md b/docs/source_en/extended_benchmark/agent/swe_bench_pro.md index 00501e8d..da39dd3a 100644 --- a/docs/source_en/extended_benchmark/agent/swe_bench_pro.md +++ b/docs/source_en/extended_benchmark/agent/swe_bench_pro.md @@ -19,50 +19,80 @@ Directory `ais_bench/configs/swe_bench_pro_examples/` provides the following exa - `mini_swe_agent_swe_bench_pro_mini.py`: SWE-bench Pro Mini — commonly used for quick iterations. - `mini_swe_agent_swe_bench_pro_full.py`: SWE-bench Pro Full — the full test set. -## 2. Prerequisites +## 2. Runtime Environment Installation -Before running, make sure the following dependencies are available: - -1) Install `mini-swe-agent` (required for infer) +### 2.1 Install from Source +1. Verify Docker version meets requirements: run `docker version` and ensure Docker version is 20.10.0 or above, Docker API version is 1.42 or above +2. Refer to [Tool Installation & Uninstallation](../../get_started/install.html) to install AISBench evaluation tool from source +3. Install `mini-swe-agent` (required for infer) > **Note**: SWE-Bench Pro official organization scaleapi has adapted mini-swe-agent. You need to download the adapted version from scaleapi's repository. ```bash -# Clone mini-swe-agent repository git clone https://github.com/scaleapi/mini-swe-agent.git - -# Enter the project directory -cd mini-swe-agent/ - -# Install dependencies +cd mini-swe-agent pip install -e . - -# Return to parent directory cd - ``` -2) Install `SWE-Bench_Pro` (required for infer and eval) +4. Install `SWE-Bench_Pro` (required for infer and eval) ```bash -# Clone SWE-Bench_Pro repository git clone https://github.com/scaleapi/SWE-bench_Pro-os.git +cd SWE-bench_Pro-os +pip install -r requirements.txt +cd - +``` -# Enter the project directory -cd SWE-bench_Pro-os/ +5. SWEBP Scripts and Docker Directory Configuration -# Install dependencies -pip install -r requirements.txt +SWE-Bench Pro evaluation **must** specify the following two paths. There is no default behavior: -# Return to parent directory -cd - +- `swebp_scripts_dir`: Absolute path to the `run_scripts` directory of the SWE-bench Pro official repository +- `swebp_docker_dir`: Absolute path to the `dockerfiles` directory of the SWE-bench Pro official repository + +```python +SWEBP_SCRIPT_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/run_scripts" # Must be specified +SWEBP_DOCKER_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/dockerfiles" # Must be specified ``` -3) Docker is available (both infer and eval depend on containerized environments) +> **Note**: You need to clone the SWE-bench Pro official repository first: `git clone https://github.com/scaleapi/SWE-bench_Pro-os.git` + + + +### 2.2 One-Click Preparation (Recommended) +If you don't want to install dependencies from source, or if Docker version is low (docker version < 20.10.0), it is recommended to use the **AISBench Agent Runtime one-click preparation solution**: ```bash -docker --version -docker ps +# 1. Prepare the mini dataset on the host (skip if already done) +# SWE-bench Pro mini dataset **must** be prepared locally, no online version available +mkdir -p /data/datasets/swebench_pro +# Download URL: https://modelers.cn/datasets/AISBench/SWE-Bench_Pro_mini +# Recommended format: parquet; after download, extract to /data/datasets/swebench_pro/ + +# 2. Start the runtime container on the host with one click (automatically select DinD/Socket mode, auto-mount datasets, and auto copy case image tar into the container for docker load) +# Online scenario: omit --runtime-tar, runtime image will be automatically pulled from ghcr.io +# Offline scenario: skip external network pull via --runtime-tar, which can be obtained from the latest release information in advance +curl -fsSL https://aisbench.obs.cn-north-4.myhuaweicloud.com/agent/ais_bench_agent_bootstrap.sh \ + | bash -s -- \ + --runtime-tar /path/to/agent_runtime_image_v3.1-20260701-master-ubuntu24.04-py312-.tar.gz \ + --datasets /data/datasets/swebench_pro \ + --container-name ais_bench_agent +# --runtime-tar (optional) pre-downloaded runtime image; if omitted, the latest is pulled automatically +# --datasets points to the local dataset directory; a same-named directory will be created inside the container to mount the dataset +# --container-name must be unique; otherwise the old container will be overwritten + +# 3. Enter the container +docker exec -it ais_bench_agent bash + +# 4. Verify runtime is ready +ais_bench_agent_doctor.sh swebench_pro + +# 5. Activate the swebench_pro venv (scaleapi fork of mini-swe-agent) +agent_env swebench_pro + ``` +> For the solution principles and script implementation, see [`docker/agent_runtime/`](https://github.com/AISBench/benchmark/tree/master/docker/agent_runtime/README.md). ## 3. Minimal Configuration (Run First, Tune Later) @@ -102,20 +132,6 @@ Different datasets have different loading methods: - Recommended format: parquet - Set `path` to the locally downloaded parquet file or directory -### SWEBP Scripts and Docker Directory Configuration - -SWE-Bench Pro evaluation **must** specify the following two paths. There is no default behavior: - -- `swebp_scripts_dir`: Absolute path to the `run_scripts` directory of the SWE-bench Pro official repository -- `swebp_docker_dir`: Absolute path to the `dockerfiles` directory of the SWE-bench Pro official repository - -```python -SWEBP_SCRIPT_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/run_scripts" # Must be specified -SWEBP_DOCKER_PATH_ABS = "{your_work_dir}/SWE-bench_Pro-os/dockerfiles" # Must be specified -``` - -> **Note**: You need to clone the SWE-bench Pro official repository first: `git clone https://github.com/scaleapi/SWE-bench_Pro-os.git` - ### First-Run Recommendations - Start with the `mini` dataset