生成模型 :Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗 :输入 ~180k tokens,输出 ~6k tokens(本节)
上一节解析了 CDP 低级层——直接通过 WebSocket 控制浏览器。这一节上升到 Playwright 层,这是 Agent 与网页交互的主要接口:智能元素定位、页面快照、交互操作、状态管理。
24.3.1 Playwright 会话管理
Playwright 通过 CDP 连接到 Chrome,但与 withCdpSocket() 的一次性连接不同,Playwright 需要持久连接 来维护页面状态:
Copy // src/browser/pw-session.ts — 连接缓存
let cached : ConnectedBrowser | null = null ;
let connecting : Promise < ConnectedBrowser > | null = null ; 通过 cached 和 connecting 实现连接复用——同一时刻只维护一个 Playwright 到 Chrome 的连接,所有操作共享这个连接。
每个 Page 对象关联一个 PageState,用 WeakMap 管理:
Copy // src/browser/pw-session.ts — 页面状态
type PageState = {
console : BrowserConsoleMessage [] ; // 控制台消息(最多 500 条)
errors : BrowserPageError [] ; // 页面错误(最多 200 条)
requests : BrowserNetworkRequest [] ; // 网络请求(最多 500 条)
requestIds : WeakMap < Request , string >;
// 角色引用(Role Refs)——页面快照中元素的标识
roleRefs ?: Record < string , { role : string ; name ?: string ; nth ?: number }>;
roleRefsMode ?: " role " | " aria " ;
roleRefsFrameSelector ?: string ;
};
const pageStates = new WeakMap < Page , PageState > () ; 衍生解释 :WeakMap 是 JavaScript 的一种特殊 Map,其键是弱引用——当键对象(这里是 Page)被垃圾回收时,对应的 entry 自动消失。这正好适合管理页面状态:当 Playwright 销毁 Page 对象后,相关的状态数据不会造成内存泄漏。
页面快照会生成角色引用 (如 e1、e2),Agent 通过这些引用来操作元素。为了保持引用稳定性(即使 Playwright 返回了不同的 Page 对象),还有一个 target 级别的缓存:
缓存键是 ${cdpUrl}::${targetId},最多存储 50 个 target 的引用,FIFO 淘汰。
24.3.2 角色快照(Role Snapshot)
角色快照是 OpenClaw 浏览器控制的核心创新 ——它将网页的可访问性树转换为 Agent 可读的文本表示,并为每个交互元素分配一个短引用 ID。
衍生解释 :ARIA(Accessible Rich Internet Applications)是 W3C 制定的标准,定义了 Web 元素的语义角色 (Role)。例如一个 <div> 可以有 role="button" 表示它是按钮,<input type="text"> 自动获得 role="textbox"。屏幕阅读器(如 VoiceOver、NVDA)依赖这些角色来向视障用户描述页面结构。OpenClaw 复用了这个标准——Agent 通过角色来"看"页面,就像屏幕阅读器一样。
角色快照的输出类似这样:
方括号中的 [e1]、[e2] 等就是角色引用 ——Agent 在后续操作中使用 e3 来点击 "Cart" 按钮。
当页面上有多个同名按钮(如两个 "Add to Cart"),追踪器会为它们分配不同的 nth 索引,确保引用不歧义。
OpenClaw 提供三种页面快照方式,各有侧重:
1. AI Snapshot(推荐)
_snapshotForAI 是 Playwright 内部的一个方法(前缀下划线表示非公开 API),它返回一个为 AI 优化的页面文本表示。
2. ARIA Snapshot
直接获取 Chrome 的可访问性树——信息最完整但体积较大。
3. Role Snapshot
Role Snapshot 支持过滤选项——可以只显示交互元素、限制深度、压缩结构性节点——适合 Agent 快速了解页面可操作元素。
24.3.4 Playwright 工具核心
pw-tools-core.ts 是一个桶文件,聚合了八个子模块:
interactions — 交互操作
核心交互操作都通过角色引用 定位元素:
refLocator(page, ref) 是关键桥梁——它在 PageState.roleRefs 中查找引用 e3 对应的 { role: "button", name: "Cart (3)" },然后构造 Playwright 的 page.getByRole("button", { name: "Cart (3)" }) 定位器。
完整的交互操作集:
downloads — 下载管理
24.3.5 AI 辅助模块聚合
pw-ai.ts 将所有 Playwright 操作重新导出为统一的 API 表面:
Playwright 连接复用 ——全局缓存一个到 Chrome 的持久连接,所有操作共享
页面状态用 WeakMap 管理 ——控制台消息、网络请求、页面错误各有容量上限(500/500/200)
角色快照是 Agent "看"网页的方式 ——将可访问性树转为缩进文本,为每个交互元素分配短引用 ID(如 e1)
三种快照模式 :AI Snapshot(Playwright 内建优化)、ARIA Snapshot(完整可访问性树)、Role Snapshot(可过滤/压缩)
所有交互操作通过角色引用定位 ——Agent 看到 [e3] 就用 ref: "e3" 来点击,底层通过 getByRole() 解析
工具核心分为八大模块 :交互、快照、下载、响应、活动、状态、存储、追踪
pw-ai.ts 聚合了 60+ 个 Playwright 操作函数 ,为浏览器服务器提供统一的 API 表面