☰
ZCode 浏览器自动化中的 Snapshot 与 Refs 机制:从紧凑快照到元素引用的完整实践指南
2026/9/29 12:57:06 网站建设 项目流程
  • 人工智能
  • 大模型
  • 代码智能体
  • AI Agent
  • 桌面应用
  • 后端
  • 前端
  • CLI

【免费下载链接】ZCode

ZCode 是 AI 编程工作台,提供桌面应用、浏览器界面和终端 Agent。本仓库包含客户端、后端服务、共享 UI,以及 Agent CLI 与运行时源码。

项目地址:https://gitcode.com/zai-org/ZCode
点击查看免费下载

导读

本文围绕 ZCode 仓库中内置的 agent-browser 浏览器自动化技能(见 .agents/skills/agent-browser/references/snapshot-refs.md)展开,深入讲解其核心设计——用紧凑的 DOM 快照(Snapshot)替代完整 HTML,为每个可交互元素分配唯一引用 ID(Ref),从而让 AI Agent 以极低 Token 成本完成页面理解与精准操作。读完本文,你将掌握agent-browser snapshot -i的完整输出格式、@e1这类元素引用的生命周期与失效规则、iframe 内元素的引用处理、常见故障排查,以及这些机制在 ZCode 内置 Browser Use 插件(apps/zcode-cli/packages/browser-use-plugin/README.md)中以playwright.domSnapshot()形式落地的实现原理。

Snapshot 与 Refs 解决了什么问题

在传统浏览器自动化方案中,AI Agent 理解页面通常走这样的链路:

Full DOM/HTML → AI parses → CSS selector → Action (~3000-5000 tokens)

完整 DOM/HTML 动辄数万字符,AI 需要自行解析标签结构、推断语义、再手工构造 CSS 选择器,单次交互的成本高达 3000~5000 Token,且选择器脆弱、页面一变化就失效。

agent-browser 的路线则完全不同:

Compact snapshot → @refs assigned → Direct interaction (~200-400 tokens)

它先把页面压缩成一份紧凑的可访问性快照,自动为每个元素分配@e1、@e2这样的唯一引用 ID,AI 后续只需用click @e6、fill @e10 "..."这类命令直接交互,单次交互成本降到 200~400 Token,约为传统方式的十分之一。这正是 Snapshot 与 Refs 机制的核心价值:用一次性的小额快照开销,换来后续所有操作的低成本、高确定性。

在 ZCode 的浏览器插件实现中,这一思想被进一步落实为tab.playwright.domSnapshot()——它返回的是紧凑的 AI/ARIA 树而非页面outerHTML,并作为定位元素(locator)的事实来源(见 apps/zcode-cli/packages/browser-use-plugin/docs/overview.md)。

Snapshot 命令:如何获取元素引用

基本用法

# 基础快照(展示页面结构) agent-browser snapshot # 交互式快照(-i 参数)—— 推荐使用 agent-browser snapshot -i

-i(interactive)只输出可交互元素并附带引用 ID,是 Agent 日常工作最推荐的形态。完整的命令参考中还提供了其他快照变体(见 .agents/skills/agent-browser/references/commands.md):

agent-browser snapshot # 完整可访问性树 agent-browser snapshot -i # 仅可交互元素(推荐) agent-browser snapshot -c # 紧凑输出 agent-browser snapshot -d 3 # 限制深度为 3 层 agent-browser snapshot -s "#main" # 用 CSS 选择器限定范围

快照输出格式详解

一次典型快照的输出如下:

Page: Example Site - Home URL: https://example.com @e1 [header] @e2 [nav] @e3 [a] "Home" @e4 [a] "Products" @e5 [a] "About" @e6 [button] "Sign In" @e7 [main] @e8 [h1] "Welcome" @e9 [form] @e10 [input type="email"] placeholder="Email" @e11 [input type="password"] placeholder="Password" @e12 [button type="submit"] "Log In" @e13 [footer] @e14 [a] "Privacy Policy"

输出由三部分组成:

  1. 页面头部:Page:标题与URL:地址,用于确认当前所处的页面上下文;
  2. 元素引用(@refs):@e1~@e14是分配给每个元素的唯一 ID,缩进体现 DOM 嵌套层级;
  3. 元素描述:方括号内是标签名与关键属性,双引号内是可见文本。

这种结构对 AI Agent 极其友好——角色、名称、状态、层级关系一目了然,无需再解析任何 HTML 标签对。

Using Refs:拿到引用后直接交互

拿到 refs 之后,所有操作都变得直接:

# 点击 "Sign In" 按钮 agent-browser click @e6 # 填充邮箱输入框 agent-browser fill @e10 "user@example.com" # 填充密码输入框 agent-browser fill @e11 "password123" # 提交表单 agent-browser click @e12

除了 click 与 fill,refs 还可用于更多交互命令(完整清单见 .agents/skills/agent-browser/references/commands.md):

agent-browser dblclick @e1 # 双击 agent-browser hover @e1 # 悬停 agent-browser check @e1 # 勾选复选框 agent-browser uncheck @e1 # 取消勾选 agent-browser select @e1 "value" # 选择下拉选项(可传多个值) agent-browser scrollintoview @e1 # 滚动元素到可视区域 agent-browser drag @e1 @e2 # 拖放 agent-browser upload @e1 file.pdf # 上传文件 agent-browser get text @e1 # 读取元素文本 agent-browser get html @e1 # 读取 innerHTML agent-browser get value @e1 # 读取输入框值 agent-browser get attr @e1 href # 读取属性 agent-browser get box @e1 # 读取边界框

ZCode 插件侧的等价实现同样遵循"快照事实驱动交互"原则:browser-use-plugin的 workflow 文档明确要求只用快照中出现过的角色、可访问名称、文本、占位符、data-*、href等事实来构造 Playwright locator,严禁凭记忆猜测选择器(见 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md)。

Ref Lifecycle:引用的生命周期与失效规则

最重要的规则:页面一旦变化,所有 refs 立即失效!

# 获取初始快照 agent-browser snapshot -i # @e1 [button] "Next" # 点击触发了页面跳转 agent-browser click @e1 # 必须重新快照才能获得新的 refs! agent-browser snapshot -i # @e1 [h1] "Page 2" ← 同一个 @e1 现在指向了完全不同的元素!

上例清楚展示了失效的本质:@e1只是本次快照内的序号,不是元素的持久身份。页面跳转后 DOM 结构变化,@e1的绑定对象随之改变。因此 Agent 绝不能跨页面复用记忆中的 refs。

ZCode 的 control-browser 技能对这条规则做了更工程化的约束:每个逻辑操作批次开始时,必须在一个独立的 JS 调用中返回完整的await browser.tabs.list()结果供模型查看,然后在下一次 JS 调用中用验证过的 id/url/title 匹配目标标签页——禁止用记忆中的 tab id 或数组位置直接操作(见 apps/zcode-cli/packages/browser-use-plugin/skills/control-browser/SKILL.md)。这与 refs 失效规则的底层逻辑完全一致:Agent 环境没有跨调用的持久绑定,一切以最新观测为准。

Best Practices:快照的正确使用姿势

1. 交互之前必须先快照

# 正确做法 agent-browser open https://example.com agent-browser snapshot -i # 先拿 refs agent-browser click @e1 # 再使用 ref # 错误做法 agent-browser open https://example.com agent-browser click @e1 # ref 还不存在,必然报错!

2. 导航之后重新快照

agent-browser click @e5 # 点击链接跳转新页面 agent-browser snapshot -i # 获取新页面的 refs agent-browser click @e1 # 使用新 refs

3. 动态内容变化后重新快照

agent-browser click @e1 # 点击展开下拉菜单 agent-browser snapshot -i # 查看下拉项 agent-browser click @e7 # 选择目标项

4. 复杂页面只快照特定区域

# 只快照表单区域 agent-browser snapshot @e9

缩小快照范围不仅能降低 Token 消耗,还能避免无关元素干扰 Agent 的定位判断。ZCode 侧与之对应的是snapshot -s "#selector"与 Playwright 的getByRole/getByText/getByLabel等定向 locator——都是"用最小观测回答当前问题"思想的体现。

Ref Notation Details:引用符号的完整语法

每条快照记录都可以拆解为:

@e1 [tag type="value"] "text content" placeholder="hint" │ │ │ │ │ │ │ │ │ └─ 附加属性 │ │ │ └─ 可见文本 │ │ └─ 关键属性 │ └─ HTML 标签名 └─ 唯一引用 ID

常见元素模式速查

@e1 [button] "Submit" # 带文本的按钮 @e2 [input type="email"] # 邮箱输入框 @e3 [input type="password"] # 密码输入框 @e4 [a href="/page"] "Link Text" # 锚点链接 @e5 [select] # 下拉框 @e6 [textarea] placeholder="Message" # 文本域 @e7 [div class="modal"] # 容器(相关时才会出现) @e8 [img alt="Logo"] # 图片 @e9 [checkbox] checked # 已勾选的复选框 @e10 [radio] selected # 已选中的单选按钮

这套记法在 ZCode 的 Playwright 快照中同样成立:domSnapshot()返回的 AI/ARIA 树包含计算后的角色(role)、可访问名称(accessible name)、状态以及展开的 shadow DOM 与 iframe 内容,与上述 CLI 快照格式一脉相承(见 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md)。

Iframes:快照自动内联与跨框架操作

快照会自动检测并内联 iframe 内容。主框架快照执行时,每个Iframe节点都会被解析,其子可访问性树直接内联在该节点之下;分配给 iframe 内元素的 refs 携带帧上下文,因此click、fill、type等交互无需手动切换 frame:

agent-browser snapshot -i # @e1 [heading] "Checkout" # @e2 [Iframe] "payment-frame" # @e3 [input] "Card number" # @e4 [input] "Expiry" # @e5 [button] "Pay" # @e6 [button] "Cancel" # 直接用 refs 操作 iframe 内的元素 agent-browser fill @e3 "4111111111111111" agent-browser fill @e4 "12/28" agent-browser click @e5

iframe 处理的三个关键细节

  • 只展开一层嵌套:iframe 内的 iframe 不会被递归展开;
  • 跨域 iframe 静默跳过:阻止可访问性树访问的跨域 iframe 会被直接略过;
  • 空 iframe 省略:无内容或无交互元素的 iframe 不会出现在输出中。

若需要将快照限定到单个 iframe,先frame @ref再snapshot -i:

agent-browser frame @e2 # 切换到支付 iframe agent-browser snapshot -i # 只输出该 iframe 的内容 agent-browser frame main # 切回主框架

frame命令支持三种目标:元素引用(frame @e3)、CSS 选择器(frame "#payment-iframe")、以及帧名/URL 匹配。ZCode 插件同样遵循"iframe 内容自动内联"的设计,control-browser技能描述中明确提到快照包含 "expanded iframe content when available"(见 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md)。

Troubleshooting:常见问题与解法

"Ref not found" 错误

# ref 可能已随页面变化而失效——重新快照 agent-browser snapshot -i

ZCode 侧的故障恢复逻辑与之完全对应:任何 Playwright 超时、严格模式失败或选择器解析失败后,禁止重试同一个 locator,必须先取一份新的domSnapshot()再基于快照事实重建 locator(见 apps/zcode-cli/packages/browser-use-plugin/docs/browser-troubleshooting.md 与 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md)。

元素不在快照中

# 先滚动让元素进入可视区域 agent-browser scroll down 1000 agent-browser snapshot -i # 或者等待动态内容加载 agent-browser wait 1000 agent-browser snapshot -i

元素太多、快照过大

# 只快照指定容器 agent-browser snapshot @e5 # 或者用 get text 只做纯文本提取 agent-browser get text @e5

此外,ZCode 的 Browser Use 插件还提供了两个"逃生通道"用于快照看不见的目标:tab.cua(坐标路径,用于 canvas/自绘控件)和tab.dom_cua(节点路径,node_id来自get_visible_dom()),二者可在快照无法覆盖视觉型元素时兜底(见 apps/zcode-cli/packages/browser-use-plugin/skills/control-browser/SKILL.md)。

核心工作流串联:从打开页面到完成交互

将上述机制串成一条完整链路,就是 agent-browser 推荐的标准流程(见 .agents/skills/agent-browser/SKILL.md):

  1. 导航:agent-browser open <url>
  2. 快照:agent-browser snapshot -i(获得@e1、@e2等 refs)
  3. 交互:用 refs 执行 click、fill、select
  4. 重新快照:导航或 DOM 变化后获取新 refs
agent-browser open https://example.com/form agent-browser snapshot -i # 输出: @e1 [input type="email"], @e2 [input type="password"], @e3 [button] "Submit" agent-browser fill @e1 "user@example.com" agent-browser fill @e2 "password123" agent-browser click @e3 agent-browser wait --load networkidle agent-browser snapshot -i # 检查操作结果

命令可以通过&&在同一 shell 调用中串联,浏览器进程在命令之间由后台守护进程保持,因此链式调用既安全又高效;但当中间命令的输出需要先解析(比如快照发现 refs 再据此交互)时,应分步执行。

在 ZCode 插件侧,同一工作流以js工具(mcp__node_repl__js)承载:每次调用先运行 bootstrap 初始化agent.browsers,随后await tab.playwright.domSnapshot()作为默认观测手段,locator 只从快照事实构建,操作后用最廉价的观测(定向 locator 状态检查或一次新快照)确认效果——同一观测周期内最多执行一个有状态变更的动作(见 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md)。

与 ZCode 内置 Browser Use 插件的关系

上文多次出现的domSnapshot()、快照失效恢复、iframe 内联等规则,均来自 ZCode 仓库内置的官方浏览器自动化插件 apps/zcode-cli/packages/browser-use-plugin。该插件提供js工具(由node_replMCP host 承载)、scripts/browser-client.mjs引导模块,以及control-browser(浏览器驱动技能)与web-gui-tester(纯 GUI 黑盒测试技能)两个技能。control-browser技能把本主题的快照/refs 思想工程化为可执行协议:以playwright.domSnapshot()为默认页面观测与 locator 事实来源,以快照失效后的重建代替盲目重试,以"快照足够就不再截图"控制 Token 与延迟(见 apps/zcode-cli/packages/browser-use-plugin/skills/control-browser/SKILL.md)。

这份技能文档源自 vercel-labs/agent-browser 并经过 ZCode 本地化改造,许可与来源信息见仓库根目录的 THIRD-PARTY-NOTICES.md。如需查看完整命令参考、快速上手与更多深度主题(认证、会话管理、录制、性能剖析、代理支持),可继续阅读同目录下的 commands.md 与 SKILL.md。

总结

Snapshot 与 Refs 是 agent-browser 让"AI 驱动浏览器"变得可行的关键设计:一份紧凑快照承担了页面理解的全部成本,而@ref引用把后续交互简化为确定性命令。用好它的四件事是:交互前必快照、页面变化后必重新快照、复杂页面只快照局部、失效时重建而不是硬猜。这套机制在 ZCode 中以playwright.domSnapshot()完整落地,并沉淀为control-browser技能中"快照事实 → 稳定 locator → 单动作单观测"的工程纪律,是任何在 ZCode 中构建网页自动化、表单测试或数据提取流程的 Agent 都应当优先掌握的底层能力。

  • 人工智能
  • 大模型
  • 代码智能体
  • AI Agent
  • 桌面应用
  • 后端
  • 前端
  • CLI

【免费下载链接】ZCode

ZCode 是 AI 编程工作台,提供桌面应用、浏览器界面和终端 Agent。本仓库包含客户端、后端服务、共享 UI,以及 Agent CLI 与运行时源码。

项目地址:https://gitcode.com/zai-org/ZCode
点击查看免费下载

相关推荐

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

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

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

立即咨询