browser-use:让 LLM 直接操控浏览器的 Python Agent 框架
browser-use 用自然语言指令驱动浏览器完成点击、填表与信息提取。
一句「Find the number of stars of the browser-use repo」,程序打开浏览器、访问页面、读取数字、返回结果——中间没有一行选择器,没有一个 page.click()。这是 browser-use 想让你习惯的编程方式:把「怎么做」交给模型,你只描述「做什么」。
但真正值得拆的不是这个演示,而是它为了让这件事在生产环境里成立,堆了多少层东西。
三条路径,一个内核
README 一上来就把产品拆成三条入口,这个划分本身就说明了项目的定位——它不是「一个库」,而是「一个浏览器 Agent 能力」的三种交付形态:
| 路径 | 形态 | 谁在跑 Agent | 浏览器在哪 | 典型使用者 |
|---|---|---|---|---|
| Path 1 | Fully Hosted Cloud | Browser Use 云端 | 云端(stealth、住宅代理、验证码求解) | 要规模化跑任务、不想管基础设施的团队 |
| Path 2 | CLI | 你已有的 Agent(Claude Code、Codex、Cursor 等) | 本地或云端 | 想给自己手上的编码 Agent 加一双「手」的开发者 |
| Path 3 | Python Library | 你自己的 Python 进程 | 本地 Chrome 或云端 | 要把 Agent 嵌进自己应用的工程师 |
关键区别在 FAQ 里写得很清楚:cloud browser 托管的是浏览器,fully hosted API 连 Agent 一起托管。也就是说,Path 3 里你换成 Browser(use_cloud=True),变化的是「浏览器跑在哪」,Agent 的推理循环仍然在你自己的进程里;而 Path 1 是连这个循环都不用你写。
这三条路径共享同一个内核:一个由 LLM 驱动的「观察—决策—动作」循环。下面按 Path 3 的代码把它拆开。
循环里到底有什么
从 README 的 quickstart 能直接读出四个核心组件,它们构成了 Agent 的最小骨架:
pythonimport asyncio from browser_use import Agent, Browser, ChatBrowserUse, ChatOpenAI from dotenv import load_dotenv load_dotenv() async def main(): llm = ChatOpenAI(model='gpt-5.6-luna', reasoning_effort='xhigh') # llm = ChatBrowserUse(model='bu-2-0') # Use BU2 instead; requires BROWSER_USE_API_KEY agent = Agent( task="Find the number of stars of the browser-use repo", llm=llm, # browser=Browser(use_cloud=True), # Use a cloud browser; requires BROWSER_USE_API_KEY ) history = await agent.run() print(history.final_result()) if __name__ == "__main__": asyncio.run(main())
四个组件各自的位置:
Agent:编排者。持有task(自然语言目标)、llm(决策模型)、browser(执行环境),暴露run()返回一个history对象。注意返回值不是字符串而是history——说明它保留的是完整执行轨迹,final_result()只是从中取最终答案。这个设计对调试很重要:任务失败时你能回看每一步。llm:决策层。README 给了两条路线,ChatOpenAI走任意第三方模型,ChatBrowserUse(model='bu-2-0')走自研的 BU2。两者接口对齐,替换只改一行。Browser:执行层。Browser(use_cloud=True)是唯一的开关,决定浏览器是本地起还是连云端。README 明确写了云端「no Chrome to install; works in Docker, CI, and serverless」——这是它存在的主要理由,不是性能,是部署形态。history:结果层。承载轨迹与最终输出。
一次 await agent.run() 内部的流转,按 README 的功能描述可以归纳成这样的分层:
- 任务层:
task字符串进入 Agent,成为整个循环的目标约束。 - 感知层:浏览器把当前页面状态(DOM、可交互元素)整理成模型能读的表示,喂给 LLM。这是整个项目最脏最难的活——网页是给人看的,不是给模型看的。
- 决策层:LLM 基于任务 + 当前页面状态,输出下一步动作。
- 动作层:动作被执行到浏览器上(点击、输入、导航等),页面状态改变,回到第 2 步。
- 终止层:模型判断任务完成,结果写入
history,final_result()可取。
这个循环没有魔法,难点全在「感知层怎么把网页压成模型能消化的上下文」和「动作层怎么保证执行可靠」——README 没有展开这两块的具体实现,但从它反复强调的能力(stealth、CAPTCHA solving、residential proxies)能反推出:真实网页上的失败大多不是模型不够聪明,而是被反爬挡住、被验证码卡住、被环境差异绊住。
换模型只是换一行,换浏览器也只是换一行
这套抽象的设计意图很明确:把「智能」和「环境」这两个变量解耦。
模型侧,README 的 FAQ 说 ChatBrowserUse 接受带 provider 前缀的模型 ID,也就是说 Claude、GPT、Gemini 都能通过同一个入口调用。官方推荐的是自家的 BU2,理由是「optimized for browser automation」,并指向 model card 和 benchmark 做对比。这里要诚实:README 里没有给出任何具体的成功率数字,只提到 BU Bench V2 是一个「very hard benchmark」,展示的是 60 个任务的子集结果。要选模型,得自己去看那份 benchmark。
环境侧,Browser 的三种形态覆盖了从本地调试到无头部署的全谱:
| 浏览器形态 | 配置方式 | 前置条件 | 适用场景 |
|---|---|---|---|
| 本地浏览器 | 默认(不传 browser) | 本机装有 Chrome | 开发调试、需要登录态 |
| 云端浏览器 | Browser(use_cloud=True) | BROWSER_USE_API_KEY | Docker、CI、serverless |
| 已有远程浏览器 | 通过 CDP 连接 | 一个可连的 CDP 端点 | 复用已开着的浏览器会话 |
第三行来自 README 对 Claude toolsets 集成的描述:「can control a local browser, a Browser Use Cloud browser, or an existing remote browser over CDP」。CDP 这个关键词也出现在仓库 topics 里,说明它不是附带能力,而是底层协议。
云端浏览器的定价 README 写得很直白:$0.02 per browser-hour plus network traffic。这个数字反复出现(官网描述里也是 $0.02/hour),可以放心引用。它附带的能力清单是:stealth、住宅代理、验证码求解、live view URL。live view 这一项对调试很实用——你能实时看到 Agent 在页面上干什么。
当 Claude 需要一个浏览器
README 里有一段容易被略过但信息量很大的内容:Browser Use 为 Claude 提供了官方维护的 toolset 集成。
它的定位很清晰——Claude 是大脑,Browser Use 是手。README 说 Browser Use 实现了全部 31 个 browser actions,通过 Anthropic SDK 暴露给 Claude 调用,另外还带一个 Bash 工具用于处理数据和写文件。架构图上标明了分工:浏览器可以本地也可以远程,但 Bash 跑在 SDK 所在的主机上。
pythonimport os from anthropic import AsyncAnthropic from browser_use.integrations.toolsets_for_claude import Bash, BrowserUse task = 'Open example.com and report its page title.' driver = BrowserUse() # Or BrowserUse(use_cloud=True) bash = Bash(output_dir='outputs') async with driver, AsyncAnthropic() as client: runner = client.beta.messages.tool_runner( model=os.environ['ANTHROPIC_MODEL'], max_tokens=32_768, max_iterations=100, tools=[driver, bash], messages=[{'role': 'user', 'content': task}], ) result = await runner.until_done()
这段代码值得注意的地方有三个。第一,BrowserUse 和 Bash 都是上下文管理器,async with driver 负责资源的建立与释放——浏览器是有状态的重资源,这个约束是必要的。第二,max_iterations=100 是硬性护栏,防止 Agent 在某个页面上无限打转。第三,Bash 要求 Linux 或 macOS 上有 /bin/bash,Windows 得走 WSL——这是个真实的部署约束,不是可选项。
这个集成的意义在于:它把 browser-use 从一个「自己带 LLM 的框架」变成了「别人的 Agent 可以调用的能力层」。Path 2 的 CLI 是同一个思路的另一种包装——README 让你把一段安装 prompt 直接粘给 Claude Code、Codex、Cursor 之类的工具,让它们自己把 browser-use 装好并连上浏览器。它甚至准备了失败兜底:装不上就去看 browser-harness 的 install.md。
和同主题项目比,它站在哪
把几个同主题项目摆在一起,定位差异比单个项目的功能列表更能说明问题:
| 项目 | 语言 | 核心抽象 | 解决的核心问题 | 与 browser-use 的差异 |
|---|---|---|---|---|
| browser-use | Python | Agent + Browser + LLM 三元组 | 让模型直接操作真实网页 | 唯一以「浏览器」为第一公民,环境问题(stealth/代理/验证码)是产品的一部分 |
| deepseek-harness | TypeScript | 插件 | 按需组装 Agent 能力 | 通用编排框架,浏览器只是它可能接入的众多工具之一 |
| graphify | Python | 知识图谱 | 让 Agent 读懂代码库全貌 | 解决的是「上下文从哪来」,browser-use 解决的是「动作往哪去」 |
| TradingAgents | Python | 多角色 Agent 协作 | 金融决策的辩论式推理 | 垂直领域多 Agent,browser-use 是单 Agent 的通用执行层 |
| rea | TypeScript | 逆向分析 Agent | 从行为到二进制的安全分析 | 同样是「Agent 操作系统」,但目标是闭源程序而非网页 |
最能说明问题的是和 deepseek-harness 的对比。后者把工具调用、prompt 编排都拆成插件,本质是一个组装框架——它不关心你的工具是浏览器还是数据库,只关心怎么把它们拼起来。browser-use 反过来:它把浏览器这一件事做到很深,深到连「怎么绕过反爬」「怎么解验证码」都做成了产品的一部分。
这也是为什么它的 topics 里同时有 playwright 和 cdp、stealth-browser、cloud-browser、remote-browser。Playwright 是通用的浏览器自动化库,browser-use 站在它(或类似的 CDP 层)之上,把「写脚本」换成「下指令」。它没有取代 Playwright,而是给 Playwright 加了一个会思考的上层。
它适合谁,不适合谁
从 README 的三条路径反推,适用边界其实很清楚。
适合:任务目标能用一句话描述、但执行路径依赖页面实时状态的场景——订一个驾考时间(README 首页的演示就是「handle the CAPTCHA, and book a driving test」)、在多个站点采集结构化信息、给已有的编码 Agent 补上「打开网页看看」的能力。这类任务的共同点是你写不出稳定的选择器,或者写出来也很快会失效。
不太适合:需要确定性、可重放、零成本的批处理。每跑一次都要过一遍 LLM,成本和延迟都是硬开销;云端浏览器按 $0.02/小时计费,流量另算。如果你的目标页面结构稳定、路径固定,手写脚本仍然更快更便宜。
部署上要注意:Python 版本要求 >= 3.11,README 的示例用 uv 管理并建议 --python 3.12。没有本地 Chrome 的环境(Docker、CI、serverless)必须切到云端浏览器,也就必须有 BROWSER_USE_API_KEY。想用 BU2 模型同样需要这个 key。换句话说,纯本地、纯第三方模型的组合是可行的,但只要想要官方优化的模型或托管浏览器,就得接上它的云服务——这也是这个开源项目与其商业产品之间的接缝所在。
项目坐标
先把硬数据摆出来:
- 源码:github.com/browser-use/browser-use
- 官网:browser-use.com
- 许可:MIT
- 语言:Python(README 提到同时提供 TypeScript 版本)
- 星标 118341 · forks 13127 · open issues 568
- 仓库创建于 2024-10-31,最近推送 2026-10-17
MIT 许可 + 上万 forks + 持续推送,说明它既被大量使用也被大量改造。568 个 open issues 对一个这个量级的项目不算异常,但也提示你:真实网页的边界情况是无穷的,这个领域没有「装好就不用管」的状态。
如果只记一件事:browser-use 的价值不在于「让 LLM 点按钮」这个演示,而在于它把浏览器 Agent 落地时那些不体面的部分——反爬、验证码、代理、无头环境、模型选型——都收进了同一套抽象里。Agent、Browser、ChatOpenAI/ChatBrowserUse 三个名字,就是它给你的全部接口面。剩下的复杂度,它替你扛了,也替它自己定价了。