跳到正文

浏览器智能体的惨痛教训

随着模型能力提升,浏览器框架必须做出改变。而且是大改。

本文目录文章开头
部分图表可能显示不完整

Our own agent loop, predefined state space and predefined action space are crossed out. Browser Harness combines Pi, Codex or OpenCode with browser_exec.Our own agent loop, predefined state space and predefined action space are crossed out. Browser Harness combines Pi, Codex or OpenCode with browser_exec.

当我们于2024年11月推出 Browser Use 时,GPT-4o 并非为计算机操作而训练。它基于下一词元预测构建,无法可靠地理解自己在页面上能做什么。我们必须把一切都明确写出来。

随着模型在编码方面变得更强,我们从预定义的状态和动作转向代码:起初模型编写它的动作,然后是它的观察。现在它通过原始 CDP 在现有的智能体框架内完成这两件事。

定义状态与动作空间文章图表

我们定义了状态:页面上有什么,什么可以点击。然后是动作空间:点击、输入、滚动。每一次交互都必须符合这些规则。

Our early ReAct-style loop: the browser becomes our page state, GPT-4o reasons, then selects click, type, or scroll from our fixed action menu. The browser returns the next observation.Our early ReAct-style loop: the browser becomes our page state, GPT-4o reasons, then selects click, type, or scroll from our fixed action menu. The browser returns the next observation.
我们早期的循环:我们决定模型能看到什么、能做什么。

模型选择一个动作,我们执行它并返回下一个状态。但浏览器自动化是一场边缘情况的游戏。每一个异常都需要另一次修复。

用代码取代固定动作文章图表

模型的编码能力变得强得多。我们在2025年9月试验了 JavaScript 执行,在10月试验了 持久化笔记本。模型可以编写程序,而不是选择动作。

The same loop, but the action menu is replaced by a model-written program with a for loop. Our predefined page state remains. Variables and helpers persist between calls.The same loop, but the action menu is replaced by a model-written program with a for loop. Our predefined page state remains. Variables and helpers persist between calls.
让它编写动作。页面状态仍由我们提供。代码仅为示意。

绘制签名或循环遍历评论不再需要新的动作。变量得以持久化,因此模型可以检查结果并继续进行。

Hermes agent 用 browser_exec 取代了12个浏览器工具,由我们的 Browser Use CLI 驱动。Opus 4.8 的平均词元使用量下降了60%,Kimi K3 下降了66%。两个版本在每个模型上都完成了18/18次运行(六个任务,三次运行)。

预定义状态的局限文章图表

我们开放了动作,但仍然决定了模型能看到什么。这成了下一个问题。

一个 Cookie 按钮可能就在屏幕上,却在我们发送的状态中缺失。也许无障碍树没有暴露它,或者我们的处理将其丢弃。无论哪种情况,模型都看不到这个按钮。

The website shows an Accept button, but our extracted state lists only Article and Read more. The missing button shows how our processing became the bottleneck.The website shows an Accept button, but our extracted state lists only Article and Read more. The missing button shows how our processing became the bottleneck.
按钮就在那里。只是我们没能展示它。

一个电子健康记录(EHR)下拉菜单可能看起来像这样(简化的 DevTools 树):

<ehr-app>
  #shadow-root (open)
    <iframe src="https://ui.example">
      #document <!-- other origin -->
        <dropdown-menu>
          #shadow-root (closed)
            <button>Choose...</button>

我们的状态启发式方法无法预见每一个网站。我们给了模型行动的自由,但它仍在透过我们的假设进行观察。

移除预定义状态文章图表

如果我们让它也编写观察结果呢?

我们让大语言模型直接访问 CDP,即 Chrome 开发者工具协议。没有强制性的可点击元素列表。它可以编写代码来检查 DOM、截图或查看某个框架内部。

Before, our extraction layer sent the model a fixed list of clickable elements. Now the model chooses its observations through CDP commands, and the browser returns the view it asked for.Before, our extraction layer sent the model a fixed list of clickable elements. Now the model chooses its observations through CDP commands, and the browser returns the view it asked for.
模型选择要检查什么。CDP 命令仅为示意。

浏览器仍然有状态。消失的是我们要求一切都符合一种预定义表示的规定。一张截图可能回答一个问题。一次 DOM 查询可能回答下一个问题。模型决定它需要看到什么。

为什么选择 CDP 而不是 Playwright?文章图表

CDP 是 Chrome 的原生控制协议。模型可以直接使用它。

With Playwright, agent code reaches Chrome through an extra layer above CDP. Browser Harness exposes CDP directly to the agent's code, removing the Playwright layer while retaining the connection and runtime.With Playwright, agent code reaches Chrome through an extra layer above CDP. Browser Harness exposes CDP directly to the agent's code, removing the Playwright layer while retaining the connection and runtime.
对于 Chrome,CDP 让模型能够访问 Playwright 浏览器 API 之下的内容。

Playwright 增加了一些假设,例如 无法看到已关闭 shadow root 的定位器。CDP 可以 直接检查这些 root。Playwright 也暴露了 CDP;我们将直接访问设为默认。

一个简单的浏览器框架文章图表

Pi、Codex 和 OpenCode 已经处理了智能体循环。编码智能体拥有数百万用户,尝试各种各样的工作。这种测试是复用它们框架的一个理由。

进行到第五个小时质量保证的智能体,不应该因为循环中的一个 bug 而失败。我们曾遇到过压缩产生如此多的上下文,以至于立即再次触发压缩的情况。我们的客户不应该不得不去发现这些 bug。

我们添加了一个简单的浏览器工具:持久化的代码,文本、截图和错误会返回给模型。

Pi, Codex or OpenCode exchanges code and results with browser_exec, which communicates with Chrome through CDP.Pi, Codex or OpenCode exchanges code and results with browser_exec, which communicates with Chrome through CDP.
CLI 或工具调用将智能体连接到 CDP。

从我们 2026 年 1 月的 Agent SDK 到 4 月的 Browser Harness,这成为了方向。Browser Harness、BrowserCode 和 Browser Use Pi 采取了不同的方法。它们都让模型选择要看什么、做什么。

这里的苦涩教训究竟是什么?文章图表

Sutton 的苦涩教训青睐那些随计算量增加而改进的通用方法。对我们而言:

  • 复用经过验证的智能体框架。
  • 暴露模型能够良好使用的最简单的底层接口。
  • 让模型选择它的观察和行动。

浏览器、计算机、文本、音乐:同样的原则适用。随着模型的变化,重新思考框架。

阅读显示设置

调整正文排版

当前浏览器记住选择,应用于文章正文。手机上正文宽度以屏幕可用空间为限。

图表完整性提示

普通文章遇到图表保存问题时显示提示。