硅基俊宁.
← 返回文章

漫画拆解 agent-browser:从网页快照到动作验证

俊宁 · 2026-11-01
文章目录

通过 snapshot 原理漫画与公开源码,拆解 agent-browser 的语义观察、元素引用、动作执行与结果核验边界。

本文讨论通用机制和设计判断;示意不对应任何具体产品的已交付状态。源码阅读坐标沿用原稿,本次整理不构成新的运行时验收。

给 Agent 一句“查一下《网络基础》有没有库存”,需要完成的是一串具体工作:打开书店,找到搜索框,填入书名,触发查询,再确认结果对应的是这本书。网页上的某次点击成功,只能证明一个动作完成了,距离回答用户的问题还差一次结果核对。

agent-browser 把观察网页和操作浏览器整理成了命令行接口。这篇借小界和小南的一次查询,把这些接口串成一个完整任务,再说明工具与 Agent 各自承担什么。漫画中的书店、库存和命令输出均为教学示意,不是实际业务执行记录。

封面:小界和小南一起查看浏览器中的书店页面

一句话总结

agent-browser 的核心定位是面向 AI Agent 的浏览器自动化 CLI,提供网页观察、元素引用和浏览器动作;基础命令通常由上层 Agent 决策调用。实现需要按版本区分:0.19.0 默认走 Node.js + Playwright,0.41.1 默认 Chrome 路径走 Rust daemon + CDP。

理解这项分工,才能看清两个容易混淆的问题:@e1 为什么能指向一个控件,以及执行了 click 为什么还不能直接宣布任务成功。

本文按 2026 年 11 月 1 日核验的上游 0.41.1 版本与官方文档解释,默认讨论 Chrome / CDP 路径。已有系统若固定在旧版本,需要分别核对实现,不能把新版原理直接套到旧适配器上。版本依据

定位是 Agent 工具,实现要按版本区分

“SDK 还是 Agent”混合了两个问题:SDK、CLI 描述怎样接入,Agent 描述谁承担模型决策循环。agent-browser 的核心定位是面向 AI Agent 的浏览器自动化 CLI。通常由外部 Agent 理解目标、选择命令并核对结果,工具负责观察、动作和会话。官方定位

定位与版本对照:CLI 工具、旧版 Playwright、新版 Rust CDP,以及两条路径都可能使用 CDP

核心命令与可选 chat 模式

snapshot、click 等基础命令不靠 LLM 决定业务下一步。0.41.1 也提供可选的 agent-browser chat:配置模型后,将自然语言转成命令并执行。因此,不能把整个项目概括为“完全没有 Agent 能力”;本文的调用链对照主要解释基础工具层,可选 chat 在其上增加模型决策入口。AI Chat 说明

旧默认路径与新默认 Chrome 路径

对照项0.19.0 默认路径0.41.1 默认 Chrome 路径
CLIRust CLI,解析并传递命令Rust CLI,解析并传递命令
后台运行时Node.js daemon,管理 Playwright 浏览器实例Rust daemon,直接使用 CDP 驱动 Chrome
快照来源locator.ariaSnapshot(),再加工文本与引用Accessibility.getFullAXTree,再构树、关联引用并过滤输出
daemon 关键依赖Node.js、Playwright不需要 Node.js 或 Playwright
0.19.0 默认 CLI 路径:
外部 Agent → Rust CLI → Node.js daemon → Playwright → 浏览器

0.41.1 默认 Chrome 路径:
外部 Agent → Rust CLI → Rust daemon → CDP → Chrome

这些箭头描述 CLI 入口。若项目通过 SDK 在 Node.js 进程内直接导入 BrowserManager,则可能绕过 CLI 和独立 daemon;确认本机 CLI 版本,不能替代确认 SDK 实际解析的依赖版本。

SDK 包版本与底层浏览器包版本也要分别看。2026 年 11 月 2 日核对 npm 发布信息时,@mastra/agent-browser 的稳定版为 0.6.0,其 dependencies 仍固定 agent-browser: "0.19.0"。因此,升级这个适配器并不自动切到上游 0.41.1 默认 Chrome 的 Rust 原生路径。Mastra 适配器 0.6.0 发布元数据

关键变化包括后台运行时和浏览器控制层,不能简化成“旧版是 Node CLI,新版才有 Rust CLI”:0.19.0 的默认 CLI 就已经是 Rust;该版本还提供实验性、需选择启用的 --native Rust daemon。上表比较的是两版指定的默认路径,不代表 0.19.0 只有 Playwright,也不把 0.41.1 的其他引擎都归成 Chrome。0.19.0 架构与 native 模式、0.41.1 运行要求

两个版本的快照也不能混讲。旧路径的 ARIA snapshot 由 Playwright 生成,再加工引用;本文核验的新 Chrome 路径直接请求浏览器的原生 AX 数据,再进行工具侧整理。后者仍包含 DOM 范围筛选和其他补充处理,不能推成纯 AX-only 系统。旧版快照源码、新版快照源码

还有一个容易误判的线索:旧版 Playwright 也能通过 connectOverCDP() 连接 Chrome。看到 CDP 地址、Chrome 进程或相同的 CLI 命令,都不足以认定已经使用新版 Rust 原生路径。需要同时检查依赖版本、所选运行模式、后台进程和实际调用链;本文不据此推断两版速度或成功率。旧版 CDP 连接实现

第一幕:把“查库存”变成网页上的动作

(此版本省略该配图。)

小界拿到的是业务目标:“查《网络基础》的库存。”小南需要把这个目标落实到页面控件:哪个输入框接受书名,哪个按钮发起查询,哪里能读到结果。

打开网页之后,snapshot 返回一份带引用的紧凑无障碍语义快照。角色和名称帮助 Agent 判断控件用途,引用则用于后续命令。snapshot -i 偏向可引用的操作目标,适合先找输入框、链接和按钮;具体保留范围见后文的裁剪说明。快照选项

下面将漫画中的操作写成命令。book.example 是示意域名,引用编号也是示例;实际使用时必须换成目标页面,并读取真实快照。

agent-browser open https://book.example
agent-browser snapshot -i

假设快照里出现“搜索书名”输入框 @e1 和“搜索”按钮 @e2,接下来可以执行:

agent-browser fill @e1 "网络基础"
agent-browser click @e2

这里发生了两次不同的转换。Agent 根据角色、名称和任务目标,选择应该操作哪个控件;agent-browser 根据引用定位元素,再完成填写或点击。控件“叫什么”有助于决策,控件“指向哪里”支撑执行,二者缺一都会影响操作。

这也解释了语义信息的价值:页面若把搜索按钮暴露成一个有明确名称的 button,Agent 就有直接证据。若它只是一块没有名称的图形,单靠这份语义观察可能无法确定用途,需要补充截图、上下文或其他受控读取。

snapshot 内部:从 AX Tree 到可操作引用

snapshot 的采集、引用管理和格式整理由工具代码完成,工具不会调用 LLM 来生成页面语义。模型得到这份观察后,再决定下一步动作。下面八格漫画将这段过程拆开,仍以本文核验的 Chrome 原生路径为准。

snapshot 原理上篇:CLI 交给后台、浏览器维护语义树、CDP 读取及元素引用表

AX 是 Accessibility(无障碍)的常用缩写,AX Tree 即 Accessibility Tree,无障碍树。浏览器根据 DOM、原生 HTML 语义、ARIA 属性及元素状态维护这份语义表示。工具通过 Accessibility.getFullAXTree 取得节点信息,再组织角色、名称、状态和层级。指定 -s 时,会结合目标 DOM 子树筛选范围。生成引用时,后台保留引用与节点、frame 和文档的关联;后续文本中出现的 @e1 因而能回到浏览器中的具体目标。固定版本快照源码

snapshot 原理下篇:过滤输出、click 查表定位、引用失效,以及 Playwright 对照

这些信息随后按输出选项整理成紧凑文本。-i 偏向交互目标,-c 压缩空的结构分支,-d 限制展示深度。它们控制观察的体积与范围,不负责理解库存、订单等业务含义。读取 AX Tree 也不代表整套工具只使用 AX 信息:当前实现还包含 DOM 范围解析、可点击线索补充等处理,不能把这张漫画理解为纯 AX-only 约束。

执行 click @e2 时,后台解析此前保存的引用,优先尝试关联的缓存节点,再进入元素定位和可操作性处理。节点替换或文档导航会影响这项关联;角色与名称恢复存在歧义时应停止动作。引用让观察和动作有了对应关系,业务对象与最终结果仍需调用方核对。固定版本引用解析源码

Playwright 同样提供 locator.ariaSnapshot();当前文档中的 mode: "ai" 还支持带引用的 AI 快照。因此,agent-browser 的价值主要在于把观察、引用、动作命令和跨命令会话管理配套提供。两套 API 的快照引用各自属于其工具上下文,不能拿一套工具生成的编号去调用另一套工具。Playwright 快照 API

所谓“DOM 剪枝”,实际裁剪的是页面观察

面对节点很多的页面,首先要区分三个对象:浏览器正在运行的 DOM、浏览器维护的 AX 语义树,以及最后送给模型的文本快照。本文这条路径更适合称为页面观察裁剪,具体包括语义投影、结构压缩和快照输出过滤。这些处理不会把网页里的 DOM 节点删除,也不会改变页面的业务状态。

这里继续以本文固定的 0.41.1 Chrome 原生实现为依据,补充核验日期为 2026 年 11 月 2 日。漫画中的卡片和书店结果都是教学示意。

页面观察裁剪上篇:观察副本、AX 简称、包装压平与文本合并

先做语义投影,再压缩结构

从 DOM 换到 AX Tree,是把页面表达成角色、名称和状态等语义信息,不是逐字缩短 HTML。随后,工具跳过部分包装节点自身,继续遍历它们的孩子;压平符合条件的单子 generic 容器;合并连续 StaticText,清除空文本和部分父子重复文本。跳过包装仍须让有效子节点进入观察,不能把整个有用分支一起丢掉。结构整理与遍历源码

这些都是工具代码执行的规则。哪些内容对“查库存”有业务意义,需要上层根据任务选择观察范围和读取方式。

按范围和用途过滤,保留必要的上下文

选项裁剪方式使用时要核对什么
-s "#results"组织指定 DOM 子树对应的观察目标、状态和结果是否都在范围内
-d 5限制输出展示层级深层的控件或证据是否被截掉
-c保留有引用、文本或值等内容的行及其祖先链,去掉空分支紧凑输出是否仍能说明内容属于哪个区域
-i按可引用节点过滤输出,偏向操作目标普通结果正文和错误提示是否消失

官方文档把 -i 概括为交互元素模式。但本文固定源码用的是 has_ref 条件,表格单元格及部分具名标题、区域也能获得引用,因此不能将它理解为“严格只剩可点击控件”。普通文字仍可能被过滤;“快照没出现”不能证明“页面没有”。官方选项、引用分配、输出与紧凑处理

页面观察裁剪下篇:范围过滤、库存与对象身份、状态证据和渐进展开

哪些信息不能因为“不能点击”就丢掉

假设书店把结果标题暴露为 heading,把库存暴露为普通文本,观察可以简化表示如下。编号和值均为说明风险的例子,不是实测输出:

- heading "网络基础(精装版)" [ref=e7]
- StaticText "库存:3 本"
- button "购买" [ref=e8]

过滤后即使标题和购买按钮都留下了,库存文字仍可能消失。按钮可以定位,只说明存在一个动作目标,不能据此回答“有货”。裁剪策略至少要保住当前任务需要的三类信息:

  1. 动作目标与上下文:输入框、按钮、关联标签及所属区域,避免同名控件之间失去区分。
  2. 业务对象身份:书名、版本、规格及结果行的对应关系,避免把其他对象的库存接到当前对象上。
  3. 结果与约束证据:库存、价格、加载状态、禁用或选中状态、错误提示及失败原因。保留哪些字段由任务决定,不要求每次把全部页面都读进来。

DOM 节点引用也不能替代第二类信息:列表可能复用同一个节点展示另一条记录。引用仍可解析时,业务对象仍需重新核对。

信息不足就展开,验证后再结束

对于这个示意书店,可以先读操作目标,再读取结果区域。以下假设已经确认结果容器的真实选择器是 #results:

agent-browser snapshot -i
# 填写、查询后重新观察;读取结果时不带 -i
agent-browser snapshot -s "#results" -c
# 若还缺证据,取消紧凑过滤或扩大范围
agent-browser snapshot -s "#results"

观察仍不完整时,再读取已确认的结果节点文本,或结合截图检查图标、遮挡与布局。任务相关性选择和扩大观察的决策属于上层执行循环,不能假定 agent-browser 会自动理解库存验收标准。

还要分别衡量采集成本与模型输入成本:本文固定实现读取 getFullAXTree 后再组织输出。-i/-c/-d 让快照变短,不代表浏览器采集成本同比下降。评价观察裁剪,应同时检查目标控件能否找到、业务证据是否完整、任务是否正确完成,再比较 token 和延迟。

@ref 绑定页面元素,业务身份仍需核对

引用省去了为每一步重新编写 selector 的工作,但它不是商品 ID、订单号,也不是跨页面永久有效的地址。

当前官方文档的规则是:仍然存在的 DOM 元素可以在后续快照和同一文档更新中保留引用;页面或 iframe 导航、元素替换会影响引用有效性。没有对应 DOM 节点的虚拟无障碍节点,其引用只适用于当前快照。导航之后必须重新读取快照,交互之后也应重新观察页面变化。引用生命周期

因此,稳定的节点引用也不能独立证明业务对象没变。列表可能复用同一个 DOM 容器展示另一条记录;“购买”按钮可能仍然存在,但页面当前商品已经不同。执行涉及具体对象的动作之前,还需要核对书名、商品规格、订单号等任务条件。

当前变化执行循环应检查什么
搜索后进入结果页重新 snapshot,读取结果页中的控件和内容
同一页面更新库存重新观察库存值,不按旧观察回答
列表重排或复用节点核对该控件所属的业务记录,不能只看引用是否仍可解析
出现多个同名按钮补充行、区域或业务字段以消歧;无法确认时停止操作

重新观察的目的包括获取可用引用,也包括更新决策证据。即使 @e1 仍然有效,页面条件也可能已经不允许继续执行原计划。

第二幕:点击之后,验证用户要的结果

(此版本省略该配图。)

查询触发后,下一步通常是读取结果。这里有一个实际影响验收的过滤条件:snapshot -i 偏向可引用的操作目标,“有货”这样的普通结果文字可能被排除;某些标题和表格单元格能够留下,也不保证所需字段完整。找动作目标时可以压缩观察,检查业务结果时则需要保留相关正文、状态或表格内容,不能把“交互快照里没出现”理解为“页面没有”。

漫画中重新读取完整快照,假设结果标题(heading)包含“网络基础:有货”,并获得引用 @e7,才继续读取它的文本。普通文本并不保证获得独立引用,实际使用时要依据快照中暴露的结果标题、区域或表格单元格定位内容:

agent-browser snapshot
agent-browser get text @e7

上层循环还需要把读取结果与任务对照:书名是否正确,是否区分版本,库存是否对应当前地区,结果是否已经加载完成。对于这个简化任务,“书名匹配且库存明确”可以构成完成条件;真实书店若按门店、配送地区或规格区分库存,就必须补齐这些条件。

截图提供另一类证据。screenshot --annotate 会在交互元素上叠加编号,编号 [N] 对应引用 @eN,用于结合视觉画面判断目标。带标注的截图

agent-browser screenshot --annotate page.png

截图能帮助判断图标、布局和视觉遮挡;是否将它作为模型输入、怎样结合语义结果,仍由调用方决定。给一个查询结果截了图,也不代表系统已经完成业务核验。

动作失败时同样需要观察。弹窗遮住按钮,应先确认弹窗内容并按任务允许的方式处理,再重新读取页面。若请求超时而动作效果未知,应先检查页面是否已经发生变化。尤其是提交、支付、删除等操作,不能仅凭未收到成功响应就重复执行。官方命令与超时说明

第三幕:Rust CLI、daemon 和 CDP 怎样分工

(此版本省略该配图。)

当前上游采用 client-daemon 架构。Rust CLI 解析命令并与 Rust daemon 通信,daemon 直接使用 CDP 驱动默认 Chrome 路径。后台在首次命令时自动启动,并在命令之间延续,避免把每条命令都处理成一次全新的浏览器任务。原生 daemon 运行时不需要 Node.js 或 Playwright;这句话描述的是当前实现,不代表所有基于 agent-browser 的历史封装也移除了这些依赖。官方架构说明

参与者在这次查询中负责什么单靠它不能证明什么
上层 Agent / 执行循环理解查库存的目标、选择动作、组织恢复与验收计划正确不代表页面已经执行成功
Rust CLI将 open、snapshot、fill、click 等命令交给后台命令格式有效不代表业务目标正确
Rust daemon维护浏览器控制状态,组织观察与动作执行浏览器动作成功不代表库存核对完成
CDP 与 Chrome暴露浏览器控制能力,实际运行页面并处理交互页面显示一条结果不代表符合所有业务条件

CDP 是 Chrome DevTools Protocol,即浏览器暴露的调试与控制协议。本文用它解释默认路径;不能据此推导所有浏览器后端都使用相同协议。

还要区分新旧实现。本站只用 Accessibility Tree,浏览器 Agent 能走多远?核验的是 @mastra/agent-browser 0.4.1 与 agent-browser 0.19.0 的组合,那条路径通过 Playwright ariaSnapshot() 生成工具快照。本文核验的上游 0.41.1 Chrome 原生路径直接读取 CDP AX Tree。工具名和命令相似,不能代替对依赖版本及真实调用链的检查。

会话延续、状态恢复与账号隔离要分别判断

漫画最后让任务收尾,是因为完成目标之后还要处理浏览器资源。同一会话可以延续此前的页面状态;使用命名会话时,后续操作也要保持相同的会话标识。

agent-browser --session books open https://example.com
agent-browser --session books snapshot
agent-browser --session books close

这组命令可以用于观察一个真实公开页面的会话操作,但不包含漫画中的库存查询逻辑。安装与浏览器准备应先按官方安装文档完成。

会话仍在运行、浏览器关闭后能恢复状态、两个账号完全隔离,是三个不同要求。官方说明,各会话分别启动浏览器时拥有独立状态;多个会话通过 --cdp 连接同一个 Chrome 时,不能仅靠不同会话名推断 Cookie 等状态完全隔离。跨次恢复则需要按实际需求配置 profile、保存状态或恢复机制。会话与隔离边界

接入多任务系统前,应先决定浏览器归谁管理、任务绑定哪个 tab、完成和异常时怎样释放,以及下次启动允许恢复哪些状态。复用一个有登录态的浏览器很方便,也意味着调用方需要了解它当前关联的账号与数据范围。

接入前,用四种变化检查执行循环

漫画展示的是简化任务。把它迁移到真实页面之前,可以用下面四类变化检查系统有没有保留足够的证据。这是建议的验收方法,不是本次已经完成的测试结果。

给页面增加的变化应观察到的处理暴露的问题
两条结果都带“查看”按钮先结合书名或所在行消歧,再操作目标记录模型是否把同名控件当成同一对象
查询后替换整块结果区域重新读取页面,使用当前观察中的引用执行循环是否沿用失效证据
弹窗挡住搜索按钮识别阻挡原因,处理后再观察是否把失败当成重复点击的理由
点击成功,但库存仍在加载等待明确结果或返回受阻状态是否把动作成功当成任务成功

这些检查比单独记录“能不能点到按钮”更接近 Browser Agent 的任务质量。后续若比较速度、token 或费用,还需要固定任务、页面状态和完成条件,并将失败与恢复过程计入;本文没有进行这样的性能对照,不据此给出降本或提速比例。

我的判断框架

agent-browser 适合为已经具备命令调用能力的 Agent 提供统一的网页观察与操作接口。评估接入价值时,我会先看三项条件:页面语义是否足够表达目标,引用与页面状态能否持续对应,以及结果是否有可检查的完成标准。

如果任务需要根据页面实时变化选择下一步,这些接口能提供执行循环所需的基础。若流程长期固定、定位条件清晰、主要目标是回归测试,也可以继续使用现有自动化测试工具,不必为了引入 Agent 而改写成熟流程。

接入后的验收重点应落在具体对象和完成条件上:选中的是哪一本书,读到的是哪个地区的库存,失败后有没有重复产生副作用,以及任务结束后浏览器资源是否按约定处理。工具提供了观察与动作,可靠的任务交付需要把这些证据组织起来。

资料与核验范围

本文是基于官方文档与固定源码版本的机制解析,漫画为原创教学插画。未宣称执行真实书店查询,也不构成任何具体产品已经接入该上游版本的证明。

本文使用 writting-skill 辅助写作,配图使用 better-imagegen 生成。项目已开源,欢迎在 GitHub 点个 Star。