06 - LLM 多模型适配
06 - LLM 多模型适配
学习目标
本章将带你分析 LlamaIndex 的 LLM 多模型适配机制。你将学到:
- BaseLLM 的 8 个抽象方法统一接口
- 插件注册机制(条件导入 + 自动注册)
- resolve_llm() 字符串解析
- LLMMetadata 的模型元数据管理
- 多模型切换时的状态保持
前置知识
- 多模型适配架构 — 多模型管理基础
项目实践
BaseLLM 统一抽象层
BaseLLM 定义了 8 个抽象方法,覆盖所有调用模式:
| 同步 | 异步 |
|---|---|
chat() / complete() | achat() / acomplete() |
stream_chat() / stream_complete() | astream_chat() / astream_complete() |
设计原因:LLM 的调用方式本质上只有两个维度——输入格式(chat vs completion)和执行方式(同步/异步/流式)。2×4=8 种组合,每种对应一个抽象方法。
LLMMetadata 元数据
每个 LLM 实现提供自己的元数据:
@propertydef metadata(self) -> LLMMetadata: return LLMMetadata( context_window=128000, # 上下文窗口大小 num_output=4096, # 最大输出 token 数 is_chat_model=True, # 是否为 chat 模型 is_function_calling_model=True, # 是否支持 function calling model_name="gpt-4o", # 模型名称 )元数据的消费者:
PromptHelper.from_llm_metadata()— 自动配置 prompt 管理FunctionAgent— 检查is_function_calling_model决定是否可用resolve_llm()— 用于字符串解析
插件注册机制
Core 包通过条件导入实现插件注册:
RECOGNIZED_LLMS = {}
# 核心包只预装这几个try: from llama_index.llms.openai import OpenAI RECOGNIZED_LLMS["openai"] = OpenAIexcept ImportError: pass其余 300+ 模型通过独立集成包注册。每个集成包在自己的 loading.py 中将 LLM 类注册到全局注册表。
resolve_llm() 字符串解析
llm = resolve_llm("openai") # OpenAI() 默认配置llm = resolve_llm("openai/gpt-4o") # OpenAI(model="gpt-4o")llm = resolve_llm("anthropic/claude-sonnet-4-20250514")字符串格式:"provider/model_name" 或仅 "provider"(使用默认模型)。
多模型切换与状态保持
LlamaIndex 的多模型切换通过替换 LLM 实例实现,不涉及状态迁移:
# 切换 Settings 中的 LLMSettings.llm = OpenAI(model="gpt-4o")# 或Settings.llm = Ollama(model="llama-3.1")状态保持:每个 LLM 实例是独立的——切换模型不会迁移任何状态(如对话历史、工具定义)。对话历史存储在 Agent 的 Context.store["memory"] 中,与 LLM 实例无关,切换模型后对话历史仍然可用。
陷阱:不同模型的 tokenizer 不同。切换 LLM 后,Settings.tokenizer 不会自动更新。如果依赖准确的 token 计数(如 PromptHelper),需要同步更新 tokenizer:
from transformers import AutoTokenizerSettings.tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")问题与规避
| 陷阱 | 对策 |
|---|---|
| resolve_llm 找不到模型 | 确认对应集成包已安装 |
| 切换 LLM 后 token 计数不准确 | 同步更新 Settings.tokenizer |
| FunctionAgent 在不支持 function calling 的模型上失败 | 检查 llm.metadata.is_function_calling_model |
| 不同模型的 prompt 格式不兼容 | 使用 messages_to_prompt 自定义转换函数 |
设计取舍
抽象层 vs 直接调用
| 维度 | BaseLLM 抽象层 | 直接调用 OpenAI SDK |
|---|---|---|
| 模型切换 | 一行代码 (Settings.llm = ...) | 大量代码修改 |
| 异步/流式 | 统一接口 | 各 SDK 不同 API |
| 调试 | CallbackManager 统一追踪 | 各自实现 |
| 性能 | 轻微开销(抽象层转发) | 无开销 |
参考来源
- LlamaIndex LLM 源码:
llama-index-core/llama_index/core/llms/ - LlamaIndex LLM 集成:
llama-index-integrations/llms/