ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

LiteLLM Proxy实战:统一管理多模型API接入、用户预算与用量审计

LiteLLM Proxy实战:统一管理多模型API接入、用户预算与用量审计 1. 先把LiteLLM的能力边界看清楚最近手头项目又接了个新模型供应商API风格和OpenAI不完全一样加上之前在阿里云百炼、本地vLLM实例、Anthropic上部署的几个模型光维护各家SDK就够头疼。后来把LiteLLM Proxy统一接入到核心链路里做模型网关整个模型、用户、用量管理才算理顺。今天这篇不聊基础概念直接以LiteLLM Proxy为底座把模型接入、用户与Key生命周期、预算与用量审计这三块实操讲透。LiteLLM本质上是一个开源的大模型代理服务对外完全兼容OpenAI的/chat/completions、/embeddings等接口格式。不管是OpenAI、Anthropic、Google Gemini、Azure OpenAI还是本地vLLM、Ollama只要在config.yaml里配好上游地址和密钥就能用一个统一入口对外提供服务。团队内部项目只需要认准LiteLLM的Base URL和虚拟Key不需要关心背后是哪个厂商。这套方案最大的收益在于模型切换对下游是透明的。今天把某个模型从GPT-4o切到Claude Sonnet只需要在配置文件里调整路由或模型映射业务方改个model参数就行代码里不用写一堆if-else。另外LiteLLM对用户和用量的管理也是围绕“虚拟Key”展开的。它可以为每个用户、每个业务线签发独立Key给这个Key设置预算上限、并发限制和速率限制所有的token消耗都会记录到SQLite或PostgreSQL里方便做成本分摊和异常消费排查。这篇指南适合三种人一是公司内部想统一管理多家大模型API的运维或平台工程师二是需要在业务系统里做多用户模型调用、按部门计费的开发者三是自己折腾过多个模型服务、被账号密钥搞到头疼的独立开发者。2. 模型管理配置、映射与动态接入2.1 最基础的config.yaml模型配置LiteLLM的所有模型配置都写在config.yaml里启动时通过litellm --config config.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-20240620 api_key: os.environ/ANTHROPIC_API_KEY - model_name: deepseek-chat litellm_params: model: openai/deepseek-chat api_base: https://api.deepseek.com/v1 api_key: os.environ/DEEPSEEK_API_KEY - model_name: local-llama3 litellm_params: model: openai/vllm-llama3-8b api_base: http://localhost:8000/v1 api_key: fake-key配置逻辑分两层model_name是暴露给下游的别名litellm_params里才是真正的上游请求参数。model字段的写法是provider/model-idprovider决定走哪套SDK协议比如openai/、anthropic/、bedrock/、vertex_ai/等。这里有个关键点容易被忽略LiteLLM判断是否要发起“转换”逻辑靠的是model前缀不是api_base。如果你本地跑的是vLLM、FastChat这类兼容OpenAI的服务写成openai/本地模型名称就行LiteLLM会照OpenAI协议发请求然后靠api_base指向地址。这个前缀不能写错否则会尝试去真的OpenAI官方API请求。api_key支持os.environ/环境变量名的引用方式安全性和可维护性都比直接写在YAML里高。启动服务前用export OPENAI_API_KEYsk-xxx设置好即可。2.2 路由策略、fallback与负载均衡模型越来越多之后单一映射就不够用了。LiteLLM在router_settings里提供了三块比较实用的能力路由优先级、fallback降级、同一模型多后端负载均衡。先看路由优先级示例router_settings: routing_strategy: usage-based-routing-v2 model_group_alias: gpt4_group: gpt-4orouting_strategy决定LiteLLM如何在同一个model_name下多个候选上游里做选择。默认是简单轮询usage-based-routing-v2会结合历史请求延迟、失败率和tpm用量做动态分配适合线上流量比较杂的场景。fallback配置更直白。在litellm_params里加fallbacks请求主模型失败或超时时自动调用备用模型model_list: - model_name: main-model litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY fallbacks: - anthropic/claude-3-5-sonnet-20240620请求main-model时如果GPT-4o返回5xx或连接超时LiteLLM会自动转成Claude请求调用方无感知。这对生产环境非常重要一家厂商出现故障时业务不会直接断掉。负载均衡是把同一个模型部署在多个供应商或实例上在model_name下重复配置即可model_list: - model_name: chat-model litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: chat-model litellm_params: model: azure/gpt-4o api_key: os.environ/AZURE_API_KEY api_base: https://my-azure-openai.openai.azure.com/这两个配置共用chat-model这个对外名称LiteLLM会在两者之间分配流量。此时litellm_settings里可以设num_retries和request_timeout防止单实例故障导致请求长时间挂起。2.3 动态添加模型调用时改model参数或启动后/new/model静态配置适合模型数量稳定的场景。但如果你有个后台功能允许运营随时添加一个新模型每次改YAML再重启服务很痛苦。LiteLLM提供了两个缓解方案。第一个是“调用时指定模型”。LiteLLM的请求兼容OpenAI格式请求体里的model字段可以直接传上游模型标识比如传openai/gpt-4o-mini或azure/gpt-4o不需要预先在model_list注册。更适合快速测试生产环境还是建议用注册过的alias便于做路由和预算控制。第二个是使用管理接口POST /model/new动态注册模型请求示例curl -X POST http://localhost:4000/model/new \ -H Authorization: Bearer sk-admin-key \ -H Content-Type: application/json \ -d { model_name: new-model, litellm_params: { model: openai/gpt-4o-mini, api_key: sk-test } }动态注册的模型存在数据库里不需要改YAML适用于运维平台或管理后台集成。需要注意动态模型不会自动出现在model_list的配置里介意的话启动时仍建议把长期使用的模型写进YAML。3. 用户管理从创建用户到Key生命周期3.1 用户、虚拟Key与预算的关系LiteLLM里“用户”不是一个传统意义上的登录账号它更像一个用于归集计费和权限的实体。你可以给用户绑定多个虚拟Key每个Key可以独立设置预算同时用户本身也可以有总预算。这样无论Key怎么拆分最终成本都能归集到同一个用户下。用户和Key关系可以用一个简单表格来理解对象作用关联方式用户User计费主体、权限主体通过user_id标识虚拟KeyVirtual Key调用API时的凭证通过user_id绑定用户团队Team多用户分组共享预算和限流Key可归属Team预算Budget最大消费金额、速率限制可设在用户或Key层级所以实际调用链路是客户端拿虚拟Key请求LiteLLMLiteLLM解析Key知道它属于哪个用户和团队然后执行对应层级的预算检查、速率限制、鉴权逻辑再转发给上游模型。创建用户这一步很关键因为后面所有用量统计、成本分摊都要挂在用户ID上。我建议对外的user_id一定用有业务含义的ID比如工号、项目代号或内部系统主键而不是随便生成一串UUID。这样后续对账的时候能从LiteLLM日志里一眼看出是哪个业务方。3.2 用API和后台页面创建用户LiteLLM的用户创建最方便的是调POST /user/new接口。先给个curl示例curl -X POST http://localhost:4000/user/new \ -H Authorization: Bearer sk-admin-key \ -H Content-Type: application/json \ -d { user_id: project-ai-assistant, user_email: assistantexample.com, max_budget: 50, budget_duration: 30d, allowed_model_region: us, models: [gpt-4o, claude-sonnet] }这个请求做了三件事创建用户project-ai-assistant、设置月度50美元预算上限、限制只能调用列表里的两个模型。models数组的另一个用法是传[*]表示不限制模型。响应中会返回一个key字段这是自动生成的虚拟Key直接给用户用即可。LiteLLM 1.x版本之后响应里的这个Key是全量明文Key数据库里存的是哈希值丢失后无法找回只能重新生成。所以拿到响应后建议立刻保存到自己的密钥管理系统里或者直接发给对应的业务方。如果你启用了LiteLLM自带的Admin UI新版本内置了UI可以在浏览器里打开http://localhost:4000/ui用管理员Key登录后在用户管理页面点击创建用户。填写字段和API接口基本一致。UI适合少量用户操作批量操作还是走API更高效。3.3 Key的创建、轮换与回收用户创建好之后可以为同一个用户签发多个Key。典型场景是一个用户下前端项目用一个Key后端定时任务用另一个Key各自设置不同的限额和限速。生成用户维度Key的接口是POST /key/generatecurl -X POST http://localhost:4000/key/generate \ -H Authorization: Bearer sk-admin-key \ -H Content-Type: application/json \ -d { user_id: project-ai-assistant, max_budget: 20, budget_duration: 30d, models: [gpt-4o], rpm_limit: 60, tpm_limit: 10000 }rpm_limit是每分钟请求数限制tpm_limit是每分钟token吞吐限制。这两个参数对防止某个线上服务突发流量烧钱非常有效。密钥轮换是个日常操作。假设某个Key泄露了需要立即废除旧Key并创建新Key。废除用DELETE /key/deletecurl -X DELETE http://localhost:4000/key/delete \ -H Authorization: Bearer sk-admin-key \ -H Content-Type: application/json \ -d {key: sk-旧的Key或Key哈希}删除后这个Key立即失效在LiteLLM日志里会表现出401鉴权失败。建议把轮换流程做成后台按钮运维不需要直接敲curl。创建Key时还可以通过auto_rotate参数开启自动轮换设置key_rotate_after_days到期后旧Key自动失效这个功能需要数据库支持。我实际用下来自动轮换适合IoT或长期驻留的客户端互联网SaaS业务还是手动轮换更可控。3.4 管理用户列表与权限归属查询用户信息用GET /user/info?user_idproject-ai-assistant响应里会带该用户所有Key、已用token、剩余预算、关联模型列表。这个接口非常有用我经常在写月报前用它拉一份全量用户消费概览。如果是管理员想一次性看所有用户可以调用GET /user/list。它支持分页参数page、page_size返回每个用户的基本信息和预算使用情况。注意这个接口需要管理员Key普通虚拟Key没有权限。4. 用量管理预算、限流与审计4.1 三层预算Key、用户、全局用量管理的核心是“预算”。LiteLLM的预算设定有三个层级独立生效取最先触发的那个作为限制单Key预算针对某个虚拟Key的消费上限单用户预算跨该用户所有Key的累计消费上限全局预算整个LiteLLM实例的总消费上限或每日上限这三者是叠加的。比如你给每个用户设了50美元月预算又给公司总共设了1000美元月预算那么某个用户跑满50美元会先被拦截如果所有用户加起来跑满1000美元整个网关就会拒绝新请求。配置全局预算在YAML里加general_settings: max_budget: 1000 budget_duration: 30d也可以在启动时用--max_budget参数传入但YAML方式更直观、便于Git管理。预算单位是美元LiteLLM会根据模型单价自动计算。如果使用的是自定义模型或本地模型需要额外确认一下价格信息。LiteLLM内置了很多常见模型的价格表但vLLM部署的一些开源模型、企业内部微调模型往往不在表里需要用到cost_map来补充。4.2 限流参数rpm、tpm与并发控制预算管的是“钱”限流管的是“请求速度”和“资源用量”。即使预算充足也该给每个Key设置合理的rpm_limit和tpm_limit防止某个异常脚本把网关和上游打挂。三个指标的差异参数含义典型用途rpm_limitRequests Per Minute每分钟请求次数控制调用频率防止刷接口tpm_limitTokens Per Minute每分钟token消耗控制模型计算资源消耗max_parallel_requests最大并发请求数防止突发并发打爆上游这三个可以同时存在于Key或用户上。比如一个客服机器人正常一分钟不超过30次对话每次对话上千token就可以设rpm_limit: 30、tpm_limit: 30000并发设到5就够了。到了限流阈值之后LiteLLM返回429错误响应体里带Retry-After头。下游SDK一般会自动重试但要看具体实现OpenAI官方SDK会读这个头所以整体表现还算丝滑。4.3 用量统计与对账查询预算能拦住超支但要搞清楚“钱花在哪了”必须靠用量统计接口。LiteLLM提供了几个常用查询GET /spend/logs按时间范围返回所有支出的明细日志包含用户ID、Key、模型、token数和费用GET /global/spend返回整个网关的总支出GET /user/info?user_idxxx单个用户的用量和预算GET /key/info?keysk-xxx单个Key的用量和预算下面这个例子查询昨天所有用户的消费情况curl -G http://localhost:4000/spend/logs \ -H Authorization: Bearer sk-admin-key \ --data-urlencode start_time2025-01-01 \ --data-urlencode end_time2025-01-02响应是一个JSON数组每条记录包含api_key、user、model、prompt_tokens、completion_tokens、total_tokens、spend等字段。把这个接口接入到自己的报表系统就能做出按模型、按用户、按天维度的成本报表。如果发现某个Key花费激增第一时间查/spend/logs结合user_id和request_id定位到具体请求再回溯到业务日志。这个流程我处理过几回基本十分钟内能锁定问题源头。4.4 数据库、监控与接入PrometheusLiteLLM的用量数据默认保存在SQLite中但生产环境建议启用PostgreSQL并发高和数据量大的时候更稳定。启动时指定litellm --config config.yaml \ --database_url postgresql://user:passwordhost:5432/litellm启用数据库后LiteLLM会自动建表存储用户、Key、SpendLog等数据。用PostgreSQL的另一个好处是可以直接用SQL做复杂对账比如统计某个时间段每种模型的调用量。SQLite在单机场景也能用只是当Key数量超过几万个、日志表数据到几百万条之后查询会明显变慢。监控方面LiteLLM暴露了一个Prometheus端点/metrics直接抓取即可。常用指标包括litellm_total_spend总消费litellm_proxy_total_requests总请求数litellm_request_latency_histogram_ms延迟分布litellm_llm_api_status_code_code上游状态码计数把这些接到Grafana后能做实时看板。有一次上游模型商出现高延迟我就是在Grafana上看到p95延迟指标飙升才及时切掉了那个模型的路由权重。监控不一定要很复杂但“有”和“没有”差别很大。5. 常见问题与排查技巧实录5.1 鉴权失败Key无效或过期反映最多的问题就是突然报401 Unauthorized。排查路径基本固定先用GET /key/info?keysk-xxx查Key是否存在、状态是否正常确认Key是否被删除了或是自动轮换过期了确认Key是否因为预算触顶被临时禁用确认请求头是否传对格式是Authorization: Bearer sk-xxx如果Key在后台接口里查得到但调用还是401检查一下是否把“Key哈希”误当成了明文Key。数据库里存的是哈希明文Key只在创建时返回一次丢了就得重新生成。5.2 用量统计不准或费用为0这个坑多半出在“LiteLLM不知道模型单价”上。如果是OpenAI、Anthropic这些内置模型默认有价格表统计很准。如果用的是本地模型、微调模型、自定义供应商模型LiteLLM缺少价格信息spend字段会是0但token数还是会记录。解决办法是在litellm_params里附带cost信息或者直接在模型配置的model_info字段中指定价格model_list: - model_name: local-llama3 litellm_params: model: openai/vllm-llama3-8b api_base: http://localhost:8000/v1 api_key: fake-key model_info: input_cost_per_token: 0.000001 output_cost_per_token: 0.000002这样LiteLLM就会按这个价格计算消费。如果模型单价在不同region或不同时间是浮动的还可以用cost_map配合litellm_settings做更复杂一点的价格覆盖。5.3 模型路由不生效、用的是默认模型有时候明明配了model_list和fallback但请求时LiteLLM却报“model not found”或者总是转发到同一个上游。常见原因有三个请求体里的model字段没传对。它必须和model_name完全一致大小写敏感model_list里同一个model_name配了多个上游但LiteLLM版本的默认路由策略对所有上游都没做健康检查某一台挂了依然会把流量分过去。需要开启router_settings.enable_pre_call_checks才能真正实现故障转移fallback写在了YAML里但litellm_params中的fallbacks数组只接受完整的上游模型名而不是model_name别名。我见过有人写fallbacks: [gpt-4o]结果一直不生效改写成fallbacks: [openai/gpt-4o]之后立刻就好了遇到路由问题建议打开debug模式litellm --config config.yaml --debug这个模式下会打印每个请求的路由决策能看到命中了哪个供应商、为什么触发fallback、缓存命中情况。排查效率翻倍。5.4 数据库表快速增长LiteLLM会把每次请求的spend log写进数据库数据量大了之后表会膨胀得比较快。生产环境一定要做数据清理或归档策略。比如只保留最近90天的原始日志老数据定期迁移到冷存储或用定时任务清理。在config.yaml里可以通过general_settings下的database_retry_interval和database_pool_size调节数据库连接池行为但清理动作本身还是建议用外部定时任务。我自己写过一个简单的cron每天凌晨删除90天前的spend log跑了大半年没出过问题。5.5 推荐的生产配置参考最后给一份我目前在生产环境使用的精简配置可以直接作为起点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-20240620 api_key: os.environ/ANTHROPIC_API_KEY litellm_settings: drop_params: true set_verbose: false num_retries: 3 request_timeout: 60 router_settings: routing_strategy: usage-based-routing-v2 enable_pre_call_checks: true general_settings: master_key: sk-master-key max_budget: 1000 budget_duration: 30d database_url: postgresql://user:passwordhost:5432/litellmdrop_params: true的作用是自动丢弃上游不支持的多余请求参数比如有些模型不支持logprobs开着这个选项可以避免整个请求报错兼容性好了不少。在生产环境我强烈建议所有上游API密钥都通过环境变量注入而不是直接写进YAML。LiteLLM的YAML文件通常会被Git管理如果密钥直接落在仓库里一旦仓库代码泄露或员工离职拿到权限整个模型服务就裸奔了。根据我个人的经验LiteLLM最划算的投入就是把用户、Key、预算这三张表设计好建模方式尽量贴近业务侧的真实产品和组织架构。模型接入反而是最简单的部分——花一上午写配置后面长期受益。如果之后接入更多供应商你还会发现最早给每个业务线配独立Key的决定能帮你在对账时省下大量的时间。
返回列表