【免费下载链接】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.
导读
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.mjs中commandSmoke的try/finally保证即使断言失败也会server.stop()); - JSON 报告与截图统一写入被 Git 忽略的
evals/browser/results/目录,不会污染仓库; BSK_AUTO_UPDATE=off用于关闭 bsk 的自动更新探测,保证测试针对本地刚编译的二进制;- CLI 兼容 pnpm 的前导
--写法,即pnpm run eval:browser -- coverage与pnpm eval:browser coverage等价。
注意:
smoke使用--bsk指向刚编译的本地二进制;若未指定则回退为bsk(环境变量中的命令)。--timeout默认 60000ms(见 cli.mjs 中commandSmoke的timeoutMs参数)。
三、Suite 体系与筛选:为什么默认只跑 core
3.1 五个 suite 的定位
| Suite | 用途 | 默认执行 |
|---|---|---|
core | 日常 smoke 与 CI 使用的小而稳定的验收集 | 是 |
matrix | seed 驱动的 DOM、时序、布局组合变体 | 显式选择 |
regression | 从用户 badcase 缩减、与 issue/修复关联的回归用例 | 显式选择 |
stress | 更高次数或更慢的边界测试 | 显式选择 |
manual | 必须依赖真人或真实用户标签页的能力 | 显式选择 |
smoke与run-agent默认只选core(在 cli.mjs 的selectCases中通过defaultSuite: "core"实现),因此往stress或regression里新增 case 绝不会悄悄拖慢现有 CI;而list、coverage、validate默认检查整个语料库。
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.mjs或cases/**/*.fixture.mjs都会被注册为页面 fixture; - case 排序规则:先按 suite 字典序,再按可选的数字
order,最后按 id 字典序(见loadCaseManifests尾部的排序比较器); validate会拒绝:重复 case id、重复路由、缺失 fixture 路由、未知 operation/action、无效 workflow 变量、以及没有证据生产者却声明 adapter 断言的 manifest。
manifest 的顶层键集合由TOP_LEVEL_KEYS硬编码约束($schema、schemaVersion、id、title、order、suite、tags、seed、source、fixture、prompts、coverage、assertions、smoke),出现未知键会直接报错——这保证了语料库的 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:必须同时提供en与zh-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.mjs的renderPrompt)。
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)覆盖:
- 导航/历史:
navigate、back、forward、reload; - 等待:
wait(需duration字符串)、wait-site-event(需type,可带where与timeoutMs); - 检查:
observe、snapshot、html、screenshot、console、network; - 交互:
click、hover、fill(需selector与value)、select(需selector与非空values数组)、press(需key); - 标签页:
tab-list、tab-create、tab-select、tab-close(后两者需tabId)、borrow、return; - 视口/模拟:
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步骤必须提供selector或ref之一,否则校验失败。
六、真实 case 解剖:form-controls 与 generated-form
6.1 core 示例:form-controls
evals/browser/cases/core/form-controls.case.json 覆盖 7 项操作:session.start、session.stop、page.navigate、interact.fill、interact.select、interact.press、inspect.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→ 两次fill→select→ 带artifactName与evidence的screenshot→press(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-OK与SEED-标记),但会确定性变化:label 关联方式、DOM 嵌套深度、hydration 延迟、干扰控件(decoy controls)、字段顺序与 element id。该 case 通过wait-site-event(matrix.ready,超时 5000ms)等待表单完成 hydration 后再交互,是测试“动态 DOM + 延迟 hydration”场景的典型写法。
七、新增一个普通 case 的完整流程
- 写 fixture:新增一个导出
{ id, routes, render(context) }的*.fixture.mjs,可放在共享的fixtures/pages/,也可与自包含的 regression case 放在一起; - 写 manifest:新增
*.case.json,包含中英文 prompt、coverage、三类断言与 smoke steps; - 事件按 run 隔离:页面内上报事件必须使用共享的
browserEval.send(...)客户端辅助函数(事件会带上当前 runId,避免并发 run 互相污染); - 本地校验:运行
pnpm eval:browser validate与pnpm eval:browser:test; - 真实链路验证:用
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-42,normalizeSeed会将其规范化为可重放的种子值); - 逗号分隔或重复的 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 可定义字段:command、args(数组直接传给可执行程序,不经过 shell,杜绝注入)、cwd、env、timeoutMs、variant、自由格式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 10run-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/*.jsonsummarizeReports(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 verified、0 execution failure/error;
- 结束后
bsk session list --json必须为[](即没有任何 session 泄漏); - 不得为了凑通过而削弱 oracle 或替换稳定 marker;若产品行为确实改变,case 与预期基线必须在同一个受审查的改动中更新。
12.3 manual lane:哪些操作不参与默认测试
直接 smoke 自动覆盖 28 项操作中的25 项。tabs.borrow、tabs.return、assist.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.
相关推荐
BrowserSkill 浏览器评测用例库:Case 清单结构、fixture 发现机制与验收流程详解
BrowserSkill 浏览器评测用例库:Case 清单结构、fixture 发现机制与验收流程详解 导读 本文围绕 BrowserSkill 仓库中 eva
BrowserSkill 种子化矩阵用例(Seeded Matrix Cases):用确定性 DOM 变体做浏览器自动化回归测试
BrowserSkill 种子化矩阵用例(Seeded Matrix Cases):用确定性 DOM 变体做浏览器自动化回归测试 导读 BrowserSkill
BrowserSkill 的 browser-skill 技能指南:用 bsk CLI 驱动真实登录态浏览器完成自动化任务
BrowserSkill 的 browser skill 技能指南:用 bsk CLI 驱动真实登录态浏览器完成自动化任务 BrowserSkill 通过 bs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考