内容
# Cowork Bench
[](./LICENSE)
**Cowork Bench 是一个多工具代理基准测试平台,包含 496 个端到端任务,模拟真实办公工作流程。这些任务通过 MCP(Model Context Protocol)服务器执行,涉及从模拟数据库中提取数据、生成 Excel/Word/PPTX 文档、安排日历事件、发送电子邮件等。评估过程完全确定性(程序化检查 + SQL 副作用验证,无 LLM 作为评判标准),并且完全在本地运行:只需一个 Docker Compose,一个已初始化的 PostgreSQL 数据库,无需任何外部 API 调用。所有任务语句和系统提示均为俄语(标识符保持拉丁语以进行精确匹配),并使用俄罗斯特定域名(铁路,莫斯科交易所,1C HR,电子商务)。要求:Docker + bash;请参见下面的快速入门(俄语)。该项目基于 [Toolathlon](https://github.com/hkust-nlp/Toolathlon)(Apache 2.0)构建。**
— 多工具基准测试,用于 LLM 代理:现实工作流程任务,本地 PostgreSQL,无外部 API 调用。
在现实工具使用场景中,训练和评估 LLM 代理很复杂:现有数据集要么工具覆盖范围有限,要么规模小,要么依赖于随时可能变化的外部 API。**Cowork Bench** 提供了一个大规模、自包含的任务集,配备丰富的模拟数据库,完全在本地运行:在评估阶段无需任何外部调用。所有任务和系统提示均为**俄语**;标识符(文件名、表格、列、电子邮件、股票代码、状态标签)保留为拉丁语,以确保确定性检查。
每个任务要求代理执行端到端目标 — 例如,从模拟数据库中提取数据、生成 Excel 报告、在日历中安排事件、发送电子邮件 — 使用固定的一组 MCP 服务器作为工具。
每个任务都经过完全自动化:`preprocess/main.py` 准备工作空间的初始状态,代理使用可用工具执行任务,而 `evaluation/main.py` 将结果与标准答案进行比较。无需人工标记或外部服务。
该基准测试评估在现实场景中至关重要的能力:跨不同工具的多步骤规划、结构化格式的读写、系统间的数据同步以及在固定步骤预算下完成长期任务的能力。
## 运行器
存储库中包含两个运行器:
- **CAMEL** (`main.py`) — 默认:代理 + 评估一次性通过,最小化开销。
- **Strands** (`main_strands.py`) — 分阶段运行器,带有标准隔离(代理看不到 `groundtruth_workspace/` 和 `evaluation/`),具有强大的流式处理和重试机制;此运行器获得了下表中的 solo 结果。启用方式:`AGENT_ENTRY=main_strands.py`,`AGENT_PHASE_AWARE=1` + `LLM_*` 变量 — 参见 [`docs/STRANDS.md`](./docs/STRANDS.md)。
默认运行器为 **CAMEL 代理** (`main.py`)。任务完成由模型停止调用工具决定 — **无需 `claim_done` 工具**:当代理在没有新工具调用的情况下完成时,状态设置为 `SUCCESS`(参见 `utils/roles/task_agent.py`)。评估由任务评估器根据副作用而非调用信号工具进行。
对于 CAMEL 运行器,模型和提供商按优先级顺序指定:
1. 环境变量 `MODEL_NAME` 和 `MODEL_PROVIDER`(由 `main.py` 读取);
2. 命令行参数 `--model_name` / `--provider`;
3. `scripts/eval_config.json` 文件(备用)。
`MODEL_API_KEY` 和 `MODEL_API_URL` 用于密钥和端点。允许的 `MODEL_PROVIDER` 值:`openai`,`anthropic`,`gemini`,`deepseek`,`aihubmix`,`openai_compatible`。
## 快速入门
只需 **Docker** 和 **bash**。所有其他内容(Python、MCP 服务器、迁移)都在容器内。
```bash
cp .env.example .env # 配置 MODEL_*(参见下文)
docker build -t cowork-pack:latest . # 构建镜像(一次,大约 10-15 分钟)
./cowork_bench up # 启动 Postgres(cowork_pg)+ cowork_net 网络
./cowork_bench test-db # 测试 db/* 迁移
./cowork_bench run <task-name> # 运行单个任务(代理 + 评估)
./cowork_bench stability <task> 5 # 连续运行 5 次,总结 PASS/FAIL
./cowork_bench bench 3 # 并行运行所有任务(并发度 = 3)
./cowork_bench tasks [pattern] # 列出任务(可选,按子字符串)
./cowork_bench stop # 清理容器 + 锁
./cowork_bench help # 完整命令列表
```
`./cowork_bench up` 启动 `docker compose up -d`(Postgres `cowork_pg`,网络 `cowork_net` 和可选的开发容器 `cowork`)。对于单个任务运行(`run`),只需 `cowork_pg` 处于健康状态,`cowork_net` 网络存在 — `scripts/run_containerized.sh` 会为每个任务启动一个临时容器。`cowork_bench` 会读取 `.env` 并默认使用 CAMEL 运行器(`AGENT_FRAMEWORK=camel`,`IMAGE=cowork-pack:latest`);任何默认值都可以通过 `.env`/env 覆盖。环境变量的说明参见 [`docs/ENVIRONMENT_QUIRKS.md`](./docs/ENVIRONMENT_QUIRKS.md)。
### CAMEL 运行器的最小 `.env` 配置
```bash
MODEL_PROVIDER=openai_compatible # openai | anthropic | gemini | deepseek | aihubmix | openai_compatible
MODEL_NAME=your-model-name
MODEL_API_KEY=sk-REPLACE_ME
MODEL_API_URL=https://your-llm-endpoint/v1 # openai_compatible / aihubmix 需要
```
### 结果评估
使用默认 CAMEL 运行器,评估会在同一运行中**自动进行**:`main.py` 在代理完成任务后调用评估器并将结果写入 `eval_res.json`。无需运行单独的命令。
独立的 `scripts/run_eval.py` 评估器(和 `run_containerized.sh` 中的独立评估容器)仅用于带有标准隔离的阶段感知运行器(参见“连接您自己的运行器”)。
### 查看结果
```
dumps/<task>/<timestamp>/.../SingleUserTurn-<task>/
├── traj_log.json # 运行配置 + 状态
├── traj.json # 完整轨迹(消息 + 工具调用)
├── eval_res.json # {"pass": true|false, "details": "..."}
└── workspace/ # 代理生成的文件
```
并行运行的聚合结果位于 `benchmark_logs/fully_parallel_<timestamp>/summary.csv`。
## 连接您自己的运行器
`scripts/run_containerized.sh` 通过以下方式选择代理入口:
- `AGENT_ENTRY=<path>` — 您的运行器脚本的显式路径(最高优先级);
- 否则 `AGENT_FRAMEWORK=strands` → `main_strands.py`;
- 否则默认 → `main.py`(CAMEL)。
引擎接口:
- 接受 `--task_dir <task>` 和 `--max_steps <N>`;
- 将 `traj_log.json` 和 `workspace/` 目录写入 `/workspace/dumps` — 评估器 `scripts/run_eval.py` 将其找到。
**标准隔离(可选)**。为了确保代理不会看到 `groundtruth_workspace/` 和 `evaluation/`,运行分为两个阶段(代理在干净的容器中 → 单独评估)。这在运行器为 `main_strands.py` 或设置了 `AGENT_PHASE_AWARE=1` 时启用;然后代理必须支持 `--phase agent` 标志。否则,将执行单个传递(代理 + 评估一起,完整的挂载,**无** 隔离)。
```bash
# 使用标准隔离连接您自己的运行器
AGENT_ENTRY=my_runner.py AGENT_PHASE_AWARE=1 \
bash scripts/run_containerized.sh <task-name> 100
```
运行器和评估器的代码被编译到镜像中(`Dockerfile: COPY . .`),因此从此存储库构建的镜像无需主机挂载即可工作。对于快速迭代开发运行器,请使用 `DEV_MOUNTS=1`(主机代码叠加)。
---
## 架构:MCP 服务器
`configs/mcp_servers/*.yaml` 注册 MCP 服务器,`local_servers/<name>/` 包含其代码。“SQL 类似”MCP 的后端共享 PostgreSQL `cowork_pg`,每个 MCP 有自己的模式(例如 `canvas`,`moex`,`wc`,`hr1c_data`)。
数据以确定性的方式加载: **`db/init.sql.gz`** — 完整转储(所有模式,包括俄语数据 `rzd`,`teamly`,`moex`,`hr1c`,`gform`,以及 `canvas`,`wc` 的重新标记),由 Postgres 的 docker-entrypoint 在首次启动时自动应用。
添加新域 → 在 `local_servers/` 中分叉 MCP,编写 post-init 迁移 `db/zzz_<name>_after_init.sql`(前缀 `zzz_` 确保在 `init.sql.gz` **之后** 加载 — 入口点按字母顺序对文件进行排序),在 `docker-compose.yml` 中注册它(`/docker-entrypoint-initdb.d/` 中的卷)和 `configs/mcp_servers/<name>.yaml` 中的服务器。现成的配方参见 [`docs/RUSSIFICATION.md`](./docs/RUSSIFICATION.md)。
---
## 任务结构
所有任务都位于 `tasks/finalpool/`。每个任务目录都有一个统一的布局:
```
<task-name>/
├── task_config.json # 哪些 MCP 服务器和本地工具可用于代理
├── docs/
│ ├── task.md # 任务描述(显示给代理)
│ └── agent_system_prompt.md
├── evaluation/main.py # 自动评估器
├── preprocess/main.py # 准备数据库状态(在任务前运行)
├── initial_workspace/ # 代理工作空间中的输入文件
└── groundtruth_workspace/ # 用于检查的标准输出
```
任务描述 (`task.md`) **不含品牌工具名称** — 知识库、共享日历或 LMS 等服务以通用方式描述。这是与原始 Toolathlon 项目中使用的混淆约定相同:它防止代理通过识别关键词来取捷径,而是强制它们思考实际的工具使用。
## 模拟数据库
**连接**: 容器 `cowork_pg` 上的 `cowork_gym` 数据库(在网络内 — `cowork_pg:5432`,在主机上 — `localhost:15433`;用户名 `eigent`,密码 `camel`)。
所有数据均由本地 PostgreSQL 提供,使用压缩转储 (`db/init.sql.gz`) 和 post-init 迁移进行初始化。运行时无需外部调用 — 环境完全可控,无 API 限制、模式更改或数据漂移。
数据从现实来源导出或模拟: **Kaggle OULAD** (开放大学学习分析)用于 LMS,**Kaggle HR Analytics** 用于企业 HR,金融市场数据用于财务,**Kaggle Amazon** 和 **DummyJSON** 组合用于电子商务,以及俄语分叉(俄罗斯铁路,知识库,表单)。
### 丰富的模式
| 领域 | 描述 | 模式 |
|-------|----------|-------|
| **canvas** | LMS — 课程,用户,注册,作业,提交,测试,类别,公告(俄语名称/现实) | `canvas` |
| **moex** | 交易所 — 报价,财务报告,新闻,期权,持有者 | `moex` |
| **woocommerce/insales** | 电子商务 — 产品,订单,客户,优惠券,评论 | `wc` |
| **rzd** | 铁路 — 站点,火车,路线,地点 | `rzd` |
| **teamly** | 知识库(俄罗斯 Confluence 模拟) | `teamly` |
| **forms** | PostgreSQL 后端调查/表单 | `gform` |
| **hr1c** | 企业 HR | `hr1c_data` |
| **youtube** | 视频平台 — 频道,播放列表,视频,字幕 | `youtube` |
## 结果
2026 年 6 月至 7 月的运行结果,所有 496 项任务,**pass@1** 指标。**solo** 方法 — 使用 Strands 运行器(并发度为 1)的单线程运行:纯粹的 pass@1,无基础设施故障。**parallel** 方法 — 较早的多线程运行,并带有 ex-stall 校正(参见脚注)。
| 模型 | 窗口 | PASS@1 | 方法 |
|---|---|---|---|
| **MiniMax-M3** (428B-A23B, FP8) | 400k | 323 / 496 — **65.1%** | parallel |
| **Qwen 3.5 397B-A17B** (BF16, MoE) | 262k | 312 / 496 — **62.9%** | solo |
| **Qwen 3.6 27B** (Dense, FP8) | 262k | 309 / 496 — **62.3%** | solo |
| **Qwen 3.6 35B-A3B** (FP8, MoE) | 262k | 300 / 496 — **60.5%** | solo |
| **GigaCode Agentic v1.6** \* (80B-A3B, FP8) | 262k | 120 / 421 — **28.5%** | parallel, ex-stall |
| **GigaChat-3.5** (432B-A28B) \*\*\* | 130k | 119 / 496 — **24.0%** | solo |
| **GigaChat-3-Max** \*\* (90B Dense, FP8) | 130k | 41 / 375 — **10.9%** | parallel, ex-stall |
| **GigaChat-3-Pro** \*\*\* | 130k | 24 / 496 — **4.8%** | solo |
> \* **GigaCode Agentic v1.6** — 排除基础设施故障:75 次 stream-stall。指标 **28.5%** = 120/421 到达评估(原始 pass@1 = 120/496 = 24.2%)。
>
> \*\* **GigaChat-3-Max** — 排除基础设施故障:59 次 stream-stall + 22 次 HTTP 500 + 32 次 task_timeout。指标 **10.9%** = 41/375 到达评估(原始 pass@1 = 41/496 = 8.3%)。
>
> \*\*\* **GigaChat-3.5 / 3-Pro** — 通过带有转换代理的 legacy `functions` API 运行(**1 个工具/步** — 结构性障碍);实际窗口 ≈ 130k。3-Pro — 无推理。
该基准测试在模型实力上表现出较大的差异(65% → 5%);Qwen 家族聚集在 60–63%,与模型大小无关(27B ≈ 35B ≈ 397B 在诚实单线程测试中)。
## Cowork Bench 的特点
- **规模和多样性。** 数百个任务,多个 MCP 服务器和数据域;任务需要真正的跨系统协调,而不是单个查找。
- **完全本地和可复制。** 所有环境都使用单个 Docker Compose 启动。评估期间不需要外部服务密钥。PostgreSQL 转储是版本控制的和确定性的 — 结果在不同机器和时间之间可复制。
- **现实复杂性。** 任务源自现实工作流程:Excel 中的 HR 分析,根据日历中的截止日期检查 LMS 提交,收集数据生成演示文稿以及类似的多步骤目标。多数任务需要 4–7 个工具。
## 致谢
Cowork Bench 建立在项目的数据管道和基础设施之上:
> **Toolathlon: Benchmarking LLM Agents on Real-World Tool-Use Tasks**
> HKUST-NLP — https://github.com/hkust-nlp/Toolathlon
基准测试的数据库模式、MCP 服务器接口和评估框架来自 Toolathlon 项目(Apache License 2.0,参见 [`LICENSE`](./LICENSE))。Cowork Bench 将任务池本地化为俄语,用俄罗斯替代方案替换了一些外部服务,并扩展了数据集。
`local_servers/` 目录包含第三方开源 MCP 服务器(文件系统、Excel、Word、PowerPoint、Playwright、Fetch 等)的分支版本 — 授权和许可证在相应子目录的自身声明中指定。