- 人工智能
- 大模型
- 代码智能体
- AI Agent
- 桌面应用
- 后端
- 前端
- CLI
【免费下载链接】ZCode
ZCode 是 AI 编程工作台,提供桌面应用、浏览器界面和终端 Agent。本仓库包含客户端、后端服务、共享 UI,以及 Agent CLI 与运行时源码。
导读
本文围绕 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"输出由三部分组成:
- 页面头部:
Page:标题与URL:地址,用于确认当前所处的页面上下文; - 元素引用(@refs):
@e1~@e14是分配给每个元素的唯一 ID,缩进体现 DOM 嵌套层级; - 元素描述:方括号内是标签名与关键属性,双引号内是可见文本。
这种结构对 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 # 使用新 refs3. 动态内容变化后重新快照
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 @e5iframe 处理的三个关键细节
- 只展开一层嵌套: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 -iZCode 侧的故障恢复逻辑与之完全对应:任何 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):
- 导航:
agent-browser open <url> - 快照:
agent-browser snapshot -i(获得@e1、@e2等 refs) - 交互:用 refs 执行 click、fill、select
- 重新快照:导航或 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 与运行时源码。
相关推荐
ZCode agent-browser Snapshot 与 Refs 完全指南:用紧凑元素引用大幅削减 AI Agent 上下文消耗
ZCode agent browser Snapshot 与 Refs 完全指南:用紧凑元素引用大幅削减 AI Agent 上下文消耗 导读 本文讲解 ZCod
agent-browser 快照与 Refs 机制:为 AI Agent 打造的紧凑元素引用体系
agent browser 快照与 Refs 机制:为 AI Agent 打造的紧凑元素引用体系 在 AI Agent 驱动浏览器时,传统的「全量 DOM →
浏览器控制CLIAI 应用GUI 自动化开发工具AI 技能MCP 服务open-agents 中 agent-browser 的 Snapshot + Refs 工作流:用紧凑元素引用把浏览器自动化上下文开销降低一个数量级
open agents 中 agent browser 的 Snapshot + Refs 工作流:用紧凑元素引用把浏览器自动化上下文开销降低一个数量级 age
人工智能AI Agent代码智能体Agent 工作流Agent 沙箱工具调用后端前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考