BrowserUse11-源码-LLM模块

LLM模块
模块一:当前文件夹核心内容梳理
1.1 核心知识极简概括
- 统一的大语言模型接口抽象 :通过 BaseChatModel 协议定义统一接口,封装各大厂商 API 差异,实现无缝切换和统一调用。
- 多厂商模型集成与适配:集成 OpenAI、Anthropic、Google、Azure、Mistral 等主流厂商模型,通过定制化适配器解决各厂商 API 差异和特殊要求。
- 结构化输出与模式优化 :提供结构化输出支持,通过 SchemaOptimizer 优化模型 schema,确保各种模型都能正确处理 Pydantic 模型定义。
- 健壮的错误处理与重试机制:内置网络超时、API 限流、服务不可用等异常处理机制,通过指数退避策略保证请求稳定性。
- 消息序列化与内容处理:定义统一的消息类型和序列化机制,支持文本、图像、工具调用等复杂内容类型,屏蔽不同厂商的序列化差异。
1.2 子知识扩展
统一的大语言模型接口抽象
- 输入输出 :接口接受 BaseMessage 列表和可选的输出格式类型,返回 ChatInvokeCompletion 对象包含结果和用量信息。
- 异常处理 :定义统一的异常类型如 ModelProviderError 和 ModelRateLimitError,便于上层统一处理。
- 配置覆盖关系:通过环境变量、构造参数等方式灵活配置模型参数,构造参数优先级高于环境变量。
- 动态加载 :通过
__getattr__实现模型实例的懒加载,减少启动时间和内存占用。 - 协议验证:使用 Pydantic 的 Protocol 特性,确保实现类符合接口规范。
多厂商模型集成与适配
- 输入输出 :每种模型实现都接受特定于该厂商的参数(如 API 密钥、基础 URL 等),但对外暴露统一的 ainvoke 接口。
- 异常处理:处理各厂商特有的错误码和错误信息格式,转化为统一的内部异常。
- 配置覆盖关系:优先使用构造函数传入的参数,其次从环境变量获取,最后使用默认值。
- 厂商特殊要求:如 Anthropic 的缓存机制、Google 的 Gemini schema 优化、Mistral 的模式关键字移除等。
- 认证机制:支持 API Key、Bearer Token、OCI 认证等多种认证方式。
结构化输出与模式优化
- 输入输出:接受 Pydantic 模型类型作为输出格式参数,返回验证后的模型实例。
- 异常处理:处理模型返回不符合 schema 的情况,提供解析失败的详细错误信息。
- 配置覆盖关系 :通过 SchemaOptimizer 参数控制优化策略,如是否移除 minItems 等。
- schema 优化策略:展开 $ref 引用、移除不支持的关键字、确保与严格模式兼容。
- 厂商适配:针对不同厂商的 schema 要求进行专门优化,如 Gemini、Mistral 等。
健壮的错误处理与重试机制
- 输入输出:在网络请求失败时自动重试,达到最大重试次数后抛出异常。
- 异常处理:区分可重试异常(如超时、限流)和不可重试异常(如认证失败)。
- 配置覆盖关系:通过构造参数控制最大重试次数、基础延迟、最大延迟等。
- 重试策略:采用指数退避算法,添加随机抖动避免惊群效应。
- 日志记录:详细记录重试过程,便于问题排查和性能分析。
消息序列化与内容处理
- 输入输出 :将内部 BaseMessage 对象序列化为目标模型 API 所需格式。
- 异常处理:处理序列化过程中可能出现的数据类型不匹配等问题。
- 配置覆盖关系:支持不同类型内容(文本、图像、工具调用)的序列化配置。
- 内容类型支持:支持文本、图像 URL、Base64 图像、工具调用等多种内容类型。
- 厂商适配:针对不同厂商的消息格式要求进行适配,如 Anthropic、OpenAI 等。
1.3 知识点详细说明
统一的大语言模型接口抽象
LLM 模块的核心设计理念是通过抽象接口统一不同厂商的大语言模型调用方式。这种设计使得上层应用可以无缝切换不同的模型提供商,而无需修改业务逻辑。
接口设计与实现
BaseChatModel 协议定义了所有模型必须实现的方法和属性:
<<protocol>> BaseChatModel +str provider +str name +ainvoke(messages, output_format) ChatOpenAI +str model +str api_key +ainvoke(messages, output_format) ChatAnthropic +str model +str api_key +ainvoke(messages, output_format) ChatGoogle +str model +str api_key +ainvoke(messages, output_format)
消息类型系统
模块定义了一套统一的消息类型系统,包括 UserMessage、SystemMessage 和 AssistantMessage,支持文本、图像、工具调用等复杂内容。
响应与用量统计
ChatInvokeCompletion 类封装了模型调用的完整响应,包括生成内容和用量统计信息。ChatInvokeUsage 类提供了详细的 token 使用情况。
多厂商模型集成与适配
模块集成了多个主流大语言模型提供商,每种实现都需要处理各自 API 的特殊要求。
主要模型实现
- OpenAI 系列 :包括 OpenAI、Azure OpenAI,通过 ChatOpenAI 和 ChatAzureOpenAI 实现。
- Anthropic 系列 :通过 ChatAnthropic 实现,支持缓存机制。
- Google 系列 :通过 ChatGoogle 实现,针对 Gemini 模型进行了优化。
- Mistral 系列 :通过 ChatMistral 实现,处理了特定的 schema 限制。
- BrowserUse 专属模型 :通过 ChatBrowserUse 实现,连接到 BrowserUse 云服务。
厂商适配策略
每种实现都采用了相似的架构模式:
- 继承自标准库的异步 HTTP 客户端
- 通过序列化器处理消息格式转换
- 实现重试和错误处理机制
- 支持结构化输出
结构化输出与模式优化
结构化输出是现代大语言模型的重要特性,允许模型直接返回符合特定 schema 的 JSON 数据。
Schema 优化器
SchemaOptimizer 类负责优化 Pydantic 模型生成的 JSON schema,确保其能在各种模型中正确工作:
- 引用展开 :将 schema 中的
$ref引用展开,避免某些模型不支持引用 - 关键字清理 :移除特定模型不支持的关键字,如
minLength、maxLength等 - 严格模式兼容:确保 schema 符合 OpenAI 严格模式要求
多模型适配
不同模型对 schema 的支持程度不同,模块通过专门的优化方法处理:
- OpenAI/GPT 系列:支持完整的 JSON schema
- Anthropic/Claude 系列:需要特殊的引用处理
- Google/Gemini 系列:需要保留 explicit required 数组
- Mistral 系列:需要移除特定的关键字
健壮的错误处理与重试机制
网络请求天然具有不稳定性,模块内置了完善的错误处理和重试机制。
重试策略
采用指数退避算法进行重试:
- 基础延迟时间乘以 2 的尝试次数次方
- 添加随机抖动避免惊群效应
- 设置最大延迟时间防止无限增长
错误分类处理
是 否 可重试错误 认证错误 限流错误 否 是 HTTP请求 请求成功? 返回结果 错误类型 指数退避重试 抛出异常 重试或抛出异常 超过最大重试次数? 抛出异常
异常类型体系
定义了层次化的异常类型:
- ModelProviderError:基础模型提供商错误
- ModelRateLimitError:限流错误
消息序列化与内容处理
为了在不同模型间传递复杂的内容,模块实现了统一的消息序列化机制。
内容类型支持
支持多种内容类型:
- 纯文本内容
- 图像内容(URL 或 Base64 编码)
- 工具调用信息
- 拒绝消息
序列化器架构
每种模型实现都配有专门的序列化器,如:
- OpenAIMessageSerializer:处理 OpenAI 格式
- AnthropicMessageSerializer:处理 Anthropic 格式
- GoogleMessageSerializer:处理 Google 格式
厂商差异化处理
不同厂商对消息格式有不同的要求:
- Anthropic 需要将系统消息作为用户消息的一部分
- Google 需要特殊处理图像内容
- Mistral 需要将工具调用转换为特定格式
模块二:核心代码逻辑
2.1 核心类/方法速查表
| 类/方法名 | 定位(文件:行号) | 输入输出 | 使用场景示例(1句话) | 调试提示(如:断点打在哪) |
|---|---|---|---|---|
| BaseChatModel | base.py:16 | 消息列表和输出格式 → 结构化响应 | 定义所有LLM实现必须遵循的接口协议 | 在协议方法定义处查看接口规范 |
| ChatOpenAI | openai/chat.py:33 | OpenAI API参数 → 结构化响应 | 使用OpenAI的GPT系列模型进行推理 | 在 _make_request 方法前后打断点观察请求和响应 |
| ChatAnthropic | anthropic/chat.py:50 | Anthropic API参数 → 结构化响应 | 使用Anthropic的Claude系列模型进行推理 | 在 serialize_messages 方法中查看消息序列化过程 |
| ChatGoogle | google/chat.py:37 | Google API参数 → 结构化响应 | 使用Google的Gemini系列模型进行推理 | 在 _fix_gemini_schema 方法中查看schema优化过程 |
| ChatBrowserUse | browser_use/chat.py:33 | BrowserUse云API参数 → 结构化响应 | 使用BrowserUse优化的云模型进行推理 | 在 ainvoke 方法中查看重试逻辑 |
| SchemaOptimizer | schema.py:12 | Pydantic模型 → 优化的JSON Schema | 为不同模型优化输出格式定义 | 在 create_optimized_json_schema 方法中查看优化过程 |
2.2 最小复现示例(伪代码)
python
# ① 依赖注入
from browser_use.llm import ChatOpenAI, UserMessage, SystemMessage
from pydantic import BaseModel
# 定义输出格式
class ResponseModel(BaseModel):
answer: str
confidence: float
# 创建模型实例
llm = ChatOpenAI(
model="gpt-4.1-mini",
api_key="your-api-key" # 或通过环境变量OPENAI_API_KEY设置
)
# ② 关键调用
messages = [
SystemMessage(content="你是一个有用的助手"),
UserMessage(content="什么是人工智能?请用一句话回答。")
]
# 发起异步调用
import asyncio
response = asyncio.run(
llm.ainvoke(messages, output_format=ResponseModel)
)
# ③ 断言验证
assert response.completion.answer is not None
assert 0 <= response.completion.confidence <= 1
assert response.usage.prompt_tokens > 0
print(f"答案: {response.completion.answer}")
print(f"置信度: {response.completion.confidence}")
print(f"提示词token数: {response.usage.prompt_tokens}")