做AI应用开发这几年我踩过最多的坑就是各家模型API不统一这家用prompt那家用messages这家叫max_tokens那家叫max_tokens_to_sample返回结构更是千奇百怪换一个模型就要重写一遍客户端。后来我用LiteLLM把这堆事情全部收编了一个接口接所有模型省下来的时间足够我多调好几轮prompt。如果你也在被多模型接入折磨或者想给团队搭一个统一的模型网关这篇分享应该能给你省下不少弯路。LiteLLM本身是一个开源项目核心就一句话把市面上主流大模型API全部转成OpenAI兼容接口。它有两种用法一种是作为Python库直接嵌进你的代码里另一种是起一个代理服务让整个团队或所有后端服务都通过这一个网关去访问不同模型。配合上密钥管理、成本追踪、负载均衡、自动重试这些能力它基本就是一个轻量级的LLM网关。我在实际项目里同时用到了这两种形态本地脚本和快速验证用SDK线上服务统一走代理。这篇就把我的使用经验、踩过的坑和关键配置都整理出来希望能给你一个可参考的落地路径。1. 为什么需要LiteLLM多模型接入的切肤之痛在聊配置和代码之前先得搞明白一个问题市面上已经有那么多模型服务商和封装工具为什么我还要专门维护一个LiteLLM说白了是因为多模型接入这件事远比你想象的更折磨人。1.1 各家的API从来就没有统一过先说最直观的请求格式。OpenAI系的接口用messages数组传对话历史每条消息有role和content有些平台则用prompt直接塞字符串还有些偏学术的部署框架喜欢用inputs或者text作为字段名。你以为只是字段名不同参数名也不一样OpenAI叫temperature有的平台叫temperature但取值范围不同还有的干脆叫top_p却不支持temperature。这些还只是接口层的问题。往下挖鉴权方式也各有各的脾气有的是Authorization: Bearer有的要求x-api-key还有的要你在请求体里单独塞一个api_key字段。返回结构更不用说OpenAI的choices[0].message.content是一个固定的访问路径但别家返回的长得完全不一样有的是data.choices有的把内容放在output.text里。这种差异带来的直接后果就是你每接入一个新模型就要写一套新的请求构造逻辑、响应解析逻辑、错误处理逻辑。如果只是自己跑个Demo还好一旦在上生产环境把这些写进业务代码里后面每换一次模型就要动一次代码、发一次版、回归一轮测试。我见过不少项目半年之后代码里躺着四五套互不兼容的模型客户端维护成本高得吓人。打个比方这就跟你家里的电器一样每个厂家都用自己的插座标准你要么给每个电器配一个转接头要么干脆装一个万能插座。LiteLLM干的就是这个万能插座的活儿——你只需要写一套OpenAI格式的代码它帮你把请求翻译成各平台能听懂的语言再把各平台返回的数据翻译回OpenAI格式。1.2 统一网关的定位与设计思路LiteLLM选择把所有模型都翻译成OpenAI兼容格式这个设计决策非常聪明。原因有两个第一OpenAI的API格式是事实上的行业标准生态最成熟几乎所有的开源工具、框架、SDK都原生支持OpenAI格式第二对开发者来说学习成本最低你会了OpenAI SDK就等于会了LiteLLM。整个项目的定位可以理解为LLM请求的路由器兼翻译器。你往它里面塞配置告诉它哪个虚拟模型名对应哪家平台的哪个模型然后所有请求都打到这个统一入口由它来决定这个请求应该转发给谁、用哪个key、要不要重试、要不要记录成本。这个思路的好处是业务代码和模型提供商彻底解耦了。你的业务代码只认识gpt-4o这个名字今天它可能真的在调用OpenAI的gpt-4o明天你把这个虚拟模型名重新映射到另一个平台的同类模型业务代码不用动一行只要改配置、重启服务就行。对于需要频繁对比不同模型效果、或者担心被单一平台绑定的团队来说这个灵活性非常值钱。不过也要说句公道话LiteLLM不是万能的。各家模型的特殊参数它虽然大部分都转发了但极个别独特的、不常见的参数可能没法完全兼容需要你在虚拟模型配置里用extra_body之类的字段手动透传。所以它解决的是80%的通用场景剩下20%的个性化需求还是要有Backup方案。2. 架构与核心功能拆解想把这个工具用好光知道能接很多模型不够还得理解它的整体结构。LiteLLM的架构核心其实就两层入口统一出口多样。入口永远是一个OpenAI风格的API出口则通过配置决定。2.1 SDK与Proxy两种工作模式LiteLLM提供两种工作模式适用场景完全不同。第一种是SDK模式。你在Python代码里直接import litellm然后调用litellm.completion()方法传入model参数和messages参数就行。SDK模式下面LiteLLM库本身承担了翻译、鉴权、重试、成本统计这些工作。这种方式的好处是轻量、灵活适合在本地脚本、数据分析、模型对比测试这类场景里用代码部署起来最简单不依赖额外的服务进程。第二种是Proxy模式。LiteLLM起一个独立的HTTP服务监听一个端口默认4000所有请求都通过HTTP发到这个服务再由它转发到底层模型平台。这个模式更接近企业级网关的用法部署一次团队共享前端、后端、测试脚本都通过这个网关访问模型。密钥集中管理不需要把各家平台的key发给每个开发人员成本统一统计方便核算还可以在网关层做限流、配额、负载均衡。我的建议是个人项目或者初期探索期用SDK模式足够了简单直接一旦进入团队协作或者生产环境果断切到Proxy模式。理由很简单SDK模式把逻辑都打进业务代码里换模型要改代码、发版Proxy模式把模型接入做成一个独立服务换模型只改配置文件。生产环境追求的是变更频率越低越好Proxy模式天然更适合。2.2 核心功能模块模型注册、密钥路由、成本追踪、负载均衡LiteLLM代理能做的事远不止格式翻译这一项。我在生产环境实际用得最频繁的是下面这四个模块第一模型注册与映射。在config.yaml里设置model_list每个条目定义一个虚拟模型名和它对应的真实模型。比如虚拟名gpt-4o映射到openai/gpt-4o带上api_key。之后所有请求都只提虚拟名网关负责查表、翻译、转发。你甚至可以把gpt-4o映射到一个完全不同的平台模型只要你想虚拟名而已不绑定任何厂商。第二密钥路由与轮询。一个模型可以有多个API key比如你注册了多个账号每个账号都有额度。LiteLLM可以在这一组密钥之间自动做负载均衡一个key触发限流了就自动切到下一个key。这个功能对高频调用场景来说简直是续命神器直接绕开了单个账号的速率限制。第三成本追踪。LiteLLM会记录每次请求的输入token数和输出token数再结合模型单价算出费用。在代理模式下它还提供了一个/spend接口可以按key、按用户、按模型维度查询历史花费。做预算管理或者给客户做计费报表这个功能非常关键。第四负载均衡与重试回退。当多个模型都能完成同一个任务时可以在配置里定义一个模型组LiteLLM会根据你设置的策略轮询、随机、优先级等自动分发请求。某个模型返回错误或超时它会自动尝试组里的另一个模型对业务方完全透明。这种容灾设计在依赖大模型的生产链路里至关重要毕竟任何一家平台的稳定性都不是百分之百。这四个模块单独拎出来每个都有对应的专业产品可以做但LiteLLM把它们整合到了一个工具里而且和模型接入这件事本身紧耦合。这就是它的核心价值不是解决一个点而是把接入模型这段路上你能遇到的所有通用问题打包处理了。3. 从零搭建LiteLLM的完整实操理论说再多不如跑一遍。这一章我带你从安装开始一步步搭出一个能用的LiteLLM代理服务验证它能转发请求到真实模型平台。3.1 安装与环境准备环境要求其实很宽松我用的是Python 3.10理论上3.8以上都能跑。安装命令很简单pip install litellm[proxy]这里注意[proxy]这个扩展必须装它才会带上代理服务所需的依赖比如FastAPI、uvicorn这些。如果你只用SDK模式直接pip install litellm就够了。装完之后设置环境变量。LiteLLM约定每种模型平台的API key都通过特定的环境变量名读取比如某主流平台的key默认读OPENAI_API_KEY另一个主流对话模型平台的key默认读ANTHROPIC_API_KEY。如果你是在Linux或macOS上export OPENAI_API_KEYsk-你的key export ANTHROPIC_API_KEYsk-ant-你的keyWindows下就用set命令或者干脆写到.env文件里用export $(cat .env)加载。这一步非常关键我在刚开始用的时候经常忘记设置环境变量结果所有请求都报401还以为是自己代码写错了排查半天才发现是环境变量没加载。3.2 config.yaml的模型映射详解代理模式的灵魂全在这个配置文件里。下面是一份我常用的最小配置model_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 - model_name: llama3-70b litellm_params: model: ollama/llama3:70b api_base: http://localhost:11434这个配置文件里面有几个重要细节一定要理解了再上手model_name是虚拟模型名也就是你对外暴露的名字业务方只认这个名字。litellm_params.model是真实模型标识格式是提供商/模型名。openai/gpt-4o表示走OpenAI标准接口anthropic/claude-3-5-sonnet表示走Anthropic接口ollama/llama3:70b表示走本地Ollama服务。前缀决定了LiteLLM用什么协议去访问写错了它就会按错误的协议去请求大概率报错。api_key这里可以直接放明文但更好的是用os.environ/VAR_NAME这种写法让LiteLLM从环境变量读取。这样你的key不会明文暴露在配置文件里安全性高很多也方便在不同环境之间切换。对于本地模型比如Ollama通常不需要api_key但可能需要指定api_base告诉LiteLLM本地服务监听在哪里。模板还有个隐藏功能model_name可以和真实模型不一样。你可以故意把所有模型都映射到同一个真实模型比如A/B测试时避免业务方感知也可以把一个真实模型映射成多个虚拟名给不同业务线分别配额计费。灵活性很高。3.3 启动代理服务配置文件写好了启动服务就一条命令litellm --config config.yaml --port 4000看到类似Uvicorn running on http://0.0.0.0:4000的日志说明服务起来了。这时候先别急着写代码用curl探探路curl http://localhost:4000/health如果返回一个正常的JSON状态说明网关活着。接下来发一个真正的对话请求curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的代理密钥 \ -d { model: gpt-4o, messages: [{role: user, content: 你好介绍一下你自己}] }这里要特别注意两个地方。第一个是URL路径LiteLLM兼容OpenAI的/v1/chat/completions路径你不用自己拼路径直接按OpenAI的习惯来。第二个是请求头代理默认需要一个key才能访问这个key可以通过环境变量LITELLM_MASTER_KEY设置如果没设LiteLLM会在启动日志里打印一个临时key。我之前没设master key结果发现测试客户端一直连不上日志里才看到临时key早知道就不用白折腾了。如果你是用Python的OpenAI SDK访问这个代理写法也几乎不用改只需要把base_url和api_key指向你自己的服务from openai import OpenAI client OpenAI( base_urlhttp://localhost:4000, api_keysk-你的代理密钥 ) response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 讲个冷笑话}] ) print(response.choices[0].message.content)这段代码的要点在于除了base_url和api_key其他东西跟直接调OpenAI完全一样。你换模型的时候只需要改model字段比如改成claude-3-5-sonnet代码其他地方一行都不用动。这种偷懒带来的好处在你同时接十个模型的时候体会最深。4. 生产环境关键配置成本、限流与重试开发环境通了只是第一步真上生产你会发现另外三件事特别重要成本要能看到流量要能控制失败要能自愈。这一章我聊聊这三个方面的配置实践。4.1 成本追踪与预算管控记账这件事别看简单做不好很头疼。LiteLLM默认会对大部分主流模型预设单价所以请求进来之后它自动就能算出这轮对话花了多少钱。每次请求的日志里会带上spend字段精确到小数后四位。如果你用的是比较新的模型或者自己部署的开源模型LiteLLM可能不认识它的价格这时候需要手动在配置里补充价格信息。在model_list里给对应的模型条目加上model_info比如model_list: - model_name: my-custom-llm litellm_params: model: openai/my-custom-llm api_base: http://your-endpoint api_key: os.environ/CUSTOM_API_KEY model_info: input_cost_per_token: 0.000002 output_cost_per_token: 0.000006input_cost_per_token和output_cost_per_token按你的实际成本填单位是美元/token。这里有个坑成本单位极其容易记错。有的平台文档给的是每千token的价格LiteLLM要的是每token的价格换算差了1000倍的话账本会离谱到没法看。我在一次项目里就因为这个成本统计比实际高了几十倍排查了半天才发现是单位没换算。成本数据看哪里代理模式下LiteLLM启动时会打印各key的使用情况你也可以调它的/spend接口拿历史聚合数据。我自己的习惯是写一个定时任务每小时调一次/spend接口把数据落到自己的监控面板里这样团队看到的花费永远是最新的。至于预算管控可以在配置文件里设置litellm_settings比如每月总预算、单key预算超过阈值直接拒绝请求避免半夜有人跑了个大循环把额度烧光。4.2 速率限制与多Key轮询生产环境的高频调用几乎必然撞上平台的速率限制Rate Limit。LiteLLM为此准备了两种武器限制和轮询。先看限制。你可以在配置里给每个key或每个虚拟模型设置请求速率限制比如每分钟最多200个请求超过的直接返回429给调用方而不是傻乎乎地继续往平台冲。这个配置在litellm_settings里定义具体字段可以按官方文档配。我一般会按模型和用户两个维度设置限制按模型限制是为了保护平台配额按用户限制是为了防止某个使用方把资源都占了。再看多Key轮询。如果你有多个API key可以在模型条目的litellm_params里传一个key列表LiteLLM会在这些key之间自动做轮询和故障转移。这个功能解决的是单账号速率限制问题一个key每秒只能打那么多次那就用10个key轮流打等效频率直接乘以10。不过这里有个前提你的多个key得来自同一个平台账号体系而且平台允许你这种用法别违反人家的服务条款。我在一个真实项目里用4个key轮询同一个模型把每天能处理的请求量硬生生翻了4倍而且全程几乎不需要改代码。这个操作执行起来非常简单但效果立竿见影推荐有高频调用需求的团队都试试。4.3 重试、超时与模型回退模型服务的稳定性从来不是100%的今天你可能碰见超时明天可能碰上5xx错误。LiteLLM在代理层帮你把这些失败逻辑做了兜底。先说超时。我通常会在配置里设置一个合理的请求超时时间默认值可能偏长或偏短你得根据自己的场景调。比如跟用户交互的场景超过10秒用户就受不了那超时时间就设成10秒如果是离线批量处理任务可以设到120秒甚至更长。再看重试。当请求因为瞬时故障失败时LiteLLM可以自动重试。重试次数和重试间隔都可以配置但这里有个经验教训重试一定要配合指数退避否则你的服务刚恢复所有重试请求同一时间涌过来直接把平台打到限流反而更糟。LiteLLM在这方面有内置的退避策略默认行为还算合理你自己不要额外写一个失败就疯狂重试的循环那是自找麻烦。最后说模型回退Fallback这个功能我是真的很喜欢。比如我有一个主力模型出问题就切备用模型的需求正常情况下用贵一点的强模型一旦它报错或超时自动降级到便宜一点的模型保证业务不中断。在LiteLLM里这可以通过模型分组和回退配置实现。我配置过一个场景主力模型挂了自动切到备用模型再不行就切到本地模型兜底。三层保障那之后我的服务因为模型供应商故障导致的线上事故基本绝迹了。5. 常见问题与排查技巧实录配置和代码写得再顺也免不了在实际运行中遇到各种诡异问题。这一章我把自己和身边同事踩过的坑整理成一份速查清单每个问题的症状、原因和解决办法都写清楚。5.1 模型返回401或403鉴权失败这个问题的典型症状是请求到了LiteLLM但返回401 Unauthorized或者403 Forbidden。排查思路按顺序来。先确认代理本身有没有启动成功如果代理需要用master key而你落了LITELLM_MASTER_KEY环境变量那代理会打印一个临时key你用临时key说不定就好了。接着确认目标平台的key是不是有权限、有没有过期。最后也是最多人踩的坑环境变量没加载。你明明在config.yaml里写了os.environ/OPENAI_API_KEY但当时Shell里根本没这个变量LiteLLM读到的是空值自然鉴权失败。我现在的习惯是任何新环境部署完LiteLLM首先在命令行里printenv | grep API_KEY确认所有用到的环境变量都存在再启服务。别嫌麻烦这一步能帮你省掉后面一小时的排查时间。5.2 提示模型不存在或模型名错误症状是请求报错大概意思是Model xxx does not exist。这通常不是说你调的模型在平台上不存在而是LiteLLM的配置里没有你要用的那个虚拟模型名。比如你在配置文件里定义的是gpt-4o请求里却写gpt-4那LiteLLM当然找不到映射关系直接报错。解决办法很简单要么请求方改成配置里存在的虚拟名要么在配置里把gpt-4也加上映射。这里我建议把虚拟模型名设计得跟业务语义相关比如叫chat-main、chat-backup这样就算背后真实模型换了好几次虚拟名都不需要变。还有一种情况你在litellm_params.model里写错了平台前缀。比如把openai/gpt-4o写成anthropic/gpt-4oLiteLLM就会用Anthropic的协议去请求OpenAI的模型名返回的报错会很莫名其妙。遇到这种报错先回头看一眼前缀对不对。5.3 成本数据不准确或统计不到这个问题我前面提过一嘴最常见的原因是模型价格没配置或者配置错了。LiteLLM对不认识的模型不会自动记账你必须在model_info里手动填价格。填的时候千万注意单位是按token算还是按千token算差了1000倍账就废了。第二种情况是你的自定义API端点返回的token用量字段跟标准格式不一致导致LiteLLM解析不出来。这种就属于模型的兼容性问题需要在配置里调整响应解析逻辑或者在上游先把响应格式规范化。5.4 日志太多刷屏、性能变慢代理模式的日志默认会打印每一个请求的完整信息包括输入输出。流量一大日志文件膨胀得很快磁盘满了服务直接就挂了。这个问题我踩过一次后续学乖了配置日志轮转控制日志级别生产环境只输出WARNING以上的日志。另外如果你发现代理服务的性能变慢先别怀疑LiteLLM本身。检查一下是不是把大模型调用都压在一个网关进程上如果是要么考虑给LiteLLM加并发配置要么在网关前面再加一层负载均衡把一个实例拆成多个实例。5.5 调用OpenAI SDK时连接被拒绝症状很直接Connection refused。原因通常就是代理服务没启动或者你填的base_url不对。很多人在本地测试时填了localhost:4000但代理服务跑在容器或远程服务器上那当然连不上。还有一个常见错误地址里漏了端口号或者多了个/v1。比如base_url填成http://localhost:4000/v1而LiteLLM的路由本身已经带了/v1结果拼起来变成/v1/v1/chat/completions照样404。我建议统一约定base_url只填到主机和端口http://localhost:4000后面的/v1/chat/completions让OpenAI SDK自己拼。这样最不容易出问题。6. 写在最后一点个人体会实际操作下来LiteLLM给我的最大帮助不是少写代码这么简单而是把模型接入这件事从每个项目重复造轮子变成了一次配置、到处复用。团队里新来的同学要接一个新模型我只需要告诉他在config.yaml里加一段映射然后请求里换个模型名五分钟搞定完全不需要理解各家API的差异。这省下来的沟通成本和维护成本只有经历过的人才知道有多值。如果你打算上手我的建议是先在本地用SDK模式跑一遍你常用的两三个模型确认效果和成本都满意再把它包装成代理服务接进你的统一开发环境最后再逐步加入限流、预算、回退这些生产配置。这个路径平滑踩坑最少。最后再分享一个小技巧很多团队不是从零开始接LiteLLM而是已经有一堆调用各种模型的代码。这时候别急着重写利用LiteLLM的OpenAI兼容接口可以先把一个最常用的模型切换过去跑通之后再慢慢把其它模型也迁移进来风险小很多。真正的生产系统从来不是靠一次大重构赢的而是靠一次次小步快跑稳下来的。