litellm 这个项目我第一次注意到它是在做多模型对比需求的时候。当时要在一个工具里同时接入好几家大模型的接口每家都有独立的鉴权方式、消息格式和返回结构代码里全是 if-else 适配层加一个新供应商就得改一遍调用代码。litellm 的价值在于它把这一堆杂乱的东西统一成一套 OpenAI 风格的标准接口你只需要维护一份调用代码剩下的格式转换、重试、模型路由全部交给它处理。如果你是做 AI 应用开发、后端接口封装或者正在搞企业内部的模型网关这篇文章会比较适合你。我会从它解决的问题出发拆清楚核心工作原理再给出本地部署的最小配置、生产环境的关键能力最后聊几个实际落地时容易踩的坑。全程用实操视角讲尽量少废话。1. 先搞清楚 litellm 在解决什么问题多模型调用的“方言”困境1.1 碎片化调用带来的维护成本现在的模型接口生态很像一个有好几种方言的社区。OpenAI 系用/chat/completions有的厂商用/messages有的用/generate消息结构有的是messages数组有的是prompt字符串返回内容有的在choices[0].message.content有的在output.text。如果你的应用只需要调一家模型那问题不大写死就好。但只要你想做模型对比、多供应商容灾、或者根据不同场景切换更便宜的模型碎片化问题立刻变成实打实的开发成本。我见过不少团队的做法是写一个自己的llm_client.py里面堆满各种 provider 的适配函数。前几个供应商还好加到第五六个的时候异常处理、重试逻辑、token 统计全混在一起改一个厂商的参数都有可能影响另外几家。更麻烦的是有些新模型只提供 OpenAI 兼容接口有些只提供自家 SDK你的封装层会越来越厚直到某天有人不敢再动那个文件。1.2 litellm 统一抽象层为什么能成立litellm 做的事情本质上是一个统一抽象层。它把上百家模型 API 的差异消化在内部对外暴露 OpenAI 风格的/v1/chat/completions接口。这样做的关键原因是OpenAI 的接口格式已经成为事实标准大部分新发布的模型都会自带一个 OpenAI 兼容模式你的代码只要按这套格式写就能通吃绝大多数场景。举个例子你在 litellm 里配置gpt-4o-mini和某国产开源模型应用层发送的请求体完全一样都由 litellm 翻译成各家模型认识的格式再把各家返回结果翻译成统一的响应体。这个思路类似于数据库连接池或者 API 网关应用不直接和每个后端打交道而是统一走一个代理。不仅少写代码后续加新模型只需要改配置文件不用动核心逻辑。2. litellm 的代理模式核心一个端点所有人都能兼容2.1 请求从进入到返回的流转链路litellm 有两种使用方式直接当 SDK 用或者起一个代理服务。SDK 方式适合脚本和内部工具代理方式适合多服务共享、需要统一管理和鉴权的场景。生产上我更推荐代理模式因为配置集中、故障可观察、密钥不用分发到每个业务服务。代理模式的请求链路大致是这样客户端把 OpenAI 格式的请求发给 litellm 服务litellm 根据配置的model_name找到对应的真实模型和后端供应商它把请求转换成目标厂商要求的格式发出去拿到响应后litellm 再统一成 OpenAI 格式返回。中间还会插入额外的逻辑比如记录 token 消耗、触发重试、检查限流、做负载均衡。这个链路的妙处在于业务方完全无感。你后端服务里用的是openai这个 SDKbase_url 指向 litellmAPI key 用自己的虚拟 key剩下的复杂度和故障都隔离在 litellm 这一层。2.2 一套 OpenAI 格式打天下的边界不过也别把“统一格式”想得太完美。实际使用中你会发现有些能力是不能完全统一的。比如视觉模型传图片的方式、工具调用function calling的参数结构、某些厂商特有的参数如thinking或reasoning_effort这些在不同模型之间差异很大。litellm 的做法是尽量兼容共同子集把厂商特有参数通过特殊字段传下去。我给大家的建议是如果只是文本对话、文本补全、Embedding 这类基础能力统一格式完全可以覆盖。如果你要深度使用某个厂商的独有功能比如 Claude 的长上下文缓存或 Gemini 的多模态细节参数那最好为这个场景单独配置一个模型入口在应用侧针对性地写一小段代码不要强行塞进统一抽象里。否则调试排查的时间可能比省下来的代码量还多。3. 本地跑起来安装、启动与第一次调用3.1 环境准备和小白避坑点本地部署 litellm 其实要求很低一台能跑 Python 的机器就行。安装很简单pip install litellm装完之后可以先验证一下版本python -c import litellm; print(litellm.__version__)这里有个很容易忽略的点litellm 依赖很多可选包比如openai、anthropic、azure-identity等。如果你只用到其中某几家模型建议让 litellm 按需安装依赖而不是一把梭把所有的 provider SDK 全装进来干脆是也没问题就是环境会臃肿不少。另外如果你 Python 环境比较乱我强烈建议先建一个虚拟环境再装避免和系统级 Python 的包打架。3.2 最小配置配置文件里到底要写什么litellm 代理服务支持--config指定一个 YAML 文件最小配置看起来像这样model_list: - model_name: my-gpt litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY注意这里model_name是你自己定义的别名业务端请求时用的就是这个名字。litellm_params.model才是真正的后端模型标识openai/前缀表示走 OpenAI 供应商。还需要设置两个环境变量export LITELLM_MASTER_KEYsk-your-master-key export LITELLM_SALT_KEYyour-random-saltLITELLM_MASTER_KEY是管理权限的密钥用来访问管理接口和生成虚拟 key。LITELLM_SALT_KEY是用来加密虚拟 key 的盐值随便生成一串足够长的随机字符串就行。如果你跳过这一步代理会默认不鉴权启动本地测试问题不大一旦部署到服务器上风险很高后面我会专门说这个问题。3.3 第一次调通代理用 curl 验证全链路启动服务litellm --config config.yaml --port 8000看到日志里出现Uvicorn running on http://0.0.0.0:8000就说明服务起来了。然后用 curl 发一个最简单的对话请求curl http://localhost:8000/v1/chat/completions \ -H Authorization: Bearer sk-some-virtual-key \ -H Content-Type: application/json \ -d { model: my-gpt, messages: [{role: user, content: 你好介绍一下你自己}] }如果把model换成my-gptlitellm 会去查配置表转发给真实的模型。第一次调用建议把litellm --debug加上能看到详细的请求日志方便排查密钥和网络问题。如果你觉得 curl 不够直观直接在 Python 里用 OpenAI SDK 测也行from openai import OpenAI client OpenAI( base_urlhttp://localhost:8000/v1, api_keysk-some-virtual-key, ) resp client.chat.completions.create( modelmy-gpt, messages[{role: user, content: 写一段 Hello World 代码}], ) print(resp.choices[0].message.content)跑通这一步你已经把多模型接入的第一步走完了。后面要做的就是在配置里继续堆模型、配策略。4. 上生产前的关键能力模型路由、重试降级与成本追踪4.1 多个模型共用一个别名路由策略配置litellm 支持一个model_name对应多个真实模型每次请求时按策略选择其中一个。这个能力太重要了因为这是做模型容灾和成本优化的基础。model_list: - model_name: my-gpt litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY model_info: weight: 80 - model_name: my-gpt litellm_params: model: anthropic/claude-3-haiku api_key: os.environ/ANTHROPIC_API_KEY model_info: weight: 20同一个my-gpt下挂两个真实模型litellm 会按权重分配流量。80% 的请求走 GPT20% 走 Claude某一供应商报错时自动转移到另一个。这样配置的优势是业务侧代码完全不用关心后端换没换你甚至可以白天用贵模型保证质量晚上切到便宜模型降低成本。litellm 的路由策略还支持按请求负载来选例如 least busy 策略会优先选择当前在途请求数最少的后端。如果你们的流量波动大我觉得权重模式通常够用如果某个后端经常慢least busy 会更稳一点启动时加个参数或者配置里指定就行。4.2 重试与降级别把业务方的错误直接抛给用户模型接口出现超时、限流、5xx 错误是家常便饭。litellm 内置了重试机制在配置里可以这样写litellm_settings: num_retries: 3 timeout: 600 fallbacks: [{my-gpt: [my-fallback-model]}]num_retries控制失败重试次数timeout是单次请求超时时间fallbacks是更彻底的降级策略主模型全挂了就切换到备选模型。你可以配置一个便宜、稳定但质量稍低的模型作为最后防线这样用户体验不至于直接被一个 503 打断。这里有个容易忽略的细节重试之间最好有退避策略否则后端限流刚恢复又被你连续打挂。litellm 支持设置重试退避时间我在生产环境一般配置 1 秒到 3 秒的递增等待实测对限流恢复比较友好。4.3 成本追踪搞清楚每个请求到底花了多少钱多模型接入的隐藏痛点其实是成本看不清楚。不同模型单价天差地别如果不做追踪月底账单出来基本是笔糊涂账。litellm 自带spend记录功能它会记录每个请求的输入 token 数、输出 token 数、预估成本、模型名、API key、用户信息。如果你把 litellm 的 metering 功能打开它会在 SQLite 或 Postgres 里建表之后可以通过管理接口查询curl http://localhost:8000/spend/logs \ -H Authorization: Bearer sk-master-key我建议从第一天就把这个功能打开哪怕本地测试也用上。否则上线后再补历史数据只能靠猜运维成本会高很多。5. 落地时最容易翻车的几个细节个人踩坑合集5.1 密钥管理配置文件和虚拟 Key 的安全边界我见过不少团队把 API key 直接写进 YAML 文件提交到代码仓库这是最危险的做法。litellm 支持用os.environ/VAR_NAME形式引用环境变量千万不要把真实密钥硬编码。另外生产环境要启用虚拟 keyVirtual Keys功能业务方使用的是 litellm 生成的虚拟 key真实供应商密钥只存在于 litellm 服务端。虚拟 key 的另一个好处是可以设置预算上限。某个内部工具、某个临时脚本需要调模型你不想给它开放全部权限可以创建一个预算 50 美元的虚拟 key超额自动拒绝。这在多人团队场景下非常实用。5.2 运维层面的两个问题并发超时和日志缺失litellm 默认服务对单个请求的排队和并发控制其实比较基础。流量一大你可能发现某个慢模型阻塞了整个代理线程池。建议在 litellm 前面加一层 Nginx 或负载均衡同时给每个模型设置合理的 timeout。不要觉得 timeout 越大越好一个请求卡住五分钟背后往往拖着数据库连接和业务线程。我的经验是大多数文本对话接口 30 到 60 秒足够长上下文场景再单独调。日志也很重要。litellm 自带控制台日志但生产环境应该接入结构化日志和可观测系统。至少要能查到这几个维度哪些模型调用失败率高、哪些 key 用了多少额度、平均首 token 延迟是多少。没有这些数据你根本没法判断是模型供应商的问题还是自己配置的问题。5.3 多实例部署时注意状态一致性litellm 如果只跑一个实例配置存在本地文件就行。但一旦做高可用部署多个实例共享同一个 metering 数据库会带来并发写入问题同时虚拟 key 的加密信息也要保持一致。我的建议是生产环境至少部署两个实例前面挂负载均衡Postgres 做统一状态存储。LITELLM_SALT_KEY必须在所有实例中保持一致否则一个实例生成的虚拟 key另一个实例无法解析。另外一个比较隐蔽的坑是业务服务如果直接调用 litellm 实例的 IP而不是通过服务发现和负载均衡入口一旦实例重启或者扩缩容连接就会断。最好统一通过内部 DNS 或网关访问 litellm这样扩缩容对业务完全透明。最后再分享一个小技巧litellm 的配置文件变更后可以先执行litellm --config config.yaml --test做一次配置校验确认每个模型的路由和密钥都能正确连通再重启服务。这个命令能省掉很多“启动没报错但一调用就 500”的尴尬时刻。