数据截至 (上游 commit 898f23f0b672)
05 · beta 架构:Python 薄壳 + Rust 核心
本章讲 0.13 引入的新路线
from browser_use.beta import Agent。它和经典版完全不同:Python 这边只是个客户端,真正的浏览器操作循环跑在一个 Rust 编译出来的二进制browser-use-terminal里。诚实声明:Rust 核心不在本仓库,所以本章只能讲清 Python 侧怎么驱动它。
5.1 它要解决的小问题
README 给出的理由(README.md):0.13 的 beta agent「powered by a Rust core and a browser harness built for current frontier models」,给模型一个真实的浏览器/电脑动作空间、持久工具、像编码 agent 那样的恢复循环。一句话:把性能敏感、需要紧密控制浏览器的核心循环下沉到 Rust。
架构口号(README):
Python API -> Rust core -> Browser harness -> Web task done
5.2 怎么找到那个二进制
find_browser_use_terminal_binary(beta/service.py:186)按优先级找 browser-use-terminal:
- 环境变量
BROWSER_USE_TERMINAL_BINARY; - 随
browser-use-corepip 包打包的二进制(_find_packaged_browser_use_terminal_binary,beta/service.py:212,从browser_use_core.binary_path取); ~/.browser-use-terminal/~/.local/bin下的安装;PATH里的。
找不到就报错,提示用 curl -fsSL https://browser-use.com/terminal/install.sh | sh 安装(beta/service.py:206)。注意 pyproject.toml 里 [core] extra 装的就是 browser-use-core==0.13.3(限定平台,pyproject.toml:62-66)——这是个平台相关的预编译包,源码不在这个 Python 仓库。
5.3 通信:stdio 上的 JSON-RPC
RustSdkClient(beta/service.py:323)是「最小的 stdio JSON-RPC 客户端」。它 spawn 子进程,用 stdin 发请求、stdout 收响应:
Python (RustSdkClient) Rust (browser-use-terminal sdk-server)
│ │
│ start(): create_subprocess_exec │
│ stdin/stdout/stderr = PIPE ───────────►│ 启动 sdk-server
│ │
│ call(method, params): │
│ 写 {jsonrpc,id,method,params}\n ──────────►│ 处理
│ await future │
│◄────────── {jsonrpc,id,result} 一行 JSON ────│
│ │
│ notifications(agent.event / ───────────────│ 流式推进度
│ agent.projected_event) ◄───────────│
机制要点:
- 请求/响应配对:每个请求一个自增
id,挂一个Future在_pending[id];读到带相同id的响应就set_result/set_exception(beta/service.py:485-505)。call()在beta/service.py:364。 - 按行解析:stdout 是一行一个 JSON 对象,
_read_stdout按\n切(beta/service.py:417),有 64MB 流上限、512MB 单行上限的保护(beta/service.py:338-340)。 - 通知(notification)单独走:
method为agent.event/agent.projected_event且无id的消息,进notification_queue(beta/service.py:476),这是 Rust 核心向 Python 流式推送步骤进度的通道。 - 错误:Rust 返回的
error对象包成RustSdkJsonRpcError(beta/service.py:314)。子进程提前退出会_fail_all把所有挂起的 future 用 stderr 末尾内容报错(beta/service.py:444)。
5.4 beta.Agent 怎么用它
beta 的 Agent(beta/service.py:4236)对外 API 和经典版几乎一样(task + llm + browser_profile),run()(beta/service.py:5030)内部分两条路:
_run_terminal(beta/service.py:5052):跑交互式终端模式;_run_sdk_agent(beta/service.py:5200):用上面的RustSdkClient以 SDK server 模式驱动 Rust 核心。
它复用了经典版的很多 view/事件类型(AgentOutput、ActionResult、各 cloud_events,见 beta/service.py:31-55 的 import),并有 _CloudEventAgentProxy(beta/service.py:4157)把 Rust 推来的事件适配成统一的云端事件。LLM 适配器也共用(beta/__init__.py 懒加载 ChatOpenAI/ChatAnthropic/ChatBrowserUse 等)。
5.5 诚实的边界
- 看不到 Rust 核心的动作循环。 「DOM 怎么序列化、点击怎么落地」在 beta 路线里发生在 Rust 二进制内部,本仓库无源码。本套文档 §01–§04 描述的是经典 Python 路线的实现;beta 路线的等价逻辑只能从 JSON-RPC 的方法名和事件名旁推(本段为 inferred)。
- 想读原理,读经典版。 如果目的是理解「DOM agent 怎么工作」,经典
browser_use/agent+browser_use/dom+browser_use/tools+browser_use/browser是完整可读的;beta 是工程化/性能化的外包层。
5.6 代码地图
| 主题 | 文件 | 符号 |
|---|---|---|
| 找二进制 | beta/service.py | find_browser_use_terminal_binary |
| JSON-RPC 客户端 | beta/service.py | RustSdkClient、RustSdkClient.call、_handle_message |
| beta 入口 | beta/service.py | Agent、Agent.run、_run_sdk_agent、_run_terminal |
| 错误类型 | beta/service.py | RustSdkJsonRpcError、BetaAgentError |
| 懒加载导出 | beta/__init__.py | _LAZY_IMPORTS |
| core 包声明 | pyproject.toml | [project.optional-dependencies].core → browser-use-core |