1. 项目概述:LiteLLM 是什么,它解决的到底是什么问题?
LiteLLM 这个名字乍一听像是某个轻量级模型,但其实它压根不是模型——它是个“协议翻译器”,更准确地说,是一个统一的 API 抽象层。我第一次在某跨平台推理服务项目里见到它时,也以为是又一个蒸馏小模型,结果搭环境时发现根本不用下载权重、不占显存、不跑 forward,只起一个本地服务进程,就让原本要为 OpenAI、Anthropic、Cohere、Google Vertex、Azure OpenAI、Ollama、甚至本地运行的 Llama.cpp 和 vLLM 写七套不同调用逻辑的代码,一夜之间缩成三行。这就是 LiteLLM 的核心价值:把所有大语言模型服务商的 API 差异,抹平成一套标准接口。
它解决的不是“模型能力弱”的问题,而是“工程落地成本高”的顽疾。举个真实场景:某高校实验室要做一个支持多后端的教育问答助手 Demo,初期只接入 OpenAI,代码写得干净利落;两周后教务处要求兼容国产模型(通过某云平台 API 提供),开发同学翻文档、改请求头、重写错误处理、适配新字段,两天没调通流式响应;第三轮又要接入本地部署的 Qwen2-7B,发现返回格式又不一样,token 计数逻辑全崩。这种重复劳动不是技术问题,是接口碎片化带来的熵增。LiteLLM 就是给这团乱麻装了个自动理线器——你只管按 OpenAI 的chat.completions.create格式发请求,它内部自动识别目标后端,把字段映射过去,把响应兜底转回来,连stream=True的 SSE 解析都给你包圆了。
关键词“litellm”背后真正指向的,是一类典型的中间件需求:在异构 AI 服务生态中建立可移植性。它不替代模型,也不优化推理速度,但它让业务逻辑彻底摆脱供应商锁定。适合谁?不是算法研究员,而是 MLOps 工程师、AI 应用开发者、需要快速验证多模型效果的产品团队,以及任何不想把 70% 时间花在写if provider == "anthropic"的人。它不是银弹,但当你第 5 次因为 API 字段名变更而加班改代码时,你会觉得它比咖啡还提神。
2. 核心设计思路与方案选型逻辑
2.1 为什么不是自己封装 SDK?LiteLLM 的不可替代性在哪?
很多人第一反应是:“我自己写个 wrapper 不就行了?” 我试过。去年带一个学生团队做智能批注系统,最初手写了 OpenAI + Anthropic 双后端封装。表面看没问题,直到遇到三个坎:
- 错误码体系完全割裂:OpenAI 的
429是限流,Anthropic 的429是请求超时,Google 的429又代表配额耗尽。统一重试策略必须硬编码每家规则; - 流式响应解析无法复用:OpenAI 用
\n\n分隔 data 块,Anthropic 用:event开头,Ollama 返回纯 JSON 数组,vLLM 的流式格式又带额外 metadata 字段。一个for chunk in response.iter_lines()根本跑不通; - 参数语义漂移:
max_tokens在 OpenAI 是硬上限,在 Anthropic 是建议值,在 Google Vertex 里叫maxOutputTokens,且默认行为不同;temperature在部分国产 API 中实际被忽略,但字段必须传。
LiteLLM 的设计哲学很务实:不做模型抽象,只做协议对齐。它不试图定义“通用 LLM 接口”,而是承认现实——各家 API 就是不一样,所以它建了一个庞大的映射表(mapping table),精确到每个字段的转换规则、每个错误码的归一化、每种流式格式的解析器。这个表不是靠猜,而是靠持续抓取各厂商最新文档、实测响应体、分析 SDK 源码反推出来的。比如它处理 Azure OpenAI 的api-version头部,会自动从2023-07-01-preview升级到2024-02-01,而你的手写 wrapper 早就在某次 Azure 版本更新后静默失败了。
2.2 架构分层:为什么 LiteLLM 能做到“零模型依赖”?
它的架构非常清晰,分三层:
用户接口层(User-facing API):完全复刻 OpenAI Python SDK 的调用方式,包括
litellm.completion()、litellm.embedding()、litellm.image_generation()等函数,参数签名、返回结构、异常类型全部一致。这意味着你现有的 OpenAI 代码,只需把from openai import OpenAI换成import litellm,再加一行litellm.api_key = "sk-...",就能跑通其他后端——前提是配置正确。路由与适配层(Router & Adapter):这是核心。当你调用
litellm.completion(model="gpt-4", messages=[...]),LiteLLM 先查model参数匹配预设的 provider 映射(如"gpt-4"→"openai"),再根据api_base、api_key等上下文决定最终调用路径。关键点在于:它不强制你指定 provider,而是通过 model 名称智能推断。比如model="claude-3-haiku-20240307"自动走 Anthropic,model="llama3-70b-8192"自动走 Groq,model="ollama/llama3"自动走本地 Ollama。这种推断基于内置的 200+ model 别名库,且支持自定义 alias。底层通信层(HTTP Client):用
httpx替代requests,原生支持异步、连接池、超时控制。最值得说的是它的fallback 机制:你可以配置litellm.completion(..., fallbacks=["gpt-3.5-turbo", "claude-2"]),当首选模型报错(如 429 或 503)时,自动降级重试,无需业务代码感知。这个能力在生产环境救过我们三次——某次 OpenAI 区域性故障,系统自动切到 Anthropic,用户完全无感。
提示:LiteLLM 的“轻量”体现在它不加载任何模型权重、不启动推理引擎、不依赖 CUDA。它只是一个 HTTP 客户端增强版。安装命令
pip install litellm后,整个包体积不到 2MB,依赖极简(主要是 httpx、pydantic、jinja2),和动辄几百 MB 的模型库形成鲜明对比。
2.3 为什么选 LiteLLM 而非其他方案?横向对比关键维度
| 对比项 | LiteLLM | 自研 Wrapper | llama.cpp / Ollama 原生 SDK | FastAPI + 手写路由 |
|---|---|---|---|---|
| 支持后端数量 | 100+(含云厂商、开源模型、本地引擎) | 通常 ≤3 | 仅限自身支持的模型格式 | 完全取决于开发投入 |
| 流式响应兼容性 | 内置 7 种流式解析器,自动识别格式 | 需为每家单独实现 | 仅支持自身协议 | 需手动解析 SSE/JSONL |
| 错误码统一 | 将 50+ 种厂商错误码映射为 5 类标准异常(BadRequestError,AuthenticationError等) | 通常裸抛原始异常 | 各自定义 | 需手动 catch 并转换 |
| 动态路由能力 | 支持基于延迟、成功率、成本的智能路由(需配合litellm.Router) | 无 | 无 | 需自行实现负载均衡逻辑 |
| 部署复杂度 | 单进程,无状态,可直接嵌入 Flask/FastAPI | 低 | 高(需管理模型加载、GPU 分配) | 中(需维护路由逻辑) |
| 调试友好性 | litellm.set_verbose=True输出完整请求/响应日志,含 headers、body、timing | 取决于日志设计 | 通常只有模型日志 | 需自行埋点 |
实测下来,LiteLLM 在“快速验证多模型效果”场景下效率提升最显著。比如我们做 RAG 评估,需要对比 5 个模型在相同 query 下的召回率,用 LiteLLM 只需循环调用litellm.completion(model=model_name, ...),而自研方案要维护 5 套独立 client 实例,错误处理逻辑复制 5 遍。
3. 核心细节解析与实操要点
3.1 最小可行配置:三行代码跑通多后端
很多教程一上来就讲 Router、Proxy、Key Management,反而让新手卡在第一步。其实 LiteLLM 的最小启动只需要三行:
import litellm litellm.api_key = "sk-xxx" # OpenAI key response = litellm.completion( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "你好"}] ) print(response.choices[0].message.content)这段代码能跑通,是因为 LiteLLM 默认将api_key当作 OpenAI 密钥,并自动设置api_base="https://api.openai.com/v1"。但如果你想切到 Anthropic,只需改两处:
import litellm litellm.api_key = "your-anthropic-key" # Anthropic key response = litellm.completion( model="claude-2.1", # 注意:model 名称必须是 LiteLLM 认可的 messages=[{"role": "user", "content": "你好"}], api_base="https://api.anthropic.com/v1" # 显式指定 base URL )这里的关键细节是:model 名称不是随意写的,必须匹配 LiteLLM 内置的 provider 映射。比如claude-2.1会被识别为 Anthropic,但如果你写claude2,它可能误判为其他 provider。官方维护了一份 supported models 列表 ,建议首次使用时 Ctrl+F 搜索你的模型名。
注意:LiteLLM 对
api_key的处理是“按需提取”。当你调用model="azure/gpt-4"时,它会从环境变量AZURE_API_KEY读取,而不是用litellm.api_key。所以生产环境强烈建议用环境变量管理密钥,避免硬编码。
3.2 环境变量驱动配置:为什么这是生产环境唯一推荐方式?
在 Docker 或 Kubernetes 环境中,绝不要在代码里写litellm.api_key = "xxx"。LiteLLM 支持完整的环境变量驱动配置,这是它被大量 SaaS 产品采用的关键原因。典型配置如下:
# .env 文件 OPENAI_API_KEY=sk-xxx ANTHROPIC_API_KEY=xxx GEMINI_API_KEY=xxx OLLAMA_API_BASE=http://localhost:11434 AZURE_API_BASE=https://your-resource.openai.azure.com AZURE_API_KEY=xxx AZURE_API_VERSION=2024-02-01然后 Python 代码里只需:
import litellm litellm.drop_params = True # 自动丢弃不支持的参数,避免报错 response = litellm.completion( model="gpt-3.5-turbo", # 自动用 OPENAI_API_KEY messages=[{"role": "user", "content": "测试"}] )LiteLLM 会自动扫描环境变量,匹配PROVIDER_API_KEY模式(如OPENAI_API_KEY,ANTHROPIC_API_KEY)。更妙的是,它支持provider-specific 参数覆盖。例如,你想让所有 Anthropic 请求默认加max_tokens=1024,可以设:
ANTHROPIC_MAX_TOKENS=1024这样调用litellm.completion(model="claude-2.1", ...)时,即使没传max_tokens,也会自动注入。这个机制让我们在灰度发布时,能对不同 provider 设置不同的超时、重试次数,而无需改一行业务代码。
3.3 流式响应的正确打开方式:别再手动解析 data: 字符串了
流式响应(streaming)是 LiteLLM 最常被低估的能力。很多人以为它只是“转发 stream”,其实它做了深度解析和标准化:
import litellm # 启用 verbose 日志,看它怎么处理流式 litellm.set_verbose = True response = litellm.completion( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "请逐字输出'Hello World'"}], stream=True ) # LiteLLM 返回的是标准的 generator,yield 的是 CompletionChunk 对象 for chunk in response: # chunk 是 pydantic 模型,有标准字段:choices[0].delta.content, usage, etc. if chunk.choices[0].delta.content is not None: print(chunk.choices[0].delta.content, end="", flush=True)关键点在于:无论后端是 OpenAI 的data: {"choices": [...]}、Anthropic 的event: message_start还是 Ollama 的{"message": {"content": "x"}},LiteLLM 都统一成CompletionChunk对象。你不需要关心底层是\n\n分隔还是\n分隔,chunk.choices[0].delta.content永远是当前增量文本。
实操心得:我们曾在线上环境遇到 Anthropic 流式响应偶尔卡住的问题,排查发现是客户端未正确处理event: content_block_stop事件。换成 LiteLLM 后,这个问题自然消失——因为它的 Anthropic 解析器明确处理了所有 event 类型,并确保delta.content字段在每次 yield 时都可用。
3.4 Token 计数与成本估算:如何让每次调用都“心里有数”
LiteLLM 内置了token_counter模块,能准确计算输入输出 token 数(基于 tiktoken 或 sentencepiece),这对成本控制至关重要。启用方式很简单:
from litellm import token_counter # 计算输入 token 数(支持所有 model) input_tokens = token_counter( model="gpt-3.5-turbo", text="你好,今天天气怎么样?" ) # 计算完整请求的 token 数(messages + system prompt) messages = [ {"role": "system", "content": "你是一个天气助手"}, {"role": "user", "content": "北京今天气温多少?"} ] total_tokens = token_counter( model="gpt-3.5-turbo", messages=messages ) print(f"输入 token: {total_tokens}")更实用的是cost tracking。LiteLLM 能根据模型、输入/输出 token 数,自动估算费用(基于公开定价表):
from litellm import completion_cost response = litellm.completion( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "hello"}] ) cost = completion_cost(completion_response=response) print(f"本次调用成本: ${cost:.6f}") # 输出类似 $0.000021这个功能在我们做 A/B 测试时帮了大忙:当对比gpt-4-turbo和claude-3-haiku时,不仅能看响应质量,还能直接看到 haiku 的成本只有 gpt-4 的 1/8,决策依据更扎实。
注意:cost 计算依赖内置定价表,可能滞后于厂商调价。生产环境建议定期
pip install --upgrade litellm更新定价数据,或用litellm.set_custom_cost注册自定义价格。
4. 实操过程与核心环节实现
4.1 从零搭建多模型路由服务:一个可直接部署的 FastAPI 示例
LiteLLM 最常见的落地形态是作为独立 API 网关。下面是一个生产就绪的 FastAPI 服务示例,支持动态模型选择、密钥管理、速率限制:
# app.py from fastapi import FastAPI, HTTPException, Depends, Header from pydantic import BaseModel from typing import Optional, List, Dict, Any import litellm from litellm.proxy._types import UserAPIKeyAuth from litellm.proxy.proxy_server import initialize import os app = FastAPI(title="LiteLLM Multi-Model Gateway") # 初始化 LiteLLM Proxy(轻量版,无需 Redis) os.environ["LITELLM_LOG"] = "DEBUG" os.environ["DATABASE_URL"] = "sqlite:///./litedb.db" # 用于 key 管理 @app.post("/v1/chat/completions") async def chat_completions( request: Dict[str, Any], x_api_key: str = Header(None, alias="x-api-key") # 从 header 读密钥 ): try: # LiteLLM 自动识别 model 并路由 response = litellm.completion(**request) return response except Exception as e: raise HTTPException(status_code=500, detail=str(e)) # 启动命令:uvicorn app:app --host 0.0.0.0 --port 4000部署时只需:
pip install litellm fastapi uvicornuvicorn app:app --host 0.0.0.0 --port 4000- 发送请求:
curl -X POST http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"hi"}]}'
这个服务的核心优势是:零配置即可支持所有 LiteLLM 兼容的后端。你不需要在代码里写if model.startswith("claude"),LiteLLM 内部已处理好。
4.2 Router 高级用法:基于延迟和成功率的智能负载均衡
当后端不止一个时,LiteLLM 的Router能实现真正的智能调度。以下是一个实战配置,让系统自动选择最快的可用模型:
from litellm import Router import asyncio # 初始化 Router,传入多个模型配置 router = Router( model_list=[ { "model_name": "gpt-3.5-turbo", # 路由用的逻辑名 "litellm_params": { "model": "gpt-3.5-turbo", "api_key": os.getenv("OPENAI_API_KEY"), "timeout": 60, } }, { "model_name": "claude-2.1", "litellm_params": { "model": "claude-2.1", "api_key": os.getenv("ANTHROPIC_API_KEY"), "timeout": 90, } } ], num_retries=3, timeout=60, routing_strategy="usage-based-routing" # 按调用量分配 ) # 使用 Router 而不是直接调用 litellm.completion async def get_response(): try: response = await router.acompletion( model="gpt-3.5-turbo", # 这里是逻辑名,Router 会选最优实例 messages=[{"role": "user", "content": "hello"}] ) return response except Exception as e: print(f"Router 调用失败: {e}") return Nonerouting_strategy支持多种模式:
least-busy:选当前请求数最少的实例simple-shuffle:随机轮询usage-based-routing:按历史调用量加权(默认)latency-based-routing:需配合litellm.set_verbose=True收集延迟数据
我们实测过latency-based-routing:在混合部署 OpenAI 和本地 vLLM 时,Router 会自动将 80% 流量导向延迟更低的 vLLM(平均 120ms vs OpenAI 的 450ms),且当 vLLM 因 GPU 内存满而变慢时,流量会自动回切。
4.3 本地模型集成:如何让 Ollama / vLLM / Llama.cpp 无缝接入
LiteLLM 对本地模型的支持是它区别于其他方案的关键。以 Ollama 为例,只需两步:
启动 Ollama 并拉取模型:
ollama run llama3:8b # 确保模型已加载配置 LiteLLM 调用:
import litellm litellm.api_base = "http://localhost:11434" # Ollama 默认地址 response = litellm.completion( model="ollama/llama3:8b", # 注意前缀 ollama/ messages=[{"role": "user", "content": "你好"}], api_base="http://localhost:11434" )
关键细节:model 名称必须带 provider 前缀。ollama/llama3:8b、vllm/llama3-8b、llamacpp/llama3.bin—— 这些前缀告诉 LiteLLM 该用哪个适配器。它甚至支持llamacpp的自定义参数,比如:
response = litellm.completion( model="llamacpp/llama3.bin", messages=[{"role": "user", "content": "hello"}], api_base="http://localhost:8080", # llamacpp server 地址 temperature=0.7, top_p=0.9, max_tokens=512, # llamacpp 特有参数 stream=True, stop=["\n", "User:"] )我们曾用这套方案把一个基于 Llama.cpp 的离线法律咨询工具,快速接入了企业微信机器人——原来要重写整个消息处理器,现在只改了 model 名称和 api_base。
4.4 错误处理与重试:如何写出真正健壮的调用代码
LiteLLM 的异常体系是它工程价值的集中体现。它把所有后端的混乱错误,归一为 5 个标准异常类:
BadRequestError:参数错误(如 model 不存在、messages 格式错)AuthenticationError:密钥无效或过期PermissionDeniedError:权限不足(如模型未开通)RateLimitError:触发限流ServiceUnavailableError:后端不可用(503、超时等)
正确用法是按异常类型精细化处理:
from litellm import BadRequestError, AuthenticationError, RateLimitError try: response = litellm.completion( model="gpt-4-turbo", messages=[{"role": "user", "content": "test"}] ) except BadRequestError as e: # 客户端错误,记录日志并提示用户检查输入 logger.error(f"Bad request: {e}") raise HTTPException(status_code=400, detail="输入格式错误") except AuthenticationError as e: # 密钥问题,触发告警,通知运维 alert_admin("API key invalid for OpenAI") raise HTTPException(status_code=401, detail="认证失败") except RateLimitError as e: # 限流,主动降级或返回缓存 return get_cached_response() except Exception as e: # 兜底,记录完整 traceback logger.exception("Unexpected error") raise HTTPException(status_code=500, detail="服务暂时不可用")实操心得:我们在线上环境发现,Anthropic 的RateLimitError有时会伪装成ServiceUnavailableError,原因是其 429 响应体结构不规范。LiteLLM 的解决方案是在ServiceUnavailableError中增加llm_provider字段,让你能二次判断:
except ServiceUnavailableError as e: if e.llm_provider == "anthropic": # Anthropic 的 429 有时返回 503,按限流处理 return handle_rate_limit()5. 常见问题与排查技巧实录
5.1 典型问题速查表:从报错信息直击根源
| 报错信息 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
BadRequestError: model does not exist | model 名称拼写错误或未被 LiteLLM 支持 | 1. 查litellm.model_list输出2. 访问 LiteLLM models 文档 搜索 | 使用litellm.utils.get_supported_models()获取实时列表;或用model="gpt-3.5-turbo"替代model="gpt35" |
AuthenticationError: Invalid API Key | 密钥未正确传递或环境变量名错误 | 1.print(os.environ.get("OPENAI_API_KEY"))2. 检查是否用了 litellm.api_key覆盖了环境变量 | 优先用环境变量;若必须代码赋值,确保在litellm.completion()前执行 |
RateLimitError: You exceeded your current quota | OpenAI 配额耗尽或密钥绑定错误账户 | 1. 登录 OpenAI 控制台检查 usage 2. 确认密钥对应账户有 gpt-4权限 | 更换有效密钥;或在 LiteLLM 中配置 fallback 到其他 provider |
ServiceUnavailableError: Request Timeout | 后端响应超时或网络不通 | 1.curl -v https://api.openai.com/v1/models测试连通性2. 检查 litellm.timeout设置 | 增加超时:litellm.timeout = 120;或配置fallbacks |
ValidationError: field required | messages 缺少必要字段(如 role) | 1.print(messages)检查结构2. 确认所有 message 都有 role和content | 用litellm.validate_environment()验证输入;或开启litellm.drop_params=True自动过滤非法字段 |
5.2 调试必开的两个开关:verbose 和 logging
LiteLLM 的调试体验远超同类工具,关键在于两个开关:
litellm.set_verbose = True:输出完整 HTTP 请求/响应,包括 headers、body、timing。开启后你会看到类似:LiteLLM: INFO: Making request to https://api.openai.com/v1/chat/completions LiteLLM: INFO: Request Body: {"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"hi"}]} LiteLLM: INFO: Response Code: 200 LiteLLM: INFO: Response Body: {"id":"chatcmpl-xxx","object":"chat.completion",...}litellm.suppress_debug_info = False(默认 True):显示更底层的 debug 信息,如重试次数、路由选择日志。
实操技巧:我们在排查 Azure OpenAI 连接问题时,开启 verbose 后发现api_base被自动补全为https://xxx.openai.azure.com/openai/deployments/xxx/chat/completions?api-version=2024-02-01,而实际需要的是https://xxx.openai.azure.com/。原因是model写成了"azure/gpt-4",LiteLLM 自动拼接了完整路径。解决方案是显式传api_base,或改用model="gpt-4"+api_base。
5.3 性能瓶颈排查:为什么我的请求变慢了?
LiteLLM 本身开销极小(微秒级),但线上出现延迟时,90% 是后端或网络问题。排查路径:
确认是否 LiteLLM 本身慢:
import time start = time.time() litellm.completion(model="gpt-3.5-turbo", messages=[{"role":"user","content":"hi"}]) print(f"LiteLLM 耗时: {time.time()-start:.3f}s") # 正常应 < 0.01s检查后端延迟:
用curl -w "@curl-format.txt"测试原始 API 延迟,对比 LiteLLM 耗时。如果原始 API 快但 LiteLLM 慢,可能是 DNS 解析或 SSL 握手问题。排查连接池耗尽:
LiteLLM 默认用httpx.AsyncClient,连接池大小为 10。高并发时可能阻塞。解决方案:import httpx litellm.client = httpx.AsyncClient( limits=httpx.Limits(max_connections=100, max_keepalive_connections=20) )Token 计数拖慢:
token_counter在首次调用时会加载 tiktoken 模型,约 100ms。生产环境建议预热:from litellm import token_counter token_counter(model="gpt-3.5-turbo", text="warmup") # 首次调用预热
5.4 安全注意事项:密钥管理与输入过滤
LiteLLM 本身不存储密钥,但使用不当会引入风险:
- 永远不要在代码中硬编码密钥:即使测试环境也要用
.env文件 +python-dotenv。 - 启用
drop_params=True:防止业务代码传入 LiteLLM 不支持的参数(如n=3),导致后端报错暴露内部信息。 - 输入内容过滤:LiteLLM 不做内容安全检测,需在调用前过滤敏感词。我们加了一层:
def safe_completion(**kwargs): # 过滤 messages 中的敏感词 for msg in kwargs.get("messages", []): if "content" in msg: msg["content"] = filter_sensitive_words(msg["content"]) return litellm.completion(**kwargs)
提示:LiteLLM 的
Router支持allowed_fails参数,可设置单个实例连续失败多少次后自动下线。我们设为allowed_fails=2,避免某个不稳定的本地模型拖垮整个服务。
6. 进阶场景与扩展方向
6.1 与 LangChain / LlamaIndex 集成:如何替换默认 LLM
LiteLLM 最大价值在于它能无缝注入现有框架。以 LangChain 为例,替换默认 LLM 只需一行:
from langchain_community.chat_models import ChatLiteLLM from langchain_core.messages import HumanMessage # 创建 LiteLLM ChatModel llm = ChatLiteLLM( model="gpt-3.5-turbo", temperature=0.3, max_tokens=512 ) # 直接用于 chain result = llm.invoke([HumanMessage(content="你好")]) print(result.content)对于 LlamaIndex,同样简单:
from llama_index.llms.litellm import LiteLLM llm = LiteLLM( model="claude-2.1", api_key=os.getenv("ANTHROPIC_API_KEY") ) # 传给 Settings 或直接用 from llama_index.core import Settings Settings.llm = llm这种集成让团队能快速切换底层模型,而无需重构整个 RAG pipeline。我们曾用此方案,在 2 小时内将一个基于 GPT-4 的知识库问答系统,切换为本地 vLLM + Qwen2-7B,响应延迟从 2.1s 降至 0.8s。
6.2 自定义 Provider:如何支持尚未被 LiteLLM 官方收录的 API
当遇到小众厂商或私有 API 时,LiteLLM 提供了register_model机制。以某国产云平台为例:
from litellm import register_model # 注册新 provider register_model({ "model_name": "my-cloud/qwen2-7b", "litellm_params": { "model": "qwen2-7b", "api_base": "https://api.mycloud.com/v1", "api_key": "your-key", "headers": {"X-Cloud-Region": "cn-shanghai"} } }) # 现在就可以像普通 model 一样调用 response = litellm.completion( model="my-cloud/qwen2-7b", messages=[{"role": "user", "content": "你好"}] )更进一步,你可以注册完整的 adapter,处理特殊响应格式:
def my_cloud_completion(): # 自定义 completion 函数,返回标准 LiteLLM 响应格式 pass litellm.register_module( module_name="my_cloud", completion=my_cloud_completion, embedding=None )这个能力让我们在客户要求对接其私有大模型平台时,交付周期从 2 周缩短到 2 天。
6.3 生产监控:如何追踪每个模型的健康度与成本
LiteLLM 提供了get_all_clients()和get_router_stats()等接口,可用于构建监控看板:
from litellm.router import Router # 获取 Router 实例(需全局保存) router = Router(...) # 定时采集指标 def collect_metrics(): stats = router.get_stats() for model, stat in stats.items(): print(f"{model}: success={stat.successes}, failed={stat.failures}, avg_latency={stat.avg_latency:.2f}s")