数据截至 (上游 commit 544ec87f2ede)
Stagehand — 架构与原理
30 秒导读: Stagehand 是「用自然语言 + 代码一起写」的浏览器自动化框架,对外四个动词——
act/observe/extract/agent。v4 做了一次大胆的外科手术:引擎不再是一个 npm 库,而是一整个 Chrome 扩展——packages/extension/里装着 understudy CDP 引擎和全部 AI 编排,service worker 里跑 JSON-RPC 服务器;packages/sdk-ts、sdk-go、sdk-python退成讲stagehand.v4协议的瘦客户端。灵魂设计没变:不让模型「看图猜坐标」,而是给它一棵带唯一 ID 的无障 碍文本树,模型回一个元素 ID,框架用 ID→XPath 字典确定性落点。
1. 这是什么(零基础也能懂)
一句话定义: Stagehand 是 browserbase 的 AI 浏览器自动化框架——确定的步骤写代码,不确定的页面交给 AI;v4 起,它以「浏览器扩展 + 多语言瘦客户端」的形态交付。
解决什么问题 / 给谁用: 写自动化脚本去网页上抓数据/填表单/跑测试。传统工具(Selenium/Playwright)选择器易碎;纯 AI agent 太黑盒。Stagehand 让你按需混用。面向要在生产环境跑浏览器自动化的开发者。
它能做什么(四个动词):
| 动词 | 干什么 |
|---|---|
act | 执行一个原子动作(点击/输入) |
observe | 只看不做:返回候选可交互元素 |
extract | 按 Zod schema 从页面抽结构化数据 |
agent | 给一个高层目标,自主多步完成 |
用起来什么样(SDK 侧,packages/sdk-ts/src/stagehand.ts:206-208 的 act 重载):
// 示意,非源码:SDK 客户端的用法和 v3 时代几乎一样
await stagehand.act("click on the stagehand repo"); // 单步动作
const data = await stagehand.extract("get the PR title", schema); // 结构化抽取
差别在底下:这个 stagehand 对象是 个 RPC 客户端,每个调用都被打成 JSON-RPC 请求发给浏览器扩展里的真引擎。
一句话直觉/类比: v3 是「你的 Node 进程里住着一位司机」;v4 是「司机直接住进了 Chrome(扩展),你的程序只剩一部对讲机(JSON-RPC)」。好处:引擎离浏览器最近(同源同进程),客户端可以随便用什么语言。
2. 顶层全景(它大概怎么转)
你的程序(TS/Go/Python) Chrome
┌──────────────────┐ ┌─────────────────────────────┐
│ SDK 瘦客户端 │ │ packages/extension │
│ stagehand.act() │ JSON-RPC │ service worker: │
│ (打参数、发请求) │ ────────▶ │ RPCRouter → Controller │
└──────────────────┘ CDP/WS │ → Service(act/extract/ │
│ observe)→ inference │
│ → understudy CDP 引擎 │──▶ 页面 DOM
│ (a11y 快照 + 落点) │
└─────────────────────────────┘
| 部件 | 干什么 | 在哪个文件/目录 |
|---|---|---|
stagehand.v4 协议 | JSON-RPC 契约:方法、参数 schema、版本 | packages/protocol/stagehand.v4.json、protocol-version.ts |
| SDK 客户端(TS) | 参数校验、发 RPC、收结果 | packages/sdk-ts/src/stagehand.ts |
| service worker 组合器 | 把 RPC 客户端、路由、运行时组装成扩展 | packages/extension/service-worker.ts(startStagehandServiceWorker) |
RPCRouter | 按方法名派发到 controller | packages/extension/rpcRouter.ts:48 |
| controllers | init/close/act/extract/observe 的参数与协议版本门 | packages/extension/controllers/ |
| services | act/extract/observe 的 AI 编排 | packages/extension/services/ |
| understudy 引擎 | 自研 CDP 层:page/frame/locator/a11y 快照 | packages/extension/understudy/ |
主线走一遍(一次 act): SDK act("click the login button") → JSON-RPC 到扩展 → RPCRouter 派给 stagehandController → 先查协议版本兼容性 → actService.act 抓 a11y 混合快照 → 喂 LLM → 拿回 elementId → 反查 XPath → understudy 落点 → 结果沿 RPC 返回。
3. 阅读地图
- 01-protocol-and-clients.md — 先看 v4 为什么这样拆:协议契约 + 版本协商 + 瘦客户端。
- 02-extension-runtime.md — 扩展怎么组装、请求怎么被路由。
- 03-engine-services.md — 引擎灵魂:a11y 快照、两步推理、缓存与自愈。
代码地图(导航索引)
| 主题 | 文件路径 | 符号名 |
|---|---|---|
| 协议契约 | packages/protocol/stagehand.v4.json | JSON-RPC 方法/schema 清单 |
| 版本协商 | packages/protocol/protocol-version.ts | STAGEHAND_PROTOCOL_VERSION、checkProtocolCompatibility |
| TS 客户端 | packages/sdk-ts/src/stagehand.ts | act/extract/observe 重载 |
| 扩展组装 | packages/extension/service-worker.ts | startStagehandServiceWorker |
| 路由 | packages/extension/rpcRouter.ts | RPCRouter |
| act 编排 | packages/extension/services/actService.ts | act(两步推理、自愈) |
| observe/extract | packages/extension/services/ | observe、extract |
| 缓存 | packages/extension/services/cacheService.ts | buildCacheContext、buildActCacheData |
| a11y 快照 | packages/extension/understudy/a11y/snapshot/capture.ts | captureHybridSnapshot |
| CDP 引擎 | packages/extension/understudy/ | page.ts、frame.ts、locator.ts、cdp.ts |