BrowserGym 与任务型 Agent 基准测试
- Published on
BrowserGym 与任务型 Agent 基准测试
聊天模型的评测很容易:给它一个问题,看答案对不对。浏览器 Agent 就复杂多了。它可能需要打开网页、查找信息、填写表单、切换页面和提交结果。最后页面看起来完成了,不代表中间没有越权;最后一句话说得很漂亮,也不代表订单真的被修改。
我第一次测试浏览器 Agent 时,最初只记录最终文本。结果非常不可靠:有一次 Agent 说“已经完成”,实际上还停在确认页;另一次最终状态碰巧正确,但它中间点开了不该访问的管理页面。只看答案,会把真正重要的动作全部遮住。
任务型 Agent 的基准测试,应该像驾驶考试:既看是否到达目的地,也看路线、操作和遇到突发情况时是否安全。BrowserGym 这类环境的价值,不只是提供网页,而是让任务、状态、动作和结果都可以被记录和复现。
一、先定义任务的成功状态
一个任务不应该只写“帮我处理订单”,而要描述起始状态和目标状态:
type BrowserTask = {
taskId: string
instruction: string
initialState: string
goalState: string
allowedDomains: string[]
forbiddenActions: string[]
riskLevel: 'low' | 'medium' | 'high'
}
例如“把订单 A1001 的地址改为上海”需要明确:订单存在、用户有权限、页面初始在哪,最后要检查数据库或页面状态中的地址确实改变。仅仅点击了“保存”按钮,不足以说明任务成功。
成功条件最好由程序检查:URL、DOM 字段、数据库状态、文件内容或任务记录。让另一个模型判断“看起来完成了”,只能作为补充。
二、浏览器环境要可复现
基准环境应该固定浏览器版本、窗口大小、网络、登录账号、数据状态和第三方服务响应。否则同一 Agent 每次遇到的页面都不一样,失败无法比较。
type BrowserEnv = {
browserVersion: string
viewport: { width: number; height: number }
locale: string
seedDataVersion: string
networkMode: 'offline' | 'recorded' | 'live'
snapshotId: string
}
可控的录制网络适合回归测试,真实网络适合观察复杂情况,但两者结果不能混在一张榜单里。登录态和测试账号也要隔离,不要把生产数据带进基准环境。
三、记录完整轨迹
每一步至少保存观察、动作、结果和时间:
type AgentStep = {
stepIndex: number
observation: ScreenState
action?: ScreenAction
result?: 'success' | 'failed' | 'blocked'
error?: string
timestamp: string
}
type AgentTrajectory = {
taskId: string
steps: AgentStep[]
finalState: string
taskSuccess: boolean
totalCost: number
totalLatencyMs: number
}
轨迹让你可以定位失败发生在哪一步:视觉理解错了、元素定位错了、工具参数错了、页面没有加载,还是 Agent 没有确认上一步结果。没有轨迹,任务失败只是一句“没完成”,无法推动改进。
四、指标至少分五类
1. 任务结果
任务成功率、部分成功率和失败类型是最直接的指标。对于多步骤任务,可以记录完成了多少必要步骤,但不能用“完成 8/10 步”掩盖关键最后一步失败。
2. 动作质量
记录工具调用是否合法、参数是否正确、是否重复点击、是否访问了禁止域名。动作正确但最终失败,和动作越权后最终碰巧成功,风险完全不同。
3. 效率
包括步骤数、Token、模型调用次数、页面等待时间、总延迟和成本。步骤越少不一定越好,盲目减少观察可能会增加错误;真正要看的是单位成功任务成本。
4. 恢复能力
网络短暂失败、元素变化、工具超时后,Agent 是否能安全恢复,而不是重新执行已经完成的副作用。
5. 安全性
越权访问、未经确认的高风险操作、敏感数据外传和错误状态下的继续行动都应该有单独的指标。安全违规不能被总体成功率平均掉。
五、轨迹评测和最终评测要分开
一个 Agent 可能最终结果正确,但中间走了危险路线;也可能轨迹都很合理,却因为网站临时错误没有完成。两类结果分别记录:
轨迹安全且任务成功 → 理想成功
轨迹安全但任务失败 → 环境或能力问题
轨迹越权但任务成功 → 安全失败,不能计为成功
轨迹混乱但结果碰巧正确 → 需要人工复核
这也是为什么不能只用最终网页截图评测。状态变化和动作路径本身就是结果的一部分。
六、基准任务要覆盖边界
任务集应该包含正常和困难样本:
- 页面加载慢或部分失败;
- 同名按钮和相似链接;
- 表单字段缺失或格式错误;
- 用户权限不足;
- 弹窗、分页和多标签页;
- 需要多跳搜索的信息;
- 用户中途修改目标;
- 涉及删除、付款和发送的高风险动作。
如果所有任务都是干净页面和明确按钮,Agent 得分会很好看,但上线后遇到真实页面变化就容易失控。基准要模拟现实中的摩擦,而不是为模型准备一条铺好的红毯。
七、不要让 Agent 记住答案
任务型基准也会被过拟合。固定网页、固定账号和固定任务文本可能让模型记住路径。可以做模板变体、数据随机化、不同布局、不同措辞和未公开测试集。
训练任务:把发票下载到指定目录
测试变体:换用户、换文件名、换页面布局、换下载格式
测试数据不能被 Prompt 优化流程无限读取。保留一部分隐藏测试集,并定期新增真实失败样本,才能知道 Agent 学到的是通用策略,还是背下了路径。
八、工具执行要有沙箱
浏览器 Agent 的环境应该限制网络、文件系统、剪贴板和账号权限。浏览器测试本身也可能访问外部网站、提交表单或下载文件,不能因为“只是评测”就完全开放。
type SandboxPolicy = {
allowedDomains: string[]
writableDirectories: string[]
allowDownloads: boolean
allowExternalMessages: boolean
requireConfirmationFor: string[]
}
每次动作在执行前都要通过策略检查。Agent 可以看到“删除账户”按钮,不代表测试应该允许它真正点击;高风险动作可以使用模拟服务或拦截器,验证 Agent 是否提出确认,而不是让它产生真实副作用。
九、失败回放比排行榜更有用
评测结束后,先看失败轨迹聚类:
视觉定位错误:28%
页面等待不足:19%
工具参数错误:16%
权限策略阻断:12%
任务规划错误:15%
环境异常:10%
每类失败有不同的修复方向。视觉问题需要更好的观察或定位,等待问题需要状态检测,参数问题需要 Schema 和校验,规划问题需要任务拆解。一个总分无法告诉你应该改哪里,失败类别才是下一轮开发的地图。
十、BrowserGym 类基准如何服务真实产品
公开基准适合比较方法和发现研究问题,但不要直接把公开分数当成生产承诺。自己的业务基准要加入真实数据分布、权限模型、失败策略、成本和 SLO,并用离线回放和小流量线上测试互相验证。
type BenchmarkReport = {
environment: BrowserEnv
agentVersion: string
successRate: number
safetyViolationRate: number
recoveryRate: number
medianSteps: number
p95LatencyMs: number
costPerSuccess: number
failureClusters: Record<string, number>
}
报告里要写清楚环境和限制。不同基准、不同网页和不同工具权限下的分数,不能直接横向比较。
总结:Agent 的路迹也是答案
我现在评测浏览器 Agent,不会只问“最后页面对了吗”,而会看它怎么走到那里:有没有读对状态,是否调用了正确工具,权限有没有越界,遇到失败能不能停下,最终结果是否真的持久化。
BrowserGym 这类环境的重要价值,是把原本模糊的“Agent 感觉不错”变成可复现的任务、状态和轨迹。成功率告诉我们它能不能完成,动作指标告诉我们它是否可靠,安全指标告诉我们能不能托付,成本和延迟则告诉我们是否值得长期运行。
一个会刷公开任务的 Agent,不一定能处理真实用户的问题;一个偶尔失败但能诚实停下、保留轨迹并请求人工的 Agent,反而更接近可上线系统。基准测试不是给模型颁奖,而是给团队一面镜子:它在哪些条件下有效,在哪些边界上危险,下一步最值得修什么。