Cline E2E 基准测试实战:用 Harbor 与 cline-bench 在真实故障代码库中验证 Agent 能力
本篇指南围绕 Cline 仓库中 E2E Agent 测试 展开,讲解如何基于 cline-bench 生产级编码任务、Harbor 执行框架与 Docker/Daytona 环境,对 Cline 运行完整的端到端 Agent 评测;读完你可以掌握前置环境搭建、全部 CLI 参数、结果判定机制(reward 文件)与失败排查方法,并能对照 run-cline-bench.ts 源码理解 Runner 的完整调用链。
一、E2E 测试的定位:评测金字塔的第三层
在 Cline 的分层评测体系中(参见 evals/ARCHITECTURE.md),测试被划分为三层:
- Layer 1 契约测试:纯单元测试,验证 API 格式转换、工具调用解析,无 LLM 调用;
- Layer 2 冒烟测试:
evals/smoke-tests/下的 5 个精选场景,分钟级完成,调用真实模型; - Layer 3 E2E 测试:即本文主题,位于 evals/e2e/,基于 cline-bench 的生产级任务,耗时以小时计。
E2E 测试的核心设计是:让 Cline 在真实的、损坏的代码库中完成生产级问题修复。每个任务遵循统一的三段式流程(来自 evals/e2e/README.md):
- 在 Docker 中启动一个带有缺陷的代码库;
- 把任务描述交给 Cline(以
cline-cliagent 身份运行); - 用 pytest 验证修复是否成功(verifier 产出 reward)。
这相当于 SWE-bench 风格的问题集:任务源自真实用户会话衍生的生产级编码问题,而不是玩具示例。
二、前置环境搭建
按 evals/e2e/README.md 的要求,本地运行需要四项前置条件。下面给出原文档的安装命令,并补充 Runner 源码中的实际校验逻辑。
1. Python 3.13 + uv
# macOS
brew install python@3.13
pip install uv
Runner 的 checkPrerequisites()(run-cline-bench.ts)会执行 python3 --version:找不到 Python 3 直接报错退出;版本不是 3.13 只打印警告(Warning: Python 3.13 recommended, found: ...),不阻断运行。
2. Harbor(基准执行框架)
uv tool install harbor
这是硬性检查:源码中执行 which harbor,失败则返回 Harbor not found. Install with: uv tool install harbor 并终止。
3. Docker(本地执行时)
# 验证 Docker 正在运行
docker info
注意源码中 Docker 检查失败只告警不终止:Warning: Docker not available. Use --env daytona for cloud execution.——即没有 Docker 时仍可切换到 Daytona 云端执行。
4. API Key
export ANTHROPIC_API_KEY=sk-ant-...
# 或
export API_KEY=sk-ant-... # 通用回退变量
从源码可以看到,每个 provider 有专属环境变量(run-cline-bench.ts):
| Provider | 专属环境变量 |
|---|---|
anthropic |
ANTHROPIC_API_KEY |
openrouter |
OPENROUTER_API_KEY |
openai |
OPENAI_API_KEY |
gemini |
GEMINI_API_KEY |
取值逻辑是 process.env[专属变量] || process.env.API_KEY,即专属变量优先、API_KEY 兜底;两者都缺失时该任务直接记为失败(Missing API key: ...),而不是整体退出。
5. 初始化 cline-bench 子模块(文档隐含的前置步骤)
任务集存放在 git 子模块 evals/cline-bench 中。.gitmodules 定义了该子模块,Runner 在找不到目录时会提示:
Ensure the submodule is initialized: git submodule update --init
因此在首次运行前,需要执行:
git submodule update --init
若跳过这一步,Runner 会以 cline-bench not found at: ... 报错退出(run-cline-bench.ts)。
三、本地运行方式
以下为原文档给出的完整命令集(相对于仓库根目录执行):
# 以默认设置运行全部任务(Anthropic + Docker)
npx tsx evals/e2e/run-cline-bench.ts
# 只运行特定任务(子串过滤)
npx tsx evals/e2e/run-cline-bench.ts --tasks discord
# 使用其他 provider/模型
npx tsx evals/e2e/run-cline-bench.ts --provider openai --model gpt-4o
# 在 Daytona 云端运行(更快、可并行)
export DAYTONA_API_KEY=dtn_...
npx tsx evals/e2e/run-cline-bench.ts --env daytona
# 输出 JSON 结果
npx tsx evals/e2e/run-cline-bench.ts --output results.json
对应源码,各参数在 main() 中手工解析,默认值为:env=docker、provider=anthropic、model=claude-sonnet-4-20250514、tasks=all、trials=1(run-cline-bench.ts),与文档中的 CLI Options 表完全一致。
需要说明的是:当前仓库根目录的 package.json 中并未定义 eval:e2e 脚本(只有 test:unit、test:e2e 等),因此按本文档直接使用 npx tsx 调用 Runner 是当前可用方式。
四、CLI 参数详解
| 参数 | 默认值 | 说明 |
|---|---|---|
--env |
docker |
执行环境:docker 或 daytona |
--provider |
anthropic |
模型提供商:anthropic、openai、openrouter、gemini |
--model |
claude-sonnet-4-20250514 |
模型 ID |
--tasks |
all |
任务过滤模式(子串匹配) |
--trials |
1 |
每个任务重复试验次数 |
--output |
- | 将 JSON 结果写入指定文件 |
三个值得注意的源码级细节:
- Provider 到 Harbor 模型串前缀的映射并非原样透传,而是经过
PROVIDER_MODEL_PREFIX转换(run-cline-bench.ts):openai会被映射为openai-native,anthropic/openrouter/gemini保持同名前缀。最终拼成的 Harbor 模型串形如anthropic:claude-sonnet-4-20250514。若传入未收录的 provider,则直接以其自身名称作为前缀。 - 任务过滤是子串匹配:
getTaskList()读取evals/cline-bench/tasks/下的子目录名,--tasks discord会筛选出所有名称中包含discord的任务(run-cline-bench.ts),并非精确匹配。 --trials的实现方式:Runner 在循环里对同一任务重复调用 Harbor(每次都是一个完整 trial),而不是把试验数传给 Harbor 单进程(run-cline-bench.ts)。
五、Runner 内部执行链:一次任务的完整生命周期
结合 run-cline-bench.ts 源码,每个任务的执行链路如下:
-
定位任务目录:Runner 以自身位置为基准定位
evals/cline-bench/,读取tasks/子目录得到任务清单; -
拼装 Harbor 命令:核心命令为(run-cline-bench.ts)
harbor run -p tasks/<taskId> -a cline-cli -m <prefix>:<model> --env <docker|daytona>其中
-a cline-cli表明被评测的 agent 是 Cline CLI,命令在cline-bench目录下以spawnSync同步执行,并继承父进程环境变量(附带统一的API_KEY)。 -
30 分钟硬超时:每次 Harbor 调用设置了
timeout: 30 * 60 * 1000,与文档中“部分任务需要 20–30 分钟”的说法互相印证; -
结果判定靠 reward 文件:Harbor 成功退出后,Runner 扫描
evals/cline-bench/jobs/下最新的时间戳 job 目录,查找该任务对应的 trial 目录中的verifier/reward.txt,内容为1记 PASS,0记 FAIL;找不到 reward 文件则记为Could not determine task result(run-cline-bench.ts); -
汇总与退出码:所有任务跑完后生成
BenchmarkReport并在终端打印 SUMMARY(Total / Passed / Failed / Pass Rate)。只要有失败任务,进程即以退出码 1 结束(run-cline-bench.ts),这一点为将来接入 CI 的失败判定做了准备。
--output results.json 写出的 JSON 结构由 BenchmarkReport 接口定义(run-cline-bench.ts):
{
timestamp, provider, model, environment, trialsPerTask,
results: [{ taskId, passed, duration_sec, error? }],
summary: { total, passed, failed, passRate }
}
六、任务集:12 个生产级编码任务
当前 cline-bench 提供 12 个任务(来自 evals/e2e/README.md),覆盖多种语言与技术栈的修复/重构/迁移场景:
- every-plugin-api-migration — 迁移插件中的 API 调用
- police-sync-segfault — 修复段错误
- intercept-axios-error-handling — 修复 Axios 错误处理
- telegram-plugin-refactor — 重构 Telegram 插件
- discord-trivia-approval-keyerror — 修复 Discord 机器人的 KeyError
- terraform-azurerm-deployment-stacks — Terraform 提供方修复
- orpc-client-migration — 客户端迁移任务
- v-edit-workspace-tests — 修复 workspace 测试
- healthchain-prefetch-removal — 移除 prefetch 逻辑
- aenet-pytorch-pbc-neighborlist — PyTorch 周期性边界条件(PBC)修复
- suave-http-data-bleeding — 修复 HTTP 数据泄漏
- filmarchiver — 影片归档器缺陷修复
由于 --tasks 采用子串过滤,例如 --tasks discord 只会命中第 5 个任务;用 --tasks pytorch 可单独跑第 10 个任务。
七、结果目录结构
Harbor 会将结果写入 evals/cline-bench/jobs/ 目录,结构如下(来自 evals/e2e/README.md):
jobs/
└── 2025-01-25__10-00-00/
├── result.json # 聚合结果
└── <task-id>__<hash>/
├── result.json # 单次 trial 结果
├── agent/cline.txt # 完整会话日志
└── verifier/reward.txt # 1(通过)或 0(失败)
排查问题时,agent/cline.txt 记录了 Cline 与环境的完整交互过程,verifier/reward.txt 是 Runner 判定 PASS/FAIL 的唯一依据——两者结合可以精确定位是 Agent 行为问题还是验证器问题。
八、CI 集成:为什么只在夜间跑
文档明确说明 E2E 测试只在夜间调度而非每个 PR 都跑,原因有三:
- 耗时长:每个任务 20–30 分钟;
- API 成本:每次运行约 $1–5,取决于所选模型;
- 基础设施要求:依赖 Docker 或 Daytona 环境。
文档同时指向 .github/workflows/nightly-evals.yml 作为 CI 配置。这里需要基于当前仓库状态做一个审慎说明:目前 .github/workflows/ 目录下尚未看到该工作流文件,且 evals/README.md 的 TODO 一节明确写着 “Nightly E2E CI: Add scheduled workflow for cline-bench tests”(要求 Docker runner、Harbor 就绪、约 1–2 小时超时、独立 secrets)。从源码结构看,Runner 以失败即退出码 1 的行为设计,已经为接入该夜间工作流预留了条件。
九、故障排查
原文档的 Troubleshooting 章节覆盖了三个高频问题:
1. “Harbor not found”
source .venv/bin/activate # 如使用 venv
uv tool install harbor
对应源码中 which harbor 检查失败的路径。
2. “Docker not available”
# 启动 Docker daemon
docker info # 应能正常显示 Docker 信息
3. 任务超时
部分任务(如 Qt WASM、Android 相关)可能需要 20–30 分钟。本地运行时请确保 Docker 拥有足够资源(建议 8GB+ 内存)。从源码看,30 分钟正是 spawnSync 的 timeout 值,超过即被判定为失败。
十、现状说明与延伸阅读
- 当前检出的 evals/cline-bench 目录为空,说明子模块尚未初始化;首次使用必须先执行
git submodule update --init,否则 Runner 直接报错退出。 - 根据 evals/README.md,整个评测框架在切换到新的 SDK CLI 期间处于部分调整状态:冒烟测试(Layer 2)的 CI 临时停用,E2E 夜间 CI 尚在 TODO 列表中。因此本文档描述的运行方式(
npx tsx直接驱动)是当前最可靠的本地评测入口。 - 想理解 pass@k / pass^k 等指标以及完整的三层测试金字塔,可继续阅读 evals/ARCHITECTURE.md 与 evals/README.md;任务贡献入口是外部的 cline-bench 子模块仓库(见 .gitmodules)。
小结:Cline 的 E2E 评测通过 npx tsx evals/e2e/run-cline-bench.ts 一条命令,把 12 个真实故障代码库交给 Cline CLI,在 Harbor 驱动的 Docker/Daytona 沙箱中逐个验证,并以 reward.txt 作为客观判分依据。理解 Runner 的 provider 前缀映射、30 分钟超时与 reward 判定逻辑后,你就可以在本地或 CI 中稳定复现整套评测流程,并基于 --output 产出的 JSON 报告做跨模型、跨版本的回归对比。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00