我记得第一次真正被多模型API折腾到崩溃是在做跨平台项目时刚把某家模型的流式接口调通又要接另一家的工具调用格式再往后还要兼容本地部署的开源模型。代码里到处是if provider xxx每个模型一套SDK、一套鉴权、一套错误码改一个模型等于改一遍系统。后来我接触了litellm这个开源项目解决的就是这堆破事。它把这些模型提供商的API统一成一个标准格式并提供网关代理能力把路由、降级、密钥管理、成本核算、限流这些杂活全部收口到一起。本文就从实际落地角度把litellm的定位、部署方式、核心配置和上线后容易踩的坑一次讲清楚。适合正在做多模型接入的小团队也适合想在公司内部搭建统一模型入口的开发者。1. 先说清楚litellm到底替你解决了什么1.1 多模型接入的痛点到底痛在哪假设你是一个后端开发产品经理今天说要用模型A明天又说模型B效果更好后天还想试试模型C。如果你直接面向各家API开发那你需要维护的是每家的鉴权方式不同有的用请求头有的用请求体返回结构不同有的叫choices有的叫content有的还嵌套两三层流式输出的格式不同字段名和推送节奏都不一样工具调用function calling的协议差异更大参数定义和返回解析完全对不上错误处理方式不同有的返回HTTP 200但里面是错误码有的直接429还有的是500。这些差异不是靠写几个适配函数就能消化的。一旦模型数量超过两三个你的代码里就会出现矩阵式的判断逻辑每个新增模型都要改动调用层甚至调用方。litellm的解法很直接所有模型接入和调用全部通过一套API格式完成底层差异由它来转换。1.2 它到底做了什么设计取舍litellm的核心设计可以归纳成三件事。第一是统一调用格式。它把所有供应商的模型都包装成“provider/model”这种写法比如openai/gpt-4o、anthropic/claude-3-5-sonnet、ollama/llama3.1然后统一出参。你在代码里的调用是这样的from litellm import completion response completion( modelopenai/gpt-4o, messages[{role: user, content: 你好}], )换模型时只改model字段调用侧结构完全不变。这在SDK模式下体验很明显。第二是提供网关形态。lintellm不仅能在Python代码里直接当SDK用还能以一个独立服务的形式跑起来对外提供兼容OpenAI格式的/v1/chat/completions等接口。这样不管你的客户端是什么语言只要会调OpenAI就能调litellm。所有模型请求先打到网关由网关负责转发到真正的供应商再把结果统一返回。第三是把工程侧的脏活收口。密钥管理、用量统计、成本预算、限流、权限隔离、多模型自动降级这些在直接对接模型时往往要自己造轮子在litellm里都是内置能力通过配置文件就能打开。提示不要把它理解成“又一个大模型聚合网站”。它是部署在你自己环境里的组件你的数据完全走自己的链路只是对外统一了接口和策略。2. 部署之前先理解两种形态选哪一种2.1 SDK模式代码里的统一出口SDK模式适合已经确定在Python技术栈里、并且不想额外维护服务的团队。你只需要pip install litellm然后直接在业务代码里调用。好处是接入成本极低项目里不需要多一个进程。但问题也很明显密钥分散在各业务节点上成本统计只能自己汇总权限控制只能靠代码review。所以在大多数场景下我建议至少从Proxy模式起步哪怕一开始只有两个模型。2.2 Proxy模式一台网关解决所有问题Proxy模式是litellm最被低估的地方也是我强烈推荐使用的形态。你运行一个服务所有业务系统、其他开发语言的项目、甚至非技术人员手里的调试工具都往这一个地址上打请求。网关负责按模型名路由到对应的真实供应商校验调用方的虚拟密钥记录每一次请求的花费和token用量执行预算限制和限流在某个供应商挂掉或限流时自动切换备用模型。这种架构带来的一个很实际的好处是业务代码不直接持有任何供应商密钥。任何人都可以申请一个带额度限制的虚拟密钥而真正的供应商key只存于网关环境变量或配置里。这对团队协作、权限治理和合规审计都非常有价值。我个人的建议是如果你所在团队超过两个人、或者项目要长时间持续迭代直接上Proxy模式。前期多花半小时部署后面省下的绝对不止半小时。3. 手把手搭一个可用的LLM网关3.1 最小配置先把服务跑起来在开始之前先保证环境里已安装Python 3.8以上版本然后安装litellm我用的是长期稳定版本pip install litellm[proxy]安装完成后准备一个最简单的配置文件config.yamlmodel_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY general_settings: master_key: sk-master-123456这里注意几个关键点model_name是暴露给调用方的名字可以随便起代表的是“逻辑模型”litellm_params.model才是真正请求供应商时用的名字格式必须是供应商/具体模型不能写错master_key是管理网关的超级密钥调用方用的虚拟密钥要另行生成不直接用它访问模型。然后启动服务litellm --config config.yaml --port 8000看到类似Uvicorn running on http://0.0.0.0:8000就说明服务起来了。用curl测一下是否正常curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-123456 \ -d {model: gpt-4o, messages: [{role: user, content: 你好}]}如果返回了正常的completion结构恭喜第一条通道已经打通。3.2 路由策略与供应商降级是怎么回事现实场景中同一个逻辑模型往往会对应多个真实供应商渠道。比如你想访问某个开源模型本地跑了一份云端托管跑了一份那就可以在配置里写多个上游model_list: - model_name: llama3.1 litellm_params: model: ollama/llama3.1 api_key: fake-key - model_name: llama3.1 litellm_params: model: groq/llama-3.1-70b-versatile api_key: os.environ/GROQ_API_KEY当外部请求modelllama3.1时litellm会按照配置顺序选择可用上游。如果第一个上游返回超时或不可用它还能自动切换到第二个。这就是降级能力。这种做法的价值在于上游供应商出现故障时你可以做到“用户无感切换”不需要让前端改任何参数。还可以通过权重控制流量分配比如两个上游都健康时让较高亮度的渠道承担更多请求model_list: - model_name: llama3.1 litellm_params: model: ollama/llama3.1 model_info: priority: 2 - model_name: llama3.1 litellm_params: model: groq/llama-3.1-70b-versatile model_info: priority: 1priority数值越大优先级越高。默认情况下litellm优先打向高优先级上游只有失败才转低优先级。这比自己做熔断逻辑舒服得多。注意不要把优先级和负载均衡混为一谈。如果你需要的是在多个渠道间平均分摊流量要用路由策略配置而不是这里讲的降级优先级。3.3 虚拟密钥与权限隔离网关起来了最不该做的事情就是让所有同事共用master_key。litellm提供了虚拟密钥体系你可以通过管理接口生成带约束的key。首先生成一个密钥curl -X POST http://localhost:8000/key/generate \ -H Authorization: Bearer sk-master-123456 \ -H Content-Type: application/json \ -d { models: [gpt-4o, claude-3-5-sonnet], max_budget: 20, budget_duration: 30d }返回结果里有一个token字段这个就是虚拟密钥。把它分发给对应同学或业务系统就好。这套设计非常贴近实际团队管理不同项目组用不同key报表里能看出谁消耗了多少可以给一个key设置30天的总额度超了就自动拒绝可以限制这个key只能访问某些模型防止误调到高成本模型key过期、吊销、临时关停都很方便不需要去供应商控制台操作。以前我见过团队把供应商key直接写在配置文件里后来有人误调用了一个超大模型一个晚上花掉了几个月的预算。用这种带预算约束的虚拟密钥之后至少不会出现这种低级事故。上面生成密钥的接口也可以从管理UI去操作。启动时加上--ui参数或者在配置里开启ui会自动提供一个本地管理页面进去之后可以直观地管理密钥、查看实时请求和消费记录。这对非技术同事特别友好省去了教他们用curl的麻烦。3.4 成本控制和用量追踪怎么做成本管理是litellm最能直接回本的功能。它会在每次请求后自动计算token消耗与花费你可以随时查看某个key、某个模型或某个时间段的用量。先看实时日志curl http://localhost:8000/spend/logs \ -H Authorization: Bearer sk-master-123456返回里包含每次请求的时间、模型、token数、估算费用和响应耗时。如果想统计某个虚拟密钥这段时间总共花了多少curl http://localhost:8000/key/info?keytest-key \ -H Authorization: Bearer sk-master-123456这里能拿到该key的总花费、请求次数和剩余额度。不过要注意litellm的计价是基于内置的定价表估算的。如果你接入的模型不在内置定价表中费用可能会算不出来或者算成0后面我会专门讲怎么处理。另外如果想保存长期历史数据就需要给litellm配置一个数据库比如PostgreSQL或MariaDB并记录每次调用的元信息general_settings: master_key: sk-master-123456 database_url: os.environ/DATABASE_URL配置了数据库之后spend日志才能跨重启持久保存管理后台的报表也才完整。没有数据库的情况下网关一重启历史用量记录就清空了这在生产环境是绝对不能接受的。4. 常见问题与排查技巧实录4.1 请求失败时最常见的几种原因我实际用下来线上出问题大多是这几类。第一是模型名写错。很多人把model_name当作真正要调用的模型直接填结果litellm要求的是openai/gpt-4o这种带前缀的格式。解决办法就是检查配置里litellm_params.model字段是否以供应商前缀开头。第二是上游限流。供应商对每个账号或IP都有并发限制一旦同时来了大量请求就会返回429。litellm默认会自动重试一部分限流请求但重试次数有限。你可以调整重试参数general_settings: request_timeout: 600 num_retries: 3 retry_after: 5第三是上下文长度溢出。请求的对话太长供应商模型最大上下文不够会直接报400。这个问题网关层很难自动解决需要在客户端做摘要截断或分段处理。不过litellm会在错误信息里附带具体的模型上下文限制至少排查起来快很多。第四是虚拟密钥没有关联任何模型。生成key时没指定可访问模型列表调用时路由规则又要求key具备特定模型权限就会出现403。我建议生成key时统一指定models字段并和调用侧约定好逻辑模型名。还有一类是上游网络不稳定。litellm的默认超时可能偏短遇到慢模型或复杂推理请求时容易“超时失败”。可以按模型单独调长超时时间但也要注意并不是越长越好太长的超时会让整体可用性下降建议控制在合理范围内并配套降级策略。4.2 成本数据对不上怎么办成本统计是很多人第一次用litellm时会觉得“有点小问题”的地方。原因通常出在两个环节。一个是litellm内置的定价表是根据各大模型公开价格整理的但供应商可能会调整价格或者你用的是某个第三方托管的同款模型价格不同。另一个是你接入的是很小众的模型定价表里根本没有记录此时litellm会默认按0计算或直接不记录金额。解决方案是手动在配置里补充模型定价信息。以某个模型为例model_list: - model_name: my-custom-model litellm_params: model: openai/my-custom-model api_key: os.environ/OPENAI_API_KEY model_info: cost_per_1k_tokens: 0.002 cost_per_1k_tokens_output: 0.002这里cost_per_1k_tokens是输入价格按每千token多少美元计算输出价格单独设置。填好之后再发起请求spend日志里就会按你填的价格估算费用。另外一个容易忽略的细节是流式请求的token统计。开启流式输出时如果客户端提前中断了连接网关可能拿不到完整的用量数据。在私有化部署或内部使用场景中其实可以接受这种统计误差但你要是做账单级核算就要谨慎评估这个问题了。4.3 高并发和高性能场景的实践经验litellm默认的部署形态是一个FastAPI应用用Uvicorn启动默认严格来说是单进程多线程。如果内部并发量不大这种方式没问题。但一旦作为团队公共网关请求量上来了吞吐和延迟都会有压力。我的经验是从这几个方向调优。第一是用多worker启动。可以在命令行指定worker数量例如litellm --config config.yaml --port 8000 --num_workers 4需要注意的是多worker下内存型缓存和部分状态不是共享的如果启用了虚拟密钥、限流等依赖缓存的特性最好配置Redis作为共享存储。第二是给litellm配Redis。在config.yaml里general_settings: redis_url: os.environ/REDIS_URLRedis会让速率限制、key校验和缓存跨worker共享避免某个key在worker A上通过了worker B却不知道。第三是合理配置上游连接池。litellm底层依赖HTTP客户端连接复用会直接影响延迟。实测中保持keep-alive、减少重复握手对吞吐的提升非常明显。如果你的核心模型集中在少数几个供应商建议提高单个上游的并发连接数同时观察供应商侧有没有限流。第四是打开缓存。对于同样的系统提示词或重复性较高的请求开启响应缓存能显著降低上游调用量。用Redis做缓存后可以这样配置general_settings: cache: true cache_params: type: redis host: localhost port: 6379这个功能特别适合内部知识库问答这种场景重复问题的命中率很高上游调用成本能降不少。4.4 和现有框架集成时要注意什么litellm一个很妙的地方在于它对外提供的是OpenAI兼容接口。所以你现有的程序如果已经在用OpenAI SDK只需要把base_url换成litellm的地址、把key换成虚拟密钥即可不用改业务逻辑。我在某个跨平台系统里就是这么接入的改动量非常小。但有一个细节容易踩坑不同框架对SDK版本和base_url的处理方式不一样。有些老版本SDK会强制拼接/v1路径如果你在litellm的接口地址里已经写了/v1就可能出现重复路径。解决方法是先确认SDK版本支持的base_url写法建议统一使用不带尾部斜杠的地址再实测一次。另外如果你在用LangChain这类编排框架litellm本身也提供了集成模块可以直接在链式调用里通过ChatOpenAI指定openai_api_base或者干脆用litellm自己的callable作为LLM节点两种都试过都能跑通。这里我的建议是能走统一base_url就不走额外插件减少依赖链条将来排查问题也更简单。最后提醒一句网关不是越多越好。如果只是十几个人内部使用一台跑litellm的服务器加一个Redis完全够用。没必要因为性能焦虑把它拆成微服务徒增运维成本。我个人在这几个项目的实操中最大的收获是litellm把“接入模型”这件事从架构问题降级成了配置问题。以前每接一个新模型都要经历开发、测试、发布整个流程现在只要改配置、加密钥、通知调用方新模型名十几分钟就能上线。这个体验差异让我后续在技术选型时对“有没有统一API网关层”这件事变得特别看重。如果你所在团队也正在被多模型API折磨不妨先搭一个最小网关试试从两个模型开始你会很快感受到区别。