1. 概述

在Browser-use框架中,核心任务是使大模型能够像人类一样操作浏览器。本文深入探讨大模型如何实际控制浏览器,重点解析从模型输出到浏览器动作执行的完整流程。

上一篇(公众号首发)-Browser-use AI自动化框架深度解析(二):提示词构造机制

2. 系统架构与数据流

Browser-use采用标准的Agent-Environment交互范式,以闭环反馈机制实现大模型与浏览器的交互:

┌────────────┐    状态提示词    ┌───────────┐
│ │ ───────────────> │ │
│ 浏览器环境 │ │ 大模型 │
│ │ <─────────────── │ │
└────────────┘ 结构化动作 └───────────┘

2.1 核心交互流程

  1. 状态获取:框架捕获当前浏览器状态,包括DOM结构、可交互元素和页面元数据
  2. 状态表示:将状态转换为结构化提示词注入大模型上下文
  3. 决策生成:大模型分析状态并生成结构化的动作计划
  4. 动作执行:框架解析动作计划并在浏览器中执行相应操作
  5. 结果反馈:执行结果和新状态反馈回大模型,进入下一轮迭代

这种基于状态-动作-反馈的迭代模式支持大模型进行多步骤任务规划和执行。

3. 大模型输出设计

大模型需要生成特定格式的JSON结构以实现对浏览器的控制,主要通过工具调用(Tool Calling)机制实现。

3.1 结构化输出示例

{
"current_state": {
"evaluation_previous_goal": "成功打开了百度首页",
"memory": "我正在执行搜索四川十大景点的任务。已完成第1步:打开百度首页。",
"next_goal": "在搜索框中输入'四川十大景点'"
},
"action": [
{
"input_text": {
"index": 5,
"text": "四川十大景点"
}
},
{
"click_element": {
"index": 6
}
}
]
}

3.2 输出结构解析

  1. current_state:任务状态信息

    • evaluation_previous_goal:上一步骤完成状态的评估
    • memory:工作记忆,存储任务关键信息
    • next_goal:规划的下一步目标
  2. action:动作序列

    • 支持单步多动作执行
    • 每个动作以键值对形式表示,键为动作名称,值为参数对象

      这种设计不仅规范了输出格式,还通过 memory 字段为大模型提供了上下文记忆能力,从而支持复杂任务的分解与执行。

3.3 Pydantic模型定义

Browser-use使用Pydantic模型定义输出结构,确保类型安全和参数验证:

def _setup_action_models(self):
class CurrentState(BaseModel):
evaluation_previous_goal: str = Field(
...,
description="评估上一步目标的完成情况"
)
memory: str = Field(
...,
description="记录重要信息,用于跟踪进度"
)
next_goal: str = Field(
...,
description="下一步要完成的具体目标"
) class AgentOutput(BaseModel):
current_state: CurrentState = Field(
...,
description="当前状态评估和下一步计划"
)
action: List[Dict[str, Dict[str, Any]]] = Field(
...,
description="要执行的动作列表"
) self.CurrentState = CurrentState
self.AgentOutput = AgentOutput

这些模型不仅用于验证输出合规性,还作为函数调用的JSON Schema,指导大模型生成规范化输出。

4. 工具调用机制

4.1 多模型适配策略

Browser-use支持多种工具调用方式,以适配不同的模型能力边界:

def _set_tool_calling_method(self) -> Optional[ToolCallingMethod]:
"""Set tool calling method based on model and provided setting"""
if self.settings.tool_calling_method == 'auto':
if 'gpt-' in self.model_name or 'claude-3' in self.model_name:
return 'function_calling'
elif 'Qwen' in self.model_name or 'deepseek' in self.model_name:
return 'raw'
else:
return None
return self.settings.tool_calling_method

4.2 调用方式分类

  1. 原始模式 (raw)

    • 适用于不支持原生工具调用的模型
    • 从文本输出中解析JSON结构
    • 实现方式:
    output = self.llm.invoke(input_messages)
    output.content = self._remove_think_tags(str(output.content))
    try:
    parsed_json = extract_json_from_model_output(output.content)
    parsed = self.AgentOutput(**parsed_json)
    except (ValueError, ValidationError) as e:
    raise ValueError('Could not parse response.')
  2. 函数调用 (function_calling)

    • 适用于支持工具调用的现代模型(OpenAI/Anthropic)
    • 利用模型原生工具调用接口
    • 实现方式:
    structured_llm = self.llm.with_structured_output(
    self.AgentOutput,
    include_raw=True,
    method=self.tool_calling_method
    )
    response: dict[str, Any] = await structured_llm.ainvoke(input_messages)
    parsed: AgentOutput | None = response['parsed']
  3. 结构化输出 (None)

    • 使用LangChain的结构化输出机制
    • 提供类型安全和验证
    • 兼容各种模型

5. 动作注册与执行系统

动作系统是Browser-use的核心组件,负责将大模型的意图转换为具体的浏览器操作。

5.1 动作注册机制

Browser-use使用装饰器模式实现动作注册:

class Controller(Generic[Context]):
def __init__(self):
self.registry = Registry() @self.registry.action('Go to URL', param_model=GoToUrlAction)
async def go_to_url(params: GoToUrlAction, browser: BrowserContext):
url = params.url
await browser.goto(url)
msg = f' Navigated to {url}'
logger.info(msg)
return ActionResult(extracted_content=msg, include_in_memory=True) @self.registry.action('Click on element', param_model=ClickElementAction)
async def click_element(params: ClickElementAction, browser: BrowserContext):
state = await browser.get_state()
element_node = state.element_tree.find_by_index(params.index) if not element_node:
msg = f' Could not find element with index {params.index}'
logger.warning(msg)
return ActionResult(error=msg, include_in_memory=True) await browser.click(element_node.xpath)
msg = f'️ Clicked on element [{params.index}] {element_node.text}'
logger.info(msg)
return ActionResult(extracted_content=msg, include_in_memory=True)

动作注册时需指定三个关键要素:

  1. 动作名称:用于在大模型输出中识别动作
  2. 参数模型:定义参数类型和验证规则
  3. 实现函数:执行具体浏览器操作的异步函数

    这些模型用于验证模型输出并生成函数调用的JSON模式,帮助大模型理解预期输出格式。

5.2 内置动作类型

Browser-use预定义了多种浏览器动作类型:

类别 动作 功能
导航类 go_to_url 导航到指定URL
back 返回上一页
forward 前进到下一页
refresh 刷新当前页面
交互类 click_element 点击页面元素
input_text 输入文本
select_option 选择下拉选项
scroll 滚动页面
标签页管理 open_tab 打开新标签页
switch_tab 切换标签页
close_tab 关闭当前标签页
内容提取 extract_content 提取页面内容
任务控制 done 标记任务完成

5.3 动作执行流程

动作执行由execute_actions方法实现,该方法处理参数解析、动作调度和错误处理:

async def execute_actions(
self,
actions: List[Dict[str, Dict[str, Any]]],
browser_context: BrowserContext,
agent_output: Optional[Any] = None,
llm: Optional[BaseChatModel] = None,
sensitive_data: Optional[Dict[str, str]] = None
) -> List[ActionResult]:
"""Execute a list of actions on the browser"""
results = [] for action in actions:
# 1. 解析动作类型和参数
action_type = list(action.keys())[0]
action_params = list(action.values())[0] # 2. 处理敏感数据
action_params = self._process_sensitive_data(action_params, sensitive_data) # 3. 查找动作处理函数
try:
action_handler = self.registry.get_action(action_type) # 4. 执行动作
result = await action_handler(
browser_context=browser_context,
**action_params
) # 5. 记录结果
results.append(result) except Exception as e:
# 6. 处理错误
error_traceback = traceback.format_exc()
results.append(ActionResult(error=error_traceback, include_in_memory=True)) return results

执行流程中的关键步骤:

  1. 解析动作类型和参数
  2. 处理敏感数据(如密码等)
  3. 从注册表中查找对应的动作处理函数
  4. 执行动作并获取结果
  5. 记录执行结果,处理可能出现的异常

6. 迭代执行与状态管理

Browser-use通过_run_iteration方法实现Agent的单步迭代执行,包含完整的状态捕获、动作生成和执行环节:

async def _run_iteration(self) -> Tuple[bool, bool]:
"""Run one iteration of the agent loop"""
# 1. 获取当前浏览器状态
state = await self.browser_context.get_state() # 2. 创建步骤信息
step_info = AgentStepInfo(
step_number=self.state.n_steps,
consecutive_failures=self.state.consecutive_failures,
) # 3. 将状态添加到消息管理器
self._message_manager.add_state_message(
state=state,
result=self.state.last_result,
step_info=step_info,
use_vision=self.settings.use_vision,
) # 4. 运行规划器(如果启用)
if self.settings.planner_llm and self.state.n_steps % self.settings.planner_interval == 0:
plan = await self._run_planner()
self._message_manager.add_plan(plan, position=-1) # 5. 获取消息历史
input_messages = self._message_manager.get_messages() # 6. 获取下一个动作
action_output = await self.get_next_action(input_messages) # 7. 保存状态和输出
self.state.last_state = state
self._message_manager.add_model_output(action_output) # 8. 检测是否完成任务
done = any(list(a.keys())[0] == 'done' for a in action_output.action)
if done:
return True, False # 9. 执行动作
results = await self.controller.execute_actions(
actions=action_output.action,
browser_context=self.browser_context,
agent_output=action_output,
llm=self.settings.page_extraction_llm or self.llm,
sensitive_data=self.sensitive_data
) # 10. 处理结果
self.state.last_result = results # 11. 检查结果是否包含错误
any_error = any(r.error for r in results) return False, any_error

这种迭代执行模式实现了完整的感知-决策-执行闭环,使大模型能够基于当前状态调整策略,处理动态变化的网页环境。

7. 元素选择与跟踪机制

7.1 基于索引的元素选择

Browser-use通过索引机制简化元素选择,大模型根据提示词中的元素索引选择交互对象:

Interactive elements from top layer of the current page inside the viewport:
[0]<input type="text" placeholder="搜索关键词">搜索</input>
[1]<button>搜索</button>
[2]<a href="https://example.com">链接文本</a>

大模型通过指定索引实现元素选择:

{
"click_element": {
"index": 1
}
}

7.2 智能元素跟踪

为应对动态网页中元素位置的变化,Browser-use实现了元素跟踪机制:

async def _update_action_indices(
self,
historical_element: Optional[DOMHistoryElement],
action: ActionModel,
current_state: BrowserState,
) -> Optional[ActionModel]:
"""
更新动作索引以匹配当前页面状态。
如果找不到元素,返回None。
"""
if not historical_element or not current_state.element_tree:
return action # 在当前元素树中查找历史元素
current_element = HistoryTreeProcessor.find_history_element_in_tree(
historical_element,
current_state.element_tree
) if not current_element or current_element.highlight_index is None:
return None # 如果索引变化了,更新动作索引
old_index = action.get_index()
if old_index != current_element.highlight_index:
action.set_index(current_element.highlight_index)
logger.info(f'元素在DOM中移动,索引从{old_index}更新为{current_element.highlight_index}') return action

元素跟踪的核心逻辑:

  1. 保存历史元素的关键属性(XPath、属性、文本等)
  2. 在新状态中查找匹配度最高的元素
  3. 自动更新动作索引以适应元素位置变化
  4. 处理元素消失的情况并提供错误反馈

这一机制使Browser-use具备适应动态网页的能力,提高任务执行的稳定性。

8. 可扩展性与自定义动作

8.1 自定义动作注册

Browser-use提供了简洁的API用于扩展自定义动作:

from browser_use import Agent, Browser, ActionRegistry
from pydantic import BaseModel, Field
from browser_use.agent.views import ActionResult # 定义动作参数模型
class TakeScreenshotAction(BaseModel):
filename: str = Field(..., description="保存截图的文件名") # 创建Agent实例
browser = Browser()
agent = Agent(task="测试截图功能", llm=llm, browser=browser) # 注册自定义动作
@agent.controller.registry.action("Take screenshot", param_model=TakeScreenshotAction)
async def take_screenshot(params: TakeScreenshotAction, browser_context):
# 获取页面对象
page = await browser_context.get_current_page() # 执行截图
await page.screenshot(path=params.filename) # 返回结果
msg = f" Screenshot saved to {params.filename}"
return ActionResult(extracted_content=msg, include_in_memory=True)

自定义动作需要三个关键组件:

  1. 参数模型:定义输入参数及验证规则
  2. 动作名称:注册动作时指定的识别标识
  3. 执行函数:实现具体操作逻辑的异步函数

8.2 后端适配层

Browser-use设计了模块化的后端适配层,支持多种浏览器自动化技术:

  • Playwright:默认后端,支持多种浏览器
  • Selenium:传统的浏览器自动化工具
  • Chrome DevTools Protocol (CDP):直接与Chrome通信
  • 自定义后端:通过实现接口扩展其他自动化技术

选择后端的示例:

from browser_use import Browser, BrowserConfig, PlaywrightBackend

config = BrowserConfig(browser_type="firefox")
browser = Browser(config=config, backend=PlaywrightBackend())
agent = Agent(task="搜索四川的10大景点", llm=llm, browser=browser)

这种可扩展的后端架构使Browser-use能够适配不同的浏览器环境和自动化需求。

技术实现案例

搜索引擎交互

完整的搜索任务执行流程展示:我需要搜索四川的10大景点

初始状态

Current url: about:blank
Available tabs:
- Tab 1 (active): about:blank Interactive elements from top layer of the current page inside the viewport:
(no elements found)
我需要搜索四川的10大景点

初始动作(导航到搜索引擎)

{
"current_state": {
"evaluation_previous_goal": "我刚开始任务,还没有执行任何目标",
"memory": "我需要搜索四川的10大景点",
"next_goal": "导航到百度搜索引擎"
},
"action": [
{
"go_to_url": {
"url": "https://www.baidu.com"
}
}
]
}

执行结果

Action result:  Navigated to https://www.baidu.com

更新状态

Current url: https://www.baidu.com
Available tabs:
- Tab 1 (active): https://www.baidu.com Interactive elements from top layer of the current page inside the viewport:
[0]<input type="text" placeholder="百度一下">百度一下</input>
[1]<button>百度一下</button>
...

搜索动作

{
"current_state": {
"evaluation_previous_goal": "成功导航到百度搜索引擎",
"memory": "我正在搜索四川的10大景点,已成功打开百度首页",
"next_goal": "在搜索框中输入'四川十大景点'"
},
"action": [
{
"input_text": {
"index": 0,
"text": "四川十大景点"
}
},
{
"click_element": {
"index": 1
}
}
]
}

执行结果

Action result: ⌨️ Input text "四川十大景点" into index 0
Action result: ️ Clicked on element [1] 百度一下

这个循环持续进行,直到满足完成条件或达到最大步骤限制。

总结

Browser-use通过结构化输出和工具调用机制,使大模型能够灵活控制浏览器。其核心组件包括工具调用机制、动作注册系统、执行引擎和状态反馈机制。这种设计使AI能够执行从简单信息收集到复杂多步骤交互的Web任务。理解这些控制机制,开发者可以更有效地利用Browser-use构建强大的浏览器自动化应用。

想了解更多技术实现细节和源码解析,欢迎关注我的微信公众号【松哥ai自动化】每周我都会带来一篇深度技术文章,从源码角度剖析各种实用工具的实现原理。

下一篇我们将深入分析Browser-use是如何进行数据处理的!

揭秘AI自动化框架Browser-use(三):Browser-use控制浏览器的核心机制的更多相关文章

  1. Web自动化框架LazyUI使用手册(7)--浏览器常用操作API

      LazyUI框架中,BrowserEmulator类提供了大量的浏览器操作,常用的API列举如下: 1. 基本操作 /** * Open the URL * 打开一个URL * @param ur ...

  2. RobotFramework自动化测试框架-Selenium Web自动化(-)-Open Browser和Close Browser

    Selenium出来已经有很多年了,从最初的Selenium1到后来的Selenium2,也变得越来越成熟,而且也已经被很多公司广泛使用.Selenium发展的过程中,分了很多模块,这里我们主要介绍W ...

  3. java接口自动化(三) - 手工接口测试到自动化框架设计之鸟枪换炮

    1.简介 上一篇宏哥介绍完了接口用例设计,那么这一章节,宏哥就趁热打铁介绍一下,接口测试工具.然后小伙伴们或者童鞋们就可以用接口测试工具按照设计好的测试用例开始执行用例进行接口手动测试了.关于手动测试 ...

  4. Selenium Web 自动化 - 项目实战(三)

    Selenium Web 自动化 - 项目实战(三) 2016-08-10 目录 1 关键字驱动概述2 框架更改总览3 框架更改详解  3.1 解析新增页面目录  3.2 解析新增测试用例目录  3. ...

  5. ui自动化笔记 selenium_webdriver,ui自动化框架(web)

    Selenium学习笔记 selenium webdriver是业界公认ui自动化测试的标准,其封装的api可以对浏览器的任何地方进行操作 selenium2.0和selenium3.0的区别? 3. ...

  6. 为测试赋能,腾讯WeTest探索手游AI自动化测试之路

    作者:周大军/孙大伟, 腾讯后台开发 高级工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处.  WeTest导读 做好自动化测试从来不件容易的事情,更何况是手游的自动化测试,相比传 ...

  7. 基于Selenium的Web自动化框架增强篇

    在写完上一篇“基于Selenium的Web自动化框架”(http://www.cnblogs.com/AlwinXu/p/5836709.html)之后一直没有时间重新审视该框架,正好趁着给同事分享的 ...

  8. 如何选择Android自动化框架的几点拙见

    首先由于我自己也是个新手,也是在学习各种框架然后给公司项目选定相应自动化框架,研究移动自动化测试框架也就近段时间而已,所以我只能从我自己今天为止的认知角度给各个框架抒发我自己的拙见,你看是否能从中接纳 ...

  9. python自动化测试(3)- 自动化框架及工具

    python自动化测试(3) 自动化框架及工具 1   概述 手续的关于测试的方法论,都是建立在之前的文章里面提到的观点: 功能测试不建议做自动化 接口测试性价比最高 接口测试可以做自动化 后面所谈到 ...

  10. Appnium移动自动化框架初探

    作者:cryanimal QQ:164166060 本文简要介绍了appnium自动化框架的架构.加载流程.支持语言.相关配置,以及元素定位工具等. 官方网站: http://appium.io Ap ...

随机推荐

  1. 闲话 717 - LGV 引理的小应用

    这是我们的某一天的联考题目: \(n\le 500\). 显然使用平面图完美匹配计数可以获得 \(O(n^6)\),但是有一种神秘的对路径的双射.当时我们都认为这是超级人类智慧,但是今天看书发现是书上 ...

  2. ClickHouse常用操作

    一.客户端连接1.1 客户端连接ck./clickhouse-client -h 127.0.0.1 --port 9900 -u default --password 123456 -m 1.2 h ...

  3. Linux环境下安装phantomjs

    一.创建文件夹,用来存放软件 cd /opt/softWare mkdir  phantomJS cd phantomJS 二.下载并解压 wget https://bitbucket.org/ari ...

  4. 中国最难入职的IT公司排行榜

    在IT行业竞争日益白热化的今天,头部企业的招聘门槛不断刷新求职者的认知.根据最新行业调研和招聘数据,我们整理出2025年中国最难入职的几家互联网公司,并揭秘其背后严苛的选拔逻辑. 通常衡量难不难,会从 ...

  5. JUC并发—12.ThreadLocal源码分析

    大纲 1.ThreadLocal的特点介绍 2.ThreadLocal的使用案例 3.ThreadLocal的内部结构 4.ThreadLocal的核心方法源码 5.ThreadLocalMap的核心 ...

  6. CDH - [01] 概述

    一.什么是CDH   CDH是Cloudera's Distribution Including Apache Hadoop的缩写,即Cloudera公司发布的Hadoop发行版.它是一个为Hadoo ...

  7. 1Panel 专业版评测:全面超越宝塔的运维面板新标杆

    一. UX体验与移动端适配:更直观的跨平台交互 1Panel 专业版在用户体验上实现了对宝塔的全面超越.其界面采用现代化设计语言,以黑金主题为代表的可定制化主题系统支持一键切换,视觉风格更符合技术审美 ...

  8. 仿京东短信验证码UI效果(鸿蒙)

    整体思路: 外层Stack布局,里面TextInput组件用来调起键盘,Row布局中循环出四个Text组件,Row布局覆盖在TextInput组件上,用来展示输入的数字. 定义两个参数,code用来接 ...

  9. Go1.24版本终于来了!各位开发者,准备好迎接这些激动人心的新功能了吗?让我们一起来探讨下Go1.24中有哪些精彩的亮点?

    前言 Gopher们,Go 1.24.0 正式发布了!与 Go 1.23.0 相比,这个版本带来了众多改进.让我们一同看看 Go 1.24.0 都有哪些新变化吧! 在 Windows 下,请在 htt ...

  10. 印度股票实时行情API数据源接口

    ​ StockTV API: 提供实时和历史行情数据,覆盖印度所有股票和指数,支持WebSocket和REST API接口.(推荐使用,对接简单,有技术支持) 新浪财经:提供股票市场数据,可以优先考虑 ...