browser-use

一句话定位

browser-use 是一个 104k star 的开源自主浏览器操作 agent:通过 CDP(Chrome DevTools Protocol)直接驱动真实 Chromium,把「索引化的可交互 DOM 元素 + 截图」喂给通用 LLM,LLM 每步输出结构化 JSON(thinking / evaluation_previous_goal / memory / next_goal / action[]),逐动作执行。与 Anthropic computer-use 的核心分野在于它不是纯像素点击:给每个可交互元素编号 [index],动作用 click(index) 按元素定位,截图仅作 vision ground-truth 校验——因此对 vision 精度依赖低,甚至可在 use_vision=False 下靠纯 DOM 文本运行。它是单 agent 架构,配一条自研浏览器专用微调模型链路(bu-2-0)与闭源云侧(sync/skills/sandbox/微调)。本文所有源码引用基于 commit f78585575905b11692186783c770f5f3f2feeb9a

核心架构总览(目录结构关键路径 + 引用的 commit)

分析基于 commit f78585575905b11692186783c770f5f3f2feeb9a2026-07-09 11:17:12 -0700 Restructure README quickstart: CLI and Python library paths (#5176)git clone --depth 1 浅克隆)。纯 Python,browser_use/ 包约 65k 行。

关键路径:

browser_use/
  agent/
    service.py                    # Agent 主类(4144 行):run/step 主循环、multi_act、judge、pause/resume、rerun
    prompts.py                    # SystemPrompt 模板选择 + AgentMessagePrompt(每步 user message 组装)
    views.py                      # AgentSettings、AgentOutput schema、ActionResult
    judge.py                      # LLM-as-judge trace 评估(225 行)
    system_prompts/system_prompt.md   # 默认 system prompt(另有 8 个变体)
    message_manager/service.py    # 上下文/记忆管理、压缩、sensitive data 过滤(597 行)
  tools/
    service.py                    # Tools 类:26 个内置 action + act() dispatch(2313 行)
    registry/service.py           # Registry:@action 装饰器、动态 param model、execute_action(611 行)
  skills/service.py               # 云端 hosted skills 拉取/执行(285 行)
  sandbox/sandbox.py              # @sandbox 装饰器,cloudpickle 远程执行(669 行)
  mcp/{server,client,controller}.py   # MCP 双角色(server 1287 行)
  sync/service.py + telemetry/service.py   # 云 sync + PostHog 遥测
  browser/watchdogs/security_watchdog.py   # allowed_domains 导航拦截
  browser/profile.py              # allowed/prohibited_domains、block_ip_addresses 配置
  llm/                            # 15+ provider 统一 BaseChatModel;llm/browser_use/ 为自研 bu-2-0
  dom/serializer/ + dom/views.py  # CDP DOM 快照 → 带 [index] 的 XML 文本(llm_representation)
skills/                          # 顶层:给编码 agent 用的 Anthropic-style Skill 文档(≠运行时能力)

另有 browser_use/beta/service.py(并行的新版 agent 实现,复用同一 judge/message_manager);一手文档还含仓库根 AGENTS.md(38KB)、CLAUDE.md(11KB)、CLOUD.md(75KB)。

Agent Loop(主循环 / 何时继续何时停)

入口 Agent.run(max_steps=500)agent/service.py:2493),while self.state.n_steps <= max_steps:2590)逐步调 _execute_stepstep()

单步 step()service.py:1027)三阶段:

  • Phase 0 captcha 等待(:1038,captcha 由 watchdog 自动解)。
  • Phase 1 _prepare_context:1079):取 browser state(DOM + 截图)、更新 page-specific action models、message_manager 组装 state message、注入各种 nudge(loop 检测 / replan / exploration)。
  • Phase 2 _get_next_action(LLM 调用,带 llm_timeout 超时,:1167)→ _execute_actionsmulti_act
  • Phase 3 _post_process(下载检查、loop 检测、失败计数)。

何时停:2600 一带):

  1. LLM 主动调 done action(is_done=True)→ break。
  2. consecutive_failures >= max_failures(默认 5) + int(final_response_after_failure)(1),即连续失败达阈值(:2600,阈值计算见 :1289 max_total_failures)。
  3. state.stopped(外部 stop)。
  4. 达到 max_steps(追加一条 error history)。

强制收尾_force_done_after_last_step:1560)在最后一步把可用工具限制为仅 done(切换 self.AgentOutput = self.DoneAgentOutput);_force_done_after_failure:1571,逻辑在 :1574)失败达上限后同样强制 done 做「最后一次回复」(msg = 'You failed N times. Therefore we terminate the agent.')。

单步内多动作 / 批处理multi_act:2720)一步可执行多个 action,但有两层 page-change guard(源码注释在 :2724)——(1) 静态标记 terminates_sequence=True(navigate / search / go_back / switch),执行后跳过队列剩余动作(判定在 :2806);(2) 运行时对比动作前后 URL + focus target,变了就中断剩余。done 只允许作为单动作。

失败恢复:_handle_step_error:1250)区分 InterruptedError / 连接类错误(尝试 reconnect,:1261)/ 普通错误(记为 ActionResult(error)consecutive_failures += 1:1291);成功一步则清零(:1232-1234)。

记忆与上下文管理(压缩、长期记忆、会话持久化)

核心设计不是无限追加消息列表。每步 message_manager 重建 单条 system message + 单条 state message + 若干 context messagemessage_manager/service.py_set_message_with_type / get_messages)。历史以文本描述形式塞进 state message 的 <agent_history>,而非多轮对话累积。

  • agent_history_items:每步一个 HistoryItem(含 eval_previous_goal / memory / next_goal / action_results),agent_history_description:150)拼成文本;超过 max_history_items 时保留首项 + [... N previous steps omitted ...] + 最近 N-1 项(:162-186)。
  • 压缩maybe_compact_messages:213)双闸门触发——step 间隔 compact_every_n_steps + 字符下限 trigger_char_count(默认 40000)。用一个 compaction LLM(可单配,默认 page_extraction_llm 或主 llm)把旧历史总结成 <compacted_memory> 块,保留首项 + 最近 keep_last_items 项。压缩 prompt 强调「只有见到显式成功确认才标 completed,否则标 IN-PROGRESS,禁止推断完成」(:259-267);压缩记忆在 prompt 里带免责注释「treat as unverified」(:155-160)。
  • 模型自管上下文(LLM 主动记忆):Agent 持有一个持久 FileSystembrowser_use/filesystem/file_system.py),system prompt 引导模型用 todo.md(checklist)、results.md 累积结果;write_file / read_file / replace_file 都是 action。这是「让模型自己决定什么留在 context」的显式机制(system prompt <file_system> 段 + AGENTS.md 强调)。
  • read_stateextract / read_file 的一次性输出放 <read_state>,只在当前步展示,图片放 read_state_images:313-330)。
  • 只带当前截图:默认不堆叠历史截图,create_state_messages 只放当前步截图(use_vision=True 时),历史步靠文本(:446-472)。
  • 会话持久化 / 恢复AgentState / MessageManagerState 可序列化;save_history / load_and_rerun:3862,:3892);add_new_task:188)支持在已有会话上追加 follow-up 任务(包成 <follow_up_user_request>)。跨 run 的长期经验库不存在(记忆只在单 run 内)。

工具体系(定义/调用协议/注册/权限)

注册Registry.action(description, param_model=None, domains=None, terminates_sequence=False) 装饰器(tools/registry/service.py:291)。_normalize_action_function_signature:75)把任意签名规范化,区分「action 业务参数」(自动生成或显式 pydantic param_model)与「特殊注入参数」(browser_session / cdp_client / page_extraction_llm / file_system / available_file_paths / has_sensitive_data / page_url / extraction_schema,见 _get_special_param_types :57)。用户可注册任意 Python 函数为 action。

调用协议:LLM 用结构化输出返回 action: [{tool_name: {params}}]create_action_model:517)把所有已注册 action 拼成一个 pydantic Union schema 塞给 LLM 的 structured output / tool calling。Tools.acttools/service.py:2164)按 model_dump(exclude_unset=True) 取 action 名 + params → registry.execute_action:331)→ pydantic 校验 → 注入特殊 context → 调用。每 action 有 action_timeout(默认 180s,可用 BROWSER_USE_ACTION_TIMEOUT_S 调)。

26 个内置 actiontools/service.py,按 @self.registry.action 顺序):searchnavigatego_backwaitinputupload_fileswitch(tab)、close(tab)、extract(LLM 抽取整页)、search_pagefind_elements(CSS)、scrollsend_keysfind_textscreenshotsave_as_pdfdropdown_optionsselect_dropdownwrite_filereplace_fileread_fileevaluate(任意 JS)、done(thinking / no-thinking 两版)、click(两版)。

权限 / 过滤:action 可声明 domains(allowed_domains 别名),get_prompt_description(page_url) 按当前 URL 过滤出「page-specific actions」,只在匹配页面暴露给 LLM(_prepare_context 用之);exclude_actions 可禁用 action。

结果类型:统一 ActionResultextracted_content / long_term_memory / error / is_done / success / attachments / include_extracted_content_only_once / images / metadata)。

Prompt 设计(系统提示结构、动态组装)

system prompt 9 个变体agent/system_prompts/),由 SystemPrompt._load_prompt_templateprompts.py:60)按条件选:is_browser_use_model(用简化版 system_prompt_browser_use*.md,专给微调模型)、flash_mode(精简)、is_anthropic / Anthropic 4.5(需 ≥4096 token 命中 caching,_is_anthropic_4_5_model :17)、use_thinking。支持 override_system_message / extend_system_message;system message 带 cache=True

默认 system_prompt.md 段落结构:<intro> <language_settings> <input> <user_request> <agent_history> <browser_state>(详述 [index]<tag/> XML 格式 + *[ 表新元素 + |SCROLL|/|SHADOW| 前缀)<browser_vision>(声明截图是 ground truth)<browser_rules> <file_system> <planning> <task_completion_rules>(含 <pre_done_verification> 6 步自检)<action_rules> <efficiency_guidelines>(动作分类:page-changing 必须放最后)<reasoning_rules> <examples> <output>(严格 JSON schema)<critical_reminders> <error_recovery>

动态每步 user messageAgentMessagePrompt.get_user_message prompts.py:391)拼装顺序:<user_request> + <agent_history> + <agent_state>(file_system describe + todo_contents + plan + sensitive_data + available_file_paths)+ <browser_state>(page_stats + tabs + page_info「N pages above/below」+ 索引化交互元素文本 llm_representation + [Start/End of page] 标记)+ <read_state> + <page_specific_actions> + <step_info>(step 计数 + 日期,故意放末尾让前缀可缓存)。截图作为 ContentPartImageParam 附在文本后,带 vision_detail_level;整条 user message 也 cache=True

输出 schemaAgentOutputviews.py:382)字段 thinking / evaluation_previous_goal / memory / next_goal / current_plan_item(opt) / plan_update(opt) / action[]。flash_mode 去掉 thinking + eval + next_goal(type_with_custom_actions_flash_mode :458)。

Router / 编排(任务分解、多 agent、子 agent)

单 agent 架构,无内建多 agent / 子 agent orchestrationgrep subagent|orchestrat|delegate|multi.?agentbrowser_use/ 无实现命中)。

任务分解靠单 agent 内的轻量 planning:system prompt <planning> 段引导模型输出 plan_update(3-10 个 todo item)+ current_plan_item 指针;plan 状态标记 [x]/[>]/[ ]/[-] 回注 <plan>_render_plan_description / _update_plan_from_model_output)。这是「模型自己在 context 里维护 todo」,不是代码层多 agent。

子任务并行 / 多 agent 编排属于 Browser Use CloudCLOUD.md 里的 subagent guide skills/cloud/references/guides/subagent.md),开源库本体不含。

Skill / 插件体系

两套「skill」概念,别混淆

  1. 顶层 skills/(browser-use / cloud / open-source / qa / remote-browser / x402,每个含 SKILL.md)——这是给**编码 agent(如 Claude Code)**用 browser-use 的 Anthropic-style Skill 文档,不是 agent 自身运行时能力。
  2. browser_use/skills/(运行时 SkillService)——从 Browser Use 云 API 拉取 hosted skills(browser_use_sdk),skill_ids=['*'] 或指定 id。Agent._register_skills_as_actionsservice.py:828)在 run 开始时把每个 skill 动态注册成一个 agent action(slug 作 action 名,skill.parameters_pydantic 作 param model),handler 调 SkillService.execute_skill(带 browser cookies)。skill 缺 cookie 时 _get_unavailable_skills_info:916)把「不可用 skill + 需要哪些 cookie」注入 prompt 提示模型。

插件扩展:主要靠 Tools / Registry.action 自定义 action(用户注册任意 Python 函数)+ MCP(见「沙箱与执行隔离」旁述,mcp/ 双角色:既作 MCP server 暴露 browser-use,也作 MCP client 接外部工具)。无独立 plugin 加载框架。

自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)

无训练层自进化 / 跨会话学习记忆(memory 仅限单 run 内 FileSystem + compacted_memory,不跨 run 沉淀经验库)。

eval 驱动(离线 / 事后)judge.pyconstruct_judge_messagesLLM-as-judgeAgent._judge_traceservice.py:1585)/ _judge_and_log:1620)在 done 后对整条 trace(task + final_result + agent_steps + 最多 10 张截图 + 可选 ground_truth)打 verdict(true/false) + impossible_task + reached_captcha。关键设计:judge 结果不覆盖 agent 自报 success,两者都进遥测供 eval 平台对比(注释 :1621-1625)。这是评测,不是在线自纠错。

在线纠错在 prompt / loop 层:<pre_done_verification> 自检、consecutive_failures 计数、loop / replan / exploration nudge、evaluation_previous_goal 强制每步判定上一步成败(截图为 ground truth)。

结论:eval 基础设施完备(judge + ground_truth + 双写遥测),但没有把 trajectory 反哺进模型 / 记忆的开源闭环(那部分在云侧微调,见下)。

可观测性(日志 / trace 格式)

  • 本地日志:大量 emoji 结构化 logger(step / action 彩色打印,_log_action :2840);save_conversation_path:169,:1718)把每步「input messages + model output」落盘。
  • Laminar (lmnr) tracingbrowser_use/observability.py 提供 @observe / @observe_debug 装饰器,未装 lmnr 则 no-op;Tools.act 给每个 action 开 Laminar span(span_type='TOOL'tools/service.py:2189)。
  • 事件总线(bubus EventBus):run 中 dispatch CreateAgentSessionEvent / CreateAgentTaskEvent / CreateAgentStepEvent / UpdateAgentTaskEvent / CreateAgentOutputFileEventcloud_events.py)。
  • 云 syncsync/service.pyCloudSync 把上述 event POST 到 Browser Use cloud(需 device auth,sync/auth.py),CONFIG.BROWSER_USE_CLOUD_SYNC 控制。
  • 匿名遥测telemetry/service.pyProductTelemetry → PostHog(phc_...,eu.i.posthog.com),匿名 device_id。
  • 产物generate_gif:2694)把整条 history 渲成 agent_history.gif;token 用量走 token_cost_service.get_usage_summary

安全与权限(审批门、密钥管理)

  • 无交互式人工审批门(no human-in-the-loop approval gate):动作直接执行,靠 domain 白名单而非逐步确认(对比 Claude Code 的 permission prompt——browser-use 没有)。
  • 域名 gatingSecurityWatchdogbrowser/watchdogs/security_watchdog.py)拦截导航——_is_url_allowed:176)对照 browser_profile.allowed_domains / prohibited_domains / block_ip_addressesprofile.py:617)。被拦截的导航重定向到 about:blank(:60-69),或对显式 navigate action 抛 ValueError;支持 glob(会 warn)。
  • 敏感数据sensitive_data{domain: {key: value}}{key: value})。LLM 只见占位符名,用 <secret>name</secret> 标签;Registry._replace_sensitive_data:427)在执行时按当前 URL 域匹配才替换真值(match_url_with_domain_pattern),且只对 input action 暴露execute_action:378)。2FA:占位符后缀 bu_2fa_code 时用 pyotp.TOTP 现算验证码(:474)。发往 LLM 的 state message 反向 _filter_sensitive_datamessage_manager:573)把真值 redact 回占位符。
  • 其它 watchdog 安全面:permissions_watchdog、crash_watchdog、popups_watchdog(自动关 JS dialog)、captcha_watchdog(自动等 captcha)。
  • 密钥:API key 走环境变量(.env.example、各 llm provider);BROWSER_USE_API_KEY 给 SkillService / cloud。

沙箱与执行隔离

  • 本地:默认在本机启动 / 连接真实 Chromium(browser/chrome.pylocal_browser_watchdog),通过 CDP over WebSocket。不是进程级沙箱——就是普通子进程 Chromium,隔离靠 browser profile(独立 user data dir / storage_state)。
  • 远程沙箱(云)sandbox/sandbox.py@sandbox 装饰器(:215)——用 cloudpickle 序列化被装饰函数 + 其引用的 imports(_get_imports_used_in_function :65,AST 去装饰器 :50),POST 到远程 sandbox 服务,SSE 流式回传 log / result / browser-created 事件(views.py SSEEvent)。即「把一段 browser 自动化代码整体丢到云端隔离沙箱里跑」,是 Browser Use Cloud 的隔离执行路径,非本地默认。
  • Docker:仓库带 Dockerfile / Dockerfile.fast / docker/,容器化部署(非 per-task 沙箱)。

与模型的协同设计

  • 通用模型优先browser_use/llm/ 有 15+ provider(anthropic / openai / google / groq / aws / azure / deepseek / mistral / ollama / openrouter / cerebras / vercel / litellm / oci …),统一 BaseChatModel + structured output。
  • 自研微调模型 ChatBrowserUsellm/browser_use/chat.py):默认 model bu-2-0,走 Browser Use cloud API,「optimized models and prompts for browser automation」。配套 system_prompt_browser_use*.md(简化 prompt)+ request_type'agent' / 'judge',见 service.py:1606-1608:仅 ChatBrowserUse 传该参,其它 provider 不支持)+ session_id。→ 一条「自研浏览器专用模型 + 专用简化 prompt + 服务端优化」的协同链路。
  • prompt / 模型适配:按 provider 切 system prompt 变体(Anthropic caching 需 4096 token;flash_mode 精简;no_thinking 变体给不支持 / 不需要 reasoning 的模型);截图 vision detail、llm_screenshot_size resize、include_tool_call_examples 均可按模型调。
  • DOM→模型接口:核心协同是「索引化可交互元素」——dom/serializer/ 把 CDP DOM 快照简化成带 [index] 的 XML 文本(dom/views.pyllm_representation),截图上叠 bounding box + index 标号(browser/python_highlights.py),让模型用 index 而非坐标操作,大幅降低对 vision 精度依赖(与 computer-use 纯坐标点击的关键分野)。

轨迹利用(session/trajectory 是否反哺训练/评测)

  • 评测(明确):trajectory 直接喂 judge;ground_truth 支持监督式评测;judge verdict + 自报 success 双写遥测供 eval 平台对比。
  • 训练反哺(推断,闭源不可见):开源库本体不含训练代码;但轨迹经 CloudSync 上传(CreateAgentStepEvent 含每步 model output + 截图),配合自研 bu-2-0强烈暗示服务端用采集轨迹微调浏览器专用模型request_type='agent'system_prompt_browser_use.md 面向 fine-tuned 模型佐证),但该训练闭环在闭源云侧,仓库不可见。
  • rerun / 复用rerun_historyservice.py:3093)/ load_and_rerun:3862)可重放历史动作序列(AI step 回退用 get_ai_step_system_prompt),用于确定性回归 / 复现,属轨迹复用的一种。

与同类 harness 的关键差异(1-3 条)

  1. 元素索引 vs 像素坐标:给每个可交互元素编号 [index],动作 click(index) 按元素定位,截图仅作 ground-truth;对 vision 精度依赖低、更稳,可在 use_vision=False 下靠纯 DOM 文本运行。而 Anthropic computer-use / 通用桌面 agent 输出屏幕坐标点击。
  2. CDP 全页语义 vs 纯截屏:走 CDP 能读整页 DOM/HTML、执行任意 JS(evaluate)、CSS 选择器(find_elements)、结构化 extract、直接读 shadow DOM/iframe——信息比像素截图丰富得多。
  3. 浏览器专属生态 + 自研模型链路:tab / download / pdf / captcha / cookie / 域名白名单等浏览器专属 watchdog 与 action,配自研 bu-2-0 微调模型 + 云执行 / 隔离沙箱 / hosted skills,是同类 GUI agent 中少见的「开源库 + 闭源云 + 专用模型」三段式。

原始源码定位

  • repo: https://github.com/browser-use/browser-use
  • commit/version analyzed: f78585575905b11692186783c770f5f3f2feeb9a(2026-07-09,--depth 1 浅克隆,克隆日期 2026-07-11)
  • 关键文件列表(相对仓库根):
    • browser_use/agent/service.py(4144 行)
    • browser_use/agent/prompts.py(588 行)
    • browser_use/agent/system_prompts/system_prompt.md(+ 8 个变体)
    • browser_use/agent/message_manager/service.py(597 行)
    • browser_use/agent/views.py(1000 行)
    • browser_use/agent/judge.py(225 行)
    • browser_use/tools/service.py(2313 行,26 个 action)
    • browser_use/tools/registry/service.py(611 行)
    • browser_use/skills/service.py(285 行)
    • browser_use/sandbox/sandbox.py(669 行)
    • browser_use/mcp/{server.py(1287),client.py(548),controller.py(264)}
    • browser_use/sync/service.py(161)+ browser_use/telemetry/service.py(141)
    • browser_use/browser/watchdogs/security_watchdog.pybrowser_use/browser/profile.py
    • browser_use/llm/browser_use/chat.py(自研 bu-2-0)、browser_use/dom/serializer/ + browser_use/dom/views.py
    • 仓库根文档:AGENTS.mdCLAUDE.mdCLOUD.md

一手源存档(sources/)

保存于 /Users/zhao/projects/self-wiki/ai-research/sources/harness/browser-use/

  • NOTES.md — 第一阶段源码级调研笔记(本 dossier 唯一输入)
  • service.py(Agent 主循环 / multi_act / judge,163KB)
  • prompts.py
  • tools_service.py(26 个 action,92KB)
  • registry_service.py
  • message_manager_service.py
  • system_prompt.md(默认 system prompt)
  • judge.py
  • skills_service.py
  • sandbox.py
  • mcp_server.py