跳到正文
LangChain Blog·· 1 小时前精选AI 评分61

LangChain 如何为 Deep Agents 优化浏览器工具

How We Optimized Browser Use for Deep Agents

AI 导读

LangChain 为 Managed Deep Agents 的浏览器能力对比了七个工具集,最终选用 Browserbase 的 Stagehand 并基于 LangSmith trace 与评测持续改造。

推荐理由

LangChain 公开了为 Deep Agents 挑选并改造浏览器工具集的全过程,含七个工具集的成本与通过率对比,方法可迁移到其他 Agent 的上下文优化。

正文 · AI 翻译

浏览器智能体现在可以承担对人类来说既痛苦又耗时的多步骤工作。像Instinct和Meta的Muse这样的个人智能体可以规划横跨全国的公路旅行、取消未使用的订阅、发布二手车出售信息,而这一切都在没有公开API的网站上完成。DataDome仅9月份就发现智能体浏览器请求量增长了4.7倍。

浏览器使用在两个方面有帮助:API无法覆盖的操作,比如使用智能体未被配置过的网站,以及对编码智能体构建的Web应用进行端到端测试。无论哪种方式,智能体都需要两样东西:

  1. 工具来驱动浏览器:打开页面、读取页面并对其执行操作。大多数工具集通过Chrome DevTools Protocol(CDP)控制浏览器,该协议让工具能够检查和操控Chrome。
  2. 一个浏览器来驱动,可以是本地的或托管的。Managed Deep Agents让你无需运行任何基础设施即可在LangSmith中构建和部署智能体,它也能为你的智能体运行浏览器(更多内容见我们的发布文章)。像Browserbase这样的托管浏览器提供商为你处理开放网络中的棘手部分,比如CAPTCHA、机器人拦截以及大规模运行多个浏览器。

本文聚焦于工具,以及如何让工具足够好,使智能体能很好地使用浏览器。

我们着手为Managed Deep Agents中的智能体提供一个浏览器。我们比较了七种工具集,选出了最好的一个,即来自Browserbase的Stagehand(GitHub)。然后我们根据智能体在LangSmith追踪记录中的行为对其进行了改进,并通过评估验证了每一项改动。最大的收获是:通过工具设计来改进智能体的空间有多大。

浏览器使用带来上下文管理挑战

浏览器使用工具集有几种形式:原生工具、MCP服务器,或智能体在shell中运行的CLI。浏览器使用给这些工具带来了两个独特的挑战:

  • 任务耗时较长,涉及大量顺序工具调用。在Playwright MCP上,单个WebVoyager任务平均需要26个模型轮次。
  • 网页承载大量内容,而其中通常只有一小部分与任务相关。通过Browserbase托管MCP服务器进行一次导航,返回内容的中位数约为17,000个字符。

这两点都意味着浏览器工具必须高效地管理上下文。

我们如何测试这些工具

我们按照智能体开发生命周期进行迭代:在基准测试上运行智能体,在LangSmith中阅读其追踪记录以查看它在哪些地方浪费了步骤或token,修改工具,然后运行评估以检查改动是否有帮助。每次运行都是一个LangSmith实验,因此我们可以并排比较不同配置,并从任意数字点击进入其背后的追踪记录。

我们使用了三个基于真实网站任务的基准测试:

  • WebVoyager:涵盖Allrecipes、Amazon和Google Flights等热门网站的100个日常任务,使用Claude Sonnet 5.5运行,并由Jev评判器评分。它已相当饱和,这使其成为比较上下文使用、成本和速度的清晰方式。
  • HardBench:来自Browserbase的102个更难任务,由其自己的验证器评分,主要使用Claude Opus 5.5运行。
  • WebTailBench:来自微软的真实世界“长尾”任务,每个任务根据简短的评分标准打分。我们通过Stagehand评估运行了其中150个任务。

我们让每个测试框架都返回结构化输出(JSON 答案)。这样一来,像对要求表格的任务只回一行这样的格式失误,就不会算到它的浏览表现头上。我们将该选项上游贡献给了 Browserbase 的评测。

工具设计……太重要了

我们首先固定模型和任务,只改变工具集。这七个工具集在智能体调用它们的方式上有所不同:

  • 原生工具:每个动作一个工具,例如 click 或 navigate,一次调用一个(Playwright MCP、browser-use 和 Browserbase MCP)。
  • CLI:智能体在 shell 中运行浏览器命令(agent-browser 和 Browserbase 的 browse CLI)。
  • 代码模式:智能体编写调用浏览器的代码,因此一次调用可以执行多个步骤(Stagehand 工具,以及从代码中调用的 Browserbase MCP)。

WebVoyager results for seven toolsets on 100 tasks with Claude Sonnet 5.5.

WebVoyager 在 100 个任务上对七个工具集使用 Claude Sonnet 5.5 的结果。

每个工具集都通过了 78% 到 90% 的任务,但成本和速度差异很大。Stagehand 工具通过率最高(90%),总成本 1.98 美元,每个任务中位耗时 17.4 秒。Playwright MCP 通过率 78%,成本 26.71 美元,约为前者的 13 倍,每个任务耗时也是三倍(完整结果)。

Stagehand 为智能体提供三个工具:

  • snapshot 读取页面的无障碍树,并用 ID 标记可交互元素。
  • run 在页面上执行操作,可以是一批动作,如 click 和 fill,也可以是使用 Playwright 风格 page 对象的 JavaScript。
  • screenshot 捕获渲染后的页面。

这一差距在更难的任务上依然存在。在 HardBench 的 38 个核心任务上,Deep Agents 使用 Stagehand 的代码编写 run 工具通过了 30 个,使用 Browserbase 的命令式 browse CLI 通过了 21 个,而每个任务的成本是三倍。

Stagehand 是为智能体而构建的

早期的浏览器工具改造了像 Playwright 这样的测试 SDK。正如 Browserbase 所说,“Playwright 是为测试而构建的,我们为你的智能体构建了 Stagehand。” Browserbase 的 Stagehand v4 公告中的三个设计选择对我们影响最大:

  • 代码模式,因此一次工具调用可以执行多个浏览器步骤
  • 快照,页面可交互元素的紧凑文本视图
  • 更少的往返,通过在浏览器内部运行

代码模式让上下文保持精简

在代码模式中,智能体编写调用工具的代码,而不是一次调用一个工具(Browserbase 在 Code mode is all you need 和 Evolving computer use with code 中阐述了理由)。它同时解决了两个挑战:

  • 调用之间无需等待模型。浏览器步骤是顺序执行的,因此使用 run 时,智能体将整个链条(打开页面、填写字段、点击、检查)写成一个片段,它运行时无需在每个步骤之间做模型决策。
  • 中间上下文不会进入窗口。片段沿途接触的一切都保留在其变量中,只有智能体在浏览器交互后返回的内容才会进入上下文。

A deep agent books a table. On the left, the agent calls snapshot, which labels the page's interactive elements e3, e5, e7, and e9, then one run call with four actions. On the right, a cursor fills in party size, picks 7:00 PM, types the name Sydney, and clicks Reserve, and the page confirms the booking.

我们在选择 Stagehand 之前就看到了效果。在解释器中从代码调用 Browserbase 的 MCP 工具,而不是一次调用一个,将其成本降低了 4 倍(从 17.87 美元降至 4.52 美元)。

Stagehand 的 run 工具原生接受代码。它平均每个任务执行 10 个步骤,而 Playwright MCP 为 26 个;一次导航返回的中位字符数为 117 个,而 Browserbase 托管的 navigate 工具约为 17,000 个。

run 也接受 Playwright 风格的代码。模型在大量 Playwright 代码上训练过,所以这是它们写得最好的代码,Stagehand 的翻译器会把它编译成 Stagehand 命令。当我们尝试一个接受 Stagehand 原生 API 的 run 时,它通过的任务少了 5.3 个百分点,每个通过任务的成本高出 19%,即使工具描述准确也是如此。

快照表示可交互元素

读取页面是浏览器智能体最昂贵的操作之一。snapshot 返回页面的可访问性树,裁剪到智能体所需的部分,并为每个可交互元素附带一个 ID。这让智能体获得一个它能理解并直接操作的页面视图,就像 run 中的 {"op": "click", "id": "0-7"} 那样,因此它永远不必读取原始 HTML 或编写选择器来点击按钮。Browserbase 报告称 v4 的 token 效率比 Playwright 高约 80%。

主要通过 snapshot 而非 screenshot 读取页面,对上下文工程是一大胜利。树是智能体可以操作的紧凑文本,而截图是模型必须解读的图像,在我们的 WebTailBench 运行中每次调用中位数为 89 KB。不过,裁剪必须在源头进行。当我们事后将快照限制在 8,000 个字符时,智能体只是再次获取页面,每个通过任务的成本保持不变。

Stagehand's snapshot of the booking form from the earlier example (left) next to a screenshot of the same page (right). The Reserve button is [0-7] in the tree, the ID the agent uses to click it.

Stagehand 对前面示例中预订表单的快照(左)与同一页面的截图(右)并排。Reserve 按钮在树中是 [0-7],即智能体用来点击它的 ID。

浏览器往返次数被最小化

单个 Playwright click 是五次 CDP 调用:将元素滚动到视图中、读取其位置,然后鼠标移动、按下和释放(来源)。Playwright 在发送下一个请求之前等待每个响应,因此一次点击在智能体和浏览器之间产生五次往返。随着浏览器离智能体越来越远,从笔记本电脑到沙箱再到云端,这一成本会不断累积。

Stagehand v4 作为扩展在浏览器内运行,因此这些底层调用发生在页面旁边,而 run 在一次往返中发送整批操作。Browserbase 报告称 v4 在其基准测试中比 Playwright 快 2 倍。

Timeline comparison. With Playwright, three clicks take about 15 round trips between the agent process and the browser. With Stagehand, one run call sends all three clicks, they run inside the browser, and the result comes back in one round trip.

探索其他优化

选定 Stagehand 后,我们继续调整测试框架。最大的收益来自修复智能体等待页面加载的方式。

在 LangSmith 中阅读追踪记录时,我们看到智能体编写像 page.waitForTimeout(8000) 这样的固定休眠来等待页面加载。大多数页面在计时器结束前很久就已就绪,因此智能体在每次运行中大量时间无所事事。

因此我们修改了 run,让每次休眠在页面安静 500 毫秒后结束,且绝不晚于智能体请求的时间。在一次测量中,8 秒的休眠在 0.6 秒内返回。然后我们用评估检查了这一改动。在 HardBench 上,结合结构化答案和模型调用超时,它将智能体中位时间从 182 秒缩短到 124 秒,准确率在噪声范围内。

Before and after. With a fixed sleep, the agent waits the full 8 seconds even though the page went quiet almost right away. With the settle wait, the same waitForTimeout(8000) returns 500 ms after the page goes quiet, at 0.6 seconds, and the agent moves on.

Stagehand 此后已向上游提交了该修复。

结论

浏览器任务比大多数工作更能拉伸智能体的上下文。我们发现的最大收益来自工具,主要来自它们向模型返回多少内容以及它们需要多少轮次。

你可以在任何智能体上使用同样的流程。理解你的用例产生的上下文,然后用追踪和评估进行迭代。追踪显示智能体在哪里浪费步骤和 token,评估告诉你某项改动是否有帮助。

这些是 Managed Deep Agents 中浏览器背后的工具。为你的 agent 提供一个 Managed Deep Agents 中的浏览器,我们上周发布了它。

要在开源 Deep Agents 中使用相同的工具,请将来自 langchain-stagehand 的 StagehandMiddleware 添加到你的 agent 中:

from deepagents import create_deep_agent
from langchain_stagehand import StagehandMiddleware
from stagehand import Stagehand, local_browser

browser = await local_browser.launch(headless=True)
stagehand = await Stagehand.create(browser=browser)

agent = create_deep_agent(
    model="openai:gpt-5.5",
    middleware=[StagehandMiddleware(stagehand=stagehand)],
)

对于大规模浏览开放网络的 agent,请改用 browserbase.launch() 在 Browserbase 上启动浏览器。浏览器使用指南涵盖了其余内容,包括浏览器作用域以及在沙箱中测试应用。试一试,并告诉我们你构建了什么!

致谢

感谢 Baihao Wang 主导 HardBench 工作,为上游至 Stagehand 的优化提供了支持;也感谢 Browserbase 的 Sean McGuire、Miguel Gonzalez 和 Kyle Jeong 对 Stagehand 的帮助。

来源:LangChain Blog · langchain.com