芥末
发布于 2026-04-23 / 0 阅读
0
0

agent-browser:面向 AI Agent 的浏览器自动化 CLI 设计

浏览器自动化并不新。Playwright、Puppeteer、Selenium 这类工具已经能完成页面打开、元素定位、点击、输入、截图、表单提交等任务。

但这些工具的默认使用方式,通常假设操作者是程序员。

程序员会提前知道页面结构,然后写出类似这样的脚本:

await page.goto("https://example.com/login")
await page.locator("#username").fill("alice")
await page.locator("#password").fill("secret")
await page.locator("button[type=submit]").click()

这套模式的核心是:

代码逻辑 + 元素选择器 + 固定流程

对于传统自动化测试、爬虫、后台任务来说,这很合理。问题在于,AI Agent(人工智能代理)并不是这样工作的。

Agent 更像是在浏览器里边观察边行动:它看到页面上有什么,再决定下一步点哪里、输入什么、是否继续等待、是否回退。它无法总是提前写好完整脚本,也不适合在每一步都推理复杂的 CSS 选择器。

agent-browser 解决的正是这个问题:它把浏览器自动化改造成更适合 Agent 使用的 CLI(命令行界面)。

它的设计重点不是让人类写脚本更舒服,而是让 Agent 更容易理解页面、更稳定地执行动作。

传统浏览器自动化为什么不适合 Agent

传统自动化工具通常围绕 DOM(文档对象模型)和选择器工作。DOM 结构很完整,但对 Agent 来说信息量太大,而且很多信息并不直接服务于“下一步该操作什么”。

一个真实页面里可能包含:

  • 大量嵌套的 div
  • 样式类名
  • 隐藏元素
  • 前端框架生成的中间节点
  • 广告、布局、装饰性内容
  • 重复出现的按钮和链接
  • 动态渲染后的复杂 DOM 层级

如果把这些内容原样塞给 Agent,Agent 面临的不是“看网页”,而是“读一大坨 HTML”。

传统模式大致是这样:

flowchart LR
    A[自动化脚本] --> B[CSS / XPath 选择器]
    B --> C[DOM 节点]
    C --> D[浏览器动作]
    D --> E[页面状态变化]

这条链路对程序员友好,因为程序员可以写选择器;但对 Agent 不友好,因为 Agent 需要先理解页面,再生成一个足够准确的选择器。

选择器还有一个现实问题:页面稍微改版,选择器就可能失效。

方式适合对象主要依赖问题
Playwright / Puppeteer 脚本程序员、测试工程师CSS 选择器、XPath、固定脚本Agent 需要自己生成选择器,容易受 DOM 噪声影响
直接读取 HTML爬虫、结构化解析任务DOM 文本上下文过大,交互语义不清晰
agent-browser 快照AI Agent可访问性树、交互元素引用更适合“观察—决策—行动”的循环

agent-browser 的核心思路是:不要让 Agent 直接面对完整 DOM,而是给它一份更像“可操作页面摘要”的快照。

agent-browser 是什么

agent-browser 是一个用 Rust 编写的浏览器自动化 CLI,目标使用者是 AI Agent,而不是直接操作浏览器的人类用户。

它有几个关键特点:

  1. 面向 Agent 设计
    命令和输出都围绕 Agent 的工作方式组织,让 Agent 可以先观察页面,再基于观察结果执行动作。

  2. 直连 Chrome DevTools Protocol
    Chrome DevTools Protocol(Chrome 开发者工具协议,简称 CDP)是 Chrome 暴露给调试器和自动化工具的一组接口。agent-browser 直接使用 CDP 控制浏览器,不依赖 Node.js,也不依赖 Playwright。

  3. 用 Rust 实现
    Rust 适合编写单文件 CLI、后台服务和系统工具。用 Rust 实现可以减少运行时依赖,让工具更接近一个独立浏览器控制器。

  4. 引入 snapshot 快照机制
    快照会把当前页面中适合交互的元素整理出来,并给每个元素分配短引用,例如 @e1@e2@e3。Agent 后续执行点击或填充时,可以直接引用这些编号。

整体结构可以理解为:

flowchart TD
    A[AI Agent] -->|自然语言目标 / skills| B[agent-browser CLI]
    B -->|CDP 调用| C[Chrome 浏览器]
    C -->|页面状态 / 可访问性树| B
    B -->|snapshot 快照| A
    A -->|click @e1 / fill @e2| B
    B -->|执行浏览器动作| C

这里最重要的变化是:Agent 不需要写 #submit.btn-primary:nth-child(2) 这种选择器,而是可以根据快照里的语义描述选择 @e1 这样的稳定引用。

snapshot:把网页变成 Agent 能读懂的操作清单

agent-browser 最关键的能力是 snapshot

它不是简单返回 HTML,也不是把 DOM 序列化后丢给 Agent。它会调用 Chrome 的可访问性接口:

Accessibility.getFullAXTree

这个接口返回的是 Accessibility Tree(可访问性树)。

可访问性树原本是为了屏幕阅读器、辅助技术、无障碍访问设计的。它关心的不是页面如何排版,而是页面上有哪些对用户有意义的对象,例如:

  • 按钮
  • 链接
  • 输入框
  • 复选框
  • 下拉框
  • 文本区域
  • 标题
  • 表单控件
  • 可点击区域

DOM 更接近“页面如何构造”,可访问性树更接近“用户能感知和操作什么”。

两者差异可以这样理解:

维度DOMAccessibility Tree
关注点HTML 结构、节点层级、样式关联用户可感知的语义和交互对象
信息量很大,包含大量布局和框架节点更精简,过滤掉不少无交互意义的内容
对 Agent 的价值需要额外推理哪些节点可操作更直接暴露按钮、输入框、链接等语义
常见用途前端渲染、脚本操作、样式计算无障碍访问、屏幕阅读器、语义理解

agent-browser 在拿到完整可访问性树后,还会继续做裁剪和重排,把真正有交互价值的元素整理成快照。

一个简化后的快照可能长这样:

Current page: Login

@e1 link "Home"
@e2 textbox "Email"
@e3 textbox "Password"
@e4 checkbox "Remember me"
@e5 button "Sign in"
@e6 link "Forgot password?"

Agent 看到这份快照后,就不需要研究页面 DOM,也不需要猜测按钮选择器。它可以直接决定:

fill @e2 "alice@example.com"
fill @e3 "secret"
click @e5

这就是快照机制的价值:把“页面理解”和“页面操作”之间的桥梁变短。

为什么短引用比选择器更适合 Agent

短引用看起来只是把元素编号了,但它解决了 Agent 操作浏览器时的几个关键问题。

1. 降低上下文长度

完整 DOM 可能非常长,尤其是现代前端页面会包含大量框架生成的节点。Agent 的上下文窗口虽然越来越大,但上下文越大,推理成本越高,干扰也越多。

可访问性树经过裁剪后,只保留与用户操作相关的信息,可以显著减少输入给 Agent 的内容。

flowchart LR
    A[完整 DOM] -->|过滤布局节点 / 隐藏节点 / 非交互节点| B[可访问性树]
    B -->|裁剪 / 重排 / 编号| C[snapshot]
    C --> D[Agent 决策]

Agent 需要的是“页面上有哪些能点、能填、能选的东西”,而不是页面所有 div 的嵌套关系。

2. 避免生成复杂选择器

让 Agent 生成 CSS 选择器是一件风险很高的事。它可能生成不存在的选择器,也可能选中多个元素,还可能在页面变化后失效。

短引用把选择器问题转移给 agent-browser。Agent 只需要使用快照里已经存在的引用。

不需要:
page.locator("div.container > form > div:nth-child(3) button.primary").click()

只需要:
click @e5

这种交互方式更接近人类使用网页:看到“登录”按钮,然后点击它。

3. 支持多轮观察和行动

Agent 的浏览过程不是一次性脚本,而是循环:

flowchart TD
    A[生成页面快照] --> B[Agent 理解当前页面]
    B --> C[选择下一步动作]
    C --> D[agent-browser 执行动作]
    D --> E[页面发生变化]
    E --> A

每一次页面变化后,Agent 可以重新获取快照,再基于新的页面状态继续行动。

这比提前写死完整流程更适合处理动态页面,例如:

  • 登录后出现验证码提示
  • 表单校验失败后出现错误信息
  • 搜索结果需要翻页
  • 页面加载慢,需要等待某个按钮出现
  • 不同账号看到的页面结构不完全一样

4. 让命令更像 Agent 的动作语言

对 Agent 来说,理想的浏览器控制接口应该接近动作描述,而不是编程 API。

例如:

snapshot
click @e1
fill @e2 "hello"
press Enter
wait
go_back

这类命令短、明确、容易组合,也方便放进 Agent 的 skills 或工具调用描述里。

agent-browser 的工作链路

agent-browser 可以拆成四层来看。

flowchart TB
    A[Agent 层] --> B[CLI 命令层]
    B --> C[浏览器控制层]
    C --> D[Chrome DevTools Protocol]
    D --> E[Chrome 页面]

    E --> F[Accessibility Tree]
    F --> G[snapshot 生成器]
    G --> B
    B --> A

各层职责如下:

层级职责
Agent 层根据任务目标决定下一步要做什么
CLI 命令层接收 snapshotclickfill 等动作命令
浏览器控制层将命令转换为 CDP 调用
CDP 层与 Chrome 通信,执行导航、点击、输入、获取页面信息等操作
snapshot 生成器从可访问性树中提取交互元素,并分配 @e1 这类短引用

关键路径是:

sequenceDiagram
    participant Agent as AI Agent
    participant CLI as agent-browser
    participant Chrome as Chrome
    participant AX as Accessibility Tree

    Agent->>CLI: snapshot
    CLI->>Chrome: Accessibility.getFullAXTree
    Chrome-->>AX: 返回完整可访问性树
    AX-->>CLI: 节点信息
    CLI-->>Agent: 返回带 @e 引用的快照

    Agent->>CLI: click @e5
    CLI->>Chrome: 通过 CDP 执行点击
    Chrome-->>CLI: 页面状态变化
    CLI-->>Agent: 动作结果

这条链路里,Agent 始终不需要直接操作 DOM。DOM 仍然存在,只是被封装在浏览器和 CDP 之后。

和 Playwright 的差异

agent-browser 并不是要替代 Playwright 的所有场景。两者面向的问题不一样。

对比项Playwrightagent-browser
主要使用者程序员、测试工程师AI Agent
典型输入脚本代码CLI 命令、动作引用
元素定位方式locator、CSS、XPath、文本选择器snapshot 中的短引用
页面理解方式人提前理解页面结构并写脚本Agent 读取快照后动态决策
依赖通常依赖 Node.js 生态Rust 实现,直连 CDP
适合任务自动化测试、稳定流程、可维护脚本Agent 浏览网页、动态任务执行、自然语言驱动操作

Playwright 更适合“流程已知、目标明确、需要长期维护脚本”的场景。

agent-browser 更适合“Agent 需要临场判断页面状态”的场景。

例如,自动化测试里要验证登录按钮是否可用,Playwright 脚本很合适;如果 Agent 要在陌生网站上查找资料、填写表单、处理不确定页面,基于快照的交互模型会更自然。

和直接让 Agent 看截图有什么不同

浏览器 Agent 还有另一种常见做法:给 Agent 截图,让它像看屏幕一样判断点击位置。

截图方式有一个优点:页面视觉信息完整。Agent 可以看到布局、颜色、位置、图标和整体外观。

但截图也有几个问题:

  • 需要视觉模型参与,成本更高
  • 点击通常依赖坐标,坐标容易受窗口大小、缩放比例影响
  • 表单字段、按钮语义不一定容易从截图中稳定识别
  • 对纯文本和结构化信息的抽取效率不如语义树

agent-browser 的快照方式更偏“语义浏览器自动化”,它不重点描述页面长什么样,而是描述页面能做什么。

方式优点局限
截图 + 坐标点击保留视觉布局,适合复杂视觉界面成本高,坐标脆弱,语义不稳定
DOM / HTML 输入信息完整,可精确定位上下文大,噪声多,Agent 负担重
Accessibility Tree 快照语义清晰,交互元素明确,上下文较小对纯视觉元素、canvas、自定义控件可能不够完整

如果页面主要由标准 HTML 控件组成,快照方式会非常高效;如果页面大量依赖 canvas、自绘 UI 或复杂视觉交互,可能还需要结合截图能力。

适合使用 agent-browser 的场景

agent-browser 的优势集中在“Agent 需要操作真实网页”的任务里。

场景是否适合原因
Agent 根据自然语言目标浏览网页适合快照能给 Agent 提供紧凑的页面语义
自动填写标准网页表单适合输入框、按钮、复选框等元素可以通过可访问性树识别
页面状态不确定的多轮任务适合Agent 可以每一步重新 snapshot
固定流程的端到端测试不一定Playwright 这类脚本化工具更成熟
大规模网页抓取不一定抓取更关注吞吐、反爬、数据抽取,未必需要 Agent 交互
canvas 游戏、复杂图形应用不太适合可访问性树可能无法表达完整视觉状态
需要像素级视觉判断的任务不太适合需要截图和视觉模型配合

一个典型 Agent 浏览任务可以这样建模:

目标:进入某个网站,搜索关键词,打开最相关结果,提取页面摘要。

循环:
1. 获取 snapshot
2. 找到搜索框引用
3. 填入关键词
4. 提交搜索
5. 再次获取 snapshot
6. 找到结果列表中的目标链接
7. 点击进入
8. 获取页面内容或继续操作

这类任务的难点不是单次点击,而是每一步都要基于页面变化重新决策。snapshot 正好提供了这个循环所需的观察接口。

Agent First 原则意味着什么

“Agent First”不是简单地给工具加一个自然语言外壳,而是从接口设计开始就考虑 Agent 的限制和优势。

Agent 擅长:

  • 根据语义描述做判断
  • 在多轮过程中调整计划
  • 从候选动作中选择下一步
  • 处理不完全确定的页面状态

Agent 不擅长:

  • 稳定生成复杂 CSS 选择器
  • 从超长 HTML 中筛出关键节点
  • 记住动态页面中节点的细节结构
  • 精确处理大量低层浏览器 API

所以 agent-browser 把低层浏览器能力封装起来,只暴露更适合 Agent 使用的操作层。

flowchart LR
    A[低层能力: CDP / DOM / AX Tree] --> B[agent-browser 封装]
    B --> C[Agent 友好接口: snapshot / ref / action]

这和传统“给人用的浏览器工具”不同。给人用的工具通常强调可视化界面、调试体验、配置能力;给 Agent 用的工具更强调输出紧凑、动作明确、状态可恢复。

snapshot 机制的边界

快照机制很有用,但它不是万能的。

可访问性信息依赖页面质量

如果网页没有正确设置无障碍属性,快照中的语义可能不完整。例如按钮没有文本、输入框没有 label、图标按钮没有 aria-label,Agent 拿到的描述就会变弱。

一个不友好的按钮可能长这样:

<button>
  <svg>...</svg>
</button>

更适合可访问性树识别的写法是:

<button aria-label="Search">
  <svg>...</svg>
</button>

agent-browser 依赖可访问性树,页面无障碍质量越好,Agent 看到的快照越清晰。

动态页面需要重新获取快照

短引用来自某次 snapshot。页面发生变化后,旧引用可能不再代表同一个元素,甚至元素已经消失。

因此,Agent 执行动作后应该重新观察页面,而不是长期复用旧引用。

推荐:
snapshot
click @e5
snapshot
fill @e2 "new value"

不推荐:
snapshot
click @e5
等待页面变化很久后继续使用旧的 @e2

复杂视觉任务仍需要其他输入

可访问性树描述的是语义结构,不是完整视觉画面。对于验证码、图表、地图、canvas、自绘控件等内容,仅靠 snapshot 可能不够。

这类场景通常需要结合截图、OCR(光学字符识别)或视觉模型。

上手时应该关注的能力

由于 agent-browser 的核心不在“写脚本”,而在“让 Agent 能循环操作浏览器”,评估和使用时可以重点看四个动作是否顺畅。

能力作用
启动或连接 Chrome建立浏览器控制通道
获取 snapshot让 Agent 观察当前页面
基于引用执行动作@e1 这类 ref 点击、输入、选择
页面变化后再次观察形成“观察—行动—再观察”的闭环

一个抽象的使用流程可以写成:

# 1. 打开目标页面
open https://example.com

# 2. 获取当前页面快照
snapshot

# 3. 根据快照中的元素引用执行动作
fill @e2 "alice@example.com"
fill @e3 "secret"
click @e5

# 4. 页面变化后重新观察
snapshot

这里的命令展示的是交互模型,实际命令名称以工具提供的 CLI 为准。关键不在具体拼写,而在这种引用式操作方式:Agent 通过快照拿到页面语义,再用短引用执行动作。

设计上的关键取舍

agent-browser 的设计可以概括为几个取舍。

取舍选择带来的结果
面向人还是面向 Agent面向 Agent输出更紧凑,命令更动作化
用 DOM 还是可访问性树可访问性树降低上下文噪声,更突出交互语义
用选择器还是短引用短引用Agent 不需要生成复杂 CSS
依赖 Playwright 还是直连 CDP直连 CDP减少外部运行时依赖,控制链路更直接
完整描述页面还是提取可操作元素提取可操作元素更适合多轮决策,但对复杂视觉界面表达有限

这套取舍背后的目标很明确:让 Agent 用更少的上下文完成更稳定的网页操作。

小结

agent-browser 把浏览器自动化从“程序员写脚本”转向“Agent 观察并行动”。

它不把完整 HTML 暴露给 Agent,而是通过 Chrome DevTools Protocol 获取 Accessibility Tree,再生成带有 @e1@e2 这类短引用的 snapshot。Agent 可以基于快照理解页面,并用引用执行点击、输入等操作。

这种设计尤其适合多轮、动态、不确定的网页任务。只要页面的可访问性语义足够清晰,Agent 就能用更小的上下文、更少的选择器推理完成浏览器操作。


评论