BrowserSkill 浏览器能力评测语料库(evals/browser)完整指南:从用例清单到确定性自动化验证
2026/9/20 13:49:14 网站建设 项目流程

【免费下载链接】BrowserSkill

Let AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.

项目地址:https://gitcode.com/GitHub_Trending/br/BrowserSkill
点击查看免费下载

导读

evals/browser/README.md 定义了 BrowserSkill 仓库内一套本地、确定性、与 Agent 无关的浏览器能力评测语料库:它用数据驱动的 case manifest、fixture 页面与断言文件描述“Agent 应该完成什么页面任务”,从而让同一个用例既能跑在 BrowserSkill 的bsk命令行直连流程上,也能跑在 DSH 或其他任意命令行 Agent 上。读完本文,你将掌握:语料库的目录与自动发现模型、case manifest 与三类断言(site / response / adapter)的完整写法、core/matrix/regression等 suite 的筛选与执行方式、如何用 seed 复现矩阵变体、如何把用户 badcase 固化成回归用例,以及一套可直接当作 CI 与提交门禁的开发基准线。


一、定位:这不是一个“测试框架”,而是一套 Agent 能力验收语料库

先明确它在整个仓库中的位置。evals/browser/目录自成一个 Node.js CLI(入口为 evals/browser/cli.mjs),与仓库其他部分解耦:被测对象是真实构建出的bsk二进制(crates/bsk-cli),以及浏览器扩展(apps/extension)与 DSH 插件(packages/dsh-plugin-browserskill),而评测本身只提供本地页面服务、prompt 渲染、断言(oracle)与报告汇总

语料库的设计目标(原文六大原则)决定了它的全部实现细节:

  • Agent-neutral(与 Agent 无关):prompt 只描述可观察的页面目标,同一组 case 可被不同 Agent 与 adapter 复用;
  • Deterministic(本地且确定):页面只依赖本地服务,使用稳定 marker 与按 run 隔离的事件;
  • Extensible(可扩展):manifest、fixture、workflow 全部从目录自动发现,新增 case 不需要修改任何中央 switch
  • Reproducible(可复现):生成式页面的所有 DOM 变体都由 seed 派生,报告会保留 seed;
  • Honest verification(如实验证):页面事件、回答文本、adapter 外部证据三路分别统计,拿不到的证据标为unverified绝不冒充通过
  • Privacy-safe(隐私安全):用户 badcase 必须先缩减为合成 DOM 与匿名数据才能提交入库。

当前语料包含6 个稳定的corecase 和 1 个 seed 驱动的matrixcase;操作清单(operation inventory)共28 项,但 28 是“能力覆盖面”而非 case 数量——同一种操作可以由多个 case 在不同页面结构、时序和浏览器状态下重复覆盖。


二、快速开始:先校验,再跑真实浏览器链路

2.1 不启动浏览器的校验(5 秒上手)

pnpm eval:browser validate # 校验全部 case manifest 与 fixture 的一致性 pnpm eval:browser list # 列出当前语料库中的 case pnpm eval:browser coverage # 输出 28 项浏览器操作的能力覆盖矩阵 pnpm eval:browser:test # 运行语料库自身的单元/集成测试

这四个命令不依赖浏览器、daemon 或扩展,适合在任何机器上作为快速健康检查。其中validate除了检查 manifest 合法性,还会做跨文件的一致性校验:重复 case id、重复路由、缺失 fixture 路由、未知操作/action、无效 workflow 变量、以及没有任何步骤产出却声明了 adapter 断言都会在此阶段被拒绝(详见下文)。

2.2 真实链路 smoke:CLI + daemon + 扩展 + 小窗 + 页面

# 先用仓库当前代码编译 bsk(产物在 ./target/debug/bsk) cargo build -p bsk # 跑 core 套件(日常冒烟/CI 默认套件) BSK_AUTO_UPDATE=off pnpm eval:browser smoke --suite core --bsk ./target/debug/bsk # 跑 matrix 套件,指定 3 个 seed(确定性 DOM 变体) BSK_AUTO_UPDATE=off pnpm eval:browser smoke --suite matrix --seed 4,7,14 --bsk ./target/debug/bsk

关键行为约定:

  • 每个 smoke case 都会新开一个浏览器 session,并在finally清理路径中关闭(cli.mjscommandSmoketry/finally保证即使断言失败也会server.stop());
  • JSON 报告与截图统一写入被 Git 忽略的evals/browser/results/目录,不会污染仓库;
  • BSK_AUTO_UPDATE=off用于关闭 bsk 的自动更新探测,保证测试针对本地刚编译的二进制;
  • CLI 兼容 pnpm 的前导--写法,即pnpm run eval:browser -- coveragepnpm eval:browser coverage等价。

注意:smoke使用--bsk指向刚编译的本地二进制;若未指定则回退为bsk(环境变量中的命令)。--timeout默认 60000ms(见 cli.mjs 中commandSmoketimeoutMs参数)。


三、Suite 体系与筛选:为什么默认只跑 core

3.1 五个 suite 的定位

Suite用途默认执行
core日常 smoke 与 CI 使用的小而稳定的验收集
matrixseed 驱动的 DOM、时序、布局组合变体显式选择
regression从用户 badcase 缩减、与 issue/修复关联的回归用例显式选择
stress更高次数或更慢的边界测试显式选择
manual必须依赖真人或真实用户标签页的能力显式选择

smokerun-agent默认只选core(在 cli.mjs 的selectCases中通过defaultSuite: "core"实现),因此往stressregression里新增 case 绝不会悄悄拖慢现有 CI;而listcoveragevalidate默认检查整个语料库。

3.2 多维筛选示例

pnpm eval:browser list --suite core # 只看 core 套件 pnpm eval:browser list --tag form # 只看带 form 标签的 case pnpm eval:browser smoke --case form-controls # 跑单个 case pnpm eval:browser smoke --case form-controls,generated-form # 跑多个 case pnpm eval:browser smoke --case all # 显式包含所有 suite

筛选规则(源码层面见selectCases):

  • --case/--suite/--tag三个维度**叠加(AND)**筛选;
  • 逗号分隔或重复传入的 case id / suite 是**“或”(OR)**关系;
  • 多个--tag必须全部命中(AND);
  • --task仍作为--case向后兼容别名
  • --case all不能与具名 case 混用,--suite all同理。

四、目录结构与自动发现模型

4.1 目录布局

evals/browser/ cases/ core/*.case.json # 6 个稳定的核心验收 case matrix/*.case.json # seed 驱动的 matrix case regression/<case-id>/ # 每个回归 case 一个自包含目录 <case-id>.case.json <case-id>.fixture.mjs README.md fixtures/pages/*.fixture.mjs # 共享页面 fixture schemas/case.schema.json # manifest 的 JSON Schema lib/ # CLI 与发现/校验/断言实现 tests/

4.2 自动发现规则

  • 任何cases/**/*.case.json都会被加载为 case manifest(实现见 lib/discovery.mjs 的递归目录遍历 + lib/case-loader.mjs 的解析);
  • 任何fixtures/**/*.fixture.mjscases/**/*.fixture.mjs都会被注册为页面 fixture;
  • case 排序规则:先按 suite 字典序,再按可选的数字order,最后按 id 字典序(见loadCaseManifests尾部的排序比较器);
  • validate会拒绝:重复 case id、重复路由、缺失 fixture 路由、未知 operation/action、无效 workflow 变量、以及没有证据生产者却声明 adapter 断言的 manifest。

manifest 的顶层键集合由TOP_LEVEL_KEYS硬编码约束($schemaschemaVersionidtitleordersuitetagsseedsourcefixturepromptscoverageassertionssmoke),出现未知键会直接报错——这保证了语料库的 schema 演进是受控的。


五、Case manifest 完全解读(含源码级约束)

一个 case manifest 需要同时描述:Agent 评测所需的信息(中英文 prompt、能力 coverage、三类断言)与 bsk 直连 smoke 的声明式步骤。以下为官方示例,并附上源码校验规则:

{ "$schema": "../../schemas/case.schema.json", "schemaVersion": 1, "id": "example-case", "title": "Example browser behavior", "order": 10, "suite": "core", "tags": ["form", "keyboard"], "seed": 17, "fixture": { "startPath": "/example" }, "prompts": { "en": "Open {url} ...", "zh-CN": "打开 {url}……" }, "coverage": ["page.navigate", "interact.press"], "assertions": { "site": [], "response": [], "adapter": [] }, "smoke": { "steps": [{ "action": "navigate" }] } }

字段级约束(与 lib/case-loader.mjs 的validateCaseManifest一一对应):

  • id:必须为小写 kebab-case(正则^[a-z0-9]+(?:-[a-z0-9]+)*$);
  • schemaVersion:必须等于1
  • order:可选,非负整数,只影响排序;
  • suite/tags:均要求小写 kebab-case,tags不允许重复;
  • fixture.startPath:必须以/开头的绝对 URL 路径;
  • prompts:必须同时提供enzh-CN两个非空字符串;
  • coverage:只接受 lib/operations.mjs 中OPERATION_CATALOG里的 28 个操作名,且不允许重复;
  • seed:可选,必须是安全整数。

5.1 prompt 占位符

prompt 支持四种占位符:{url}{baseUrl}{runId}{seed}。Agent adapter 参数还额外支持{prompt}{caseId}/{taskId}{variant}(渲染实现在lib/tasks.mjsrenderPrompt)。

5.2 三类断言:site / response / adapter

断言来自三个相互独立的信息源,这正体现了“如实验证”原则:

  • site:本地页面通过browserEval.send(...)上报的页面事件,如提交的表单值、一次历史导航。结构为{ label, type, minCount, where? }type必须匹配事件类型,where是事件字段的取值匹配(点路径读取,见 lib/oracle.mjs 的eventMatches),minCount为最小命中次数;
  • response:必须出现在 Agent 或 CLI输出文本中的稳定文字,结构为{ label, includes },判定逻辑是responseText.includes(assertion.includes)
  • adapter:页面 JavaScript 之外的事实,例如非空的截图产物确认的 session 清理,结构为{ label, key }。若结果中没有该 key 对应的证据,状态记为unverified(不会错误地算作通过)。

verifyTask(lib/oracle.mjs)的最终状态聚合规则:存在failed则为failed;无failed但有unverified则为passed-with-unverified;全部通过则为passed

5.3 声明式 smoke workflow

smoke.steps支持的操作(lib/operations.mjs 的WORKFLOW_ACTION_OPERATIONS)覆盖:

  • 导航/历史:navigatebackforwardreload
  • 等待:wait(需duration字符串)、wait-site-event(需type,可带wheretimeoutMs);
  • 检查:observesnapshothtmlscreenshotconsolenetwork
  • 交互:clickhoverfill(需selectorvalue)、select(需selector与非空values数组)、press(需key);
  • 标签页:tab-listtab-createtab-selecttab-close(后两者需tabId)、borrowreturn
  • 视口/模拟:resize(需正整数width/height)、emulate(需device);
  • 人工:request-help(需prompt)。

workflow 的两个进阶能力:

  • saveAs:某个步骤可把 JSON 结果保存为命名变量,后续步骤用{child.tab_id}这类占位符引用;
  • evidence:某步骤可为其结果声明对应的 adapter 断言 key(例如form-controls中截图步骤声明"evidence": "screenshotCreated"),从而让 adapter 断言有了证据生产者,validate才会放行。

click/hover/fill/select步骤必须提供selectorref之一,否则校验失败。


六、真实 case 解剖:form-controls 与 generated-form

6.1 core 示例:form-controls

evals/browser/cases/core/form-controls.case.json 覆盖 7 项操作:session.startsession.stoppage.navigateinteract.fillinteract.selectinteract.pressinspect.screenshot。其 fixture 页面在 evals/browser/fixtures/pages/form.fixture.mjs:

  • /form路由渲染一个含隐藏run字段(值为runId)的表单,并为 Submit 按钮绑定keydown监听:按下 Enter 时通过browserEval.send("form.enter_pressed")上报事件;
  • /result路由解析 GET 参数,调用record("form.submitted", values, { path })上报提交值,并渲染包含Received!marker 的结果页。

对应断言设计:

"assertions": { "site": [ { "label": "Enter was pressed on Submit", "type": "form.enter_pressed", "minCount": 1 }, { "label": "form values were submitted", "type": "form.submitted", "where": { "data.text": "agent-parity", "data.notes": "BrowserSkill works", "data.choice": "two" }, "minCount": 1 }, { "label": "result page was displayed", "type": "page.shown", "where": { "data.path": "/result" }, "minCount": 1 } ], "response": [{ "label": "confirmed result", "includes": "Received!" }], "adapter": [ { "label": "screenshot artifact was created", "key": "screenshotCreated" }, { "label": "browser session was closed", "key": "sessionStopped" } ] }

对应的 smoke 步骤则用声明式语言复现同一任务:navigate→ 两次fillselect→ 带artifactNameevidencescreenshotpress(Enter,聚焦#submit)→wait-site-event(等待/result页面显示)→wait200ms →observe。这组步骤既是 bsk 直连验证,也是 manifest 语法最完整的“活教材”。

6.2 matrix 示例:generated-form

evals/browser/cases/matrix/generated-form.case.json 是 seed 驱动矩阵的代表,seed默认值为20260827。它固定任务与 oracle(填seeded-agent、选Two、Enter 提交、报告MATRIX-OKSEED-标记),但会确定性变化:label 关联方式、DOM 嵌套深度、hydration 延迟、干扰控件(decoy controls)、字段顺序与 element id。该 case 通过wait-site-eventmatrix.ready,超时 5000ms)等待表单完成 hydration 后再交互,是测试“动态 DOM + 延迟 hydration”场景的典型写法。


七、新增一个普通 case 的完整流程

  1. 写 fixture:新增一个导出{ id, routes, render(context) }*.fixture.mjs,可放在共享的fixtures/pages/,也可与自包含的 regression case 放在一起;
  2. 写 manifest:新增*.case.json,包含中英文 prompt、coverage、三类断言与 smoke steps;
  3. 事件按 run 隔离:页面内上报事件必须使用共享的browserEval.send(...)客户端辅助函数(事件会带上当前 runId,避免并发 run 互相污染);
  4. 本地校验:运行pnpm eval:browser validatepnpm eval:browser:test
  5. 真实链路验证:用smoke --case <id>对本地构建产物跑一遍真实浏览器链路。

设计建议(原文明确要求):一个 case 只表达一种行为或故障机制;使用稳定的合成 marker(如Received!MATRIX-OK)而非断言偶然出现的正文文案,能让失败诊断更精准。


八、把用户 badcase 固化为 regression 用例

先用脚手架生成自包含模板:

pnpm eval:browser scaffold reported-timeout \ --title "Navigation settles after a late frame" \ --source "issue-123"

该命令会在cases/regression/reported-timeout/下生成 manifest、fixture 与复现说明(scaffold默认--suite regression,见 cli.mjs 的commandScaffold)。随后把报告缩减到最小的触发机制

  • 保留会触发 bug 的 DOM 结构、时序、跳转、frame 或浏览器状态;
  • 用合成值替换所有姓名、账号、网址、token、截图与页面文案;
  • 绝不提交HAR 文件、cookie、凭据、生产 HTML 或私有素材;
  • 记录 issue/PR 来源、相关 seed、期望结果与后续修复 PR;
  • 条件允许时,证明新 case 在已知坏构建上失败、在修复构建上通过

九、Seed 矩阵:无需浏览器即可检查变体

pnpm eval:browser generate --seed user-badcase-42 # 描述该 seed 生成的维度组合 pnpm eval:browser prompt generated-form --seed user-badcase-42 --run-id manual-42 # 只渲染 prompt pnpm eval:browser smoke --case generated-form --seed user-badcase-42 # 跑单个 seed pnpm eval:browser smoke --case generated-form --seed 4,7,14 # 跑多个 seed

要点:

  • seed 既支持数字也支持字符串(如user-badcase-42normalizeSeed会将其规范化为可重放的种子值);
  • 逗号分隔或重复的 seed 会生成相互独立的结果
  • 报告保留每个规范化 seed,因此任何失败都能精确重放;若它代表一个独立 bug,可进一步提升为命名 regression case。

十、运行任意命令行 Agent 与 28/6 工具对比

10.1 配置 adapter

把 agents.example.json 复制为已被 Git 忽略的agents.local.json,并按需修改。示例配置:

{ "agents": { "dsh-local": { "variant": "granular-28", "command": "dsh", "args": ["--profile", "headless", "{prompt}"], "cwd": "../..", "timeoutMs": 300000, "metadata": { "toolCount": 28 }, "metrics": { "toolCallPattern": "browser[_-][a-z_-]+" } } } }

adapter 可定义字段:commandargs数组直接传给可执行程序,不经过 shell,杜绝注入)、cwdenvtimeoutMsvariant、自由格式metadata,以及可选的metrics.errorPattern/metrics.toolCallPattern正则(用于从输出中统计错误与工具调用次数)。

10.2 运行与对比

pnpm eval:browser run-agent \ --config evals/browser/agents.local.json \ --agent dsh-local \ --suite core \ --repeat 3

对比“28 个细粒度工具 vs 领域工具”时,创建两个隔离的 adapter 条目并同时运行:

pnpm eval:browser run-agent \ --config evals/browser/agents.local.json \ --agent dsh-granular,dsh-domain \ --suite core \ --repeat 10

run-agent的其他选项(见cli.mjs的 usage):--variant覆盖报告标签、--locale en|zh-CN选择 prompt 语言(默认 zh-CN)、--repeat N每 case 重复次数(默认 1)、--timeout MS单 Agent 超时(默认 300000)、--out DIRECTORY报告目录。

实验卫生建议:浏览器任务应串行运行以避免 session 竞争;更大规模实验中使用干净 profile 并轮换 adapter 顺序,降低 warm-cache 偏差。


十一、读取结果:summarize 与健康标准

11.1 汇总命令

pnpm eval:browser summarize evals/browser/results/*.json

summarizeReports(lib/summary.mjs)按adapter + variant分组,输出:运行次数、通过率、完全验证率(fully verified rate)、进程失败数、错误数、平均工具调用数与平均耗时。原始 JSON 报告保留 case、suite、tags、seed、prompt、命令输出、页面事件数与每条 oracle 检查的独立结果。

11.2 一次健康运行的判据

  • 没有执行超时(timedOut)或非零退出码;
  • direct smoke 没有executionError
  • verification.status等于passed(无法暴露外部证据的 Agent adapter 可明确为passed-with-unverified);
  • 每条 session cleanup 断言都被验证;
  • 错误数、工具调用数、耗时相对所选基线没有异常上涨

十二、开发基准线:提交门禁与完整验收

12.1 变更对应的必跑检查

改动范围必跑检查
任意 case、fixture、oracle 或 harness 改动pnpm eval:browser:check
CLI、daemon、扩展、DSH 插件或浏览器操作改动上述检查 +cargo build -p bsk+ 真实浏览器smoke --suite core
DOM 发现、表单交互、时序或等待逻辑改动上述检查后再跑smoke --suite matrix --seed 4,7,14
修复已有明确复现的 bug新增regressioncase,并在修复版本单独运行该 case

12.2 提交本 harness 前的完整验收序列

pnpm eval:browser:check cargo build -p bsk BSK_AUTO_UPDATE=off pnpm eval:browser smoke --case all --bsk ./target/debug/bsk BSK_AUTO_UPDATE=off pnpm eval:browser smoke --suite matrix --seed 4,7,14 --bsk ./target/debug/bsk

硬性标准:

  • 所有命令必须以 0 退出
  • smoke 汇总必须达到100% pass、100% fully verified0 execution failure/error
  • 结束后bsk session list --json必须为[](即没有任何 session 泄漏);
  • 不得为了凑通过而削弱 oracle 或替换稳定 marker;若产品行为确实改变,case 与预期基线必须在同一个受审查的改动中更新。

12.3 manual lane:哪些操作不参与默认测试

直接 smoke 自动覆盖 28 项操作中的25 项tabs.borrowtabs.returnassist.request-help三项保留在 manual lane:前两者需要真实用户标签页与所有权确认,后者需要真人交互,纳入默认套件会使其具有破坏性或不确定性(见 lib/operations.mjs 中这三项的manualNote)。


十三、与仓库其他部分的配合关系

  • 被测二进制:crates/bsk-cli 通过cargo build -p bsk产出./target/debug/bsk,其 28 项操作(session、navigate、inspect、interact、tabs、assist 等)与 lib/operations.mjs 的操作清单一一对应;
  • 被测扩展链路:apps/extension 提供真实浏览器内的 Agent Window 与录制能力,是 smoke/run-agent 的端到端承载;
  • Agent 接入方:packages/dsh-plugin-browserskill 作为 DSH 的命令行 Agent 适配层,可直接通过run-agent的 adapter 配置接入同一语料库;
  • 既有 regression 样例:evals/browser/cases/regression/oopif-scrollbars 与 evals/browser/cases/regression/snapshot-coordinates 展示了自包含回归 case(manifest + fixture + README)的标准形态,新增 regression 时可直接参考。

这套语料库的价值在于:它把“Agent 在真实浏览器里表现如何”变成了数据驱动、可复现、可门禁的工程问题——新增 case 无需改中央逻辑,失败可精确重放,证据三路独立、不虚报通过,从而成为 BrowserSkill 从 CLI 到扩展、从普通 Agent 到 DSH 插件持续演进的可靠性护栏。

【免费下载链接】BrowserSkill

Let AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.

项目地址:https://gitcode.com/GitHub_Trending/br/BrowserSkill
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询