1. 概述
在Browser-use框架中,核心任务是使大模型能够像人类一样操作浏览器。本文深入探讨大模型如何实际控制浏览器,重点解析从模型输出到浏览器动作执行的完整流程。
上一篇(公众号首发)-Browser-use AI自动化框架深度解析(二):提示词构造机制
2. 系统架构与数据流
Browser-use采用标准的Agent-Environment交互范式,以闭环反馈机制实现大模型与浏览器的交互:
┌────────────┐ 状态提示词 ┌───────────┐
│ │ ───────────────> │ │
│ 浏览器环境 │ │ 大模型 │
│ │ <─────────────── │ │
└────────────┘ 结构化动作 └───────────┘
2.1 核心交互流程
- 状态获取:框架捕获当前浏览器状态,包括DOM结构、可交互元素和页面元数据
- 状态表示:将状态转换为结构化提示词注入大模型上下文
- 决策生成:大模型分析状态并生成结构化的动作计划
- 动作执行:框架解析动作计划并在浏览器中执行相应操作
- 结果反馈:执行结果和新状态反馈回大模型,进入下一轮迭代
这种基于状态-动作-反馈的迭代模式支持大模型进行多步骤任务规划和执行。
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 输出结构解析
-
current_state
:任务状态信息evaluation_previous_goal
:上一步骤完成状态的评估memory
:工作记忆,存储任务关键信息next_goal
:规划的下一步目标
-
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