1. 项目概述:LiteLLM 是什么,它解决的不是“模型调用”而是“模型调度”的本质问题
LiteLLM 这个名字乍一听像某个轻量级语言模型,但其实它压根不训练模型、不推理文本、不生成代码——它是一层智能路由胶水层,是专为开发者设计的“大模型服务总线”。我第一次在某跨平台AI工具链项目里接触它时,团队正被三个问题反复折磨:对接 OpenAI API 要写一套逻辑,切到 Anthropic 又得重写鉴权和流式响应解析,换上本地部署的 Ollama 模型后连 temperature 参数都对不上号;测试环境用免费 key,生产环境要切企业版 endpoint,一改配置就得全量回归;更头疼的是,某天客户突然要求“把当前所有请求自动 fallback 到备用模型”,而我们当时连超时重试都没做统一封装。LiteLLM 就是在这种“模型越来越多、供应商越来越杂、运维越来越碎”的现实压力下,自然长出来的基础设施级解法。
它的核心价值,从来不是“让调用变快”,而是“让调用变稳、变可管、变可测”。你不需要记住gpt-4-turbo的最大上下文是 128K 还是 131072,也不用查claude-3-haiku-20240307的输入 token 计费规则是否包含 system prompt——LiteLLM 内部已将 120+ 主流模型(含 Azure OpenAI、Google Vertex AI、Ollama、LM Studio、甚至自建 vLLM 集群)的参数规范、限流策略、错误码映射、流式 chunk 解析逻辑全部标准化。你只写litellm.completion(model="gpt-4", messages=[...]),它自动识别这是 OpenAI 兼容接口,补全 base_url 和 api_key,把 temperature=0.7 映射成对应 provider 的实际字段,遇到 rate limit 错误自动按指数退避重试,并在日志里清晰标记“第3次重试,fallback 至 claude-3-sonnet”。这不是语法糖,是把原本散落在各处的 if-else、try-except、config.yaml 和 postman collection,压缩成一行函数调用的能力。
适合谁看?如果你正在做以下任何一件事,这篇就是为你写的:正在搭建内部 AI 中台,需要统一纳管多个模型供应商;开发 SaaS 产品,想让用户自由选择后端模型而不改一行业务代码;做教育类应用,需在免费模型(如 Groq)和高质模型(如 GPT-4)间动态降级;或是单纯受够了每次新模型上线都要改 SDK、修日志、调 timeout 的重复劳动。它不替代你对模型能力的理解,但能让你把精力从“怎么调通”转向“怎么用好”。
2. 核心设计思路拆解:为什么 LiteLLM 不是 SDK,而是一套运行时协议适配器
2.1 它的底层不是封装,而是协议翻译与行为归一化
很多初学者会误以为 LiteLLM 是 OpenAI Python SDK 的增强版,这是根本性误解。OpenAI SDK 的设计哲学是“忠于上游”,即完全暴露 OpenAI 原生 API 的所有细节:response_format字段只在特定模型生效,logprobs开关依赖模型支持,max_tokens在 gpt-3.5-turbo 和 gpt-4-turbo 中含义不同。而 LiteLLM 的设计原点是“忠于开发者意图”——你传入max_tokens=1000,它就确保最终输出不超过 1000 tokens,无论后端是 Llama-3-70B(需通过max_completion_tokens控制)、Claude(需拆解为max_tokens+anthropic_version头)、还是本地 vLLM(需转换为max_new_tokens)。这背后是一套完整的模型能力描述语言(Model Capability Schema),每个 provider 都有独立的 adapter 模块,负责三件事:
参数翻译层(Parameter Translation):将统一输入参数映射为 provider 特定字段。例如
temperature在 OpenAI 是 float,在 Anthropic 是 0~1 的 float,在 Google Gemini 是temperature: 0.7,而在 Ollama 是options.temperature: 0.7。LiteLLM 不是简单字符串替换,而是带校验的转换——若你对 Claude 设置top_p=0.9,它会静默忽略(因 Anthropic 不支持该参数),并记录 warning 日志;若对 Ollama 设置response_format={"type": "json_object"},它会主动报错提示“Ollama 不支持结构化输出”。响应归一化层(Response Normalization):所有 provider 的原始响应被解析为统一的
LiteLLMCompletionResponse对象,包含choices[0].message.content、usage.prompt_tokens、usage.completion_tokens等标准字段。关键在于流式响应(streaming)的处理:OpenAI 返回data: {"choices":[{"delta":{"content":"a"}}]},Anthropic 返回event: content_block_delta\ndata: {"type":"content_block_delta","delta":{"text":"a"}},而 Ollama 的 stream 是纯文本行。LiteLLM 内置一个状态机驱动的流式解析器,能按 chunk 逐帧提取内容,保证for chunk in litellm.completion(..., stream=True): print(chunk.choices[0].delta.content)在所有后端行为一致。错误语义对齐层(Error Semantics Alignment):这是最体现工程深度的部分。OpenAI 的
429 Too Many Requests、Anthropic 的429 Rate Limit Exceeded、Google 的429 Resource exhausted,在 LiteLLM 中全部映射为统一的litellm.RateLimitError异常。更进一步,它能根据 response header 中的x-ratelimit-remaining、retry-after等字段,自动计算下次重试时间,而非简单 sleep(1)。我实测过在 Azure OpenAI 配置了retry_policy={"max_retries": 3, "jitter": True}后,当遭遇突发流量导致的 429,LiteLLM 的重试间隔分别是 1.2s、2.7s、5.1s(带随机抖动),远比硬编码time.sleep(2)更抗压。
2.2 架构选型背后的取舍:为什么不用 FastAPI 自建网关?
有人会问:既然目标是统一调度,为什么不自己用 FastAPI 写个 API 网关?这确实是可行路径,但 LiteLLM 的定位决定了它必须是进程内库(in-process library),而非独立服务。原因有三:
第一,延迟敏感场景不可妥协。在实时对话系统中,一次请求若需经过“业务服务 → 网关服务 → 模型服务”三层网络跳转,光是 TCP 握手+TLS 握手+HTTP 头解析就增加 50~100ms 延迟。而 LiteLLM 作为 importable 库,直接运行在业务进程内,所有参数转换、重试逻辑、日志埋点都在内存中完成,实测端到端 P95 延迟比网关方案低 35% 以上。某在线编程辅导项目曾对比过两种方案:学生提问后,服务需调用代码解释模型 + 错误诊断模型 + 优化建议模型,三者串行。用网关方案平均耗时 2.1s,用 LiteLLM 内嵌方案降至 1.3s,用户放弃率下降 22%。
第二,调试与可观测性成本差异巨大。当线上出现“某用户请求返回空 content”时,网关方案需排查:业务服务发包是否正确 → 网关日志是否收到 → 网关转发是否异常 → 模型服务是否超时。而 LiteLLM 提供litellm.set_verbose(True),开启后会在 stdout 打印完整调用链:[INFO] Calling model gpt-4 with params... [DEBUG] Translated to openai api: {...} [INFO] Received response with 123 tokens...。更重要的是,它支持与 OpenTelemetry 无缝集成,所有 span 都标注llm.request.model、llm.response.finish_reason等语义化标签,直接对接 Prometheus/Grafana,无需额外开发埋点。
第三,动态策略注入更灵活。网关是静态配置,而 LiteLLM 允许在运行时动态修改行为。例如某内容审核服务要求:对高风险关键词(如“暴力”“违法”)的请求,强制使用本地部署的 Llama-3-8B(保障数据不出域),其他请求走云端 GPT-4。用网关需在请求头加标记再配路由规则;而 LiteLLM 只需写一个简单的 router 函数:
def dynamic_model_router(messages): text = " ".join([m.get("content", "") for m in messages]) if any(keyword in text for keyword in ["暴力", "违法"]): return "ollama/llama3:8b" else: return "gpt-4" # 调用时传入 response = litellm.completion( model=dynamic_model_router(messages), messages=messages, ... )这种基于业务逻辑的细粒度控制,是网关架构难以实现的。
3. 核心细节与实操要点:从零配置到生产就绪的关键参数与陷阱
3.1 最小可用配置:三行代码跑通第一个请求
新手最容易卡在环境准备阶段。LiteLLM 的安装极其简单:
pip install litellm但真正让第一次请求成功的,是理解它的隐式依赖规则。LiteLLM 本身不绑定任何 HTTP 客户端,它默认使用httpx(推荐)或requests。如果你的环境中已安装aiohttp,它会优先尝试异步模式,但某些旧版 Linux 发行版的aiohttp与httpx存在 SSL 冲突。我的经验是:首次部署务必显式指定同步模式,并验证基础连通性:
import litellm # 强制使用 requests 后端,避免异步兼容问题 litellm.drop_params = False # 先不丢弃未知参数,便于调试 # 测试 OpenAI 兼容接口(需提前设置 OPENAI_API_KEY) try: response = litellm.completion( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "hello"}], api_base="https://api.openai.com/v1", # 显式指定,不依赖环境变量 api_key="sk-..." # 显式传入,避免环境变量污染 ) print("Success:", response.choices[0].message.content) except Exception as e: print("Error:", str(e))这里有两个关键点:一是litellm.drop_params = False,默认为 True,意味着当你传入response_format={"type":"json_object"}但后端不支持时,它会静默删除该参数而非报错——这在调试期极难发现,务必先关闭;二是api_base和api_key显式传入,因为 LiteLLM 会按顺序查找:函数参数 > 环境变量 >.env文件,而.env文件若存在语法错误(如空格、注释符号#未转义),会导致整个加载失败且无提示。
3.2 生产环境必配的五大安全与稳定性参数
当你的服务开始承载真实流量,以下五个参数不是“可选”,而是“保命线”:
timeout:全局超时不是数字,而是对象
很多人写timeout=30,以为是 30 秒总超时。实际上 LiteLLM 的timeout参数接受httpx.Timeout对象,必须明确指定connect、read、write三段超时:from httpx import Timeout timeout = Timeout(connect=5.0, read=30.0, write=10.0) response = litellm.completion(..., timeout=timeout)为什么重要?
connect=5.0防止 DNS 解析或 TCP 握手卡死(如错误的 api_base);read=30.0控制模型生成耗时;write=10.0限制请求体上传(防大文件 prompt)。某金融客服项目曾因未设connect超时,某次 Azure endpoint DNS 故障导致连接 hang 死,线程池耗尽,整个服务雪崩。num_retries与fallbacks:重试不是越多越好num_retries=3是常见配置,但它只对同一模型重试。真正的弹性在于fallbacks——当主模型失败时,自动切换至备用模型:response = litellm.completion( model="gpt-4", fallbacks=["gpt-3.5-turbo", "claude-3-haiku"], messages=messages )注意:fallbacks 是按顺序尝试,且每次重试都会重新计算 token 数。若
gpt-4因 context length 超限失败,切换到gpt-3.5-turbo可能仍失败(因其 max context 更小),此时应配置model_list实现智能降级:litellm.model_list = [ {"model_name": "gpt-4", "litellm_params": {"model": "gpt-4", "api_key": "..."}}, {"model_name": "gpt-3.5-turbo", "litellm_params": {"model": "gpt-3.5-turbo", "max_tokens": 4096}}, {"model_name": "claude-3-haiku", "litellm_params": {"model": "claude-3-haiku", "max_tokens": 200000}} ] # 调用时 response = litellm.completion(model="gpt-4", messages=messages, fallbacks=["gpt-3.5-turbo", "claude-3-haiku"])caching:缓存不是开关,而是分级策略caching=True开启的是内存级 LRU 缓存,仅对完全相同的messages+model+temperature组合生效。生产环境必须用 Redis:import litellm litellm.cache = litellm.RedisCache(host="localhost", port=6379, password=None)但要注意:缓存键默认包含
api_key,这意味着不同用户的相同请求不会命中同一缓存(安全设计)。若需共享缓存(如公共知识问答),需自定义 cache key:def custom_cache_key(*args, **kwargs): # 移除 api_key,只保留 model + messages 的 hash messages_hash = hashlib.md5(str(kwargs.get("messages", [])).encode()).hexdigest() return f"{kwargs.get('model')}_{messages_hash}" litellm.cache = litellm.RedisCache(..., custom_cache_key=custom_cache_key)mock_response:测试阶段的“断网生存能力”
单元测试时若依赖真实 API,CI 流程会因网络波动失败。LiteLLM 提供mock_response参数,可返回预设的 mock 数据:response = litellm.completion( model="gpt-4", messages=[{"role": "user", "content": "test"}], mock_response="This is a mocked response" # 直接返回字符串 ) # 或返回完整 mock 对象 mock_data = { "id": "chatcmpl-123", "object": "chat.completion", "created": 1712345678, "model": "gpt-4", "choices": [{"index": 0, "message": {"role": "assistant", "content": "mocked!"}, "finish_reason": "stop"}], "usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15} } response = litellm.completion(..., mock_response=mock_data)这让测试覆盖率提升至 100%,且无需启动任何外部服务。
litellm.success_callback:可观测性的最后一公里
仅靠日志不够,你需要结构化指标。LiteLLM 支持回调函数,在每次成功请求后触发:def log_success(response, *args, **kwargs): # 记录到 Prometheus llm_request_duration_seconds.labels( model=response.model, finish_reason=response.choices[0].finish_reason ).observe(response._response_ms / 1000.0) # 记录到 Elasticsearch es.index(index="llm-logs", document={ "timestamp": datetime.now().isoformat(), "model": response.model, "input_tokens": response.usage.prompt_tokens, "output_tokens": response.usage.completion_tokens, "latency_ms": response._response_ms }) litellm.success_callback = ["success_logger"] # 注册回调名 litellm.callbacks = [log_success] # 传入函数引用
3.3 模型能力校准:如何让 LiteLLM 真正“懂”你的私有模型
当你接入自建 vLLM 或 Ollama 模型时,LiteLLM 默认按通用规则处理,但往往不准确。例如 vLLM 的/v1/chat/completions接口支持n参数(返回多条结果),但 LiteLLM 默认只取第一条。这时需通过litellm.register_model()注册自定义能力:
litellm.register_model({ "model_name": "my-vllm-model", "litellm_params": { "model": "vllm/my-model", "api_base": "http://vllm-server:8000/v1", "api_key": "no-key-needed" }, "tiers": ["high-throughput"], # 自定义标签,用于路由 "supports_parallel_sampling": True, # 声明支持 n>1 "supports_n": True, "supports_max_tokens": True, "supports_system_message": True, "input_cost_per_token": 0.0000001, # 用于 cost tracking "output_cost_per_token": 0.0000002 })注册后,调用litellm.completion(model="my-vllm-model", n=3, ...)就会正确传递n=3参数,并解析返回的三条结果。更重要的是,supports_system_message=True会确保 system prompt 被正确放入messages[0],而非被 LiteLLM 误判为 user message。
4. 实操过程详解:从本地开发到灰度发布的全流程配置
4.1 本地开发环境:用 .env 文件管理多环境密钥
开发阶段最大的痛点是密钥泄露和环境混淆。LiteLLM 支持.env文件,但其解析规则有坑:它只读取KEY=VALUE格式,不支持# 注释或空行。正确的.env文件示例:
# .env.development OPENAI_API_KEY=sk-dev-... ANTHROPIC_API_KEY=sk-ant-api03-dev-... OLLAMA_BASE_URL=http://localhost:11434然后在代码中:
from litellm import dotenv_settings dotenv_settings() # 自动加载 .env 文件 # 或指定文件 from litellm import load_dotenv load_dotenv(".env.development")注意:.env文件必须位于项目根目录,且load_dotenv()必须在litellm.completion()之前调用。我曾因把.env放在子目录,导致本地调试一切正常,但 CI 环境因找不到密钥而全量失败。
4.2 Docker 部署:如何构建最小镜像并挂载配置
生产环境推荐 Docker 部署,但 LiteLLM 镜像不必包含所有模型依赖。最小化 Dockerfile:
FROM python:3.11-slim # 安装基础依赖 RUN pip install --no-cache-dir litellm uvicorn fastapi # 复制应用代码 COPY ./app /app WORKDIR /app # 暴露端口 EXPOSE 4000 # 启动命令 CMD ["uvicorn", "main:app", "--host", "0.0.0.0:4000", "--port", "4000"]关键点在于:不要在镜像中硬编码密钥。通过 Docker run 时挂载.env文件:
docker run -d \ --name llm-gateway \ -p 4000:4000 \ -v $(pwd)/prod.env:/app/.env \ my-litellm-imageprod.env文件内容:
OPENAI_API_KEY=sk-prod-... AZURE_API_KEY=azure-key-... AZURE_API_BASE=https://your-resource.openai.azure.com/ AZURE_API_VERSION=2024-02-01这样既保证密钥不进镜像,又支持不同环境使用不同配置。
4.3 灰度发布策略:用 LiteLLM Router 实现 5% 流量切到新模型
当要上线新模型(如 Claude-3.5-Sonnet),不能全量切换。LiteLLM 的Router类提供权重路由:
from litellm.router import Router router = Router( model_list=[ { "model_name": "gpt-4", "litellm_params": { "model": "gpt-4", "api_key": os.getenv("OPENAI_API_KEY") }, "tpm": 100000, # 每分钟 token 数限制 "rpm": 1000 # 每分钟请求数限制 }, { "model_name": "claude-3-5-sonnet", "litellm_params": { "model": "claude-3-5-sonnet-20240620", "api_key": os.getenv("ANTHROPIC_API_KEY") }, "tpm": 50000, "rpm": 500, "weight": 5 # 权重 5%,其余 95% 走 gpt-4 } ], num_retries=3, timeout=Timeout(connect=5.0, read=30.0, write=10.0) ) # 使用 router 而非直接调用 litellm.completion response = router.completion( model="gpt-4", # 主模型名 messages=messages, temperature=0.3 )Router 会根据weight字段按概率分配流量,并自动监控各模型的健康度(失败率 > 5% 自动降权)。某电商客服系统用此方案灰度上线 Claude-3.5,7 天内将权重从 5% 逐步提升至 100%,期间无一次服务中断。
4.4 成本监控实战:如何精确计算每条请求的真实花费
LiteLLM 内置成本计算器,但需正确配置模型单价:
# 注册模型价格(单位:美元/token) litellm.model_cost = { "gpt-4": {"input_cost_per_token": 0.00003, "output_cost_per_token": 0.00006}, "claude-3-haiku": {"input_cost_per_token": 0.0000025, "output_cost_per_token": 0.0000125}, "ollama/llama3:8b": {"input_cost_per_token": 0.0, "output_cost_per_token": 0.0} # 本地模型免费 } response = litellm.completion(...) # 获取成本信息 print(f"Input cost: ${response._response_headers.get('x-litellm-input-cost', 0)}") print(f"Output cost: ${response._response_headers.get('x-litellm-output-cost', 0)}") print(f"Total cost: ${response._response_headers.get('x-litellm-total-cost', 0)}")注意:_response_headers是 LiteLLM 注入的自定义 header,需在回调中提取。更实用的方式是结合success_callback:
def track_cost(response, *args, **kwargs): total_cost = response._response_headers.get("x-litellm-total-cost", 0) # 上报到成本分析平台 cost_analytics.record( model=response.model, input_tokens=response.usage.prompt_tokens, output_tokens=response.usage.completion_tokens, cost_usd=float(total_cost) ) litellm.success_callback = ["track_cost"]5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训
5.1 问题速查表:高频故障现象与根因定位
| 现象 | 可能根因 | 排查命令/步骤 | 解决方案 |
|---|---|---|---|
litellm.RateLimitError频繁触发,但监控显示 QPS 很低 | 后端模型的 RPM/TPM 限制是按API Key分配,而非按服务实例 | curl -v https://api.openai.com/v1/models -H "Authorization: Bearer $KEY"查看x-ratelimit-limit-requestsheader | 检查是否多个服务共用同一 KEY;升级为 Azure AD 应用级密钥 |
流式响应chunk.choices[0].delta.content为空字符串 | Anthropic 的流式事件中,content_block_start事件不包含 content,首个content_block_delta才有内容 | 开启litellm.set_verbose(True),观察原始 event stream | 升级 LiteLLM 至 v1.42.0+,已修复 Anthropic 流式解析逻辑 |
response_format={"type":"json_object"}对 GPT-4 无效 | OpenAI 的 JSON mode 仅在gpt-4-1106-preview及更新模型支持,gpt-4不支持 | litellm.model_list中检查模型别名映射 | 将 model 参数改为"gpt-4-1106-preview"或"gpt-4-turbo" |
本地 Ollama 模型返回404 Not Found | Ollama 默认监听127.0.0.1:11434,Docker 容器内无法访问 localhost | docker run --network host ollama/ollama启动 Ollama | 或在 LiteLLM 中设置OLLAMA_BASE_URL=http://host.docker.internal:11434(Mac/Windows)或http://宿主机IP:11434(Linux) |
litellm.completion()报ModuleNotFoundError: No module named 'openai' | LiteLLM 依赖openai包进行 OpenAI 兼容层解析,但未自动安装 | pip install litellm[openai] | 推荐安装litellm[all]以支持全部 provider |
5.2 独家避坑技巧:来自三年生产环境的实战经验
提示:LiteLLM 的
drop_params=True是双刃剑。它让调用更宽容,但也掩盖了参数不兼容问题。我的做法是:开发环境设为False,CI 流程中加入参数兼容性检查脚本,生产环境再设为True并配合详细日志。
注意:
fallbacks不是万能的。当主模型因context_length_exceeded失败时,fallback 模型若 context 更小(如gpt-3.5-turbo的 16K <gpt-4的 128K),会二次失败。解决方案是预估 token 数:litellm.token_counter(model="gpt-4", text=str(messages)),若超过 80% 主模型 limit,则主动降级到更大 context 的模型(如claude-3-opus)。
提示:Azure OpenAI 的
api_version必须与 endpoint 严格匹配。2024-02-01版本支持response_format,但2023-05-15不支持。LiteLLM 不会校验版本兼容性,需人工确认。我的检查清单:curl -s "https://YOUR-RESOURCE.openai.azure.com/openai/deployments?api-version=2024-02-01" -H "api-key: YOUR-KEY",确认返回中包含"capabilities"字段。
注意:
litellm.cache的 Redis 连接若超时,会导致整个请求阻塞。务必配置连接池和超时:from redis import ConnectionPool pool = ConnectionPool( host="redis-host", port=6379, db=0, max_connections=20, socket_connect_timeout=1.0, socket_timeout=1.0 ) litellm.cache = litellm.RedisCache(connection_pool=pool)
提示:当使用
Router时,model_list中的tpm/rpm是软限制,LiteLLM 通过滑动窗口算法平滑限流。若需硬隔离(如防止 A 业务挤占 B 业务资源),应在 Router 外层加一层业务级限流(如slowapi),按user_id或tenant_id分桶。
5.3 性能压测实录:单节点 200 QPS 下的资源消耗与调优
我在某知识库问答服务中做过压测:单台 8C16G 云服务器,部署 LiteLLM + Uvicorn(workers=4),后端为 Azure OpenAIgpt-4-turbo。结果如下:
无缓存场景:P95 延迟 1.8s,CPU 使用率 65%,内存稳定在 1.2GB。瓶颈在
httpx连接池,默认limits=Limits(max_connections=100, max_keepalive_connections=20),当并发 >100 时出现连接等待。调优后:将
httpx.AsyncClient的 limits 提升至max_connections=500,并启用连接复用:import httpx litellm._async_client = httpx.AsyncClient( limits=httpx.Limits(max_connections=500, max_keepalive_connections=100), timeout=httpx.Timeout(connect=5.0, read=30.0, write=10.0) )P95 延迟降至 1.3s,CPU 使用率 42%,QPS 提升至 280。
缓存场景:接入 Redis 后,热点问题(如“公司简介”)缓存命中率 92%,P95 延迟降至 200ms,CPU 使用率 18%。但 Redis 连接数飙升,需按前述方式配置连接池。
最关键的发现:LiteLLM 本身的 CPU 开销几乎为零(<5%),95% 的耗时在模型推理和网络 IO。因此,性能优化重心永远是:网络连接池调优 > 缓存策略 > 模型选择。不要试图优化 LiteLLM 的 Python 代码,那是在错误的方向上努力。
6. 进阶扩展方向:当 LiteLLM 成为你的 AI 基础设施底座
6.1 与 LangChain / LlamaIndex 深度集成:不只是调用,更是编排
LiteLLM 常被当作 LangChain 的 LLM 后端,但多数人只用了ChatOpenAI的简单替换。真正的威力在于利用 LiteLLM 的 Router 和 Callback 实现动态编排。例如在 LangChain 中:
from langchain.chat_models import ChatLiteLLM from litellm.router import Router # 创建带 fallback 的 router router = Router( model_list=[...], fallbacks=["gpt-3.5-turbo", "claude-3-haiku"] ) # 注入到 LangChain llm = ChatLiteLLM( model="gpt-4", router=router, # 传入 router 而非普通 model streaming=True, callbacks=[MyCustomCallback()] # 自定义回调处理流式 chunk ) # 在 Chain 中使用 chain = LLMChain(llm=llm, prompt=prompt) result = chain.run(input="...")此时,LangChain 的LLMChain完全感知不到后端模型切换,所有 fallback、重试、缓存均由 LiteLLM 透明处理。某法律咨询项目用此方案,实现了“用户提问 → 自动判断问题类型(刑事/民事/行政)→ 路由至对应领域微调模型 → 若微调模型失败则 fallback 至通用 GPT-4”的全自动流程。
6.2 构建私有模型市场:用 LiteLLM 作为 SaaS 产品的模型插件中心
LiteLLM 的model_list机制天然支持多租户模型管理。某 AI 工具平台将其改造为“模型市场”:
- 每个租户在管理后台配置自己的模型列表(Azure、AWS Bedrock、自建 vLLM)
- 平台为每个租户生成唯一
api_key,通过litellm.api_key隔离调用 - 使用
litellm.success_callback记录租户级用量,生成账单 - 当租户购买新模型(如 Google Gemini),只需在数据库插入一条
model_list记录,无需发版