Fork me on GitHub

分类 LiteLLM 下的文章

学习 LiteLLM 的防护栏机制

随着大语言模型在生产环境中的广泛应用,内容安全、隐私保护和合规性变得越来越重要。用户可能会无意中输入敏感信息,模型也可能生成不当内容,而提示词注入攻击更是对系统安全构成直接威胁。LiteLLM 的防护栏机制正是为了应对这些挑战而设计,这也是我们今天学习的主题。

防护栏概述

防护栏(Guardrails) 是 LiteLLM 中用于内容安全检查和数据保护的核心机制,它可以在 LLM 调用的不同阶段对输入和输出内容进行检查、过滤或修改,确保应用在安全合规的前提下运行。它的核心价值在于:

  • 阻止有害请求:在请求到达模型之前识别并拦截恶意内容,包括仇恨言论、暴力内容等
  • 保护敏感信息:自动识别和掩码 PII(个人身份信息)和 PHI(受保护健康信息)
  • 防御攻击行为:识别提示词注入、越狱等攻击手段
  • 规范内容输出:确保模型输出符合安全和合规要求

它支持与 20+ 专业内容审核供应商 集成,也支持完全自定义的防护逻辑,能够在 pre_call、during_call、post_call 等多个时机灵活介入,实现对 LLM 应用的全方位安全防护。

下面是 LiteLLM 支持的供应商一览:

  • Aim Security
  • Aporia
  • Azure Content Safety
  • AWS Bedrock Guardrails
  • DynamoAI
  • EnkryptAI
  • Gray Swan Cygnal
  • Guardrails AI
  • IBM Guardrails
  • Javelin
  • Lakera AI
  • Lasso Security
  • Google Cloud Model Armor
  • Noma Security
  • OpenAI Moderation
  • Pangea AI Guard
  • Presidio (PII/PHI Masking)
  • PANW Prisma AIRS
  • Pillar Security
  • Zscaler AI Guard

OpenAI Moderation 实战

我们之前在学习 Dify 的内容审查设置时曾简单介绍过 OpenAI Moderation API,这里不妨回顾下之前学习的内容。

OpenAI Moderation API 是 OpenAI 提供的内容审核服务,能够识别和阻止有害内容,包括仇恨言论、骚扰、自伤、性内容和暴力等类别。该 API 支持两种模型:

  1. omni-moderation-latest(推荐):最新的多模态模型,支持更多分类选项和文本+图像输入
  2. text-moderation-latest(遗留):仅支持文本输入的旧版模型

OpenAI Moderation 可以识别出下面这些有害内容:

openai-moderation-categories.png

防护栏定义

下面我们就以 OpenAI Moderation 为例,演示一下如何在 LiteLLM 中集成防护栏。首先在 config.yaml 文件中定义你的防护栏:

guardrails:
  # 输入内容审核
  - guardrail_name: "openai-input-moderation"
    litellm_params:
      guardrail: openai_moderation
      mode: "pre_call"
      api_key: os.environ/OPENAI_API_KEY
      api_base: os.environ/OPENAI_API_BASE
      model: "omni-moderation-latest"  # 支持多模态内容
      default_on: true  # 默认启用

其中 mode 为执行模式,表示防护栏的执行时机,pre_call 表示在 LLM 调用前对用户输入进行检查,如果要对模型输出进行检查,可以改成 post_call。下面是 LiteLLM 支持的几种防护栏执行模式,分别对应 LLM 请求的不同阶段:

  • pre_call:在 LLM 调用之前运行,检查用户输入,可以修改请求内容或直接拦截
  • during_call:与 LLM 调用并行运行,检查用户输入,不能修改内容,只能决定是否继续
  • post_call:在 LLM 调用之后运行,检查输入和输出,可以修改响应内容或拒绝返回
  • logging_only:仅在日志记录时应用掩码,不影响实际请求响应

当在 post_call 模式下处理流式响应时,防护栏会收集所有流式数据块,然后将其组装成完整的响应内容,再对完整内容进行审核,如果违规则阻止整个响应,如果安全则返回原始流式数据。

测试验证

发送如下请求测试下防护栏的效果:

$ curl -i http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {"role": "user", "content": "I hate all people of that religion and think they should be eliminated"}
    ]
  }'

另外要注意的是,上面的 default_on 参数表示默认启用,所有请求都会经过该检查。如果 default_on 没有启用,请求时需手动指定防护栏:

$ curl -i http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {"role": "user", "content": "I hate all people of that religion and think they should be eliminated"}
    ],
    "guardrails": ["openai-input-moderation"]
  }'

如果一切顺利,OpenAI Moderation 应该能识别出上面的仇恨言论,并返回错误响应:

{
  "error": {
    "message": "{'error': 'Violated OpenAI moderation policy', 'moderation_result': {'violated_categories': ['harassment', 'harassment/threatening', 'hate', 'hate/threatening', 'violence'], 'category_scores': {...}}}",
    "type": "None",
    "param": "None",
    "code": "400"
  }
}

Presidio PII 实战

Presidio 是微软开源的数据保护和去标识化工具包,名称源自拉丁语 praesidium,意为 保护,专注于识别并处理文本、图像及结构化数据中的个人可识别信息(PII),能助力企业和开发者满足 GDPR、CCPA 等隐私法规要求,广泛应用于金融、医疗、数据分析等多个领域。

Presidio 采用了微服务架构,主要包含四个核心模块:

  • Analyzer(分析器):核心功能是检测敏感信息,内置 40 多种敏感数据识别器,可识别姓名、邮箱、银行账号等信息;它结合命名实体识别、正则表达式等技术,还能借助上下文检测提升识别置信度,同时支持接入 SpaCy、Transformers 等多种 NLP 模型,也允许开发者自定义识别规则适配特殊场景;
  • Anonymizer(匿名化器):针对分析器检测到的敏感数据执行脱敏操作,提供掩码、替换、哈希、加密等多种内置方式;比如可将电话号码部分数字替换为星号,也支持通过代码自定义匿名化逻辑,甚至具备可逆匿名化能力,能在特定场景下恢复原始数据;
  • Image Redactor(图像脱敏模块):依托 OCR 技术识别图片中的敏感文本,像身份证照片、扫描表单里的个人信息等,再对其进行遮盖、模糊等脱敏处理;不过该功能目前成熟度不足,暂不建议用于生产环境;
  • Presidio Structured(结构化数据模块):专门处理表格、JSON 等结构化或半结构化数据,先识别其中包含敏感信息的列或键,再调用匿名化模块对这些字段的数据执行脱敏,适配数据库、数据仓库等批量数据处理场景;

在 LiteLLM 中集成 Presidio 可以为你的应用提供隐私保护能力。

部署 Presidio 服务

在集成之前,需要先部署 Presidio 的 Analyzer 和 Anonymizer 服务。官方提供了 Docker 镜像,我们可以通过 Docker Compose 一键部署。先创建一个 docker-compose.yml 文件:

services:
  presidio-analyzer:
    image: mcr.microsoft.com/presidio-analyzer:latest
    ports:
      - "5002:3000"
    networks:
      - presidio-network

  presidio-anonymizer:
    image: mcr.microsoft.com/presidio-anonymizer:latest
    ports:
      - "5001:3000"
    networks:
      - presidio-network

networks:
  presidio-network:
    driver: bridge

然后运行 docker compose 命令启动 Presidio 服务:

$ docker compose up -d

等待服务启动成功,使用下面的请求验证一下:

$ curl -X POST http://localhost:5002/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "text": "My email is zhangsan@example.com",
    "language": "en"
  }'

如果一切正常,应该会返回识别的结果:

[
  {
    "analysis_explanation": null,
    "end": 32,
    "entity_type": "EMAIL_ADDRESS",
    "score": 1.0,
    "start": 12
  },
  {
    "analysis_explanation": null,
    "end": 32,
    "entity_type": "URL",
    "score": 0.5,
    "start": 21
  }
]

防护栏定义

config.yaml 中配置 Presidio 防护栏:

guardrails:
  - guardrail_name: "presidio-pii-mask"
    litellm_params:
      guardrail: presidio
      mode: "pre_call"
      presidio_language: "en"  # 默认语言
      pii_entities_config:
        CREDIT_CARD: "MASK"     # 掩码信用卡号
        EMAIL_ADDRESS: "MASK"   # 掩码邮箱地址
        PERSON: "MASK"          # 掩码人名
        PHONE_NUMBER: "BLOCK"   # 阻止包含电话号码的请求

我们针对不同的 PII 设置了不同的动作,LiteLLM 的防护栏支持下面几种主要动作:

  • BLOCK(阻止):检测到违规内容时直接拒绝请求,返回错误信息
  • MASK(掩码):将敏感信息替换为占位符,如将邮箱地址替换为 [EMAIL]
  • ALLOW(允许):允许请求继续执行(用于白名单机制)

然后设置如下的环境变量:

$ export PRESIDIO_ANALYZER_API_BASE="http://localhost:5002"
$ export PRESIDIO_ANONYMIZER_API_BASE="http://localhost:5001"

测试验证

首先测试掩码功能:

$ curl http://localhost:4000/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {"role": "user", "content": "My name is John Doe and my email is john@example.com"}
    ],
    "guardrails": ["presidio-pii-mask"]
  }'

LLM 实际接收到的输入将是:

My name is <PERSON> and my email is <EMAIL_ADDRESS>

可以在 Admin UI 中的日志管理中确认:

presidio-pii-mask.png

如果只是希望在日志中屏蔽用户敏感信息,不影响实际交互,可以改为 logging_only 模式。

然后再测试下阻止功能:

$ curl http://localhost:4000/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "gpt-4o",
    "messages": [
      {"role": "user", "content": "Please call me at 425-555-0100"}
    ],
    "guardrails": ["presidio-pii-mask"]
  }'

由于配置了 PHONE_NUMBER: "BLOCK",这个请求会被直接拒绝:

{
  "error": {
    "message": "Blocked entity detected: PHONE_NUMBER by Guardrail: presidio-pii-mask. This entity is not allowed to be used in this request.",
    "type": "None",
    "param": "None",
    "code": "500"
  }
}

小结

通过本文的学习,我们系统梳理了 LiteLLM 防护栏机制的核心概念与实践方法,也深入体验了两种典型防护场景的落地流程。从整体设计来看,LiteLLM 的防护栏体系可归纳为三点:

  • 全面性:支持 20+ 专业防护供应商,覆盖内容安全、PII 保护、攻击防御等多个维度
  • 灵活性:支持 pre_call、during_call、post_call 等执行模式,以及 BLOCK、MASK 等执行动作,适应不同业务场景
  • 可扩展性:提供完整的自定义防护栏开发框架,满足特殊业务需求

我们通过 OpenAI Moderation 和 Presidio 的实战案例,从内容安全审核和 PII 隐私保护角度展示了 LiteLLM 防护栏集成能力。不过,关于防护栏机制还有很多高级的进阶场景没有展开:

  • 自定义防护栏开发:针对特殊业务规则,我们可以通过 LiteLLM 提供的接口编写自定义检查逻辑;
  • 提示词注入防护:提示词注入(Prompt Injection)是当前 LLM 应用面临的主要安全威胁之一,LiteLLM 支持输入相似度检测或 LLM 检查等机制,抵御恶意提示攻击;
  • 防护栏监控与告警:结合 LiteLLM 的监控系统,可以实现防护栏的全面监控;

感兴趣的同学可以在官方文档中找到更多资料。


实战 LiteLLM 与监控告警系统的集成

在前两篇文章中,我们学习了 LiteLLM 的内置日志系统和外部日志集成能力。基于这些丰富的日志数据,我们可以实现对 LLM 网关的全面观测。然而,在生产环境中,仅仅有日志数据是不够的,我们需要的是一套完整的监控和告警体系,能够在问题发生时第一时间通知运维团队,在预算即将超限时提前预警,在模型服务异常时及时切换,从而保障整个 LLM 服务的稳定性和可靠性。

LiteLLM 提供了完善的监控告警解决方案,支持与 Slack、Discord、Microsoft Teams 等通讯平台集成,实现实时告警通知;或者基于 PagerDuty 等专业告警平台,实现 7x24 小时的运维响应;同时它还支持 Prometheus 指标导出,可以与 Grafana 等监控平台构建企业级监控大盘。

今天,我们就来学习下如何将 LiteLLM 与监控告警系统集成,构建一个主动、智能的运维体系。我们会以 Slack 和 Prometheus 为例,演示具体的集成步骤,让你的 AI 应用具备完善的监控告警能力。

实战 Slack 告警集成

作为全球最受欢迎的团队协作平台,Slack 凭借其便捷的沟通体验、灵活的频道管理能力,以及丰富的第三方集成生态,成为了团队接收、流转重要信息的核心枢纽。将告警系统与 Slack 打通,更是能直接消除信息传递的延迟差,确保技术团队、运维团队或业务团队在第一时间捕捉到异常信号,避免因通知滞后导致的问题扩大化。

创建 Slack Webhook

LiteLLM 通过 Slack Webhooks 向 Slack 频道发送消息,从而实现告警功能。首先我们访问 Slack 页面,创建一个新的 Slack 工作区:

slack-create-workspace.png

如果你已有工作区,可跳过此步。我这里为方便演示,创建了一个名为 litellm-test 的工作区,并创建了一个名为 告警测试 的新频道:

slack-create-workspace-done.jpg

然后访问 Slack 的应用页面

slack-apps.png

点击 “Create an App” 创建一个名为 litellm-alert 的应用:

slack-create-an-app.png

创建成功后进入该应用的配置页面,我们在左侧菜单选择 “Incoming Webhooks”,点击 “Activate Incoming Webhooks” 启用 Webhook 功能:

slack-app-webhooks.png

然后点击 “Add New Webhook” 按钮,创建一个新的 Webhook 并将其关联到工作区的 “告警测试” 频道:

slack-app-add-webhook.png

这时就会生成一个 Webhook 链接,点击 “Copy” 按钮进行复制。

配置 LiteLLM

接下来修改 LiteLLM 的配置,开启 Slack 告警功能。首先配置环境变量:

export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/aaa/bbb/ccc"

然后修改 config.yaml 配置文件:

general_settings:
  # 启用 Slack 告警
  alerting: ["slack"]
  # 告警阈值(秒)- 请求超过 5 分钟视为异常
  alerting_threshold: 300
  # 消费报告频率(可选)
  spend_report_frequency: "1d"

重启 LiteLLM 服务:

$ litellm -c config.yaml

可以通过下面的命令测试 Slack 连接:

$ curl -X GET 'http://127.0.0.1:4000/health/services?service=slack' \
  -H 'Authorization: Bearer sk-1234'

如果配置正确,你应该在 Slack 频道看到类似下面这样一条测试消息:

slack-test-message.png

告警类型

接下来我们就可以做一些真实的告警测试了。LiteLLM 支持四大类告警类型,覆盖了生产环境的主要监控需求:

1. LLM 相关告警

  • LLM API 异常告警(llm_exceptions:当 LLM API 出现异常时触发告警
  • 慢响应告警(llm_too_slow:当 LLM 响应时间超过设定阈值时触发告警
  • 请求挂起告警(llm_requests_hanging:检测未能完成的 LLM 请求
  • 部署冷却告警(cooldown_deployment:当部署被置于冷却状态时的告警
  • 新模型添加告警(new_model_added:通过 /model/new 接口添加新模型时的通知
  • 停机告警(outage_alerts:当特定 LLM 部署面临停机时的告警
  • 区域停机告警(region_outage_alerts:当特定 LLM 区域面临停机时的告警,例如 us-east-1

2. 预算和支出告警

  • 预算告警(budget_alerts:与预算限制或阈值相关的通知
  • 支出报告(spend_reports:跨团队或标签的定期支出报告
  • 支出追踪失败告警(failed_tracking_spend:当支出追踪失败时的告警
  • 每日报告(daily_reports:每日支出报告
  • 回退报告(fallback_reports:LLM 回退发生情况的周报

3. 数据库告警

  • 数据库异常告警(db_exceptions:数据库相关异常的通知

4. 管理端点告警 - 虚拟密钥、团队、内部用户

  • 新虚拟密钥创建告警(new_virtual_key_created:创建新虚拟密钥时的通知
  • 虚拟密钥更新告警(virtual_key_updated:虚拟密钥被修改时的告警
  • 虚拟密钥删除告警(virtual_key_deleted:虚拟密钥被移除时的通知
  • 新团队创建告警(new_team_created:创建新团队时的告警
  • 团队更新告警(team_updated:团队详情被修改时的通知
  • 团队删除告警(team_deleted:团队被删除时的告警
  • 新内部用户创建告警(new_internal_user_created:新内部用户账户的通知
  • 内部用户更新告警(internal_user_updated:内部用户详情被更改时的告警
  • 内部用户删除告警(internal_user_deleted:内部用户账户被移除时的通知

我们可以在配置文件中手动指定要启用的告警类型(如果不指定,前三类告警默认是启用的,管理端点告警默认禁用):

general_settings:
  alerting: ["slack"]
  alerting_threshold: 300
  # 告警类型
  alert_types: [
    "llm_exceptions",       # LLM API 异常
    "llm_too_slow",         # 响应过慢
    "llm_requests_hanging", # 请求挂起
    "budget_alerts",        # 预算告警
    "spend_reports",        # 支出报告
    "db_exceptions",        # 数据库异常
    "daily_reports",        # 每日报告
    "outage_alerts"         # 停机告警
  ]

另外,在生产环境中,过多的告警会导致 告警疲劳,降低团队对重要告警的响应速度。为此 LiteLLM 实现了去重和防轰炸机制,比如:同一用户或团队的预算告警 24 小时内只发送一次;1 分钟内的多个停机告警会被聚合成一个告警;可以通过下面这些告警参数来进行控制:

general_settings:
  # 告警参数配置
  alerting_args:
    daily_report_frequency: 43200    # 12 小时发送一次日报
    report_check_interval: 3600      # 1 小时检查一次是否需要发送报告
    budget_alert_ttl: 86400         # 24 小时内不重复预算告警
    outage_alert_ttl: 60            # 1 分钟窗口聚合停机告警
    minor_outage_alert_threshold: 5 # 5 个错误触发轻微告警
    major_outage_alert_threshold: 10 # 10 个错误触发严重告警

多频道告警

LiteLLM 支持为不同类型的告警配置不同的通知频道:

general_settings:
  alerting: ["slack"]
  # 为每种告警类型指定专门的 Slack 频道
  alert_to_webhook_url: {
    "llm_exceptions": "https://hooks.slack.com/services/.../llm-alerts",
    "budget_alerts": "https://hooks.slack.com/services/.../finance-alerts",
    "daily_reports": "https://hooks.slack.com/services/.../daily-reports",
    "outage_alerts": [
      "https://hooks.slack.com/services/.../oncall-alerts",
      "https://hooks.slack.com/services/.../backup-alerts"
    ]
  }

这种配置允许我们:

  • LLM 异常告警发送到技术团队频道
  • 预算告警发送到财务管理频道
  • 每日报告发送到管理层频道
  • 停机告警同时发送到多个值班频道

兼容其他平台

LiteLLM 的 Slack 集成同样支持 Discord 和 Microsoft Teams(它们两都兼容 Slack 的 Webhook 格式):

Discord 配置:

# Discord Webhook 需要在 URL 后添加 /slack
export SLACK_WEBHOOK_URL="https://discord.com/api/webhooks/1240.../cTLWt5A.../slack"

Microsoft Teams 配置:

# MS Teams 提供 Slack 兼容的 Webhook
export SLACK_WEBHOOK_URL="https://outlook.office.com/webhook/...IncomingWebhook/..."

只需修改 Webhook URL 即可,配置文件保持不变。

实战 Prometheus 监控集成

Prometheus 是一个开源的监控和告警系统,最初由 SoundCloud 开发。它具有以下特点:

  • 时间序列数据库:专为监控数据设计的高性能存储
  • Pull 模式:主动拉取目标服务的指标数据
  • 强大的查询语言:PromQL 支持复杂的数据分析和聚合
  • 告警管理:与 Alertmanager 集成实现灵活的告警规则
  • 生态完整:与 Grafana 等可视化工具无缝集成

目前 Prometheus 已经是云原生监控的事实标准,LiteLLM 的企业版本提供了 Prometheus 集成能力。

配置 Prometheus 回调

首先安装必要的依赖:

$ pip install prometheus_client==0.20.0

然后在配置文件中启用 Prometheus 回调:

litellm_settings:
  callbacks: ["prometheus"]  # 启用 Prometheus 指标

重启 LiteLLM 服务:

$ litellm -c config.yaml

现在访问 http://localhost:4000/metrics 就可以看到 Prometheus 格式的指标数据。目前指标数据还是空的,可以发送几个测试请求后再看:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "给我讲个笑话"}]
  }'

指标详解

LiteLLM 提供的指标大致可以分为以下几个主要类别:

1. 代理服务指标(Proxy Service Metrics)

这类指标主要监控 LiteLLM 代理服务的整体运行状况和请求处理情况:

  • litellm_proxy_total_requests_metric_total (counter)
    代理服务总请求数 - 跟踪客户端向代理发起的请求总量
  • litellm_proxy_failed_requests_metric_total (counter)
    代理服务失败请求数 - 客户端未能从代理获得成功响应的请求数

2. 延迟性能指标(Latency & Performance Metrics)

这类指标用于监控请求处理的延迟情况,帮助识别性能瓶颈:

  • litellm_request_total_latency_metric (histogram)
    LiteLLM 请求总延迟时间(包含 LiteLLM 开销)
  • litellm_llm_api_latency_metric (histogram)
    LLM API 调用延迟时间
  • litellm_llm_api_time_to_first_token_metric (histogram)
    LLM API 首个 token 响应时间(仅流式请求)
  • litellm_overhead_latency_metric (histogram)
    LiteLLM 处理开销延迟

3. 成本和使用量指标(Cost & Usage Metrics)

这类指标跟踪 LLM 服务的使用成本和 token 消费情况:

  • litellm_spend_metric_total (counter)
    LLM 请求总花费
  • litellm_total_tokens_metric_total (counter)
    LLM 请求的输入+输出 token 总数
  • litellm_input_tokens_metric_total (counter)
    LLM 请求的输入 token 总数
  • litellm_output_tokens_metric_total (counter)
    LLM 请求的输出 token 总数

4. 预算管理指标(Budget Management Metrics)

这类指标监控团队和 API 密钥的预算使用情况,支持成本控制:

团队预算指标:

  • litellm_remaining_team_budget_metric (gauge)
    团队剩余预算
  • litellm_team_max_budget_metric (gauge)
    团队最大预算设置
  • litellm_team_budget_remaining_hours_metric (gauge)
    团队预算重置剩余时间(小时)

API 密钥预算指标:

  • litellm_remaining_api_key_budget_metric (gauge)
    API 密钥剩余预算
  • litellm_api_key_max_budget_metric (gauge)
    API 密钥最大预算设置
  • litellm_api_key_budget_remaining_hours_metric (gauge)
    API 密钥预算重置剩余时间(小时)

5. 流量控制指标(Rate Limiting Metrics)

这类指标监控基于模型的请求和 token 限制情况:

  • litellm_remaining_api_key_requests_for_model (gauge)
    API 密钥针对特定模型的剩余请求数(基于 RPM 限制)
  • litellm_remaining_api_key_tokens_for_model (gauge)
    API 密钥针对特定模型的剩余 token 数(基于 TPM 限制)
  • litellm_remaining_requests (gauge)
    LLM 部署的剩余请求数(来自 LLM API 提供商)
  • litellm_remaining_tokens (gauge)
    LLM 部署的剩余 token 数(来自 LLM API 提供商)

6. 部署状态指标(Deployment Analytics)

这类指标监控 LLM 部署的健康状态和运行表现:

部署状态:

  • litellm_deployment_state (gauge)
    部署状态:0=健康,1=部分故障,2=完全故障
  • litellm_deployment_cooled_down_total (counter)
    部署被负载均衡逻辑冷却的次数

请求统计:

  • litellm_deployment_success_responses_total (counter)
    LLM 部署成功响应总数
  • litellm_deployment_failure_responses_total (counter)
    LLM 部署失败响应总数
  • litellm_deployment_total_requests_total (counter)
    LLM 部署总请求数(成功+失败)

性能分析:

  • litellm_deployment_latency_per_output_token (histogram)
    每个输出 token 的延迟时间

7. 回退机制指标(Fallback Metrics)

这类指标监控主要模型失败时的回退处理情况:

  • litellm_deployment_successful_fallbacks_total (counter)
    成功回退请求数(从主模型→回退模型)
  • litellm_deployment_failed_fallbacks_total (counter)
    失败回退请求数(从主模型→回退模型)

自定义 Metrics 标签

LiteLLM 支持添加自定义元数据作为 Prometheus 标签:

litellm_settings:
  callbacks: ["prometheus"]
  # 将请求元数据添加为 Prometheus 标签
  custom_prometheus_metadata_labels: [
    "metadata.environment",
    "metadata.service",
    "metadata.version"
  ]

发送带有自定义元数据的请求:

$ curl -X POST 'http://localhost:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "测试"}],
    "metadata": {
      "environment": "production",
      "service": "chatbot",
      "version": "v1.2.3"
    }
  }'

生成的指标将包含这些自定义的标签:

litellm_total_tokens_metric{
  model="gpt-4o",
  metadata_environment="production",
  metadata_service="chatbot",
  metadata_version="v1.2.3"
} 89

使用此功能时需特别小心,避免使用高基数标签(比如 user_idrequest_id 等),可能导致指标爆炸,造成性能问题。

另一种自定义标签的方式是通过 custom_prometheus_tags 配置:

litellm_settings:
  callbacks: ["prometheus"]
  # 自定义标签
  custom_prometheus_tags: [
    "prod",
    "staging"
  ]

然后发送带标签的请求:

$ curl -X POST 'http://localhost:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "测试"}],
    "metadata": {
      "tags": ["prod"]
    }
  }'

生成的指标如下所示:

litellm_total_tokens_metric{
  model="gpt-4o",
  tag_prod="true",
  tag_staging="false"
} 89

使用 Prometheus 采集指标

创建 prometheus.yml 配置文件:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'litellm'
    static_configs:
      - targets: ['10.6.120.132:4000'] # 换成你的 IP 地址
    metrics_path: '/metrics'
    scrape_interval: 10s

然后使用 Docker 启动 Prometheus 服务:

$ docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

访问 http://localhost:9090 进入 Prometheus 的 Query 页面,输入指标即可查询:

prometheus-query.png

点击 “Graph” 以图的形式查看指标:

prometheus-query-graph.png

通过 Prometheus 采集的指标数据,我们可以更进一步,基于 Grafana 构建一个完整的 LiteLLM 监控大盘,实现对 AI 服务的全方位观测。可以参考 LiteLLM 官方提供的 Grafana 仪表盘模板:

此外,Prometheus 还可以和 Alertmanager 集成,实现比 Slack 更灵活的告警规则。具体内容可以参考 Alertmanager 的官方文档:

小结

今天我们深入学习了 LiteLLM 的监控告警系统,重点掌握了两种集成方案:

  • Slack 告警集成:提供实时的通知能力,支持多种告警类型和智能去重,特别适合团队协作和快速响应的场景
  • Prometheus 监控集成:基于时间序列数据的企业级监控方案,与 Grafana 结合可构建完整的可观测性平台,或者与 Alertmanager 集成实现更灵活的告警规则

除了这两种集成方案,LiteLLM 还支持 PagerDuty、邮件、Webhook 等其他方式,篇幅有限,此处不再赘述。

监控告警系统是生产环境的神经系统,它让我们能够感知系统的每一个变化,及时响应每一个问题。希望通过本文的学习,你能够建立起稳定可靠的 LiteLLM 监控告警体系,为用户提供更好的 AI 服务体验。

欢迎关注

如果这篇文章对您有所帮助,欢迎关注我的同名公众号:日习一技,每天学一点新技术

我会每天花一个小时,记录下我学习的点点滴滴。内容包括但不限于:

  • 某个产品的使用小窍门
  • 开源项目的实践和心得
  • 技术点的简单解读

目标是让大家用5分钟读完就能有所收获,不需要太费劲,但却可以轻松获取一些干货。不管你是技术新手还是老鸟,欢迎给我提建议,如果有想学习的技术,也欢迎交流!


实战 LiteLLM 与外部日志系统的集成

在前一篇文章中,我们学习了 LiteLLM 的内置日志系统,包括请求日志、会话日志和审核日志。这些日志为我们提供了完整的 API 调用追踪、成本分析和合规审计能力。然而,在企业级部署场景中,我们往往需要将这些宝贵的数据集成到现有的可观测性生态系统中,比如与 Elasticsearch 进行日志分析、通过 Datadog 进行性能监控,或者利用 Langfuse 进行 LLM 专业化的可观测性管理。

LiteLLM 支持与 30 多种外部日志和可观测性系统 的集成,包括传统的云存储(S3、GCS、Azure Blob)、专业的可观测性平台(Langfuse、OpenTelemetry、Datadog)、以及企业级的数据分析工具(Elasticsearch、BigQuery、DynamoDB),为我们构建完整的监控和分析体系提供了强有力的支持。

今天这篇文章,我们就来深入学习 LiteLLM 的外部日志集成能力。

支持的外部日志系统

LiteLLM 的日志集成能力非常丰富,支持多达 30+ 种不同类型的外部系统:

LLM 专业可观测性平台

  • Langfuse - LLM 专业可观测性平台,提供完整的 LLM 应用监控、分析和优化
  • Langsmith - LangChain 官方的 LLM 开发和监控平台,专为 LangChain 生态设计
  • Lunary - LLM 监控和分析平台,提供对话流程可视化和性能分析
  • Langtrace - LLM 应用的可观测性和监控平台,提供详细的追踪分析
  • Helicone - 开源的 LLM 可观测性平台,简化 LLM 应用监控
  • DeepEval - Confidential AI 的 LLM 评测平台,专注模型质量评估
  • Athina - LLM 应用的质量评估和监控平台,提供实时质量检测
  • Braintrust - AI 产品开发平台,提供评估、监控和数据管理
  • Humanloop - LLM 应用开发平台,集成提示工程和监控功能
  • Literal AI - 对话式 AI 监控平台,专注用户体验优化
  • Promptlayer - 提示工程和监控平台,帮助优化 LLM 提示效果

通用监控和可观测性平台

  • OpenTelemetry - 开源的可观测性框架,支持分布式追踪和监控
  • Datadog - 综合性能监控平台,提供全栈监控和告警能力
  • Sentry - 错误监控和性能追踪平台,帮助快速定位应用问题
  • Logfire - Pydantic 团队开发的现代可观测性平台
  • PostHog - 开源的产品分析平台,提供用户行为跟踪和 A/B 测试

机器学习和实验管理

  • MLflow - 机器学习实验管理平台,支持模型版本控制和部署
  • Arize AI - 专注于 ML 可观测性的企业级平台,提供模型漂移检测
  • Arize Phoenix OSS - Arize 的开源版本,专注 ML 模型监控
  • Galileo - AI 模型质量监控平台,专注于数据和模型性能评估
  • Weights & Biases - 机器学习实验跟踪和可视化平台
  • Comet Opik - 机器学习实验管理和模型监控平台

数据标注和质量管理

  • Argilla - 开源数据标注和质量管理平台,支持 LLM 训练数据优化
  • AgentOps - AI Agent 运行监控平台,专注 Agent 行为分析

使用量计量和费用管理

  • OpenMeter - 开源的使用量计量和计费平台,支持 API 使用监控
  • Greenscale - 云成本优化平台,帮助降低 AI 基础设施成本
  • CloudZero's AnyCost API - 企业级云成本分析和分配平台
  • Lago - 开源计费平台,支持基于使用量的灵活计费模式

云存储服务

  • AWS S3 - AWS 的对象存储服务,适合大规模日志归档
  • AWS SQS - AWS 的消息队列服务,适合实时日志处理
  • Google Cloud Storage Buckets - 谷歌云的对象存储服务
  • Google Cloud Storage PubSub Topic - 谷歌云的消息队列服务,可以被 BigQuery 消费
  • Azure Blob Storage - 微软云的存储解决方案

数据库和分析

  • Elasticsearch - 分布式搜索和分析引擎
  • DynamoDB - AWS 的 NoSQL 数据库
  • BigQuery - 谷歌云的大数据分析平台
  • Supabase - Firebase 开源替代

下面将以 Langfuse 和 OpenTelemetry 为例,实际体验下集成的详细步骤。

实战 Langfuse 集成

Langfuse 是专为 LLM 应用设计的开源可观测性平台,提供了完整的链路追踪、性能分析、成本监控和质量评估能力。

langfuse.png

作为专业的 LLM 可观测性平台,Langfuse 具有以下核心特性:

  • 追踪(Tracing):记录 LLM 应用的完整执行过程
  • 观测(Observability):提供实时的性能监控和可视化
  • 评估(Evaluation):支持多种评估指标和人工标注
  • 数据集管理:管理测试数据和历史记录
  • 成本追踪:监控 Token 使用和费用

获取 Langfuse 的 API Key

我们首先访问 Langfuse 官网,注册账号并登录,然后创建一个组织:

langfuse-new-org.png

然后在组织下创建一个项目:

langfuse-new-project.png

创建成功后,接着为项目创建 API Key:

langfuse-new-apikey.png

点击创建按钮,获取以下三个重要参数:

  • Public Key:公开密钥,用于客户端身份验证
  • Secret Key:私钥,用于服务端 API 调用
  • Host:Langfuse 服务器地址

langfuse-new-apikey-2.png

Langfuse 是开源项目,我们也可以本地部署它。

在 LiteLLM 中配置 Langfuse

首先安装依赖:

$ pip install langfuse==2.59.7

注意,如果使用最近版本的 Langfuse 可能会报错,可以使用 Langfuse OTEL 集成方案。

然后配置环境变量:

export LANGFUSE_PUBLIC_KEY="pk_xxx"
export LANGFUSE_SECRET_KEY="sk_xxx"
export LANGFUSE_HOST="https://cloud.langfuse.com"  # 可选,默认为云版本

接着在 config.yaml 中添加 Langfuse 回调:

litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]

最后重新启动 LiteLLM 并发送测试请求:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "介绍下 Langfuse"}]
  }'

进入 Langfuse 的 Trace 页面,应该能看到详细的追踪数据:

langfuse-trace.png

元数据传递

Langfuse 支持传递丰富的元数据信息,用于更精确的分析:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "介绍下 Langfuse"}],
    "metadata": {
      "generation_name": "knowledge-qa",
      "trace_id": "trace-001",
      "trace_user_id": "user-123",
      "session_id": "session-456"
    }
  }'

这些元数据在 Langfuse 中显示如下:

langfuse-trace-metadata.png

自定义标签

我们还可以使用标签对不同类型的请求进行分类:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "写一个 Python 函数来计算斐波那契数列"}],
    "metadata": {
      "tags": ["code-generation", "python", "algorithms"]
    }
  }'

这些标签可以在 Langfuse 的 Tags 一栏看到:

langfuse-trace-tags.png

注意,这个功能可能和标签路由冲突,如果开启了标签路由,tags 就不能随便传了。

除了在请求中自定义标签,LiteLLM 也内置了很多特有的字段作为标签,可以在配置文件中启用:

litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]
  # 配置要作为标签记录的 LiteLLM 字段
  langfuse_default_tags: [
    "cache_hit",               # 缓存命中状态
    "cache_key",               # 缓存键
    "user_api_key_alias",      # 用户API密钥别名
    "user_api_key_user_id",    # 用户ID
    "user_api_key_user_email", # 用户邮箱
    "user_api_key_team_alias", # 团队
  ]

这样在 Langfuse 中就能看到这些额外的标签信息,方便进行更细粒度的分析:

langfuse-trace-litellm-tags.png

实战 OpenTelemetry + Elasticsearch 集成

OpenTelemetry 简称 OTEL,是 CNCF 的开源可观测性框架,提供了统一的遥测数据收集标准。它的核心优势在于:

  • 标准化:使用业界标准的遥测数据格式
  • 灵活性:可以同时导出到多个不同的监控系统
  • 可扩展性:Collector 可以水平扩展处理大量数据
  • 厂商中立:不依赖特定的监控平台

otel.png

OpenTelemetry 的主要组件包括:

  • SDK:各种语言的客户端库,负责收集遥测数据
  • Collector:数据收集、处理和导出的中间件
  • Exporter:将数据导出到不同的后端系统

其实现架构如下:

otel-graph.png

结合 Elasticsearch 的强大搜索和分析能力,我们可以构建一个企业级的日志分析系统。

环境搭建

第一步,创建一个 Docker 网络:

$ docker network create otel-network

在该网络中启动一个单节点的 Elasticsearch 服务:

$ docker run -d \
  --name elasticsearch \
  --network otel-network \
  -p 9200:9200 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  elasticsearch:8.18.2

第二步,创建 otel_config.yaml 配置文件:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024

exporters:
  debug:
    verbosity: detailed
  elasticsearch:
    endpoint: "http://elasticsearch:9200"

service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [debug, elasticsearch]
    traces:
      receivers: [otlp]
      exporters: [debug, elasticsearch]
    logs: 
      receivers: [otlp]
      exporters: [debug, elasticsearch]

然后启动 OpenTelemetry Collector 服务,注意它和 Elasticsearch 共用一个网络,确保可以使用 elasticsearch:9200 这个地址访问 Elasticsearch 服务:

$ docker run -d \
  --name otel-collector \
  --network otel-network \
  -p 4317:4317 \
  -p 4318:4318 \
  -v $(pwd)/otel_config.yaml:/etc/otel-collector-config.yaml \
  otel/opentelemetry-collector-contrib:latest \
  --config=/etc/otel-collector-config.yaml

另一点值得注意的是,这里我使用的是 otel/opentelemetry-collector-contrib 镜像,该镜像包含大量的接收器导出器处理器连接器 和其他可选组件,包括我们这里要使用的 elasticsearch 导出器。

第三步,修改 LiteLLM 的配置文件,添加 OTEL 回调:

litellm_settings:
  callbacks: ["otel"]

并安装 OTEL 相关的依赖:

$ pip install \
  opentelemetry-api \
  opentelemetry-sdk \
  opentelemetry-exporter-otlp

然后设置环境变量:

$ export OTEL_EXPORTER=otlp_http
$ export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"

重启 LiteLLM 服务:

$ litellm -c config.yaml

测试验证

发送测试请求:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

稍等片刻,搜索 Elasticsearch 验证数据是否正确写入:

# 搜索最近的一条跟踪数据
$ curl "localhost:9200/_search?pretty&size=1" | jq '.'

如果一切顺利,应该能看到类似这样的 OpenTelemetry 跟踪数据:

{
  "took": 119,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 15,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": ".ds-traces-generic.otel-default-2025.11.25-000001",
        "_id": "AZq5FFC45Ve33J9AiHVu",
        "_score": 1.0,
        "_source": {
          "@timestamp": "2137173047.194915",
          "data_stream": {
            "type": "traces",
            "dataset": "generic.otel",
            "namespace": "default"
          },
          "trace_id": "af20113fb91ba1e2893b1c0e3a6d20e7",
          "span_id": "f8b94554ab20692f",
          "parent_span_id": "f5cf57a86811be6d",
          "name": "router",
          "kind": "Internal",
          "duration": 823751,
          "attributes": {
            "call_type": "async_get_available_deployment",
            "service": "router"
          },
          "links": [],
          "status": {
            "code": "Ok"
          },
          "resource": {
            "attributes": {
              "telemetry.sdk.language": "python",
              "telemetry.sdk.name": "opentelemetry",
              "telemetry.sdk.version": "1.38.0",
              "service.name": "litellm",
              "deployment.environment": "production",
              "model_id": "litellm"
            }
          },
          "scope": {
            "name": "litellm"
          }
        }
      }
    ]
  }
}

Kibana 可视化

我们还可以启动 Kibana 进行数据可视化,注意和 Elasticsearch 共用一个网络:

$ docker run -d \
  --name kibana \
  --network otel-network \
  -p 5601:5601 \
  kibana:8.18.2

访问 http://localhost:5601,进入 探索(Discover) 页面,创建一个新的 数据视图(Data View)

kibana-create-data-view.png

其中 索引模式(Index pattern) 填写 traces-generic.otel-default,OTEL 的 trace 数据默认会写入该 数据流(Data Stream) 中。然后选择该视图,就可以看到 LiteLLM 推送过来的日志了:

kibana-logs.png

小结

今天我们学习了 LiteLLM 与外部日志系统的集成能力,对其中的两种集成方案进行了实战演示:

  • Langfuse 集成:专业的 LLM 可观测性平台,提供了完整的链路追踪、成本分析和质量评估能力,特别适合需要深度 LLM 应用监控的场景
  • OpenTelemetry + Elasticsearch 集成:基于开源标准的企业级日志分析方案,利用 OTEL 的标准化数据收集和 Elasticsearch 的强大搜索分析能力

除了本文介绍的这两种方案,LiteLLM 还支持 30 多种其他日志系统的集成,具体内容可参考官方文档:

通过统一的回调机制和标准化的日志格式,我们可以将 LiteLLM 的日志数据与现有的可观测性生态系统无缝整合,实现全面的性能监控、成本优化和问题诊断。


学习 LiteLLM 的日志系统

对于一个 LLM 网关来说,日志系统扮演着至关重要的角色:它不仅能帮我们追踪每一笔 API 调用的成本和性能;当模型回复异常或请求失败时,还能提供详细的上下文信息来定位问题;它还确保所有管理操作都有迹可循,以满足合规性要求。

我们今天就来学习下 LiteLLM 的日志体系,主要包括 请求日志(Spend Logs)会话日志(Session Logs)审核日志(Audit Logs)

logging.png

请求日志

请求日志(Spend Logs) 是整个日志系统的核心,它记录了每一次 API 调用的详细信息,包括调用者、消耗成本、token 使用量、延迟等关键指标,能够用于成本分析和性能监控。

可以进入 Admin UI,点击 Logs 菜单,查看请求日志:

![](./images/requests-logs.png)

在这里,LiteLLM 记录了所有成功和失败的请求日志。考虑到 隐私保护存储成本,默认情况下,LiteLLM 只记录元数据信息,而不存储具体的请求和响应内容。如果业务需要进行内容分析或调试,可以通过下面的配置显式开启:

general_settings:
  store_prompts_in_spend_logs: true

注:开启此选项会增加数据库的存储压力,并且可能涉及敏感数据的合规问题,请根据实际情况谨慎开启。

开启后,你就能在 UI 界面中看到完整的对话内容:

requests-logs-request-response.png

日志保存逻辑

LiteLLM 的请求日志保存在 Postgre 数据库的 LiteLLM_SpendLogs 表中,在高并发场景下,如果每一笔请求都同步写入数据库,会对性能造成巨大影响。为了最小化对主要请求路径的性能影响,它采用了 异步队列和批量处理 的优化手段:

![](./images/requests-logs-flow.png)

这里有几个值得学习的点:

  1. 异步处理:日志记录不会阻塞主要的 API 响应路径
  2. 批量提交:多个日志记录会被聚合后批量写入数据库
  3. 内存缓冲:使用内存队列减少数据库 I/O 频次
  4. 事务安全:通过数据库事务确保数据一致性

高级配置选项

除了 store_prompts_in_spend_logs 选项之外,LiteLLM 还提供了很多其他的配置选项来控制日志行为:

general_settings:
  # 完全禁用错误日志
  disable_error_logs: true

  # 完全禁用支出日志
  disable_spend_logs: true

  # 存储详细的请求/响应内容
  store_prompts_in_spend_logs: true

  # 配置日志保留期
  maximum_spend_logs_retention_period: "30d"  # 30天后自动删除
  maximum_spend_logs_retention_interval: "1d"  # 每天执行一次清理

其中日志的自动删除功能属于企业特性。此外,在多实例部署环境中,LiteLLM 使用 Redis 分布式锁 确保清理任务不会重复执行,因此需要开启 Redis 缓存。

会话日志

会话日志(Session Logs) 在请求日志的基础上,提供了 会话级别的聚合视图,它通过 session_id 将相关的请求进行逻辑分组,让你能够跟踪用户的完整交互流程。

可以在发起请求时增加一个 litellm_session_id 参数:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[
    {"role": "user", "content": "你好,我是张三"}
  ],
  extra_body={
    "litellm_session_id": session_id
  }
)
print(response.choices[0].message.content)

然后将后续请求也关联到这个会话:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[
    {"role": "user", "content": "你好,我是张三"},
    {"role": "assistant", "content": response.choices[0].message.content},
    {"role": "user", "content": "我是谁"}
  ],
  extra_body={
    "litellm_session_id": session_id
  }
)
print(response.choices[0].message.content)

在 LiteLLM 的 UI 中,可以看到生成的两条请求日志 Session ID 是相同的:

session-logs.png

你可以通过 Session ID 筛选出该会话下的所有交互记录,这对于复现 Bug 或分析用户行为模式非常有帮助:

session-logs-details.png

使用 Responses API

使用 Chat Completions API 进行多轮对话时,每一次都要带上完整的上下文,这是非常不方便的。可以考虑使用 OpenAI 的 Responses API 接口,LiteLLM 也对该接口做了兼容。

第一次请求如下:

response = client.responses.create(
  model="gpt-4o",
  input="你好,我是张三"
)
print(response.output_text)

第二次请求时通过 previous_response_id 参数带上前一次请求的响应 ID 即可:

response = client.responses.create(
    model="gpt-4o",
    input="我是谁",
    previous_response_id=response.id
)
print(response.output_text)

LiteLLM 内部对 Chat Completions API 接口做了一层封装,使得我们也可以通过 Responses API 调用 Anthropic、Gemini 等模型。不过需要注意的是,它是根据会话 ID 查询数据库获取历史对话,因此需要开启 store_prompts_in_spend_logs: true 保存请求和响应的日志。

另一点需要注意的是,由于日志存储是异步的,因此第二次请求不能太快,太快的话可能还查不到历史对话,两次请求中间要等待个 10 秒左右。这个特性目前还是 beta 状态,后面应该会优化。

审核日志

审核日志(Audit Logs) 则专注于记录所有的管理操作,包括用户创建、权限变更、配置修改等。这类日志对于企业的合规要求、安全审计和问题追踪具有关键作用。

审核日志是企业级特性,需要显式启用:

litellm_settings:
  store_audit_logs: true

然后我们通过 /key/generate 接口生成一个 Key:

$ curl 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "metadata": {"user": "audit-test@example.com"}
  }'

进入 Admin UI,点击 Logs 菜单,查看审核日志如下:

audit-logs.png

LiteLLM 会自动为以下管理操作创建审核日志:

用户管理:
- ✅ 用户创建、更新、删除
- ✅ 用户权限变更
- ✅ 用户状态变更(激活/禁用)

API 密钥管理:
- ✅ 密钥创建、更新、删除
- ✅ 密钥轮换(regenerate)
- ✅ 密钥权限修改

团队管理:
- ✅ 团队创建、更新、删除
- ✅ 团队成员添加/移除
- ✅ 团队预算调整

模型配置:
- ✅ 模型添加、更新、删除
- ✅ 模型权限配置变更

小结

今天的内容比较简单,主要学习了 LiteLLM 的三大日志系统:

  • 请求日志(Spend Logs) 精确记录每一次 API 调用的详细信息,可以通过 store_prompts_in_spend_logs 参数开启存储具体的请求和响应内容;
  • 会话日志(Session Logs) 在请求日志基础上提供了会话级别的聚合视图,通过 Session ID 分组,支持跨多个请求的用户行为追踪和对话模式分析;
  • 审核日志(Audit Logs) 专注于管理操作的完整记录,确保每一个关键操作都有迹可循;

这套完整的日志系统,作为 LiteLLM 的核心能力,直接存储在 Postgre 数据库中。其实,LiteLLM 还支持对接很多外部日志系统或可观测平台,并基于这些丰富的日志数据构建完善的监控体系,我们将在下一篇文章中继续学习。


学习 LiteLLM 的缓存系统

随着我们的 LLM 网关承载的流量越来越大、接入的模型越来越多,除了稳定性和可靠性,成本和性能 也成为了关键的考量因素。实际上,我们的应用每天都在处理很多相似的查询,比如客服系统中的常见问题、代码生成中的重复模式、文档摘要中的相似内容。如果每次都调用真实的 LLM API,不仅延迟高、成本昂贵,还可能触发供应商的速率限制。而且,对于相同或相似的查询,LLM 的回答往往是一致的或高度相似的,这就为缓存的应用提供了天然的基础。

LiteLLM 提供了一套完整的缓存解决方案,它不仅能够缓存完全相同的请求(精确缓存),还能够基于语义相似性缓存相似的请求(语义缓存),从而显著降低成本,并大幅提升性能,同时减轻对上游 API 的压力,提高了系统稳定性。

今天这篇文章,我们就来深入了解一下 LiteLLM 的缓存系统。

缓存类型一览

LiteLLM 支持 8 种不同的缓存后端,每种都针对特定的使用场景:

传统缓存

  • 内存缓存(In-Memory):最快的访问速度,适合单机部署和开发测试
  • 磁盘缓存(Disk):持久化存储,适合单机长期缓存
  • Redis 缓存:分布式缓存,适合多实例部署和生产环境

云存储缓存

  • S3 缓存:利用 AWS S3 进行大规模、低成本的缓存存储
  • GCS 缓存:基于 Google Cloud Storage 的缓存解决方案
  • Azure Blob 缓存:微软 Azure 的对象存储缓存

智能缓存

  • Redis 语义缓存:基于向量相似度的语义匹配缓存
  • Qdrant 语义缓存:专业向量数据库的语义缓存解决方案

基本使用

首先我们来体验下最简单的内存缓存,在 config.yaml 文件中添加如下配置:

litellm_settings:
  cache: true
  cache_params:
    type: local

然后重启 LiteLLM Proxy 服务。发送第一次请求:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "给我讲个笑话"}]
  }'

第一次请求会调用真实的 API,耗时可能在 1-3 秒。再发送完全相同的请求(加了 -v 选项用于打印响应头):

$ curl -v -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "给我讲个笑话"}]
  }'

第二次请求从缓存返回,耗时通常在 50-200 毫秒,响应头中会包含缓存相关信息:

x-litellm-cache-key: 6b86d8cb3ab300d7cbe071f93176e28cc25d9da7f2db95dd8ad078176faddc94

这个 Key 是根据请求内容生成的,相同的请求参数生成的 Key 也是相同的。

Redis 缓存

内存缓存适合单机部署和开发测试,生产环境一般使用 Redis 作为缓存后端。可以用 Docker 在本地快速启一个 Redis 示例:

$ docker run -d \
  --name redis-stack \
  -p 6379:6379 \
  -p 8001:8001 \
  redis/redis-stack:latest

注意我这里使用的是 Redis Stack 镜像,它是一个包含多个模块的集成软件套件,在 Redis 的基础上,扩展了 搜索(RedisSearch)JSON(RedisJSON)图数据库(RedisGraph)时间序列(RedisTimeSeries)布隆过滤器(RedisBloom) 等功能,提供了更丰富的数据处理能力,适用于构建复杂应用。相对于 Redis Server 只是核心的内存数据结构存储,更侧重于缓存和消息队列等场景。

最简单的 Redis 缓存配置如下:

litellm_settings:
  cache: true
  cache_params:
    type: redis
    host: localhost          # Redis 服务器地址
    port: 6379               # Redis 端口
    password: your_password  # Redis 密码(可选)
    ttl: 600                 # 默认缓存时间(秒)

对于大规模部署,LiteLLM 支持配置 Redis 集群或哨兵。

验证方法和内存缓存一样,第二次请求从缓存返回,并且在 Redis 中应该能找到 x-litellm-cache-key 对应的缓存键:

redis-key.png

Redis 语义缓存

Redis 不仅可以用来做普通缓存,还可以用来做向量数据库。我们可以将文本、图像等非结构化数据转换为向量,存储到 Redis 中,并利用 Redis 的内存优势实现毫秒级的向量相似性搜索。

LiteLLM 基于 Redis 向量数据库实现了语义缓存功能,语义缓存 不同于传统的精确匹配缓存,它能够理解查询的语义含义,并返回语义相似查询的缓存结果。即使这些查询的字面表达完全不同,语义缓存也能识别它们的相似性并返回相同的结果,大大提高了缓存命中率。

Redis 语义缓存基于 Redis Vector Library (RedisVL) 实现,首先需要安装依赖:

$ pip install redisvl==0.4.1

然后在 LiteLLM 的配置文件中开启 Redis 语义缓存:

litellm_settings:
  cache: true
  cache_params:
    type: redis-semantic              # 语义缓存类型
    host: localhost
    port: 6379
    password: your_password
    ttl: 600
    similarity_threshold: 0.8                                     # 相似度阈值(0-1,1为完全匹配)
    redis_semantic_cache_embedding_model: text-embedding-3-large  # 嵌入模型名称

其中 similarity_threshold 为相似度阈值,范围 [0-1]redis_semantic_cache_embedding_model 为嵌入模型名称,必须是在 model_list 中定义。

注意,如果你的 Redis 没有密码,启动可能会报错 Missing required Redis configuration: REDIS_PASSWORD。设置一下环境变量 export REDIS_PASSWORD= 即可。

可以使用两个相似的请求来验证,第一次请求:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "什么是人工智能?"}]
  }'

第二次请求:

$ curl -v -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "AI 是什么?"}]
  }'

第二次请求的响应头中不仅包含了缓存 Key,还包含了相似度信息:

x-litellm-cache-key: 9cdf6246deaee1f8d96aa8b093029bc129f7eca32f2f8f4a9fd0352138e6ea3e
x-litellm-semantic-similarity: 0.162912428379

我们打开 Redis 管理页面,可以发现多了一个 litellm_semantic_cache_index 开头的键:

redis-sematic-key.png

它的内容包含了请求的 Prompt 和对应的响应:

redis-sematic-value.png

RedisVL 库介绍

RedisVL (Redis Vector Library) 是 Redis 官方提供的 Python 客户端库,专为 AI 应用设计,提供了高级的向量搜索抽象,主要特性包括:

  • 简化的 API:高级抽象,简化向量搜索操作
  • 强大的查询能力:支持混合查询、过滤条件、聚合等
  • 语义缓存:专门为 LLM 缓存优化的 LLMCache 组件,LiteLLM 的 Redis 语义缓存就是基于它实现的

这一节我们通过一个简单示例学习它的基本使用。

首先通过 Schema 创建索引:

from redisvl.index import SearchIndex
from redis import Redis

# 创建连接
client = Redis.from_url("redis://localhost:6379")

# 使用字典定义 Schema
schema = {
  "index": {
    "name": "product_index",
    "prefix": "product:",
  },
  "fields": [
    {"name": "title", "type": "text"},
    {"name": "brand", "type": "tag"},
    {"name": "price", "type": "numeric"},
    {"name": "category", "type": "tag"},
    {
      "name": "description_vector",
      "type": "vector",
      "attrs": {
        "dims": 3072,  # 向量维度
        "distance_metric": "cosine",  # 距离度量
        "algorithm": "flat",  # 向量索引算法
        "datatype": "float32"
      }
    }
  ]
}

# 创建索引
index = SearchIndex.from_dict(schema, redis_client=client)
index.create(overwrite=True)
print(f"索引创建成功!")

这是一个产品表,包含产品的名称、品牌、分类、价格、描述等信息,我们为描述加一个向量字段,用于语义搜索。

其中向量维度根据你使用的 Embedding 模型来定义,我这里使用的是 OpenAI 的 text-embedding-3-large 模型,维度是 3072 维。

接着定义一批示例数据,加载到 Redis 中:

import numpy as np
from litellm import embedding

# 定义产品数据
products = [
  {
    "id": "p001",
    "title": "iPhone 15 Pro Max",
    "brand": "Apple",
    "category": "smartphone",
    "price": 1199,
    "description": "最新的 iPhone,配备 A17 Pro 芯片,48MP 主摄像头,钛金属机身"
  },
  {
    "id": "p002",
    "title": "MacBook Pro 14英寸",
    "brand": "Apple",
    "category": "laptop",
    "price": 1999,
    "description": "搭载 M3 芯片的专业笔记本电脑,适合开发者和创意工作者"
  },
  {
    "id": "p003",
    "title": "AirPods Pro",
    "brand": "Apple",
    "category": "audio",
    "price": 249,
    "description": "主动降噪无线耳机,空间音频技术,透明模式"
  },
  {
    "id": "p004",
    "title": "Samsung Galaxy S24",
    "brand": "Samsung",
    "category": "smartphone",
    "price": 899,
    "description": "Android 旗舰手机,AI 摄影功能,120Hz 显示屏"
  },
  {
    "id": "p005",
    "title": "Dell XPS 13",
    "brand": "Dell",
    "category": "laptop",
    "price": 1299,
    "description": "轻薄笔记本电脑,13.3英寸 4K 触摸屏,Intel 处理器"
  }
]

# 生成向量嵌入
for product in products:
  response = embedding('text-embedding-3-large', product["description"])
  product["description_vector"] = np.array(response.data[0]['embedding'], dtype=np.float32).tobytes()

# 加载产品数据到 Redis
for product in products:
  index.load([product], id_field="id")

print(f"成功加载 {len(products)} 个产品到索引中")

我们为每个产品的描述生成对应的向量,并通过 index.load() 将产品数据加载到 Redis 中。接下来就可以执行搜索了:

from redisvl.index import SearchIndex
from redisvl.query import VectorQuery

# 使用已有索引
index = SearchIndex.from_existing('product_index', client)

# 生成查询向量
response = embedding('text-embedding-3-large', "适合程序员的电脑")
query_vector = np.array(response.data[0]['embedding'], dtype=np.float32).tobytes()

# 创建向量查询
vector_query = VectorQuery(
  vector=query_vector,
  vector_field_name="description_vector",
  return_fields=["title", "brand", "category", "price", "description"],
  num_results=3,
)

# 执行搜索
results = index.query(vector_query)

print(f"\n查询: '适合程序员的电脑'")
for doc in results:
  score = 1 - float(doc['vector_distance'])  # 转换为相似度分数
  print(f"- {doc['title']} ({doc['brand']}) - 相似度: {score:.3f}")
  print(f"  价格: ${doc['price']} | 描述: {doc['description']}")

搜索结果如下:

查询: '适合程序员的电脑'
- MacBook Pro 14英寸 (Apple) - 相似度: 0.570
  价格: $1999 | 描述: 搭载 M3 芯片的专业笔记本电脑,适合开发者和创意工作者
- Dell XPS 13 (Dell) - 相似度: 0.435
  价格: $1299 | 描述: 轻薄笔记本电脑,13.3英寸 4K 触摸屏,Intel 处理器
- iPhone 15 Pro Max (Apple) - 相似度: 0.293
  价格: $1199 | 描述: 最新的 iPhone,配备 A17 Pro 芯片,48MP 主摄像头,钛金属机身

缓存控制参数

LiteLLM 提供了灵活的缓存控制机制,允许在请求级别动态控制缓存行为。这些控制参数借鉴了 HTTP 缓存控制的设计理念,提供了细粒度的缓存管理能力。

参数类型说明使用场景
ttlint指定缓存时间(秒)短期缓存、时效性内容
s-maxageint只接受指定时间内的缓存(秒)强制刷新、数据一致性
no-cachebool跳过缓存读取,强制调用 API需要最新数据
no-storebool不存储响应到缓存敏感内容、一次性查询
namespacestr自定义缓存命名空间多租户、环境隔离

动态 TTL 控制

参数 ttl 用于控制缓存时间,我们可以为不同类型的请求设置不同的缓存时间:

# 长期缓存:百科类知识
response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "什么是量子计算?"}],
  extra_body={
    "cache": {
      "ttl": 86400  # 缓存 24 小时
    }
  }
)

# 短期缓存:实时性要求较高的内容
response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "今天的股市表现如何?"}],
  extra_body={
    "cache": {
      "ttl": 300  # 缓存 5 分钟
    }
  }
)

缓存年龄控制

参数 s-maxage 控制只接受指定年龄内的缓存:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "最新的股票价格"}],
  extra_body={
    "cache": {
      "s-maxage": 60  # 只接受 1 分钟内的缓存
    }
  }
)

强制刷新缓存

当需要获取最新结果时,可以使用 no-cache 强制绕过缓存:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "最新的股票价格"}],
  extra_body={
    "cache": {
      "no-cache": True  # 跳过缓存检查
    }
  }
)

禁用缓存存储

对于包含敏感信息的查询,可以使用 no-store 不缓存当前响应:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "敏感信息查询"}],
  extra_body={
    "cache": {
      "no-store": True  # 不存储此响应
    }
  }
)

命名空间隔离

在多租户或多环境场景中,LiteLLM 支持命名空间来实现缓存隔离:

litellm_settings:
  cache: true
  cache_params:
    type: redis
    namespace: "litellm.production"  # 命名空间前缀

这样存储在 Redis 中的键将变成 {namespace}:<hash> 格式,我们也可以在请求参数中动态控制,为不同的用户或应用使用独立的缓存空间:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "Hello"}],
  extra_body={
    "cache": {
      "namespace": "user:12345"  # 用户专用命名空间
    }
  }
)

默认关闭模式

对于需要严格控制的场景,可以将缓存设置为默认关闭,只在需要时显式启用:

litellm_settings:
  cache: true
  cache_params:
    mode: default_off  # 缓存默认关闭

客户端需要显式启用缓存:

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "Hello"}],
  extra_body={
    "cache": {"use-cache": True}  # 显式启用缓存
  }
)

小结

我们今天简单学习了 LiteLLM 的缓存系统。LiteLLM 提供了从简单的内存缓存到复杂的语义缓存等多种选择,每种缓存都有其特定的适用场景,可以根据业务需求灵活选择最合适的缓存策略。此外,LiteLLM 的缓存控制参数提供了细粒度的缓存管理能力,使开发者能够动态调整缓存行为,以适应不同场景的需求。

通过合理配置和使用这些缓存功能,应用可以更好地处理重复性和相似性的查询,有效降低对上游 LLM API 的压力,提升系统的稳定性与响应速度。


学习 LiteLLM 的路由和回退策略

在之前的系列文章中,我们学习了 LiteLLM 的基础使用,包括模型管理、用户管理、权限认证和访问控制机制等。当我们的 LLM 网关要承载越来越多的流量、接入越来越多的模型供应商时,就会面临新的挑战:某个模型供应商的 API 突然出现故障、请求量激增导致速率限制、某些模型的响应时间过长、成本控制需要在多个供应商之间进行优化选择等等。这些问题如果处理不当,会严重影响用户体验,甚至导致业务中断。

为此 LiteLLM 提供了一套完整的智能路由和容错解决方案,它通过智能的负载均衡、自动容错和多层次的回退策略,确保在复杂的多模型环境中提供稳定可靠的服务。今天这篇文章,我们就来深入学习 LiteLLM 的路由和回退策略,了解它是如何帮助我们构建一个高可用、高性能、低成本的 LLM 网关。

负载均衡

让我们从最简单的场景开始:假设你有一个 gpt-4o 模型,但是在不同的地区部署了多个实例(可能是 Azure 的不同区域,也可能是不同的云厂商),如何在这些实例之间分配请求?

LiteLLM 的路由配置非常简洁,只需要在 model_list 中将多个 model_name 配置成相同的名字即可:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: azure/gpt-4o
      api_base: https://my-endpoint-us.openai.azure.com/
      api_key: os.environ/AZURE_API_KEY
  - model_name: gpt-4o
    litellm_params:
      model: azure/gpt-4o
      api_base: https://my-endpoint-eu.openai.azure.com/
      api_key: os.environ/AZURE_API_KEY
      api_version: os.environ/AZURE_API_VERSION
  - model_name: gpt-4o
    litellm_params:
      model: gpt-4o
      api_key: os.environ/OPENAI_API_KEY

在这个配置中,三个不同的部署都映射到同一个模型名称 gpt-4o,它们被称为 模型组(Model Group),当用户请求 model="gpt-4o" 时,LiteLLM 会自动在模型组中的部署之间分配请求。

路由策略

LiteLLM 提供了多种不同的路由策略,每种策略针对不同的使用场景:

  • 简单随机策略(simple-shuffle:这是默认的路由策略,采用随机选择算法,确保请求在所有可用部署间均匀分布;其优点是实现简单,负载均匀,适用于大多数通用场景;
  • 最少忙碌策略(least-busy:开启该策略后,LiteLLM 会实时监控每个部署的活跃请求数,优先选择当前活跃请求数最少的部署;其优点是动态负载均衡,避免热点,适用于高并发场景;
  • 延迟优化策略(latency-based-routing:基于历史延迟数据,优先选择响应时间最短的部署,开启后 LiteLLM 会维护每个部署的延迟历史,并使用滑动窗口计算平均值;这种策略能优化用户体验,减少等待时间,适用于对延迟敏感的交互式应用;
  • 成本优化策略(cost-based-routing:基于模型定价信息,优先选择成本最低的部署;它的优点是控制成本,优化预算使用,适用于成本敏感的批量处理场景;
  • 使用率均衡策略(usage-based-routing:也被称为 Rate Limit Aware 策略,基于 RPM/TPM 使用率选择负载最低的部署,确保各部署的负载均衡;这种策略充分利用所有部署的配额,适用于需要精确控制流量分配的场景;不过这种策略会对性能产生影响,因为它要频繁操作 Redis 来跟踪不同部署的使用情况,从而导致延迟显著增加,不建议用于生产环境;

关于使用率策略还有一个 v2 版本(usage-based-routing-v2),它将所有 Redis 操作改为异步,有一定的性能提升。

简单随机策略

在高流量场景中,为了获得最佳性能,官方建议使用简单随机(simple-shuffle)策略,这也是 LiteLLM 的默认路由策略,它随机选择部署,性能开销最小。在 LiteLLM Proxy 中配置路由策略如下:

router_settings:
  routing_strategy: "simple-shuffle"

或者在 SDK 中通过 Router 使用:

router = Router(
  model_list=model_list,
  routing_strategy="simple-shuffle"
)

此外,简单随机策略根据配置,又分为 基于 RPM 随机(RPM-based shuffling)基于权重随机(Weight-based shuffling) 两种。下面是基于权重随机的示例:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: azure/gpt-4o
      api_base: https://my-endpoint-us.openai.azure.com/
      api_key: os.environ/AZURE_API_KEY
      weight: 9  # 90% 的概率被选中
  - model_name: gpt-4o
    litellm_params:
      model: azure/gpt-4o
      api_base: https://my-endpoint-eu.openai.azure.com/
      api_key: os.environ/AZURE_API_KEY
      api_version: os.environ/AZURE_API_VERSION
      weight: 1  # 10% 的概率被选中

跨实例的负载均衡

在生产环境中,LiteLLM Proxy 通常会部署多个实例。但多实例部署会带来一个问题:不同实例之间无法直接通信,它们无法协调已使用的 RPM/TPM。

例如,假设 OpenAI 限制我们每分钟 1000 个请求,而我们有 3 个 LiteLLM 实例:

实例 A:已用 400 个请求
实例 B:已用 300 个请求
实例 C:已用 300 个请求
总计:1000 个请求

如果没有跨实例的协调,每个实例可能还会继续发送请求,导致全局超过限制。

为了解决这个问题,LiteLLM 提供了 Redis 支持,可以将 RPM/TPM 数据存储在共享的 Redis 中:

router_settings:
  redis_host: redis.default.svc.cluster.local
  redis_port: 6379
  redis_db: 0

启用 Redis 后,所有实例都会定期同步它们的 RPM/TPM 数据到 Redis,从而实现全局的限流和负载均衡。

高级路由策略

除了基础的负载均衡,LiteLLM 还提供了多种智能化路由策略,能够根据内容、预算、标签等维度进行智能路由。

自动路由

自动路由(Auto Routing) 也被称为 语义路由 (Semantic Routing),能够根据请求内容自动选择最适合的模型。比如,你可以配置:

  • 编程相关的请求路由到代码能力强的模型
  • 创意写作请求路由到创意能力强的模型
  • 普通对话请求路由到性价比高的模型

注意,开启自动路由需要额外安装 semantic-router 依赖。

首先,需要在 router.json 文件中定义路由规则:

{
  "encoder_type": "openai",
  "encoder_name": "text-embedding-3-large",
  "routes": [
    {
      "name": "gpt-4o",
      "utterances": [
        "写一首关于春天的诗"
      ],
      "description": "通用助手",
      "score_threshold": 0.5
    },
    {
      "name": "claude-sonnet-4",
      "utterances": [
        "使用 Python 语言实现冒泡排序算法"
      ],
      "description": "代码助手",
      "score_threshold": 0.5
    }
  ]
}

然后在模型列表中配置自动路由:

model_list:
  
  # 嵌入模型(用于计算内容相似度)
  - model_name: text-embedding-3-large
    litellm_params:
      model: text-embedding-3-large
      api_key: os.environ/OPENAI_API_KEY

  # 自动路由
  - model_name: auto_router
    litellm_params:
      model: auto_router/auto_router
      auto_router_config_path: router.json
      auto_router_default_model: gpt-4o
      auto_router_embedding_model: text-embedding-3-large

  # 目标路由
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
  - model_name: claude-sonnet-4
    litellm_params:
      model: anthropic/claude-sonnet-4-20250514
      api_key: os.environ/ANTHROPIC_API_KEY

然后使用下面的命令进行测试:

# 这条请求会被自动路由到 gpt-4o
$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "auto_router",
    "messages": [{"role": "user", "content": "写一首关于春天的诗"}]
  }'
# 这条请求会被自动路由到 claude-sonnet-4
$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "auto_router",
    "messages": [{"role": "user", "content": "使用 Python 语言实现冒泡排序算法"}]
  }'

自动路由也可以在 Admin UI 中添加:

add-auto-router.png

自动路由的工作原理很简单:

  1. 内容嵌入:使用配置的嵌入模型将用户请求转换为向量;
  2. 相似度计算:计算请求向量与每条规则的 utterances 向量的相似度;
  3. 阈值判断:如果最高相似度超过 score_threshold,则选择对应模型;
  4. 默认回退:如果没有规则匹配,使用 auto_router_default_model 默认模型;

标签路由

标签路由(Tag Routing) 允许基于请求的标签来选择不同的模型部署,这在多租户场景下特别有用。比如:

  • 多租户隔离:不同租户使用不同的模型实例
  • 服务分级:免费用户使用廉价服务,付费用户使用真实服务
  • 团队隔离:不同团队使用不同的部署实例

它的配置也很简单:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
      tags: ["free"]          # 免费用户使用
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      tags: ["paid"]          # 付费用户使用
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
      tags: ["default"]       # 默认路由

router_settings:
  enable_tag_filtering: true  # 开启标签路由

注意通过 enable_tag_filtering 配置开启标签路由功能,在这个例子中,我们定义了 gpt-4o 这个模型,当免费用户(带 free 标签)请求时将路由到 gpt-4o-mini 模型,只有付费用户(带 paid 标签)请求时才会路由到真正的 gpt-4o 模型。

客户端调用方式如下:

# 免费用户请求
$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello"}],
    "tags": ["free"]
  }'

请求入参中的 tags 也可以放在 metadata 中。

# 付费用户请求
$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello"}],
    "tags": ["paid"]
  }'

我们也可以在 Admin UI 中添加标签并关联对应的模型:

create-new-tag.png

预算路由

在企业环境中,成本控制是一个关键考虑因素。LiteLLM 支持按 供应商模型标签 三个维度设置预算限制,实现自动的成本控制。

供应商预算(Provider Budget)

为不同的 LLM 供应商设置日预算或月预算:

router_settings:
  provider_budget_config:
    openai:
      budget_limit: 100.0    # $100/day
      time_period: "1d"
    azure:
      budget_limit: 500.0    # $500/month
      time_period: "30d"
    anthropic:
      budget_limit: 200.0    # $200/10days
      time_period: "10d"

当某个供应商的预算用完后,LiteLLM 会自动将请求路由到其他预算充足的供应商。

模型预算(Model Budget)

为特定模型设置预算:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      max_budget: 10.0         # $10/day
      budget_duration: "1d"
  - model_name: gpt-4o-mini
    litellm_params:
      model: openai/gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
      max_budget: 100.0        # $100/month
      budget_duration: "30d"

标签预算(Tag Budget)

为特定的业务标签设置预算(企业特性):

litellm_settings:
  tag_budget_config:
    product:chat-bot:         # 客服机器人标签
      max_budget: 50.0        # $50/day
      budget_duration: "1d"
    product:internal-tool:    # 内部工具标签
      max_budget: 200.0       # $200/day
      budget_duration: "1d"

重试策略

在生产环境中,我们还需要考虑各种故障场景,LiteLLM 提供了一套完整的可靠性保障机制,包括 重试策略(Retry Policy)回退策略(Fallbacks)

当请求失败时,LiteLLM 会自动重试,可以通过下面的参数修改重试次数和重试间隔:

router_settings:
  num_retries: 2    # 全局重试次数
  retry_after: 5    # 最小重试间隔(秒)

LiteLLM 还可以针对不同类型的错误来重试:

router_settings:
  num_retries: 2    # 全局重试次数
  retry_after: 5    # 最小重试间隔(秒)
  retry_policy:
    "RateLimitErrorRetries": 3        # 速率限制错误重试3次
    "ContentPolicyViolationErrorRetries": 2  # 内容政策违规重试2次
    "TimeoutErrorRetries": 2          # 超时错误重试2次
    "BadRequestErrorRetries": 0       # 错误请求不重试
    "AuthenticationErrorRetries": 0   # 认证错误不重试

值得注意的是,针对速率限制错误,LiteLLM 使用 指数退避(Exponential Backoffs) 重试策略,每次重试的间隔时间会按照指数级增长,而非固定间隔。

回退策略

回退(Fallbacks) 是另一种可靠性保障机制,当重试仍然失败时,LiteLLM 会尝试回退到其他模型部署或模型组,它确保在部分模型不可用时系统能够优雅降级,而不是直接失败。

回退和重试的区别:重试是针对同一部署的多次尝试,通常用于应对临时性故障(网络抖动等),而回退尝试不同的部署,用于应对永久性故障(服务宕机等)。合理使用这两种机制,能够显著提高系统的可靠性。

LiteLLM 实现了三种不同的回退策略:

  1. 上下文窗口回退 (Context Window Fallbacks) - 当请求的 token 数量超过当前模型的上下文窗口限制时,自动切换到支持更大上下文的模型;
  2. 内容策略回退 (Content Policy Fallbacks) - 当请求因内容审核被拒绝时,自动切换到内容限制更宽松的模型;
  3. 通用故障回退 (General Fallbacks) - 处理网络错误、服务不可用、速率限制等各种故障情况;

回退的配置如下所示:

router_settings:
  context_window_fallbacks: [
    {"gpt-4o": ["gpt-4o-long"]}
  ]
  content_policy_fallbacks: [
    {"gpt-4o": ["gpt-4o-permissive"]}
  ]
  fallbacks: [
    {"gpt-4o": ["gpt-4o-mini", "gpt-3.5-turbo"]}
  ]

当某个部署频繁失败时,LiteLLM 会将其放入 冷却期(Cooldown),避免继续向故障部署发送请求:

router_settings:
  allowed_fails: 3  # 允许失败 3 次
  cooldown_time: 30 # 冷却 30 秒

冷却机制可以通过下面的参数关闭:

router_settings:
  disable_cooldowns: true # 关闭冷却机制

如果客户端不希望触发回退,可以在请求中传入 disable_fallbacks 参数:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Hello"}],
    "disable_fallbacks": true
  }'

小结

到这里,我们已经完整梳理了 LiteLLM 的路由与回退策略的核心逻辑,这些能力正是构建高可用 LLM 网关的基石,能帮我们从容应对多模型场景下的流量分配、成本控制与故障容错挑战。

最后我们再对今天学习的内容总结一下:

  • 负载均衡与路由策略:LiteLLM 提供了多种路由策略来应对不同场景需求。在高并发场景下,推荐使用默认的简单随机策略获得最佳性能;在需要精细控制的场景下,可以选择延迟优化、成本优化或使用率均衡策略。
  • 智能化路由功能:除了基础的负载均衡,LiteLLM 还提供了自动路由、标签路由和预算路由等高级功能。自动路由能根据请求内容语义自动选择最适合的模型;标签路由支持多租户隔离和服务分级;预算路由则从供应商、模型、标签三个维度实现精确的成本控制。
  • 可靠性保障机制:通过重试策略和回退策略的组合,LiteLLM 构建了完整的容错体系。重试策略针对临时性故障提供自动恢复能力,支持按错误类型定制重试逻辑;回退策略则处理永久性故障,包括上下文窗口限制、内容策略违规和通用故障等多种场景。

这些能力并非孤立存在,而是可以根据实际业务场景灵活组合,最终帮我们搭建出稳定、高效且成本可控的 LLM 网关,为上层业务提供可靠的模型服务支撑。


学习 LiteLLM 的访问控制

在前两篇文章中,我们深入探讨了 LiteLLM 的认证机制和用户管理体系,认证机制解决了 你是谁 的问题,用户管理则从组织、团队到用户的多层架构,以及基于角色的访问控制(RBAC)模型解决的是 你能做什么 的问题。

而今天我们要学习的访问控制机制则是用户管理的延续,从更细的粒度控制用户的行为,没有适当的访问控制,你的 LLM 网关可能会面临很多风险,比如:用户访问了不应该访问的模型,导致成本失控;恶意用户滥用 API,造成拒绝服务攻击;缺乏配额管理,导致某些用户耗尽所有资源。

LiteLLM 提供了一套完整的访问控制机制:

  1. 模型访问控制:控制用户可以使用哪些模型
  2. 接口访问控制:控制用户可以调用哪些 API 接口
  3. 配额管理:管理用户的请求频率、并发数、成本预算等资源使用限制

下面我们从最基础的模型访问控制开始,逐步深入学习。

模型访问控制

模型访问控制是 LiteLLM 访问控制的第一道防线,它决定了用户或团队是否可以使用特定的模型或模型组。

虚拟 Key 级别的模型限制

最简单的模型访问控制方式是为虚拟 Key 指定允许的模型列表。其实我们之前在创建虚拟 Key 时已经用过,通过 models 参数来限制它可以访问的模型:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "metadata": {"user": "zhangsan@example.com"}
  }'

生成的密钥只能调用 gpt-4o 这个模型,如果尝试调用其他模型,则会收到错误响应:

{
  "error": {
    "message": "key not allowed to access model. This key can only access models=['gpt-4o']. Tried to access deepseek",
    "type": "key_model_access_denied",
    "param": "model",
    "code": "401"
  }
}

团队级别的模型限制

我们还可以为团队指定允许的模型列表。首先创建一个团队,并为其指定允许的模型:

$ curl -X POST 'http://127.0.0.1:4000/team/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_alias": "demo_team",
    "models": ["gpt-4o"]
  }'

或者在 Admin UI 后台创建:

create-team.png

然后为该团队创建虚拟 Key:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_id": "950db486-fa2c-46e7-bfbc-3ac39e15fad2"
  }'

此时,团队成员使用该密钥只能调用 gpt-4o 这个模型,当团队成员使用该密钥访问未授权模型时,LiteLLM 会返回错误信息:

{
  "error": {
    "message": "team not allowed to access model. This team can only access models=['gpt-4o']. Tried to access deepseek",
    "type": "team_model_access_denied",
    "param": "model",
    "code": "401"
  }
}

注意,如果使用团队级别的模型限制,调用 /key/generatemodels 参数是不生效的。

同样地,我们也可以针对组织或用户来限制模型的访问,做法基本类似,调用 /organization/new/user/new 时传入 models 参数即可,此处略过。

模型访问组

对于需要动态管理模型访问权限的场景,LiteLLM 提供了 模型访问组 的功能,允许将多个模型组织成一个逻辑组,便于批量分配权限。

首先,在配置文件中定义模型访问组:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      access_groups: ["beta-models"]  # 👈 模型访问组

  - model_name: claude
    litellm_params:
      model: anthropic/claude-sonnet-4-20250514
      api_key: os.environ/ANTHROPIC_API_KEY
    model_info:
      access_groups: ["beta-models"]  # 👈 模型访问组

然后,创建虚拟 Key 时指定访问组:

$ curl -X POST 'http://localhost:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["beta-models"]
  }'

这个 Key 可以访问所有标记为 beta-models 的模型,如果后续添加了新的模型到这个组,也会自动授权。模型访问组的主要优势在于:

  • 动态管理:可以随时向访问组添加新模型,所有使用该组的用户自动获得访问权限
  • 批量操作:一次可以为多个用户分配相同的模型权限
  • 版本控制:可以创建不同的访问组用于不同环境(如 dev、staging、prod)

对于需要更灵活访问控制的场景,LiteLLM 还支持通配符模型。你可以使用模式匹配来控制对具有特定前缀或后缀的模型的访问:

model_list:
  - model_name: openai/*
    litellm_params:
      model: openai/*
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      access_groups: ["default-models"]

  - model_name: openai/o1-*
    litellm_params:
      model: openai/o1-*
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      access_groups: ["restricted-models"]

根据配置,default-models 访问组的用户可以访问 openai/gpt-4 但不能访问 openai/o1-mini

用户可以通过 /v1/models 接口查看自己有权访问的模型:

$ curl -X GET 'http://localhost:4000/v1/models' \
  -H 'Authorization: Bearer sk-3zO1MHhHFme9aGXfWCiMXg'

接口访问控制

除了限制用户能调用哪些模型,LiteLLM 还支持限制用户能调用哪些 API 接口。

基于角色的接口权限

在用户管理体系中,我们学习了基于角色的访问控制(RBAC),不同角色的用户自动拥有不同的接口权限:

  • 代理管理员(Proxy Admin) 拥有所有接口的访问权限,包括:

    • 用户管理接口:/user/*
    • 团队管理接口:/team/*
    • 密钥管理接口:/key/*
    • 组织管理接口:/organization/*
  • 内部用户(Internal User) 只能访问自己的密钥管理接口、自己的使用情况接口和 LLM 调用接口等
  • 团队成员(Team Member) 的接口权限由团队管理员精确控制,LiteLLM 支持对每个接口进行单独的权限配置。

限制可调用的接口

除此之外,在生成虚拟 Key 时我们还可以指定 allowed_routes 参数来限制用户能调用的接口:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "allowed_routes": ["/v1/chat/completions", "/v1/embeddings"]
  }'

这样,这个 Key 就只能调用 /v1/chat/completions/v1/embeddings 这两个接口,其他接口如获取模型列表、查询成本等都会被拒绝。

请求速率限制

LiteLLM 支持三种类型的速率限制:

  • RPM(Requests Per Minute):每分钟请求数限制
  • TPM(Tokens Per Minute):每分钟令牌数限制
  • Max Parallel Requests:最大并发请求数限制

我们可以在 config.yaml 文件中对指定模型进行全局限制:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      rpm: 10
      tpm: 10000

或者在创建虚拟 Key 时加上这三个参数:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "rpm_limit": 3,
    "tpm_limit": 100,
    "max_parallel_requests": 1
  }'

通过上面这个命令生成的 Key 每分钟最多只能发送 3 个请求,最多只能消耗 100 个 Token,并且同时最多只能有 1 个并发请求。

值得注意的是,RPM 和 TPM 超过限制时,并不会报错,而是排队等待;只有并发数超过限制才会报 429 Too Many Requests 错误。

如果虚拟 Key 对应多个模型,也可以为每个模型单独设置速率限制:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o", "gpt-3.5-turbo"],
    "model_rpm_limit": {
      "gpt-4o": 30,
      "gpt-3.5-turbo": 100
    },
    "model_tpm_limit": {
      "gpt-4o": 5000,
      "gpt-3.5-turbo": 10000
    }
  }'

没有 model_max_parallel_requests 参数,暂时无法为每个模型单独设置并发路数。

灵活的限制范围

和模型限制一样,LiteLLM 也支持在组织、团队或内部用户上配置速率限制。其中团队级别的速率限制可以是针对整个团队的,也可以是针对团队内单个成员的:

$ curl -X POST 'http://localhost:4000/team/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_alias": "demo_team",
    "rpm_limit": 100,    # 团队整体 RPM 限制
    "tpm_limit": 10000,  # 团队整体 TPM 限制
    "team_member_rpm_limit": 10,   # 单个成员 RPM 限制
    "team_member_tpm_limit": 1000  # 单个成员 TPM 限制
  }'

值得注意的是,要启用团队成员速率限制,启动 LiteLLM 之前必须要设置环境变量 EXPERIMENTAL_MULTI_INSTANCE_RATE_LIMITING=true,如果不这样做,团队成员的速率限制将不会生效。

当你部署多实例时,也需要设置这个环境变量。

另外,速率限制还可以配置在终端用户上。LiteLLM 的用户分为两种:内部用户(Internal User)终端用户(End User),内部用户是管理和使用 LiteLLM 平台的内部人员,终端用户是通过 LiteLLM 平台获得 LLM 服务的外部用户,也被称为 客户(Customer),他们没有自己的 API Key,在调用接口时通过 user 参数进行区分:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": "demo_customer",
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

要对终端用户进行限流,需要先创建一个配额:

$ curl -X POST 'http://127.0.0.1:4000/budget/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "budget_id" : "free-tier",
    "rpm_limit": 3
  }'

然后使用该配额创建一个终端用户:

# 也可以使用 /end_user/new 接口
$ curl -X POST 'http://127.0.0.1:4000/customer/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id" : "demo_customer",
    "budget_id": "free-tier"
  }'

这样就限制了这个终端用户一分钟只能请求 3 次。

动态速率限制

在多个用户共享同一个模型部署的场景中,静态的速率限制可能导致资源分配不合理的情况。上文提到,速率限制可以配置在全局的配置文件中,假设我们给 A 模型限制了一分钟 60 次请求,如果某个用户突然疯狂发送请求,可能会导致其他用户的请求全部被限制。

为此,LiteLLM 提供了 动态速率限制 的功能,可以根据活跃密钥的数量动态分配 TPM/RPM 配额。

启用动态速率限制只需在配置文件中添加回调即可:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      rpm: 10 # 全局 10 RPM

litellm_settings:
  callbacks: ["dynamic_rate_limiter_v3"]

它的工作原理是:

  1. 计算当前活跃密钥数量
  2. 将模型的 TPM/RPM 配额平均分配给所有活跃密钥
  3. 定期调整分配比例以适应请求模式的变化

因此,如果同时有 5 个 Key 在发送请求,每个 Key 都能得到 2 RPM 的配额(10/5)。如果只有 2 个 Key,每个能得到 5 RPM。这样就确保了资源的公平分配。

优先级预留

对于更复杂的场景,还可以为不同的优先级预留资源。比如,生产环境的应用应该获得 90% 的资源,而开发环境只有 10% 的资源:

litellm_settings:
  callbacks: ["dynamic_rate_limiter_v3"]
  priority_reservation:
    "prod": 0.9        # 生产环境:90%
    "dev": 0.1         # 开发环境:10%
  priority_reservation_settings:
    default_priority: 0  # 未指定优先级的:0%
    saturation_threshold: 0.5  # 模型使用率达到 50% 时启用严格模式(非严格模式下,使用率可以超出限制)

创建 Key 时指定优先级:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "metadata": {"priority": "prod"}
  }'

标记为 prod 的 Key 会优先获得资源,LiteLLM 会确保这个 Key 至少获得 90% 的使用率,而标记为 dev 的 Key 只能获得 10% 的使用率。

成本追踪

我们在学习 LiteLLM 的模型管理时曾经提到过,LiteLLM 维护了一个完整的模型成本映射表,每次调用都会自动计算成本。默认情况下,成本是根据 输入和输出的 Token 数 乘以 模型的单位价格 来计算的:

cost = (input_tokens × input_cost_per_token) + (output_tokens × output_cost_per_token)

如果默认的价格不符合你的情况,可以在 config.yaml 中覆盖默认价格:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      input_cost_per_token: 0.00001  # 自定义价格
      output_cost_per_token: 0.00002

价格单位为 USD

或者在全局设置中配置供应商折扣:

cost_discount_config:
  openai: 0.1         # OpenAI 打 9 折
  anthropic: 0.15     # Anthropic 打 8.5 折
  vertex_ai: 0.2      # Vertex AI 打 8 折

折扣会在成本计算后自动应用,LiteLLM 会返回原始成本和折扣后的成本。

成本追踪数据存储在数据库中,你可以通过多种方式查询:

# 查询单个 Key 的成本
$ curl 'http://127.0.0.1:4000/key/info?key=sk-xyz' \
  -H 'Authorization: Bearer sk-1234'

# 查询用户的总消费
$ curl 'http://127.0.0.1:4000/user/info?user_id=user-123' \
  -H 'Authorization: Bearer sk-1234'

# 查询团队的消费
$ curl 'http://127.0.0.1:4000/team/info?team_id=team-xyz' \
  -H 'Authorization: Bearer sk-1234'

# 生成成本报告(企业版特性)
$ curl 'http://127.0.0.1:4000/global/spend/report?start_date=2025-11-01&end_date=2025-11-30&group_by=team' \
  -H 'Authorization: Bearer sk-1234'

LiteLLM 还支持与计费系统集成,比如可以自动将成本数据推送到 Lago 平台:

litellm_settings:
  callbacks: ["lago"]

预算限制

有了成本追踪,就能很容易实现预算限制了。LiteLLM 支持在多个层级设置预算限制,最直接的方式是在生成 Key 时设置 max_budget

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "max_budget": 100.0
  }'

这个 Key 现在最多只能消耗 $100,一旦超过预算,后续的请求会被拒绝。

或者通过 soft_budget 参数设置软预算限制,超过这个值时发送警告但不阻止请求。

和请求速率限制类似,我们还可以为用户设置总预算,即使用户有多个 Key,这些 Key 的消费会统计到用户的总预算中;或者为团队设置总预算,团队下的所有成员使用的 Key 的消费都会累计到团队的总预算中;或者通过 model_max_budget 参数为不同模型设置不同预算;或者通过 /budget/new 创建配额,然后为终端用户设置总预算。

预算周期与自动重置

有时候我们希望用户的预算能够定期重置。比如免费用户每个月重置 $10 的额度,这就需要用到 budget_duration 参数:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "max_budget": 10.0,
    "budget_duration": "30d"
  }'

支持的时间周期包括:

  • "30s" - 30 秒
  • "30m" - 30 分钟
  • "1h" - 1 小时
  • "1d" - 1 天
  • "30d" - 30 天(一个月)

临时预算增加

有时候,用户由于突然的业务需求可能需要超出预算。对于这种场景,LiteLLM 支持临时预算增加功能:

curl -L -X POST 'http://localhost:4000/key/update' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "key": "sk-your-key",
    "temp_budget_increase": 100,
    "temp_budget_expiry": "2025-11-30"
  }'

临时预算增加也是一个企业特性,它有以下特点:

  • 固定过期时间,过期后自动失效
  • 不影响原有的预算配置
  • 支持多次临时增加
  • 只能加在 API Key 上,无法为用户、团队、组织增加临时预算

标签级别的预算

对于需要跨多个维度跟踪成本的企业场景,LiteLLM 还支持按照 标签(Tag) 来分配预算,这对于按照功能、项目、成本中心来追踪成本特别有用:

$ curl -X POST 'http://127.0.0.1:4000/tag/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "marketing-chatbot",
    "description": "Marketing team chatbot",
    "max_budget": 200.0,
    "budget_duration": "30d"
  }'

然后在请求时添加标签:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-xyz' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "hello"}],
    "metadata": {
      "tags": ["marketing-chatbot", "campaign-2024"]
    }
  }'

小结

LiteLLM 的访问控制机制构成了一个多维度的安全防护体系,从三个核心维度确保平台的稳定运行和成本可控:

  • 访问范围控制:通过模型访问限制防止未授权模型使用,避免成本失控;模型访问组提供动态、批量化的权限管理能力;接口访问控制精确限制用户可调用的 API 端点;
  • 资源配额管理:通过 RPM、TPM、并发三种速率限制策略确保公平的资源分配;动态速率限制根据活跃用户数智能调整配额,避免资源浪费或抢占;优先级预留机制保障关键业务的资源需求;
  • 成本预算控制:实时成本追踪提供透明的费用可见性;多层级预算限制(Key/用户/团队/标签)满足不同场景需求;预算周期管理与临时预算增加提供灵活的额度控制;

这套完整的访问控制体系不仅保障了 LiteLLM 网关的安全性,更通过精细化的资源管理和成本控制,为企业级 AI 应用提供了可靠的治理框架。合理配置这些机制,可以在保证用户体验的同时,最大化资源利用效率并控制运营成本。


学习 LiteLLM 的用户管理体系

在上一篇文章中,我们学习了 LiteLLM 的认证机制,从基础的虚拟 Key 到企业级的 JWT/OIDC 认证,了解了如何确保 API 访问的安全性。然而,认证只是第一步,解决的是 你是谁 的问题;接下来我们需要解决的是 你能做什么 的问题,这就是 用户管理权限控制 要解决的问题。

核心概念

LiteLLM 的用户管理体系建立在四个核心概念上:

  1. 组织(Organization) 可以包含多个团队,是 LiteLLM 中最高层级的管理单位,每个组织相当于一个独立的租户;
  2. 团队(Team) 是组织内部的工作单位,可以包含多个内部用户;团队的设计非常灵活,你可以按部门划分,也可以按项目划分;
  3. 内部用户(Internal Users) 可以创建 API Key、进行 API 调用、查看使用情况等;一个用户可以拥有多个 API Key,并且可以属于多个团队;
  4. API Key 用于 LiteLLM API 的身份验证,我们在上一篇详细介绍过,它可以与团队相关联,或与用户相关联,或同时与两者相关联;

他们的关系如下:

user-heirarchy.png

三种密钥类型

正如上文所说,API Key 可以与团队或用户相关联,基于不同的组合,API Key 分为三种类型:

  1. 用户密钥(User-only Key):它关联到特定用户,跟随用户生命周期,用于个人预算和追踪,当删除用户时密钥自动失效;适用于个人用户开发测试;
  2. 团队密钥(Team Key / Service Account Key):它关联到特定团队,不绑定个人身份,团队内共享资源,用户离开团队不影响密钥有效性;适用于生产服务、CI/CD 流水线、共享服务账户等;
  3. 用户+团队密钥(User + Team Key):同时关联用户和团队,能定位个人在团队上下文中的身份,同时追踪个人+团队的使用情况,当删除用户时密钥失效;适用于团队成员在团队资源上的个人工作、个人问责制的团队项目等;

在 Admin UI 上创建密钥

当我们在 Admin UI 上为用户创建 API Key 时,可以按需选择不同的组合:

create-key-user-or-team.png

或者为团队创建 API Key,这个密钥也被称为 服务账户密钥

create-key-service-account.png

注意,团队密钥在使用时,区分不了用户,LiteLLM 提供了一个可选的配置参数:

general_settings:
  service_account_settings: 
    enforced_params: ["user"] # 强制要求所有请求包含 user 参数

要求所有通过服务账户的请求都必须包含 user 参数,以便进行用户级别的审计。

使用接口创建密钥

我们也可以直接使用接口来创建这三种密钥。创建仅用户密钥:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "zhangsan@example.com"
  }'

注意,这个 user_id 不必是系统已有用户,仅仅是一个标记而且。当然,你也可以先在平台上创建一个用户,然后将这里的 user_id 换成该用户的 ID。两者的区别在于创建的用户可以登录平台,查看或管理自己的 API Key 等。

创建团队服务账户密钥:

$ curl -X POST 'http://127.0.0.1:4000/key/service-account/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_id": "<team_id>"
  }'

创建用户+团队密钥:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "zhangsan@example.com",
    "team_id": "<team_id>"
  }'

注意,这个 team_id 必须先在平台上创建团队获得。

基于角色的访问控制

了解了上面的层次结构之后,接下来学习 LiteLLM 的权限控制机制。LiteLLM 采用了 RBAC(基于角色的访问控制) 模型,这是业界最成熟的权限管理方式之一。RBAC 是一种将权限与角色关联,而不是与用户直接关联的访问控制方法。这种方式的优势在于:

  • 简化管理:不必为每个用户单独分配权限,只需为角色分配权限
  • 权限复用:多个用户可以共享同一个角色
  • 动态调整:调整角色权限即可影响所有相关用户

LiteLLM 定义了两类角色系统:全局代理角色(Global Proxy Roles)组织/团队特定角色(Organization/Team Specific Roles),理解这些角色是使用 LiteLLM 权限管理的基础。

全局代理角色

全局代理角色又分为 代理管理员(Proxy Admin)代理查看者(Proxy Admin Viewer)内部用户(Internal User)内部用户查看者(Internal User Viewer) 四种,这些角色在整个 LiteLLM 平台范围内生效,不受组织或团队边界限制。

代理管理员

这是最高权限角色,控制整个 LiteLLM 平台,只有运行 LiteLLM 实例的人才应该有这个角色:

✅ 创建和管理所有组织
✅ 创建和管理所有团队(跨所有组织)
✅ 创建和管理所有用户
✅ 为任何人创建/删除 API 密钥
✅ 查看整个平台的消费成本
✅ 更新团队预算、速率限制
✅ 管理团队成员

代理查看者

这是一个只读的管理员角色,可查看所有信息但不能修改,适合财务或审计人员:

可以做:
✅ 查看所有组织、团队和用户
✅ 查看整个平台的消费数据
✅ 查看所有 API 密钥信息
✅ 登录到管理面板

不能做:
❌ 创建或删除密钥
❌ 添加或删除用户
❌ 修改预算或速率限制

内部用户

这是一般用户角色,拥有基本的操作权限,如管理自己的密钥和查看自己的消费,适用于普通员工:

可以做:
✅ 创建和删除自己的 API 密钥(如果允许)
✅ 查看自己的消费成本
✅ 使用 API 密钥进行 LLM 调用

不能做:
❌ 添加新用户
❌ 查看其他用户的信息
❌ 创建或管理团队

内部用户查看者

⚠️ 注意:这个角色已经被新的组织/团队特定角色所取代。建议迁移到更灵活的 org_adminteam_admin 角色。

组织/团队特定角色

这些是 LiteLLM 企业版中的角色,提供了更细粒度的权限控制,主要分为 组织管理员(Org Admin)团队管理员(Team Admin) 以及 团队成员(User) 四种:

组织管理员

该角色拥有特定组织内的所有管理权限,适用于部门主管、组织负责人等:

可以做:
✅ 创建团队(在自己的组织内)
✅ 添加用户到团队(在自己的组织内)
✅ 查看组织的消费成本
✅ 为组织内的用户创建 API 密钥

不能做:
❌ 创建其他组织
❌ 修改组织预算和速率限制
❌ 添加全局代理级别的模型

团队管理员

该角色拥有特定团队内的所有管理权限,适用于团队负责人,比如项目经理、小组组长、产品负责人等:

可以做:
✅ 添加或删除团队成员
✅ 为团队成员创建/删除密钥
✅ 更新团队成员的预算和速率限制
✅ 修改团队设置(预算、速率限制、模型访问)
✅ 配置团队成员权限
✅ 为团队添加自定义模型(如微调模型)

不能做:
❌ 创建新团队
❌ 修改团队的全局预算和速率限制
❌ 访问其他团队的资源

团队成员

该角色对应团队内的普通成员,拥有团队内的基础权限,团队管理员可以对团队成员的权限进行精确控制,LiteLLM 支持的权限项包括:

权限请求方法描述
/key/infoGET查看密钥信息
/key/healthGET检查密钥健康状态
/key/listGET列出团队所有密钥
/key/generatePOST创建新密钥
/key/service-account/generatePOST创建服务账户密钥
/key/updatePOST修改现有密钥
/key/deletePOST删除密钥
/key/regeneratePOST轮换密钥
/key/blockPOST禁用密钥
/key/unblockPOST启用密钥

用户管理实操

创建一个名为 XYZ Corp 的组织:

$ curl -X POST 'http://127.0.0.1:4000/organization/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "organization_alias": "XYZ Corp"
  }'

得到组织 ID:

{
  "organization_id": "42bea353-4697-4f01-a362-25fd096aeb5a",
  "organization_alias": "XYZ Corp",
  // ...
}

为组织创建一个组织管理员:

$ curl -X POST 'http://127.0.0.1:4000/organization/member_add' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "organization_id": "42bea353-4697-4f01-a362-25fd096aeb5a", 
    "member": {
      "role": "org_admin", 
      "user_id": "desmond@example.com"
    }
  }'

注意,该接口会自动在系统中创建一个 user_iddesmond@example.com 的用户,角色为 org_admin 组织管理员。

为该用户创建 API Key:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "desmond@example.com"
  }'

调用结果如下:

{
  "user_id": "desmond@example.com",
  "key": "sk-xTiqwzA2xJWzac2xk8og7w",
  "key_name": "sk-...og7w",
  // ...
}

然后组织管理员就可以通过他的 API Key 去创建团队了:

$ curl -X POST 'http://127.0.0.1:4000/team/new' \
  -H 'Authorization: Bearer sk-xTiqwzA2xJWzac2xk8og7w' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_alias": "engineering_team",
    "organization_id": "42bea353-4697-4f01-a362-25fd096aeb5a"
  }'

得到团队 ID:

{
  "team_alias": "engineering_team",
  "team_id": "36100710-1fb1-4d6a-abd7-1fda8d171771",
  "organization_id": "42bea353-4697-4f01-a362-25fd096aeb5a",
  // ...
}

组织管理员可以为团队创建一个团队管理员:

$ curl -X POST 'http://127.0.0.1:4000/team/member_add' \
  -H 'Authorization: Bearer sk-xTiqwzA2xJWzac2xk8og7w' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_id": "36100710-1fb1-4d6a-abd7-1fda8d171771", 
    "member": {
      "role": "admin", 
      "user_id": "stonie@example.com"
    }
  }'

同样的,该接口会自动在系统中创建一个 user_idstonie@example.com 的用户,角色为 admin 团队管理员。

也为该用户创建 API Key:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "stonie@example.com"
  }'

调用结果如下:

{
  "user_id": "stonie@example.com",
  "key": "sk-jhSg1qFKYEIg8ndYmmmFHg",
  "key_name": "sk-...mFHg",
  // ...
}

这里看官方文档,应该使用组织管理员的 API Key 去生成团队管理的 API Key,但是我在测试时报错 User can only create keys for themselves,因此使用了代理管理员的 API Key。

团队管理员可以添加或移除团队成员、修改团队的预算和费率限制、配置团队成员的权限等,下面是添加成员的接口示例:

$ curl -X POST 'http://127.0.0.1:4000/team/member_add' \
  -H 'Authorization: Bearer sk-jhSg1qFKYEIg8ndYmmmFHg' \
  -H 'Content-Type: application/json' \
  -d '{
    "team_id": "36100710-1fb1-4d6a-abd7-1fda8d171771", 
    "member": {
      "role": "user", 
      "user_id": "zhangsan@example.com"
    }
  }'

为该用户生成 API Key:

$ curl -X POST 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "zhangsan@example.com",
    "team_id": "36100710-1fb1-4d6a-abd7-1fda8d171771"
  }'

调用结果如下:

{
  "user_id": "zhangsan@example.com",
  "key": "sk-If8su0G3z3GlgwaA6acpLg",
  "key_name": "sk-...cpLg",
  // ...
}

这里看官方文档,应该使用团队管理员的 API Key 去生成用户的 API Key,但是我在测试时报错 User can only create keys for themselves,因此使用了代理管理员的 API Key。

用户自助服务

上面创建的这些用户,无论是组织管理员、团队管理员还是团队用户,目前都无法登录平台,只能通过 API Key 来进行管理操作,这是相当繁琐的。LiteLLM 支持用户自助服务,它让用户可以在不依赖管理员的情况下管理自己的密钥和查看使用情况。

首先,为他们生成邀请链接:

$ curl -X POST 'http://127.0.0.1:4000/invitation/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "desmond@example.com"
  }'

该接口生成的是邀请 ID:

{
  "id": "35186fe0-5b96-4e75-a285-f17fbf3add0d",
  "user_id": "desmond@example.com",
  // ...
}

将邀请 ID 拼接到 http://127.0.0.1:4000/ui?invitation_id= 后面,得到类似下面的链接地址:

http://127.0.0.1:4000/ui?invitation_id=35186fe0-5b96-4e75-a285-f17fbf3add0d

将链接地址发送给用户,他就可以登录平台了:

invitation-link.png

登录平台后,根据用户的角色,展示的菜单也不一样。比如普通用户可以查看或创建自己的 API Key:

user-login.png

注意上面的邮箱地址是空的,虽然也能登录,但是下次用户再登录时就麻烦了(需要管理员编辑用户邮箱)。可以使用下面的接口来创建用户,为用户设置邮箱地址:

$ curl -X POST 'http://127.0.0.1:4000/user/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_email": "stonie@example.com",
    "user_role": "internal_user"
  }'

这个接口在创建用户的同时也会为其创建一个 API Key:

{
  "user_id": "72f9e797-0e9a-41f5-a227-03a8a813c7cc",
  "key": "sk-EIKmPPTyBriwpCW1NYV8aw",
  "key_name": "sk-...V8aw",
  "user_email": "stonie@example.com",
  "user_role": "internal_user",
  // ...
}

然后使用该用户的 ID 来生成邀请链接:

$ curl -X POST 'http://127.0.0.1:4000/invitation/new' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "72f9e797-0e9a-41f5-a227-03a8a813c7cc"
  }'

之后用户就可以通过邮箱登录平台了。

小结

通过这篇文章,我们系统地学习了 LiteLLM 的用户管理体系,主要内容包括:

  • 多层次管理架构:从组织 → 团队 → 用户的三层结构,组织层用于大型企业的多租户隔离,团队层用于项目组的资源共享和协作,用户层用于个人开发者的独立预算和追踪;
  • 灵活的权限控制:支持代理管理员、代理查看者、内部用户等全局代理角色,以及组织管理员、团队管理员、普通成员等组织/团队特定角色,还可以精确地控制每个用户能执行的操作;
  • 用户自助服务:支持为用户生成邀请链接,允许用户在不依赖管理员的情况下管理自己的密钥和查看使用情况;

在下一篇文章中,我们将学习 LiteLLM 的 访问控制机制,包括如何为不同的用户和团队分配不同的模型访问权限,如何设置和执行流量控制策略,以及如何进行成本预算管理和预警。这是用户管理体系的延伸和深化,将帮助我们构建一个完整的 LLM 网关安全体系。敬请期待!


学习 LiteLLM 的认证机制

在之前的两篇文章中,我们分别学习了 LiteLLM 的快速入门和模型管理。我们了解到,LiteLLM 不仅是一个统一的 SDK,更是一个功能强大的企业级 LLM 网关。在生产环境中,如何确保 LLM 资源的安全访问?如何为不同用户和团队分配不同的权限?如何追踪每个用户的使用情况和成本?如何精确控制成本和防止滥用?这些都是访问控制需要解决的核心问题。

LiteLLM 的访问控制系统采用多层次的安全架构,从基础的 API Key 认证到企业级的 JWT 认证,从简单的用户管理到复杂的团队权限体系,为不同规模的应用提供了灵活的解决方案:

认证层次

  • 虚拟 API Key:为每个用户或团队生成唯一的虚拟 Key
  • JWT Token:支持企业级 OpenID Connect (OIDC) 认证
  • 自定义认证:集成企业现有的身份认证系统

授权体系

  • 用户级权限:基于角色的访问控制(RBAC)
  • 团队级权限:团队成员共享模型访问权限
  • 组织级权限:大型企业的多层级管理

控制维度

  • 模型访问:控制用户可以使用的模型
  • 接口访问:限制可调用的 API 接口
  • 流量控制:请求频率和并发数限制
  • 成本控制:预算限制和消费追踪

我们今天主要关注第一部分,来学习下 LiteLLM 的认证机制。

虚拟 Key 认证

在之前的学习中,我们在调用模型接口时使用的 API Key 一直都是 sk-1234,这个是我们在配置文件中配置的 Master Key,也就是管理员密钥:

general_settings:
  master_key: sk-1234

对于个人开发者来说,只用一个简单的 API Key 可能就足够了,但是对于团队或企业来说,一个 Key 无法区分不同的用户或应用,而且 Master Key 的权限过大,这时我们就需要引入 Virtual Key 的概念了。

虚拟 Key(Virtual Key) 是 LiteLLM 最核心的认证机制,它借鉴了云服务商的 API Key 管理模式,为每个用户或应用生成独立的访问密钥。LiteLLM 的虚拟 Key 提供了一层抽象,使得:

  • 你可以为不同的用户、团队、应用生成不同的 Key
  • 每个 Key 可以独立配置访问权限和预算限制
  • 支持 Key 的轮换和撤销
  • 所有使用行为都由 Proxy 记录和追踪

接下来我们生成一个虚拟 Key 验证下。虚拟 Key 的生成需要数据库支持,因此首先配置数据库连接(昨天学习模型的动态管理时已经配过):

general_settings:
  master_key: sk-1234
  database_url: "postgresql://postgres:password@127.0.0.1:5432/litellm"

然后通过 /key/generate 接口生成 Key:

$ curl 'http://127.0.0.1:4000/key/generate' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "models": ["gpt-4o"],
    "metadata": {"user": "zhangsan@example.com"}
  }'

接口响应如下:

{    
  "key": "sk-qC5b02PjnQVdq3FPYY37wQ",
  "key_name": "sk-...37wQ",
  "models": [
    "gpt-4o"
  ],
  "metadata": {
    "user": "zhangsan@example.com"
  },
  "user_id": null,
  "team_id": null,
  "model_max_budget": {},
  "model_rpm_limit": null,
  "model_tpm_limit": null,
  "max_budget": null,
  "max_parallel_requests": null,
  "guardrails": null,
  "allowed_routes": [],
  // ...
}

可以看到,接口响应中除了 key 之外,还有一些关于用户、团队、请求频率、并发限制等信息,这些内容涉及 LiteLLM 的授权体系和访问控制机制,我们后面再具体学习。

使用这个虚拟 Key 请求 /chat/completions 接口:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer sk-qC5b02PjnQVdq3FPYY37wQ' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

接口验证正常,说明虚拟 Key 生成成功。

支持多种 Header 格式

LiteLLM 的灵活设计使其能够支持多种 Header 格式,兼容不同的客户端库和工具:

Header 名称用途优先级
x-litellm-api-keyLiteLLM 自定义 Key1 (最高)
AuthorizationOpenAI 兼容格式2
API-KeyAzure 风格3
x-api-keyAnthropic 格式4
x-goog-api-keyGoogle AI Studio5
Ocp-Apim-Subscription-KeyAzure APIM6
其他自定义 Header配置化支持7

比如像下面这样请求也是可以的:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'x-litellm-api-key: sk-qC5b02PjnQVdq3FPYY37wQ' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

这样的设计让 LiteLLM 可以轻松地代理来自各种来源的请求,而无需修改客户端代码。

虚拟 Key 的存储和验证

为了保证安全性,虚拟 Key 在数据库中采用 哈希值存储,这样做的好处是,即使数据库被泄露,攻击者也无法直接使用 Key(因为数据库中只有哈希值)。

另外,LiteLLM 使用 分层缓存策略 进行虚拟 Key 的验证:

api-key-verification.png

通过分层缓存,大多数请求不需要访问数据库,大大提高了虚拟 Key 的验证性能。

客户端凭据透传

除了传统的服务器端认证,LiteLLM 还支持让客户端直接传递自己的 API Key,这在某些场景下可能有用,比如开发者使用自己的 API Key 进行测试,或者用户希望使用自己的 API Key,但又不希望配置到 LiteLLM 里。

通过下面的参数启用客户端凭据透传:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      configurable_clientside_auth_params: ["api_key", "api_base"] # 支持透传的字段

客户端调用示例如下:

import openai

client = openai.OpenAI(
  api_key="sk-1234",
  base_url="http://localhost:4000"
)

response = client.chat.completions.create(
  model="gpt-4o",
  messages=[{"role": "user", "content": "Hello"}],
  extra_body={
    "api_key": "sk-client-xxx",  # 客户端自己的 API 密钥
    "api_base": "https://api.openai.com/v1"
  }
)

LiteLLM 会遍历 configurable_clientside_auth_params 参数,将客户端传递的参数和系统配置的参数进行合并。

有意思的,客户端不仅可以传 api_keyapi_base 等字段,甚至可以传整个 model_list,将 LiteLLM 的配置完全架空。

JWT 认证与 OIDC 集成

虽然虚拟 Key 是 LiteLLM 最核心的认证方式,但对于某些企业场景,这种认证方式可能不够灵活,企业往往已经有一套比较成熟的 身份认证系统(Identity Provider, IDP),比如:

  • Azure AD:Microsoft 的企业身份平台
  • Keycloak:开源身份和访问管理解决方案
  • Google Cloud Identity:Google 的企业 SSO
  • Okta:专业的身份管理服务

他们更希望能直接复用这套认证机制。

LiteLLM 支持通过 JWT 令牌 与这些系统集成,而无需维护独立的用户数据库。

注意,这是一个企业级特性,需要购买授权。

OIDC 简介

LiteLLM 和身份认证系统之间的交互遵循 OIDC 标准。

OpenID Connect (OIDC) 是一个基于 OAuth 2.0 的身份认证协议,它在 OAuth 2.0 的基础上增加了身份层,使得应用可以验证用户的身份,它已经成为企业级应用的标准认证方式。

OIDC 的核心优势如下:

  • 标准化:遵循 OAuth 2.0 和 OpenID Connect 规范
  • 单点登录:支持 SSO,用户一次登录,全组织访问
  • 令牌安全:JWT 令牌可以包含丰富的用户信息,支持签名和加密
  • 广泛支持:被所有主流云服务和身份提供商支持

下面是 OIDC 规范,对此感兴趣的朋友可以看看:

JWT 简介

JWT(JSON Web Token) 是一种基于 JSON 的轻量级身份认证与信息交换标准(RFC 7519),广泛用于分布式系统、API 接口、前后端分离架构中,核心作用是在客户端与服务器之间安全传递 可验证的声明(如用户身份、权限范围等),无需服务器存储会话状态。

在传统的会话认证(如 Session)中,服务器需要存储用户的会话信息,当用户量增大或服务分布式部署时,会面临会话同步复杂、服务器存储压力大等问题。而 JWT 通过 客户端存储令牌 + 服务器验证令牌 的模式,解决了这些痛点,其核心优势包括:

  • 无状态:服务器无需存储会话数据,仅通过令牌本身即可验证合法性,降低服务器存储成本,便于服务水平扩展(多台服务器可共享认证逻辑);
  • 跨域友好:JWT 基于 HTTP 头传递,天然支持跨域场景(如前后端分离、多服务间调用);
  • 轻量灵活:基于 JSON 格式,体积小、传输快,且可自定义声明字段,满足不同业务需求;
  • 自包含:令牌本身包含了用户身份、权限等核心信息,减少服务器查询数据库的次数(无需每次认证都查用户表);

一个 JWT 令牌由三部分组成,用点号分隔:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

分别代表:

  • Header:算法和令牌类型信息
  • Payload:用户信息和声明(Claims)
  • Signature:数字签名,用于验证数据完整性

可以通过下面的网站验证和查看 JWT 令牌中的内容:

基于 Keycloak 的 JWT 认证实战

下面我使用 Keycloak 这款开源的身份认证系统来演示下如何在 LiteLLM 中实现 JWT 认证。

keycloak.png

这是一款由 Red Hat 主导开发并维护的开源 身份和访问管理(IAM) 工具,旨在为现代应用(包括 Web 应用、移动应用、API 服务等)提供统一、安全且标准化的 身份认证(Authentication)授权(Authorization) 能力,帮助开发者快速集成身份管理功能,无需重复造轮子。

Keycloak 环境准备

首先使用下面的命令启动 Keycloak 服务:

$ docker run \
  -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:26.4.2 start-dev

服务启动成功后,在浏览器访问 http://localhost:8080/ 并使用默认的用户名和密码登录:

keycloak-admin-ui.png

点击 “Manage realms” 菜单,创建一个名为 litellm领域(Realm),这是 Keycloak 中最高级别的隔离单位,相当于 租户

keycloak-create-realm.png

创建完成后会自动切到这个领域,然后点击 “Users” 菜单,在这个领域下创建一个用户,用户名为 zhangsan

keycloak-create-user.png

创建完成后进入该用户的详情,点击 “Credentials” 菜单,再点击 “Set password” 按钮,为用户设置一个长期密码(注意将 Temporary 勾掉):

keycloak-create-user-set-password.png

然后再点击 “Clients” 菜单,创建一个客户端:

keycloak-create-client.png

其中 Client ID 命名为 litellm,点击 Next 进入 “Capability Config” 页面:

keycloak-create-client-capability.png

将 “Client authentication” 选项开启,同时在 “Authentication flow” 中将 “Direct access grants” 开启。接着,点击 Next 进入 “Login Settings” 页面,保持默认即可,点击 Save 按钮,完成客户端的创建。

开启 JWT 认证

至此 Keycloak 环境准备就绪,接下来让 LiteLLM 开启 JWT 认证。第一步,通过环境变量设置 Keycloak 的公钥端点:

# 注意 `litellm` 是领域名称
export JWT_PUBLIC_KEY_URL="http://localhost:9009/realms/litellm/protocol/openid-connect/certs"

这个 URL 是 OpenID Connect 标准的 JWKS(JSON Web Key Set) 端点,方便客户端批量获取所需密钥,里面包含了用于验证签名或加密的公钥。

第二步,在配置中启用 JWT 认证:

general_settings:
  master_key: sk-1234
  database_url: "postgresql://postgres:password@127.0.0.1:5432/litellm"
  enable_jwt_auth: true # 开启 JWT 认证

第三步,重启 LiteLLM Proxy 服务:

$ litellm -c config.yaml

第四步,使用 Client ID、Client Secret、用户名、密码,调用 Keycloak 获取 JWT 令牌:

$ curl -X POST \
  http://localhost:9009/realms/litellm/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=litellm" \
  -d "client_secret=0CtlgEvGHU3XNjDAmwHPn5p8wT78JGEp" \
  -d "username=zhangsan" \
  -d "password=12345678"

其中 Client Secret 可以在 Client 详情中找到:

keycloak-clients-details.png

接口返回结果如下:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5...",
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": "eyJhbGciOiJIUzUxMiIsInR5...",
  "token_type": "Bearer",
  "not-before-policy": 0,
  "session_state": "dca8f2d7-eac4-d6e7-799b-f7b80da4d841",
  "scope": "profile email"
}

这个 access_token 就是 JWT 令牌,我们可以用它来调用 /chat/completions 接口:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5...' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

LiteLLM 会根据从 JWT_PUBLIC_KEY_URL 获取的公钥对该令牌进行验证(类似数字签名的原理),这就是 LiteLLM 的 JWT 认证流程。

自定义认证

虽然 LiteLLM 提供了虚拟 Key、JWT 等多种认证方式,但在某些高度定制化的场景中,你可能需要实现自己的认证逻辑。比如:

  • 现有系统集成:你有一套自定义的用户认证系统
  • 特殊业务规则:需要根据特定条件验证用户
  • 外部服务集成:需要调用外部服务进行认证
  • 多步认证:需要组合多个认证因素

LiteLLM 允许你提供自定义的认证函数,完全控制身份认证过程。其核心是实现一个异步函数,该函数接收请求和 API Key,然后返回一个认证对象:

from fastapi import Request
from litellm.proxy._types import UserAPIKeyAuth

async def user_api_key_auth(request: Request, api_key: str) -> UserAPIKeyAuth: 
  """
  自定义认证函数

  参数:
    request: FastAPI 请求对象,包含 HTTP 请求的所有信息
    api_key: 从请求头中提取的 API Key

  返回:
    UserAPIKeyAuth: 认证成功时返回用户认证对象

  异常:
    Exception: 认证失败时抛出异常
  """
  try: 
    if api_key.startswith("my-custom-key-"):
      return UserAPIKeyAuth(api_key=api_key)
    raise Exception("Invalid API key")
  except: 
    raise Exception("Authentication failed")

将上面的内容保存到 custom_auth.py 文件中,并放置于和 config.yaml 文件同级的目录下。在配置文件中指定自定义认证函数的位置:

general_settings:
  master_key: sk-1234
  database_url: "postgresql://postgres:password@127.0.0.1:5432/litellm"
  custom_auth: custom_auth.user_api_key_auth  # 模块路径.函数名

然后重启 LiteLLM Proxy 服务,此时,任何 my-custom-key- 开头的 Key 都能通过验证了:

$ curl -X POST 'http://127.0.0.1:4000/chat/completions' \
  -H 'Authorization: Bearer my-custom-key-888' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "你好"}]
  }'

值得注意的是,在认证流程中,自定义认证是最优先执行的,因此如果开启了该功能,Master Key 和 虚拟 Key 就不起作用了。为了同时兼容,企业版的 LiteLLM 支持一个更灵活的混合模式:

general_settings:
  custom_auth: custom_auth.user_api_key_auth
  custom_auth_settings:
    mode: "auto"  # 支持虚拟 Key 和自定义认证混用

当自定义认证失败后,LiteLLM 会继续沿用虚拟 Key 的验证流程。

小结

通过这篇文章,我们系统地学习了 LiteLLM Proxy 的认证机制,这是构建企业级 LLM 网关的核心基础。主要内容包括:

  • 虚拟 Key 认证:LiteLLM 最核心的认证方式,通过为每个用户或应用生成独立的 API Key,实现细粒度的权限隔离和使用追踪;采用哈希存储和分层缓存策略确保了安全性和性能的平衡;支持多种 Header 格式使其能够兼容各种客户端和工具;
  • JWT 认证与 OIDC 集成:为企业用户提供了一条与现有身份认证系统无缝集成的路径,无需在 LiteLLM 中维护独立的用户数据库,充分利用企业已有的 IAM 基础设施;
  • 自定义认证:完全开放的认证扩展机制,允许企业根据特定的业务规则实现复杂的认证逻辑,支持与任何现有系统的集成;企业版提供了混合模式,可以同时支持虚拟 Key 和自定义认证;

LiteLLM 的认证设计体现了分层的思想:从基础的虚拟 Key 面向个人开发者和小型团队,到 JWT/OIDC 面向已有 IAM 的企业,再到自定义认证面向有特殊需求的场景。这种分层的、可扩展的设计,使得 LiteLLM 能够适应从个人项目到大规模企业级应用的各种场景。

在后续的学习中,我们将继续深入 LiteLLM 的权限管理和访问控制系统,学习如何为不同的用户和团队分配不同的权限,如何追踪使用情况和成本,如何设置预算限额防止滥用。敬请期待!


学习 LiteLLM 的模型管理

在上一篇文章中,我们快速了解了 LiteLLM 的核心特性和基本用法。我们知道 LiteLLM 通过统一的 API 接口支持调用 100+ 个 LLM 服务商的模型,而 Proxy Server 可以作为一个企业级的 LLM 网关来统一管理和路由请求。

但是,当我们真正去部署和使用 LiteLLM Proxy 时,会面临一个非常实际的问题:如何有效地管理这些模型?

是否能够快速添加新模型而不需要重启服务?能否让用户清楚地了解有哪些模型可用?在使用过程中,如何追踪模型的定价和成本?怎样安全地存储和管理各个服务商的 API 凭据?这些都是模型管理需要解决的问题。

这一篇文章,我们就来深入学习 LiteLLM 的模型管理功能,看看它是如何帮助我们解决这些实际问题的。

基础配置

在前面的快速入门篇,我们已经接触过简单的模型配置,可以通过 config.yaml 文件定义模型:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY

  - model_name: claude
    litellm_params:
      model: anthropic/claude-sonnet-4-20250514
      api_key: os.environ/ANTHROPIC_API_KEY

这里的配置很直观:

  • model_name 是用户在调用 API 时使用的名称
  • litellm_params 包含了 LiteLLM 在调用该模型时需要的所有参数,包括实际的模型名称、API 密钥、URL 地址等

    • model:遵循 provider/model_id 的格式,LiteLLM 通过这个来识别实际的模型和服务商
    • api_key:支持 os.environ/KEY_NAME 的格式来从环境变量中读取,避免将密钥硬编码在配置文件中

但在实际应用中,我们往往需要更多的信息。比如,某个模型的最大 Token 数是多少?调用这个模型的成本是多少?这个模型有什么特殊的功能限制吗?这就需要用到 model_info 字段,我们可以通过 /model/info 接口了解每个模型的详细信息:

$ curl -X GET http://127.0.0.1:4000/model/info \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json'

返回结果类似下图:

model-info.png

对于一些比较常见的模型,LiteLLM 会定期维护基本信息,不过用户也可以在配置文件中进行修改,这样会覆盖默认值,用户还可以添加自定义的字段:

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      description: "这里是用户自定义字段"
      max_tokens: 4096
      supports_vision: true
      supports_function_calling: true

这个 /model/info 接口非常有用,可以用来在应用的 UI 中展示可用的模型列表和详细信息,帮助用户选择最合适的模型,进行成本估算和预算规划。

动态管理

通过配置文件管理模型固然简单,但是每次修改都需要重启 Proxy Server,这在生产环境下是不可接受的。LiteLLM 支持将模型信息保存到 Postgres 数据库中,从而实现动态管理功能。首先修改 config.yaml 文件,加上数据库配置并开启模型保存功能:

general_settings:
  master_key: sk-1234 # 管理员密钥
  database_url: "postgresql://postgres:password@127.0.0.1:5432/litellm"
  store_model_in_db: true # 是否将模型保存到数据库

然后重启 Proxy Server,现在我们就可以通过 API 接口的方式动态管理模型了,具体又可以分为 通过 API 管理通过命令行管理通过 Web UI 管理 几种方式。

通过 API 管理

通过 /model/new 接口添加模型:

$ curl -X POST "http://127.0.0.1:4000/model/new" \
  -H 'Authorization: Bearer sk-1234' \
  -H "Content-Type: application/json" \
  -d '{
    "model_name": "deepseek",
    "litellm_params": {
      "model": "deepseek/deepseek-chat",
      "api_key": "sk-xxx"
    }
  }'

通过命令行管理

LiteLLM 还提供了一个命令行工具 litellm-proxy,方便从命令行管理模型,这个工具在安装 Proxy Server 时会一起安装好:

$ pip install 'litellm[proxy]'

首先通过环境变量配置认证信息:

export LITELLM_PROXY_URL=http://localhost:4000
export LITELLM_PROXY_API_KEY=sk-1234

也可以使用 litellm-proxy login 登录,这会打开浏览器进行身份认证,认证后的凭据会保存在本地。

列出所有模型

$ litellm-proxy models list

添加新模型

$ litellm-proxy models add deepseek \
  --param model=deepseek/deepseek-chat \
  --param api_key=sk-xxxx

删除模型

$ litellm-proxy models delete <model-id>

通过 Web UI 管理

如果你不习惯使用命令行,LiteLLM Proxy 的 Web UI 也提供了可视化的模型管理界面,登录到管理后台后,点击 “Models + Endpoints” 菜单:

web-ui-model-management.png

这里列出了当前系统的所有模型,包括配置文件中的和数据库中的。点击 “Add Model” 标签添加新模型:

web-ui-add-model.png

填写 Provider、Model Names、Model Mappings、API Key 等参数,点击确认即可。

注意,Model Mappings 中的 Public Model Name 就对应配置文件中的 model_name 参数,LiteLLM Model Name 对应 litellm_params.model 参数。

如果有一些额外参数,可以展开 “Advanced Settings” 进行配置:

web-ui-add-model-adv.png

模型发现

手动维护模型列表可能会很繁琐,特别是对于那些有大量模型的服务商,比如 OpenAI、Anthropic 等,每次他们发布新模型时我们都要手动更新配置。为此,LiteLLM 推出了 模型发现(Model Discovery) 功能,通过 Wildcard 模型 LiteLLM 可以自动从服务商处获取最新的模型列表,无需手动更新。

其配置非常简单,只需要在 config.yaml 中使用 /* 后缀来表示 Wildcard 模型:

model_list:
  - model_name: anthropic/*
    litellm_params:
      model: anthropic/*
      api_key: os.environ/ANTHROPIC_API_KEY

litellm_settings:
  check_provider_endpoint: true  # 启用模型发现功能

注意 litellm_settings.check_provider_endpoint 必须设为 true,表示启用模型发现功能。

配置完成后,调用 /v1/models 接口就可以看到所有自动发现的模型:

$ curl -X GET http://127.0.0.1:4000/v1/models \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json'

这里我使用的是 Anthropic 服务商,因此返回的结果包含了 Anthropic 的所有可用模型:

model-discovery.png

目前 LiteLLM 的模型发现功能支持以下服务商:

  • Fireworks AI
  • OpenAI
  • Gemini
  • LiteLLM Proxy(是的,可以级联!)
  • Topaz
  • Anthropic
  • xAI
  • vLLM
  • Vertex AI

使用 Model Hub 公开模型

在团队或企业环境中,你可能希望让用户知道哪些模型是可用的,LiteLLM 提供了一个 Model Hub 功能,可以公开展示模型列表。使用 Model Hub 有以下几点优势:

  1. 自服务探索:用户可以自己浏览可用的模型,无需询问管理员
  2. 信息透明:每个模型都展示详细的信息,包括描述、能力、局限等
  3. 降低门槛:新用户可以快速了解系统中有什么,如何使用
  4. 公开演示:可以用来向客户或合作伙伴展示你的模型能力

首先,我们需要在 Web UI 中选择要公开的模型。进入 Model Hub 页面后,点击 “Make Public” 按钮,选择要公开的模型:

model-hub-make-public.png

确认后,这些模型就会出现在公开的 Model Hub 页面上,访问下面这个 URL 进行查看:

http://127.0.0.1:4000/ui/model_hub_table

这个页面是公开的,所有人都能访问,就像一个应用商店一样:

model-hub-table.png

用户可以在这里查看每个模型的详细信息以及使用文档。

模型价格同步

在上面的学习中我们了解到,可以通过 /model/info 接口查询模型的详细信息,包括模型的上下文限制以及输入输出价格等,这些信息有助于企业进行准确的成本追踪和预算控制。

LiteLLM 在 GitHub 上维护了一个完整的模型成本映射表,包含了 100+ 个模型的详细信息:

https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json

随着新模型的发布和价格的变化,这个映射表会定期更新。为了保持你的 Proxy Server 中的成本数据最新,LiteLLM 提供了 手动同步自动同步 的功能,可以从 GitHub 获取最新的价格信息,确保成本追踪的准确性。

如果你想立即同步最新的价格信息,可以使用以下命令:

$ curl -X POST "http://127.0.0.1:4000/reload/model_cost_map" \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json"

对于生产环境,更推荐设置自动定期同步,比如每 6 小时同步一次:

$ curl -X POST "http://127.0.0.1:4000/schedule/model_cost_map_reload?hours=6" \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json"

查看同步状态:

$ curl -X GET "http://127.0.0.1:4000/schedule/model_cost_map_reload/status" \
  -H "Authorization: Bearer sk-1234"

取消定时同步:

$ curl -X DELETE "http://127.0.0.1:4000/schedule/model_cost_map_reload" \
  -H "Authorization: Bearer sk-1234"

默认情况下,LiteLLM 从 GitHub 的官方仓库获取模型成本表。如果你有一些定制模型,想使用自定义的模型成本表,可以设置环境变量:

export LITELLM_MODEL_COST_MAP_URL="https://your-server.com/your-cost-map.json"

或者使用本地文件:

export LITELLM_LOCAL_MODEL_COST_MAP=True

此时 LiteLLM 会读取 litellm 目录下的 model_prices_and_context_window_backup.json 文件,不会访问网络。

凭据管理

关于模型管理的另一个话题是 凭据管理,我们知道,LiteLLM 支持 100 多个不同的模型服务商,每个服务商都有自己的 API Key 或认证方式,如何安全的管理这些服务商的凭据呢?

在前面的 config.yaml 文件中,我们配置 api_key 时使用了 os.environ/KEY_NAME 格式从环境变量中读取,这是最简单的一种凭据管理的方式,避免将密钥硬编码在配置文件中,虽然很方便,但是这种方式难以管理,而且也不够安全,在某些情况下,你可能希望在 LiteLLM 的数据库中直接存储和管理这些凭证。

LiteLLM 提供了一个专门的凭证管理界面,进入 Models -> LLM Credentials -> Add Credential,可以添加新的凭证:

web-ui-add-credentials.png

选择你的 LLM 服务商后,输入 API Key 和其他必要信息(根据不同的服务商,界面会显示相应的字段),点击确认即可。添加凭证后,在创建新模型时就可以从下拉列表中选择已有的凭证,避免重复输入敏感信息:

web-ui-add-model-use-credentials.png

凭证在数据库中是加密存储的。LiteLLM 使用以下方式进行加密:

  • 优先使用 LITELLM_SALT_KEY 进行加密
  • 如果未设置 LITELLM_SALT_KEY,则使用 LITELLM_MASTER_KEY 进行加密

这两个密钥都应该被妥善保管,不要泄露。

企业级凭据管理

对于企业级应用,对于凭据管理可能有着更高的安全要求,LiteLLM 支持与主流的 密钥管理服务(Secrets Manager) 集成,允许你将凭据存储在企业级的密钥管理服务中,而不是 LiteLLM 的数据库中。支持的 Secrets Manager 包括:

  • AWS Secrets Manager
  • AWS Key Management Service
  • Azure Key Vault
  • Google Secret Manager
  • Google Key Management Service
  • HashiCorp Vault

除了传统的 API Key,LiteLLM 还支持 OpenID Connect (OIDC) 身份认证,这是一种更现代、更安全的认证方式。支持的 OIDC 提供商包括:

  • Google Cloud Run
  • GitHub Actions
  • Azure AD
  • CircleCI
  • Azure Kubernetes Service 等

这两个功能特别适合大型企业环境,可以显著提高安全性和合规性。详细的企业特性配置,请参考 LiteLLM 官方文档。

小结

通过这篇文章,我们详细学习了 LiteLLM Proxy 的模型管理功能。主要内容包括:

  • 基础配置:对于相对稳定的模型配置,应该在 config.yaml 中定义,这样可以版本控制,便于回滚;充分利用 model_info 字段来添加模型描述、能力说明、使用建议等,这会让用户更容易选择合适的模型;
  • 动态管理:通过 /model/new 接口在运行时动态添加模型,支持 API、命令行、Web UI 三种方式对模型进行管理,无需重启服务;
  • 模型发现:通过通配符自动获取整个服务商的模型列表;
  • Model Hub:公开展示可用的模型信息,提升用户体验;
  • 模型价格同步:手动或自动从 GitHub 同步最新的模型成本数据,支持自定义模型成本表;
  • 凭据管理:集中管理 API Key 和凭据信息,降低凭据泄露的风险;对于高安全要求场景,考虑使用企业特性(Secret Manager 或 OIDC),实现零密钥存储或临时凭据;

LiteLLM 的模型管理系统设计得相当完善,既支持初期的简单配置,也支持后期的复杂运维场景。从 config.yaml 的声明式配置,到运行时的动态管理,再到企业级的高安全凭据存储,LiteLLM 为不同规模的应用提供了灵活的解决方案。