通过自动研究循环实现自我改进的浏览器自动化。迭代运行浏览任务、读取跟踪记录,并改进导航技能(strategy.md),直到其稳定通过。支持使用子代理跨多个任务并行运行。当您想要为特定网站任务构建或改进浏览器自动化技能时使用。
AutoBrowse — 自我改进的浏览器技能
通过迭代实验构建可靠的浏览器自动化技能。内部代理浏览网站(evaluate.ts)。您——外部代理——读取发生的情况并改进指令(strategy.md)。重复直到其持续通过。
入口点
调用方式灵活——显式标志和自由形式的自然语言均可:
/autobrowse --task google-flights
/autobrowse --task google-flights --iterations 10 --env remote
/autobrowse --task google-flights --browser-trace
/autobrowse --tasks google-flights,amazon-add-to-cart
/autobrowse --all
# 也可以——自由解析:
/autobrowse https://flights.google.com/
/autobrowse book a flight on delta.com
/autobrowse fix the existing google-flights skill
--browser-trace(默认关闭,仅远程):将每次迭代与相邻的 browser-trace 技能配对——将内部代理包装在 CDP 捕获中,以获取每页的网络/控制台/页面生命周期证据。隐含 --env remote;如果与 --env local 组合则报错。需要相邻的 browser-trace 技能位于 ${CLAUDE_SKILL_DIR}/../browser-trace/,以及 BROWSERBASE_API_KEY 环境变量。
当用户提供 URL 或自由形式的指令而不是 --task <name> 时:
- 如果
${WORKSPACE}/tasks/中已有任务明显匹配站点/意图,则使用它。 - 否则,选择一个简短的 kebab-case 名称,从
${CLAUDE_SKILL_DIR}/references/example-task.md创建${WORKSPACE}/tasks/<name>/task.md,根据用户所说的填写 URL/目标,然后继续。用一行告知用户所选名称。
如何运行
第 1 步 — 解析参数并定位
检查传递的内容:
--task <name>→ 单任务模式--tasks a,b,c或--all→ 多任务模式(生成子代理)--iterations N→ 评估 → 改进循环的次数(默认:5)--env local|remote→ 浏览器环境(默认:local;对受机器人保护的站点使用 remote)--browser-trace→ 选择加入 browser-trace 集成(默认关闭)。隐含--env remote。如果同时显式传递--env local --browser-trace,则报错:browser-trace requires Browserbase; drop --env local or drop --browser-trace.
如果用户传递了自由形式的文本,则在继续之前将其映射到上述之一。
第 2 步 — 设置工作区
所有训练工件(任务定义、策略迭代、跟踪、报告)都位于当前工作目录中的工作区目录中——而不是在 ~/.claude/skills/ 内。这使内部代理的文件写入远离 Claude 的主目录和权限摩擦。
默认工作区:${CWD}/autobrowse/
mkdir -p ./autobrowse/tasks ./autobrowse/traces ./autobrowse/reports
如果任务目录(./autobrowse/tasks/<task>/task.md)尚不存在,则搭建它:
mkdir -p ./autobrowse/tasks/<task>
cp ${CLAUDE_SKILL_DIR}/references/example-task.md ./autobrowse/tasks/<task>/task.md
# 然后编辑 task.md 以描述 URL、输入、步骤和预期的 JSON 输出
位于 ${CLAUDE_SKILL_DIR} 的技能源保持只读——训练期间只写入 CWD 中的 ./autobrowse/。毕业(最后一步)将单个文件写入 ~/.claude/skills/<task>/SKILL.md。
列出可用任务:
ls ./autobrowse/tasks/
第 3 步 — 多任务:生成并行子代理
如果运行多个任务,使用 Agent 工具为每个任务同时生成一个子代理。每个子代理接收一个自包含的提示,为其任务运行完整的 autobrowse 循环:
"您正在为任务
<name>运行 autobrowse 技能。工作区:<absolute-path-to-workspace>(例如/path/to/project/autobrowse)。运行<N>次迭代:评估 → 读取跟踪 → 改进 strategy.md → 重复。使用--env <env>。将--workspace <workspace>传递给每次 evaluate.mjs 调用。如果父调用使用了--browser-trace,则每次迭代必须使用 SKILL.md 循环的跟踪路径块(预先创建会话、附加 bb-capture、将--connect-url传递给 evaluate.mjs、停止+二分、释放)——不要回退到默认的单命令路径。完全遵循 autobrowse 循环指令。毕业时,将技能安装到
~/.claude/skills/<task-name>/SKILL.md,并带有正确的 agentskills frontmatter(name + description)。不要只复制 strategy.md——编写一个自包含的技能。最后,输出一个结构化摘要,包括:任务名称、最终运行的通过/失败、总累计成本、完成的迭代次数、每次迭代表(迭代号、轮次、成本、状态、测试的假设),以及 2-3 条关键学习要点。"
并行生成所有子代理,等待所有完成,然后收集它们的摘要并编写会话报告。
对于单个任务,跳过此步骤并直接运行下面的循环。
循环(为每个任务运行此循环)
迭代开始
检查 ./autobrowse/tasks/<task>/task.md 是否存在(如果不存在,则从模板搭建——参见第 2 步)。strategy.md 由框架在首次运行时自动创建为空。
要求
ANTHROPIC_API_KEY必须在环境中(或在 CWD 中的.env文件中——evaluate.mjs自动加载它)。如果缺失,框架会打印清晰的错误并退出;不要在其他路径中寻找密钥。
运行内部代理
默认路径(无 --browser-trace) — 单命令,无编排:
node ${CLAUDE_SKILL_DIR}/scripts/evaluate.mjs --task <task-name> --workspace ./autobrowse
# 或对于受机器人保护的站点:
node ${CLAUDE_SKILL_DIR}/scripts/evaluate.mjs --task <task-name> --workspace ./autobrowse --env remote
这将运行浏览器会话并将完整跟踪写入 ./autobrowse/traces/<task>/latest/。
跟踪路径(--browser-trace,仅远程) — 外部框架预先创建 Browserbase 会话,附加 bb-capture 作为被动观察者,并将会话的 connectUrl 传递给 evaluate.mjs,以便每次内部 browse 调用使用 --cdp $connectUrl --session autobrowse-main(规范的 browser-trace 模式,为观察者提供完整的 Network/Console 事件)。每次迭代运行此块一次,$N 设置为从 1 开始的迭代号:
# 预检——如果 browser-trace 未与 autobrowse 一起安装,则快速失败。
BT_DIR="${CLAUDE_SKILL_DIR}/../browser-trace"
if [ ! -f "$BT_DIR/scripts/bb-capture.mjs" ]; then
echo "ERROR: --browser-trace requires the browser-trace skill at $BT_DIR." >&2
echo "Install it by cloning github.com/browserbase/skills and copying skills/browser-trace/" >&2
echo "into the same parent directory as autobrowse (e.g. ~/.claude/skills/browser-trace/)." >&2
exit 1
fi
# a. 会话设置——预先创建保持活动的会话并派生其 connectUrl
sid=$(browse cloud sessions create --keep-alive --verified --proxies \
| node -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>process.stdout.write(JSON.parse(s).id))")
connect_url=$(browse cloud sessions get "$sid" \
| node -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>process.stdout.write(JSON.parse(s).connectUrl))")
RUN_ID="run-$(printf '%03d' "$N")"
TRACE_ROOT="./autobrowse/traces/<task-name>/$RUN_ID"
mkdir -p "$TRACE_ROOT"
export O11Y_ROOT="$TRACE_ROOT/.o11y" # 将 browser-trace 输出放在 autobrowse 运行目录内
export O11Y_RUN_ID="$RUN_ID" # 告诉 browse CLI 将 descriptors.ndjson 写入哪个运行目录
# b. 附加 BROWSER-TRACE——被动观察者;在后台运行
node ${CLAUDE_SKILL_DIR}/../browser-trace/scripts/bb-capture.mjs "$sid" "$RUN_ID" &
sleep 2
# c. 运行 AUTOBROWSE——connectUrl 标志告诉 evaluate.mjs 将 --cdp/--session
# 注入到每次内部 browse 调用中。内部代理永远不会看到 --remote。
node ${CLAUDE_SKILL_DIR}/scripts/evaluate.mjs \
--task <task-name> --workspace ./autobrowse --env remote \
--connect-url "$connect_url" --run-number "$N"
# d. 停止 + 二分 + 统一——顺序很重要;二分需要会话仍然
# 存在,unify-trace 将二分输出与 autobrowse 的 trace.json 连接
# 成单个按时间排序的 NDJSON,外部代理每次迭代首先读取。
node ${CLAUDE_SKILL_DIR}/../browser-trace/scripts/stop-capture.mjs "$RUN_ID"
node ${CLAUDE_SKILL_DIR}/../browser-trace/scripts/bisect-cdp.mjs "$RUN_ID"
node ${CLAUDE_SKILL_DIR}/scripts/unify-trace.mjs \
--trace-dir "$TRACE_ROOT" \
--o11y-dir "$O11Y_ROOT/$RUN_ID"
# e. 释放
browse cloud sessions update "$sid" --status REQUEST_RELEASE
这将内部代理跟踪写入 ./autobrowse/traces/<task-name>/latest/,CDP 二分写入 ./autobrowse/traces/<task-name>/latest/.o11y/<run-id>/。跟踪的 browse CLI 还会向 .o11y/<run-id>/cdp/descriptors.ndjson 发出每个命令的丰富节点描述符(每个页面驱动调用一个 JSON 对象:target tag/id/role/accessibleName/attributes/xpath/bounding-rect)。描述符文件为下游代码生成提供支持;它不是形成假设所必需的——读取跟踪时跳过它。
读取跟踪
cat ./autobrowse/traces/<task-name>/latest/summary.md
摘要包含持续时间、成本、轮次、决策日志和最终 JSON 输出。
如果代理失败或卡住,请深入查看:
- 读取
./autobrowse/traces/<task-name>/latest/trace.json— 搜索失败轮次 - 使用 Read 工具读取失败点周围的截图
当使用 --browser-trace 时——从 unified-events.jsonl 开始。 框架将代理的轮次日志和浏览器的 CDP 事件流连接成一个按时间排序的 NDJSON 流,位于运行根目录。一个文件,带有来源标记(source: "agent" | "browser"),按墙钟时间交错。从上到下浏览;失败原因通常是一两行相邻的行(代理发出命令 X,浏览器响应 Y)。
cat ./autobrowse/traces/<task-name>/latest/unified-events.jsonl
结构化文件(trace.json、.o11y/<run-id>/cdp/*)也可作为代理可消费的深入分析,当统一流指向您需要更多信息的内容时:
| 需要 | 深入分析文件或命令 |
|---|---|
| 每页总计 + 计时(事件、网络计数、按页错误) | .o11y/<run-id>/cdp/summary.json |
| 所有失败的网络请求集中在一处 | .o11y/<run-id>/cdp/network/failed.jsonl |
| 完整的控制台异常负载(堆栈跟踪等) | .o11y/<run-id>/cdp/console/exceptions.jsonl |
| 每页切片(仅页面 N 上的事件) | .o11y/<run-id>/cdp/pages/<pid>/ |
| 特定轮次的完整推理文本 / 未截断的工具输出 | trace.json(按 turn === N 过滤) |
| 临时分组查询(例如顶级主机、按页错误) | O11Y_ROOT=./autobrowse/traces/<task-name>/latest/.o11y node ${CLAUDE_SKILL_DIR}/../browser-trace/scripts/query.mjs <run-id> <cmd> |
统一流是默认;仅当您需要分组查询、全文负载或流无法提供的过滤时才深入结构化文件。
形成一个假设
找到问题发生的确切轮次。哪个单一启发式方法本可以防止它?
在 --browser-trace 下,假设必须引用 unified-events.jsonl 中的特定事件(行号或时间戳)——或者如果您必须深入某个文件,则命名深入分析文件。这使更新基于证据而不是感觉。仅基于代理命令的假设可能会说“点击不起作用”;基于统一流,它可以说“unified-events.jsonl 的第 47 行:browse open 之后是 Network.responseReceived 状态 403 在 /api/checkout 上——切换到 --verified --proxies。”
示例:
- “点击下拉菜单后,等待 1 秒——选项在可点击前会动画显示”
- “直接导航到
/pay-invoice/——完全跳过着陆页” - “使用
browse fill #field_3 value而不是browse type——此字段在聚焦时清除” - “页面在第 8 轮显示旋转器——在快照前添加
browse wait timeout 2000” - (使用
--browser-trace)“在 unified-events.jsonl 的第 47 行,browse open后/api/availability上的 3 个连续Network.responseReceived事件返回 403——站点正在指纹识别;下一次迭代需要--verified --proxies。”
更新 strategy.md
编辑 ./autobrowse/tasks/<task-name>/strategy.md。保留所有有效的内容。修复特定失败。添加具体的启发式方法。
好的策略具有:
- 快速路径:直接 URL 或快捷方式以跳过探索
- 分步工作流:带有计时说明的精确顺序
- 站点特定知识:选择器 ID、表单字段名称、成功指标
- 失败恢复:当 X 出错时该怎么做
判断结果
读取新的摘要。它通过了吗?取得明显进展了吗?
- 通过或进展 → 保留,下一次迭代
- 无进展或回归 → 将 strategy.md 还原到以前的版本并尝试不同的假设
生成可运行脚本(可选)
一旦任务收敛,您可以通过 scripts/codegen.mjs 在一个或多个框架中生成确定性的、可运行的脚本。这是每个框架的一次 LLM 调用,按内容哈希缓存,可选地对新会话进行验证并在失败时重写。
node ${CLAUDE_SKILL_DIR}/scripts/codegen.mjs \
--task <name> \
--workspace ./autobrowse \
--frameworks playwright,stagehand \
--verify
每个框架在 tasks/<name>/<framework>/ 下有自己的子目录,包含生成的脚本和自包含的脚手架(package.json、tsconfig.json)。该目录可独立运行,使用 cd tasks/<name>/playwright && npm install && npx tsx <name>.ts — 唯一的运行时要求是 BROWSERBASE_API_KEY(以及 Stagehand 目标的 ANTHROPIC_API_KEY)。
内置框架:playwright、stagehand。使用 --prompt-template <path> --frameworks custom 添加自定义框架(并提供您自己的运行器或传递 --no-verify)。
常用标志:
| 标志 | 目的 |
|---|---|
--frameworks a,b,... |
逗号分隔;默认 playwright |
--verify / --no-verify |
对新 BB 会话运行生成的脚本;默认 --verify |
--max-retries N |
验证失败时重写的上限;默认 2 |
--cache-only |
如果缓存未命中则报错(CI 友好) |
--force |
破坏缓存 |
--dry-run |
估计提示大小 + 成本;不调用 LLM |
--run <id> |
强制特定 run-NNN(默认:最新通过) |
输出是每个框架在标准输出上的一行 JSON。如果任何选定框架的最终状态为 passed: false,则非零退出。
有关生成的脚本遵循的规范 connectOverCDP 模式,请参阅 references/playwright-cdp-bridge.md。
所有迭代后 — 如果准备好则发布
如果任务在最后 3 次迭代中通过 2 次以上或已达到最大迭代限制,则将其安装为 Claude Code 技能。不要只复制 strategy.md — 技能必须自包含,并且对从未见过此代码库的人有用。如果在最大迭代次数时毕业而没有干净通过,请注明已知失败点,但仍记录所有学到的内容。
通过写入 ~/.claude/skills/<task-name>/SKILL.md 安装:
mkdir -p ~/.claude/skills/<task-name>
对 SKILL.md 使用此结构:
---
name: <task-name>
description: <1-2 句话描述此技能的作用和何时使用。包括触发关键词。>
---
# <任务标题> — 浏览器技能
## 目的
<1-2 句话:这自动化了什么以及为什么存在。>
## 何时使用
<何时应该使用此技能。>
## Browse CLI 参考
内部代理使用 `browse` CLI。此任务的关键命令:
- `browse stop` — 终止现有会话(切换到远程前始终运行)
- `browse open <url> --remote` — 启动新的 Browserbase 云会话并导航
- `browse open <url> --local` — 启动干净的本地浏览器并导航
- `browse tab new <url>` — 在新标签页中打开 URL
- `browse wait load` — 等待页面完成加载
- `browse wait timeout <ms>` — 等待固定时间以处理旋转器或动画
- `browse wait selector "<selector>"` — 等待元素变为可见
- `browse get title` — 验证您在正确的页面上
- `browse get text body` — 提取所有可见文本(内容提取首选)
- `browse snapshot` — 获取可访问性树;每个节点都有一个 `[X-Y]` 格式的引用(例如 `[0-5]`、`[2-147]`)
- `browse click [X-Y]` — 按最新快照中的引用点击元素(包括方括号)
**切勿在 SKILL.md 中使用 `--session <name>` 标志。** 命名会话是并行运行的变通方法——它们用基础设施问题污染技能。技能必须使用默认会话独立工作。
## 工作流
### 第 1 步 — 启动会话
<按顺序的精确 browse 命令>
### 第 2 步 — 导航
<精确 URL 和验证步骤>
### 第 3 步 — 提取
<精确提取命令>
### 第 4 步 — 输出
<要发出的 JSON,引用下面的模式>
## 站点特定注意事项
<来自迭代的每个来之不易的启发式方法的项目符号列表。这是技能的核心价值。>
## 失败恢复
<当导航失败、会话被污染或提取返回垃圾时该怎么做>
## 预期输出
```json
<paste the exact expected output schema from task.md>
写入 SKILL.md 后,确认其已安装:
```bash
ls ~/.claude/skills/<task-name>/SKILL.md
该技能现在在 Claude Code 中作为 /<task-name> 可用。
最终报告(多任务模式)
所有子代理完成后,打印一个 markdown 表格:
| 任务 | 迭代次数 | 最终状态 | 已毕业 | 成本 |
|---|---|---|---|---|
| google-flights | 5 | ✅ pass | yes | $0.42 |
| amazon-add-to-cart | 5 | ❌ fail | no | $1.20 |
然后将持久会话报告写入 ./autobrowse/reports/,以便在工作区内有运行的持久记录:
mkdir -p ./autobrowse/reports
写入文件 ./autobrowse/reports/YYYY-MM-DD-HH-MM-<tasks>.md,包含:
# AutoBrowse 会话报告
**日期:** <ISO 日期>
**任务:** <逗号分隔列表>
**环境:** remote|local
**总成本:** $X.XX
## 结果
| 任务 | 迭代次数 | 通过率 | 最终状态 | 已毕业 | 成本 |
|------|-----------|-----------|--------------|-----------|------|
| ... | ... | X/5 | ✅/❌ | yes/no | $X.XX |
## 每个任务的学习
### <task-name>
- **关键见解 1:** <代理学到了什么>
- **关键见解 2:** <另一个启发式方法>
- **修复的失败模式:** <什么失败以及如何解决>
## 迭代日志
### <task-name>
| 迭代 | 轮次 | 成本 | 状态 | 测试的假设 |
|------|-------|------|--------|-------------------|
| 1 | 79 | $18.75 | ❌ fail | baseline |
| 2 | 9 | $0.26 | ✅ pass | session contamination fix |
| ... | ... | ... | ... | ... |
规则
- 只编辑
strategy.md— 永远不要碰task.md(除非从模板创建它)或evaluate.mjs - 留在工作区内 — 所有训练写入都到
./autobrowse/,永远不要到~/.claude/skills/autobrowse/。技能源是只读的。 - 每次迭代一个假设 — 一次测试一个更改
- 建立在胜利之上 — 保留有效的内容,添加更多
- 信任跟踪 — 内部代理准确显示它看到和做了什么
- 毕业到
~/.claude/skills/— 您在那里写入的唯一文件是最终毕业的SKILL.md - 在二分之前不要释放 — 在
--browser-trace下,每次迭代结束时的顺序不可协商:stop-capture→bisect-cdp→browse cloud sessions update REQUEST_RELEASE。二分依赖于跟踪停止时会话仍然存在。






