跳转到内容

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 实现提供自己的元数据:

@property
def 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"] = OpenAI
except 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 中的 LLM
Settings.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 AutoTokenizer
Settings.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/