litellm 这个名字玩 LLM 应用开发的兄弟应该不陌生。简单说它是一个开源的 LLM API 网关Gateway或者说是一个统一代理层。你后端服务不用再分别对接 OpenAI、Anthropic、Google、国内各家大模型的 SDK 和鉴权体系直接统一走 litellm 这一套接口就行。我自己的项目里同时接了国内外四五家模型厂商还要给团队内部几个业务方分发 key、统计 token 消耗没有这个东西之前是真的头疼——每个接入方自己维护一套 key月底对账对到怀疑人生。litellm 解决的就是这么个实际得不能再实际的问题多模型接入、统一鉴权、成本追踪、负载均衡、自动重试。这篇文章适合谁看正在做 LLM 应用层开发、想把模型接入层做规范化的后端工程师以及团队里负责 AI 基础设施选型的技术负责人。内容会覆盖从为什么需要网关、litellm 核心机制到部署实操、生产环境踩坑尽量让读者看完能直接上手。1. 为什么你的项目需要一个 LLM 网关层1.1 多模型接入带来的三个老难题先说个真实场景。假设你是一个做智能客服系统的开发者产品需要支持大模型生成回复、向量模型做召回匹配、小模型做实时意图分类。你可能选了 GPT 系列做生成、某开源向量模型做 embedding、某个国内厂商的超小模型做分类。问题马上就来了第一套问题是接口协议不统一。OpenAI 的接口和 Anthropic 的接口格式差异很大国内厂商又各有各的封装有的兼容 OpenAI 格式但细节有差异有的干脆是自成一派的 SDK。你的业务代码里要为每一家写适配逻辑一旦想换模型供应商就要改一堆调用代码。第二套问题是API key 管理混乱。每个供应商一个 key每 key 还有不同的限额、不同的计费周期。如果团队里有七八个人同时在用 GPT-4怎么分发 key直接公用一个限额很快就爆了而且出问题时没法定位是哪个业务方在超量调用。第三套问题是成本不可控。不同模型的 token 计费方式不一样有的按输入输出分开算有的按调用次数算。没有统一记录的话月底财务来问这个月大模型花了多少钱你只能去各家平台后台导出账单再手工汇总工作量巨大。1.2 网关方案为什么是最优解其实解决上面这些问题的思路和你在微服务架构里加一个 API 网关是一模一样的逻辑。业务服务不需要知道背后是哪家模型厂商它只需要知道“我要调一个模型给它消息拿到回复”。至于这个模型实际是 OpenAI 的、Anthropic 的还是自部署的开源模型由网关层通过配置决定。网关层做流量的统一入口好处是切换模型零代码改动业务侧只需要改模型名或者压根不用改网关那边把路由配置换一下就行。鉴权和限流集中管控所有调用方只跟 litellm 通信key 由 litellm 统一发放和管理谁在什么时间调用多少量一清二楚。成本和日志统一沉淀每个请求用了几千 token、花了多少钱、响应耗时多少litellm 默认就记录下来做成表格也好接监控也好都很方便。从我自己的实践来看只要你的项目准备接入两家以上的模型供应商就值得上网关层。如果只有一家直接用官方 SDK 更省事。但如果已经开始出现 key 管理混乱、换模型要改代码这类问题再不上网关就等着继续被折磨了。1.3 备选方案对比在做选型时我也评估过其他路子。一种是直接在代码里写一个公司内部的 Model SDK 封装层统一接口再对接各家官方 SDK。这种做法的问题在于所有 provider 的轮询重试、限流退避、token 计费统计都得自己写。看起来只是几个 class 的事真正实现完你会发现比想象中多不少工作量——尤其是参数差异的处理和错误码标准化。另一种是直接用各家云厂商提供的模型聚合服务比如某些云厂商的“百模千态”API。这类服务的好处是接入省事坏处是绑定在特定云上想要切换或者接入不在他列表里的模型就又卡住了。litellm 的核心优势在于它是代码和平台中立的既可以在你自己的服务器上部署也可以本地跑一个进程几乎支持所有主流模型供应商包括开源模型的私有化部署场景。它把“接入模型”这件事变成了纯配置不用写代码。2. litellm 内部机制拆解它到底做了什么2.1 轻量代理与协议转换很多第一次接触 litellm 的人会误以为它是个很重的框架或者是一个需要大改代码的 SDK。实际上litellm 在最基础的使用形态下就是一个轻量级的 HTTP 反向代理服务。它在底层做了一件很巧的事把各家模型的 API 协议统一转换成 OpenAI 的 chat completions 协议格式。也就是说你的业务代码只需要用 OpenAI 的 SDK 或者任何兼容 OpenAI 协议的客户端把 base_url 指向 litellm 服务的地址同时把 api_key 换成 litellm 给你生成的虚拟 key就可以调通背后任何一家模型了。举个例子你的代码里可能是这么写的from openai import OpenAI client OpenAI( # 指向 litellm 服务地址 base_urlhttp://localhost:4000, # 用 litellm 分配的虚拟 key api_keysk-litellm-mock-key-12345, ) response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: user, content: 你好介绍一下自己} ], ) print(response.choices[0].message.content)这个请求到了 litellm 之后它会根据model参数里的模型名查找配置确认这个模型名对应的实际供应商是哪个、真实 API key 是哪个然后内部再向真正的供应商发起请求拿到结果后再按 OpenAI 协议的格式返回给你的代码。这一整个过程中你的业务代码完全感知不到背后的模型供应商是谁。这个设计最大的价值是成本极低。团队里已有的代码、工具链、监控埋点只要它们兼容 OpenAI 协议就能直接接上 litellm。我知道很离谱的一点是有时候我在排查问题的时候会直接在浏览器里把 litellm 当一个 OpenAI API 的调试服务器用因为它会把请求和响应的完整信息打到日志里比官方 API 的调试体验还舒服。2.2 路由规则与模型别名机制litellm 的模型路由靠一个 YAML 配置文件管理。你想在业务代码里使用什么模型名完全可以自定义然后映射到实际要调用的供应商模型。这就是“模型别名”机制。看一个最小化的配置示例model_list: - model_name: gpt-4o # 对外暴露的模型名 litellm_params: model: openai/gpt-4o # 实际调用的模型 api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet # 对外暴露的别名 litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEY - model_name: embedding-general litellm_params: model: openai/text-embedding-3-small api_key: os.environ/OPENAI_API_KEY配置写好启动之后你的业务代码里model参数传gpt-4olitellm 就会转发到真实的 OpenAI GPT-4o传claude-sonnet就转发到 Anthropic 的 Sonnet。为什么要做这么一层别名主要出于三点考虑第一方便多环境管理。开发环境用的是某开源模型生产环境用的是 GPT-4o业务代码不用改只要在对应环境的配置文件里把model_name: gpt-4o映射到不同的实际模型就行。第二兼容旧代码。比如你原来的系统里所有地方都硬编码了text-davinci-003现在这个模型已经停服了但你不想全量改代码。那你可以在 litellm 配置里把text-davinci-003这个别名映射到openai/gpt-4o-mini代码零改动就完成了迁移。第三做 A/B 测试。你可以把同一个业务流量分到不同的模型上做质量对比——这在方案选型阶段非常实用。2.3 负载均衡、失败重试与多 provider 容灾litellm 的另一个核心功能是负载均衡和容灾。这个特性在配置上也很简单——同一个model_name可以配置多个实际模型地址litellm 会自动做轮询分发和失败切换。model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_1 - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY_2 - model_name: gpt-4o litellm_params: model: azure/openai-gpt-4o api_key: os.environ/AZURE_API_KEY api_base: os.environ/AZURE_API_BASE上面的配置里同一个对外模型名gpt-4o对应了三个实际的 provider 配置两个 OpenAI 的 key一个 Azure 上托管的服务。litellm 在收到请求后默认按轮询round-robin方式把请求分发给三个 provider如果某个 provider 返回了限流429错误litellm 会根据配置自动重试到下一个 provider如果某个 provider 返回了 5xx 服务器错误也会自动切换尽可能保证业务调用的成功率。这个机制对稳定性要求高的场景很有价值。比如某些业务要保证晚上高峰期的可用性单一供应商可能因为限流导致大量请求失败而多 provider 容灾能把失败率显著降低。我这里补充一下litellm 也支持自定义重试策略包括最大重试次数、退避策略、超时时间等这些配置在你真正需要细粒度调优时会非常有用。2.4 虚拟 Key、预算管控与可观测性litellm 不仅仅是一个代理它还内置了完整的虚拟 API key 体系。你可以为每个业务方、每个开发者、甚至每个功能模块生成一个独立的虚拟 key并且为这个 key 设置单独的速率限制RPM每分钟请求数、并发限制和 token 预算。比如团队里的 A 同学在做数据分析助手你可以给他一个虚拟 key限制每分钟最多 60 次请求每月最多消耗 100 万 tokenB 同学在做内部知识库问答你给他另一个 key限制每分钟 20 次请求。谁超出预算了litellm 会直接返回 429不用你去供应商后台里折腾配额。配合这个机制litellm 默认会把每一个请求的日志和用量都记录下来包括调用者身份虚拟 key 的归属模型名输入 token 数、输出 token 数请求耗时估算费用成功/失败状态这套可观测性数据可以直接在 litellm 自带的管理后台 UI 里看到也可以把数据导出到 Prometheus 等外部监控系统做大盘。有统计才有优化你才能回答“这周模型账上还剩多少钱”“哪个业务方最费钱”这类问题。3. 快速入手从 pip 安装到第一个请求3.1 部署方式与启动命令litellm 的环境要求很低只要你的机器上有 Python 3.8 以上环境就行。它本质上是一个 Python 包安装命令很简单pip install litellm如果你更喜欢用 Docker 部署官方也提供了镜像用 docker-compose 一把梭docker pull ghcr.io/berriai/litellm:main-latest docker run -p 4000:4000 ghcr.io/berriai/litellm:main-latest这个容器默认会跑在 4000 端口并内置了一个管理 UI。我这里建议正式部署到生产环境时用 systemd 托管一个 Python 虚拟环境里的 litellm 进程比直接用 Docker 更轻便也好维护。当然这属于个人偏好两种方式都能用。启动方式如果是用配置文件的话# 默认端口 4000 litellm --config /path/to/config.yaml --port 4000服务起来后先测一下健康检查curl http://localhost:4000/health/liveliness正常会返回一个表示存活状态的 JSON 响应。如果你看到 200 OK说明服务已经起来了。3.2 配置第一个模型路由接着把前面的最小配置扩展开来写一个能直接用的例子。假设你有 OpenAI 的 key想在 litellm 里暴露一个gpt-4o-mini的入口# config.yaml model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: sk-xxxxxx # 替换成你的真实 key为了安全不建议在配置文件里直接写明文 key。litellm 支持从环境变量读取export OPENAI_API_KEYsk-xxxxxx再把配置改为model_list: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: os.environ/OPENAI_API_KEY启动后你就可以直接用 OpenAI 的 SDK 打过来了。我这里用 curl 做一次原始请求方便看完整效果curl http://localhost:4000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-litellm-mock-key \ -d { model: gpt-4o-mini, messages: [{role: user, content: 用一句话介绍你自己}] }如果你的配置没问题应该会返回一份完整的 OpenAI 格式 JSON 响应里面包含choices字段和usage字段。看到usage.total_tokens不为 0说明一次调用已经完整走通了。3.3 新增供应商与模型类型的接入方法接入了 OpenAI 之后其他供应商就是依样画葫芦的事。关键点在于litellm_params.model字段的命名规则provider 前缀 斜杠 模型名。常用示例model_list: - model_name: claude-opus litellm_params: model: anthropic/claude-opus-4-20250514 api_key: os.environ/ANTHROPIC_API_KEY - model_name: gemini-pro litellm_params: model: gemini/gemini-2.0-flash-exp api_key: os.environ/GEMINI_API_KEY - model_name: deepseek-chat litellm_params: model: deepseek/deepseek-chat api_key: os.environ/DEEPSEEK_API_KEY - model_name: qwen-plus litellm_params: model: openai/qwen-plus api_key: os.environ/DASHSCOPE_API_KEY api_base: https://dashscope.aliyuncs.com/compatible-mode/v1特别注意openai/这个前缀。只要某个供应商提供了 OpenAI 兼容接口你都可以用这个前缀配合api_base字段指向它的接口地址。这一下就打通了国内绝大多数模型服务商因为他们很多都做了 OpenAI 兼容层。类似的还有接自己内网部署的 vLLM 服务model_list: - model_name: my-vllm-model litellm_params: model: openai/my-custom-model api_base: http://192.168.1.100:8000/v1 api_key: dummy内部服务不需要真实 key但请求里必须带一个非空字符串所以给个dummy占位就行。3.4 管理后台 UI 的日常使用litellm 内置的管理后台 UI 默认在根路径/或按部署方式在某个子路径下。打开后你会看到一个 Dashboard里面有几个核心区块模型管理查看当前所有模型别名和对应的真实供应商配置。虚拟 Key 管理创建、吊销虚拟 key查询每个 key 的消费记录。日志检索按时间、模型、key、状态筛选请求日志。预算报表按天或按月看整体 token 消耗和费用估算。对一个团队管理员来说这算是最省心的日常操作面板了。给新人开一个 key点几下鼠标就能完成确实比发一个共享 key、事后查账这种传统做法顺心得多。4. 生产环境下的进阶玩法与配置实战4.1 用 systemd 托管 litellm 进程我一般建议在正式的服务器环境上把 litellm 作为一个 systemd 服务托管起来这样开机自启、崩溃自动拉起、日志统一收集都方便。具体的 service 文件可以这样写[Unit] DescriptionLiteLLM API Gateway Afternetwork.target [Service] Userwww-data Groupwww-data WorkingDirectory/opt/litellm EnvironmentFile/etc/litellm/litellm.env ExecStart/opt/litellm/venv/bin/litellm --config /etc/litellm/config.yaml --port 4000 Restartalways RestartSec5 [Install] WantedBymulti-user.target要点EnvironmentFile指向一个包含所有 API key 环境变量的文件避免 key 直接写在 service 文件里。WorkingDirectory单独设一个工作目录不要放在家目录下方便权限管控和日志隔离。如果想让多个实例跑在不同的端口可以用--port区分比如 4000 和 4001再在前层用 Nginx 做负载均衡。启动方式systemctl daemon-reload systemctl enable litellm systemctl start litellm查看状态和日志systemctl status litellm journalctl -u litellm -f4.2 环境变量与敏感信息管理这一步很关键也是我踩过坑之后才总结出来的。litellm 的配置里经常需要写 API key如果你把真实 key 以明文写进config.yaml然后这个文件又提交到了 Git那基本等于把 key 裸奔了。正确的姿势是在config.yaml里统一用os.environ/KEY_NAME引用环境变量。把真实 key 放到.env文件或 systemd 的EnvironmentFile里。.env文件一定要加入.gitignore绝不进版本库。团队协作时提供一个config.example.yaml和.env.example只留占位符。如果你用 Docker 部署也建议用--env-file方式传入环境变量不要把 key 写进镜像或 docker-compose 文件里。4.3 预算管控与限流配置实战预算管控是 litellm 的杀手级功能。假设你想给某个内部业务方每个月设置 500 万 token 的上限并且每分钟最多 100 次请求配置方法是这样# 通过管理后台 UI 创建 virtual key 时可设置 # 也可以直接用命令行 API 创建更便于自动化 curl http://localhost:4000/key/generate \ -H Content-Type: application/json \ -H Authorization: Bearer sk-master-key \ -d { models: [gpt-4o-mini], max_budget: 5000000, rpm_limit: 100, metadata: {team: data-analysis} }这里的sk-master-key是 litellm 的 master key一般在首次启动时通过环境变量LITELLM_MASTER_KEY指定用于管理操作不是用来调模型的。创建成功后返回的 JSON 里会包含一个sk-...开头的虚拟 key把这个 key 发给业务方使用。当某个 key 的用量达到预算上限时litellm 后续请求会直接返回 429。这个能力对防止“月底账单爆炸”极其有效——你可以给每个业务方一个明确的预算边界超出就不服务总比月底对账时再来质问业务方强得多。4.4 日志、监控与可观测性接入litellm 默认记录的请求日志存储在后端数据库里默认 SQLite生产建议配 PostgreSQL 或 MySQL。这些数据除了在 UI 上看还可以通过以下方式利用起来导出 Prometheus 指标litellm 提供了/metrics端点你可以在服务配置里开启用 Prometheus 抓取。这样请求量、延迟分布、错误率、token 消耗量都能在 Grafana 上实时看了。回调通知litellm 支持把请求日志推送到各种 Webhook你可以接上企业微信机器人或钉钉机器人。比如设定一个“某个 key 当天消耗超过预期阈值”的告警推送到群里提前预警。自定义日志存储如果你想自己保存完整请求日志做审计litellm 支持配置自定义回调把日志同步到自己的存储里。生产环境强烈建议把 SQLite 换成 PostgreSQL并发能力强查询性能也好避免后期日志量大导致 UI 响应变慢。4.5 接入已有业务代码的三种方式如果你的业务服务已经在对接 OpenAI API接入 litellm 几乎不需要改代码。三种接入方式按推荐程度排列方式一改环境变量如果你的代码用了 OpenAI SDK 且支持OPENAI_BASE_URL环境变量直接设export OPENAI_BASE_URLhttp://litellm-server:4000 export OPENAI_API_KEYsk-litellm-virtual-key代码完全不用动。这是最推荐也最省事的方案。方式二改初始化参数代码里显式指定base_url和api_key适合 SDK 不支持环境变量覆盖的场景。方式三反向代理替换如果连代码都懒得改业务代码里已经写死了https://api.openai.com可以在业务服务的容器网络层做一层代理或者在 Nginx 里把/v1路径反向代理到 litellm。这种方式侵入性最低但排查问题时路径太长建议短时间过渡用。4.6 多模型容灾与 Fallback 配置除了前面提到的一个模型名对应多个 providerlitellm 还支持模型级别的 fallback 链。比如router_settings: fallbacks: [ {gpt-4o: [claude-sonnet, qwen-plus]}, {claude-opus: [gpt-4o]} ]意思是当gpt-4o主 provider 连续出错比如限流、超时、5xxlitellm 会自动依次尝试claude-sonnet和qwen-plus。这个机制在做稳定性兜底时特别好用。需要提醒的是fallback 的模型最好能力相似避免在用户无感知的情况下返回质量差异过大。如果业务对输出格式有强要求还建议在业务层把 fallback 的响应打上标记方便后面对比和追溯。5. 常见问题与故障排查实录5.1 启动时报错“No model list provided”这个错误一般发生在没传配置文件或者配置文件格式不对。检查litellm --config /path/to/config.yaml确认配置文件的model_list键存在且为一个列表。如果model_list为空也会有类似报错。排查建议先用一个极简配置验证服务能起来再加模型。别一上来就写几十行配置出了问题反而不好定位。5.2 请求返回 401 Authentication Error这种情况通常有三种原因虚拟 key 没有设置为对应模型可访问。在创建 key 时如果限制了models列表而请求使用的模型名不在列表内就会 401。上游真实的 API key 失效或未正确配置。litellm 转发时会用litellm_params.api_key去调用真实模型如果这个 key 过期上游也可能返回 401。请求头格式不对。注意Authorization: Bearer后面跟的是 litellm 的虚拟 key不是上游模型提供商的 key。排查方式先看 litellm 日志里这次请求的完整链路确认是入口鉴权失败还是上游鉴权失败。5.3 请求超时与限流 (429) 怎么调如果你的业务流量较大会遇到上游模型的限流。litellm 默认的重试策略是按 2 的指数退避可以自己调整router_settings: retry_policy: retries: 3 timeout: 30 max_retries_per_request: 5这里的参数要根据实际场景调。如果业务对延迟敏感建议retries别设太高因为每次重试都会增加延迟。如果业务对成功率要求高可以适当提高重试次数同时配置多个 provider 做切换。参数之间的取舍还是靠真实流量压测来定不要照抄别人的。5.4 虚拟 Key 的预算设置无效有几次我遇到配置了max_budget但请求还是能成功的情况最后发现原因是对应的虚拟 key 创建时传了models限制但业务请求的模型名是另一个名字等于命中了一个没有配预算限额的默认 key 上。如果你是全局预算需要在配置里加general_settings里的预算参数并且确保测试时用的 key 真的关联到了正确的模型。检查方式在管理后台 UI 里看这个 key 的“用量”页面如果显示“未设置预算”说明 key 创建时参数没传全。把 key 吊销重新创建一个即可。5.5 Docker 部署时容器频繁重启Docker 版 litellm 容器频繁重启十有八九是环境变量缺失。比如.env文件没挂载全LITELLM_MASTER_KEY没设置导致启动后立即退出。排查方法docker logs container_id看日志里的报错信息。大部分情况下把缺的环境变量补上就好了。另外注意docker run和docker-compose的 env 文件格式有细微差异不要直接互用。5.6 请求成功但 Token 统计不完整litellm 的 token 计数是根据上游模型的返回usage字段获取的。如果某个模型供应商的接口没有返回usage字段litellm 会用自己的 tokenizer 估算这时统计会存在偏差。例如某些自部署的模型网关可能就不返回标准的 usage。要解决这个问题一是确认上游确实返回了完整的 usage 数据二是针对特定的模型配置自定义 token 计费规则三是如果只是估算成本用接受换算误差也行但要对齐各模型之间的数量级别在对比时把一个估算值和一个准确值放在一起直接比。5.7 负载均衡没有按预期切换负载均衡是有条件的不是发了错误立刻切换。默认情况下litellm 只有遇到连接错误、超时、5xx、429 限流时才切换。如果某个 provider 返回了 200 但内容本身是业务层错误比如“这个模型不存在”litellm 是感知不到的也不会切换。所以配置容灾时要在业务侧也做基本的响应校验把真正的服务不可用和内容异常区分开。6. 踩坑总结与我的个人体会litellm 这块我自己用了快一年接过的模型数量可能比不少人都多过程中总结了几个值得分享的经验。第一先小后大。别一次性把所有模型、所有业务方都迁到 litellm选一个边缘业务先试把配置、日志、预算、报警这一套磨合到位了再大规模推广。一上来就想一步到位很容易在迁移过程中遇到一堆新的环境问题忙乱中难以定位是网关的问题还是业务代码的问题。第二key 和配置要严格分离。我见过不少把 secret 直接写进 yaml 的案例这只是个习惯问题但一旦仓库内容泄露损失就是真实真金白银。把config.yaml提交到版本库、把.env留在服务器应该是底线。第三日志数据要定期归档。SQLite 存储的日志会随时间变得很大建议配置定期清理策略或者直接切 PostgreSQL。否则 UI 查询越来越慢最后你可能想复盘某个线上事故结果查询超时了。第四不要忽视监听网关自身状态。litellm 作为中间节点它本身也有可能成为瓶颈。在高流量场景下建议前置负载均衡并对 litellm 进程本身做存活探测和资源监控。之前我就遇到过一次 litellm 内存缓慢增长的问题确认是日志累积导致之后调整了日志轮转策略就解决了。这个项目后续还可以怎么扩展如果你想在它上面再做深一层可以尝试自己实现一套按用户维度的配额管理——litellm 原生支持团队隔离但实际业务方之间可能还有更细粒度的资源隔离需求。也可以考虑把它和内部的 A/B 测试平台结合起来用模型别名机制做流量切分。这些都是另一个话题了等以后有机会再单独写一篇。litellm 的价值不在它有多炫酷而是它把一批琐碎但重要的底层问题都解决掉了。至少对我来说现在接一个新模型就是改几行 YAML切一个模型就是换个配置条目稳定的基础设施确实能省下不少心。如果你也在为多模型接入和成本管理头疼这个工具值得花半小时先跑起来试试。
阅读完成 · 觉得有帮助?