首页
/ Cline E2E 基准测试实战:用 Harbor 与 cline-bench 在真实故障代码库中验证 Agent 能力

Cline E2E 基准测试实战:用 Harbor 与 cline-bench 在真实故障代码库中验证 Agent 能力

2026-09-06 15:21:45作者:咎竹峻Karen

本篇指南围绕 Cline 仓库中 E2E Agent 测试 展开,讲解如何基于 cline-bench 生产级编码任务、Harbor 执行框架与 Docker/Daytona 环境,对 Cline 运行完整的端到端 Agent 评测;读完你可以掌握前置环境搭建、全部 CLI 参数、结果判定机制(reward 文件)与失败排查方法,并能对照 run-cline-bench.ts 源码理解 Runner 的完整调用链。

一、E2E 测试的定位:评测金字塔的第三层

在 Cline 的分层评测体系中(参见 evals/ARCHITECTURE.md),测试被划分为三层:

  1. Layer 1 契约测试:纯单元测试,验证 API 格式转换、工具调用解析,无 LLM 调用;
  2. Layer 2 冒烟测试evals/smoke-tests/ 下的 5 个精选场景,分钟级完成,调用真实模型;
  3. Layer 3 E2E 测试:即本文主题,位于 evals/e2e/,基于 cline-bench 的生产级任务,耗时以小时计。

E2E 测试的核心设计是:让 Cline 在真实的、损坏的代码库中完成生产级问题修复。每个任务遵循统一的三段式流程(来自 evals/e2e/README.md):

  • 在 Docker 中启动一个带有缺陷的代码库
  • 任务描述交给 Cline(以 cline-cli agent 身份运行);
  • 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=dockerprovider=anthropicmodel=claude-sonnet-4-20250514tasks=alltrials=1run-cline-bench.ts),与文档中的 CLI Options 表完全一致。

需要说明的是:当前仓库根目录的 package.json 中并未定义 eval:e2e 脚本(只有 test:unittest:e2e 等),因此按本文档直接使用 npx tsx 调用 Runner 是当前可用方式。

四、CLI 参数详解

参数 默认值 说明
--env docker 执行环境:dockerdaytona
--provider anthropic 模型提供商:anthropicopenaiopenroutergemini
--model claude-sonnet-4-20250514 模型 ID
--tasks all 任务过滤模式(子串匹配)
--trials 1 每个任务重复试验次数
--output - 将 JSON 结果写入指定文件

三个值得注意的源码级细节:

  • Provider 到 Harbor 模型串前缀的映射并非原样透传,而是经过 PROVIDER_MODEL_PREFIX 转换(run-cline-bench.ts):openai 会被映射为 openai-nativeanthropic/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 源码,每个任务的执行链路如下:

  1. 定位任务目录:Runner 以自身位置为基准定位 evals/cline-bench/,读取 tasks/ 子目录得到任务清单;

  2. 拼装 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)。

  3. 30 分钟硬超时:每次 Harbor 调用设置了 timeout: 30 * 60 * 1000,与文档中“部分任务需要 20–30 分钟”的说法互相印证;

  4. 结果判定靠 reward 文件:Harbor 成功退出后,Runner 扫描 evals/cline-bench/jobs/ 下最新的时间戳 job 目录,查找该任务对应的 trial 目录中的 verifier/reward.txt,内容为 1 记 PASS,0 记 FAIL;找不到 reward 文件则记为 Could not determine task resultrun-cline-bench.ts);

  5. 汇总与退出码:所有任务跑完后生成 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),覆盖多种语言与技术栈的修复/重构/迁移场景:

  1. every-plugin-api-migration — 迁移插件中的 API 调用
  2. police-sync-segfault — 修复段错误
  3. intercept-axios-error-handling — 修复 Axios 错误处理
  4. telegram-plugin-refactor — 重构 Telegram 插件
  5. discord-trivia-approval-keyerror — 修复 Discord 机器人的 KeyError
  6. terraform-azurerm-deployment-stacks — Terraform 提供方修复
  7. orpc-client-migration — 客户端迁移任务
  8. v-edit-workspace-tests — 修复 workspace 测试
  9. healthchain-prefetch-removal — 移除 prefetch 逻辑
  10. aenet-pytorch-pbc-neighborlist — PyTorch 周期性边界条件(PBC)修复
  11. suave-http-data-bleeding — 修复 HTTP 数据泄漏
  12. 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 分钟正是 spawnSynctimeout 值,超过即被判定为失败。

十、现状说明与延伸阅读

  • 当前检出的 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.mdevals/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 报告做跨模型、跨版本的回归对比。

登录后查看全文
热门项目推荐
相关项目推荐