← 返回博客列表

Agent Benchmark 实战:SWE-bench、WebArena 与 OSWorld 评测避坑指南

为什么你需要认真对待 Agent Benchmark

2026 年,几乎每周都有新 Agent 框架宣称”在 SWE-bench 上达到 SOTA”。但当你尝试复现时,往往发现:分数差 10 个点、环境跑不通、评测脚本有隐含假设。

Benchmark 不是排行榜游戏——它是你选型、优化、上线前的工程决策依据。跑不明白 Benchmark,等于在生产环境里盲飞。

本文覆盖三个最具代表性的 Agent 评测基准:

Benchmark评测维度典型任务难度定位
SWE-bench代码修复给定 GitHub Issue,生成 Patch工程推理
WebArena网页操作在真实网站完成多步任务交互决策
OSWorld桌面操作跨应用完成复杂工作流端到端自主

SWE-bench:代码 Agent 的试金石

评测机制

SWE-bench 从真实开源项目(Django、scikit-learn、sympy 等)抽取已合并的 PR,将 Issue 描述作为输入,要求 Agent 生成能通过对应测试的 Patch。

# SWE-bench 评测核心流程(简化)
from swebench.harness.run_evaluation import run_evaluation

results = run_evaluation(
    predictions_path="predictions.jsonl",   # Agent 生成的 patch
    swe_bench_tasks="swe-bench-verified",   # 数据集版本
    log_dir="./logs",
    timeout=300,                            # 每个实例超时
    num_workers=4
)

# 关键指标:resolved rate = 通过测试的实例 / 总实例数
print(f"Resolved: {results['resolved']}/{results['total']}")

复现陷阱

陷阱 1:数据集版本混淆

SWE-bench 有多个子集,分数不可直接对比:

子集实例数说明
SWE-bench Full2294完整集,含噪声实例
SWE-bench Lite300人工筛选,难度适中
SWE-bench Verified5002024 年新增,人工验证可解

很多论文只报 Lite 分数却暗示是 Full 的表现——看结果时先确认子集。

陷阱 2:环境依赖地狱

每个实例需要特定版本的 Python 和依赖。官方推荐 Docker 隔离:

# 使用官方 harness 构建评测环境
python -m swebench.harness.run_evaluation \
    --predictions_path predictions.jsonl \
    --max_workers 4 \
    --run_id my_eval_001 \
    --cache_level instance  # 缓存已构建的环境镜像

陷阱 3:隐含的上下文窗口优势

部分方案在 Agent 推理前先做 BM25 检索定位文件,这步的质量直接影响最终分数。如果你的 Agent 没有类似的 retrieval 前置步骤,对比就不公平。

工程建议

  • 先跑 Verified 子集的前 50 个实例做 sanity check,确认 pipeline 通畅
  • 记录每个实例的 token 消耗和耗时,计算 cost-per-resolve
  • 关注 “partial resolve”(patch 通过部分测试)作为调优信号

WebArena:网页交互 Agent 的竞技场

评测机制

WebArena 部署了一组自托管网站(GitLab、Reddit 论坛、电商、CMS),Agent 需要在浏览器中完成自然语言描述的任务,如”在 GitLab 上创建一个 issue 并 assign 给 user X”。

// WebArena 任务执行伪代码
interface WebArenaTask {
  intent: string;          // "Post a reply to the first thread in forum"
  start_url: string;       // 起始页面
  eval_type: "url_match" | "content_match" | "program";
  reference_answer: string;
}

// Agent 需要输出 action 序列
type BrowserAction =
  | { type: "click"; selector: string }
  | { type: "type"; selector: string; text: string }
  | { type: "scroll"; direction: "up" | "down" }
  | { type: "goto"; url: string }
  | { type: "stop"; answer?: string };

复现陷阱

陷阱 1:环境状态漂移

WebArena 的网站有预置数据。如果你连续跑多个任务不重置,前一个任务的操作会污染后续任务的环境。

# 每轮评测前重置环境(官方脚本)
bash scripts/reset_environment.sh

# 或使用 Docker snapshot 回滚
docker compose down && docker compose up -d

陷阱 2:评分函数的宽松度

WebArena 的 program 类型评分使用自定义 Python 函数判定成功。有些函数只检查 URL 包含特定字符串,有些则严格验证页面内容。同样的 Agent 行为,在不同评分函数下结果可能不同。

陷阱 3:截图 vs DOM 的信息差

纯视觉方案(截图 → 多模态模型)和 DOM 方案(accessibility tree → 文本模型)的上限不同。2026 年的趋势是混合方案:先用 DOM 定位,视觉辅助确认。

工程建议

  • 本地部署至少需要 16GB RAM(5 个网站容器同时运行)
  • 用 Playwright trace 录制每次交互,失败时可回放调试
  • 按网站类型分组统计成功率,找到 Agent 的弱点领域

OSWorld:桌面级 Agent 的终极考验

评测机制

OSWorld 在虚拟机中运行完整桌面环境(Ubuntu),Agent 需要跨应用完成任务,如”用 LibreOffice 打开附件,提取表格数据,用 Firefox 上传到指定网站”。

评测通过截图比对 + 文件内容校验 + 系统状态检查三重验证。

复现陷阱

陷阱表现解法
VM 启动慢每个实例 2-5 分钟初始化预热 snapshot + 并行 VM 池
屏幕分辨率敏感坐标点击偏移固定 1920×1080,用语义定位替代坐标
应用版本差异UI 元素位置变化锁定 VM 镜像版本,不做 apt upgrade
超时设置复杂任务需要 10+ 步按任务类别设置梯度超时
# OSWorld 评测配置示例
eval_config = {
    "vm_image": "osworld-ubuntu-22.04-v2.1.qcow2",
    "resolution": "1920x1080",
    "timeout_per_task": 600,        # 秒
    "max_steps": 30,                # Agent 最大操作步数
    "screenshot_interval": 0.5,     # 截图频率
    "eval_methods": ["screenshot_match", "file_check", "state_check"]
}

工程建议

  • OSWorld 对 GPU 没有硬性要求,但 VM 管理需要 KVM 支持
  • 优先跑 “easy” 子集(单应用任务)验证基础能力
  • 记录每步的 screenshot + action,构建错误分类体系

构建你自己的评测流水线

跑完公开 Benchmark 只是起点。生产环境需要领域特定评测

# 通用 Agent 评测框架骨架
from dataclasses import dataclass
from typing import Callable

@dataclass
class EvalTask:
    task_id: str
    instruction: str
    setup: Callable          # 环境初始化
    evaluate: Callable       # 结果判定
    teardown: Callable       # 环境清理
    timeout: int = 300
    tags: list[str] = None   # 用于分组统计

class AgentEvalPipeline:
    def __init__(self, agent, tasks: list[EvalTask], parallelism: int = 4):
        self.agent = agent
        self.tasks = tasks
        self.parallelism = parallelism

    async def run(self) -> dict:
        results = []
        for task in self.tasks:
            task.setup()
            try:
                output = await self.agent.execute(
                    task.instruction, timeout=task.timeout
                )
                success = task.evaluate(output)
            except TimeoutError:
                success = False
            finally:
                task.teardown()
            results.append({"task_id": task.task_id, "success": success})

        return {
            "total": len(results),
            "resolved": sum(1 for r in results if r["success"]),
            "resolved_rate": sum(1 for r in results if r["success"]) / len(results)
        }

关键设计决策:

  • 隔离性:每个任务独立环境,避免状态泄漏
  • 可复现性:固定随机种子、模型版本、环境镜像
  • 可观测性:记录每步 token 数、延迟、中间状态
  • 成本追踪:每次评测记录总 token 消耗和 API 费用

评测结果的正确解读

拿到分数后,避免这些认知陷阱:

分数高 ≠ 生产可用。Benchmark 任务是封闭集,生产环境是开放集。SWE-bench 60% 的 Agent 不代表能修好你仓库 60% 的 bug。

该关注的指标矩阵:

指标含义决策价值
Resolved Rate成功率基础能力门槛
Cost per Resolve每次成功的花费ROI 计算
P95 Latency尾部延迟用户体验底线
Retry Rate需要重试的比例稳定性信号
Partial Success部分通过率调优方向指引

落地 Checklist

  1. 明确评测目标:是选型对比、版本回归检测、还是 prompt 调优?目标不同,子集和指标选择不同
  2. 锁定环境:Docker 镜像 / VM snapshot 版本化管理,确保可复现
  3. 分层评测:先跑小子集快速迭代,稳定后再跑全集
  4. 成本预算:SWE-bench Full 一轮约 $50-200(取决于模型),提前规划
  5. 自动化 CI:将评测集成到 CI/CD,每次 Agent 代码变更自动触发回归测试
  6. 领域扩展:公开 Benchmark 之外,构建 20-50 个领域特定 case 作为”金标准集”
  7. 结果归档:每次评测结果入库,支持历史趋势分析和 A/B 对比