跳到主要内容

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:

  1. 环境变量 BROWSER_USE_TERMINAL_BINARY;
  2. browser-use-core pip 包打包的二进制(_find_packaged_browser_use_terminal_binary,beta/service.py:212,从 browser_use_core.binary_path 取);
  3. ~/.browser-use-terminal / ~/.local/bin 下的安装;
  4. PATH 里的。

找不到就报错,提示用 curl -fsSL https://browser-use.com/terminal/install.sh | sh 安装(beta/service.py:206)。注意 pyproject.toml[core] extra 装的就是 browser-use-core==0.13.2(限定平台,pyproject.toml:60)——这是个平台相关的预编译包,源码不在这个 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)单独走:methodagent.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 怎么用它

betaAgent(beta/service.py:4226)对外 API 和经典版几乎一样(task + llm + browser_profile),run()(beta/service.py:5019)内部分两条路:

  • _run_terminal(beta/service.py:5041):跑交互式终端模式;
  • _run_sdk_agent(beta/service.py:5189):用上面的 RustSdkClient 以 SDK server 模式驱动 Rust 核心。

它复用了经典版的很多 view/事件类型(AgentOutputActionResult、各 cloud_events,见 beta/service.py:31-55 的 import),并有 _CloudEventAgentProxy(beta/service.py:4147)把 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.pyfind_browser_use_terminal_binary
JSON-RPC 客户端beta/service.pyRustSdkClientRustSdkClient.call_handle_message
beta 入口beta/service.pyAgentAgent.run_run_sdk_agent_run_terminal
错误类型beta/service.pyRustSdkJsonRpcErrorBetaAgentError
懒加载导出beta/__init__.py_LAZY_IMPORTS
core 包声明pyproject.toml[project.optional-dependencies].corebrowser-use-core