秘钥管理:绝不能硬编码
所有 API Key 走密钥管理服务,绝不 commit 到仓库、绝不写到镜像、绝不明文出现在配置文件里:
| 场景 | 推荐方案 | LiteLLM 支持方式 |
|---|---|---|
| AWS | Secrets Manager / Parameter Store | use_aws_secret_manager: True |
| GCP | Secret Manager | use_google_kms: True |
| Azure | Key Vault | use_azure_key_vault: True |
| 自建 K8s | External Secrets + Vault | Helm secretKeyRef 注入 env |
| 本地开发 | direnv / 1Password CLI | .env 走 os.environ |
# config.yaml 里引用即可, Proxy 启动时自动去 Secrets Manager 取 general_settings: use_aws_secret_manager: True model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY # 背后是 Secrets Manager
分层限流
LLM 服务不能只在一个地方限流。至少 4 层:
| 层 | 限什么 | 工具 | 生效时机 |
|---|---|---|---|
| 1. Ingress / API Gateway | 按 IP/user 的 RPS | Nginx / Kong / Cloudflare | 最早挡 DDoS |
| 2. LiteLLM Virtual Key | 按 key 的 RPM/TPM/budget | Proxy 内置 | 业务级硬限 |
| 3. Router deployment | 按 provider 部署的 RPM/TPM | Router model_list | 保护上游不超配额 |
| 4. Provider 原生 | provider 自己的限制 | Azure/OpenAI 后台 | 最后一道保险 |
4 层里第 2 和第 3 层最关键,前者保护你(不被单个业务烧死),后者保护上游(不被打挂)。
灰度与发布
LLM 产品发版的危险源:prompt 改了、模型换了、LiteLLM 升级了。每一项都可能让答案质量骤降。
- 模型切换要灰度:gpt-4o → gpt-4o-2024-11-20。用 tag-based routing,流量 1% → 10% → 50% → 100%。
- prompt 改了要跑 eval:至少 200 条金标样本,自动化对比前后分数,掉了就 block。
- Proxy 升级要双写:新老版本并行跑,流量镜像,对比结果一致再切。
- 回滚要 1 分钟内:出事时不是 debug 时间,先回滚再复盘。Helm 一条命令。
# 灰度示例: 50% 流量走新 prompt 版本 router_settings: enable_tag_filtering: true model_list: - model_name: chat-v1 # 老版本 litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY model_info: tags: ["stable"] - model_name: chat-v2 # 新版本 litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY model_info: tags: ["canary"]
业务代码按 user_id hash 模 100 决定 tag:
tag = "canary" if hash(user_id) % 100 < 10 else "stable" # 10% 灰度 resp = client.chat.completions.create( model="chat", messages=msgs, extra_body={"metadata": {"tags": [tag]}}, )
多活与容灾
"一个 region 的 Proxy 挂了,业务不能跟着挂"——基本要求:
- Proxy 至少 3 replica,跨 AZ 部署。单 AZ 挂不影响。
- Postgres 主从 + 自动 failover(RDS Multi-AZ / Cloud SQL HA)。
- Redis Sentinel / Cluster,主挂 30s 内切从。
- 多 region:主 region + 备 region,DNS / Anycast 切换,备 region 永远预热。
- Provider 多样化:主用 OpenAI、备用 Claude + Gemini,fallback 链配齐。OpenAI 的几次全球故障已经证明:单 provider 再贵也会挂。
容量规划
开容量会议前,至少算 3 个数:
- 峰值 RPS:历史数据的 P99 峰值 × 3(预留 headroom)。
- TPM 消耗:峰值 RPS × 平均 token / 60——你会知道至少要开几个 Azure deployment。
- 月预算:日均 RPS × 平均 cost × 30 × 业务增长系数。
举例:日 500 万请求,平均 1500 token,用 gpt-4o-mini:
QPS(峰值) ≈ 500w / 86400 × 3 ≈ 173 TPM 消耗 ≈ 173 × 1500 × 60 ≈ 1560w token/分钟 ⇒ 需要至少 16 个 Azure GPT-4o-mini deployment(每个 100w TPM) ⇒ 月预算 ≈ 500w × 0.0006 × 30 = 9w 美元
这个表"月度 Review"一次,数字一漂移就提前加 deployment / 调预算,不然某天业务涨了预算烧完,服务突然 429。
故障演练
LLM 产品至少每季度演练 3 个场景:
| 演练 | 注入方式 | 期望恢复 |
|---|---|---|
| OpenAI 全球故障 | 把 OpenAI api_base 改成 404 假地址 | < 30s 切到 Claude |
| Azure East-US 配额爆 | 发 100 并发打 East-US | < 5s 切到 West-US |
| Redis 挂 | 重启 Redis Sentinel 主节点 | 限流/缓存降级模式,主流程可用 |
| Postgres 挂 | 主节点 kill | Virtual Key 校验降级,新 key 不能生成但老 key 能用 |
| Proxy pod OOM | kill -9 pod | HPA 自动拉新 pod,请求丢失 < 1s |
每个演练写一份 runbook,新值班人第一周必须看完。
性能调优要点
- 复用 httpx client:不要每次 import 重新创建。Proxy 默认处理,SDK 模式用
litellm.aclient_session。 - UVloop:
pip install uvloop+uvloop.install(),async IO 吞吐 +30%。 - worker 数:Proxy 走 uvicorn,
--num-workers 4(CPU 核数)。更多 worker 用 Redis 同步状态。 - 连接池:httpx 默认 100 keepalive。高并发场景调到 500。
- 不要无脑缓存:缓存能否命中取决于 prompt 稳定性,不稳定就别开。
- token 估算别打满:
max_tokens留 buffer,128K 上限时只给到 100K,避免被 provider 拒。
生产 config.yaml 完整模板
下面是一个能直接改成你家情况的完整生产配置,覆盖了前面 11 章的所有要点:
############################################################### # LiteLLM Proxy 生产配置 (config.yaml) # ───────────────────────────────────────────────────────────── # • 4 provider × 6 deployment (Azure/OpenAI/Anthropic/Gemini/DeepSeek) # • fallback 链 / context_window 切长 / content_policy 旁路 # • Redis 限流+缓存, Postgres 存 Virtual Keys # • Langfuse 观测 + Prometheus 指标 + S3 归档 # • Slack + PagerDuty 告警分级 ############################################################### model_list: # ── 聊天主模型: Azure 三部署 + OpenAI 备 - model_name: chat litellm_params: model: azure/gpt4o-east api_key: os.environ/AZURE_EAST_KEY api_base: os.environ/AZURE_EAST_BASE api_version: "2024-10-21" rpm: 1000 tpm: 2000000 model_info: tags: ["stable", "region:east"] - model_name: chat litellm_params: model: azure/gpt4o-west api_key: os.environ/AZURE_WEST_KEY api_base: os.environ/AZURE_WEST_BASE rpm: 800 tpm: 1500000 model_info: tags: ["stable", "region:west"] - model_name: chat litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY model_info: tags: ["stable", "provider:openai"] # ── 备用大模型: Claude Sonnet - model_name: claude-sonnet litellm_params: model: anthropic/claude-sonnet-4-5 api_key: os.environ/ANTHROPIC_API_KEY rpm: 500 tpm: 500000 # ── 廉价模型: Gemini Flash / DeepSeek - model_name: cheap litellm_params: model: gemini/gemini-2.5-flash api_key: os.environ/GEMINI_API_KEY - model_name: cheap litellm_params: model: deepseek/deepseek-chat api_key: os.environ/DEEPSEEK_API_KEY # ── 长上下文特供 - model_name: long-context litellm_params: model: gemini/gemini-2.5-pro api_key: os.environ/GEMINI_API_KEY # ── 推理模型 - model_name: reasoner litellm_params: model: openai/o3 api_key: os.environ/OPENAI_O3_KEY max_budget: 200.0 budget_duration: 1d ############################################################### router_settings: routing_strategy: usage-based-routing-v2 num_retries: 3 retry_after: 5 timeout: 60 cooldown_time: 60 allowed_fails: 3 enable_pre_call_checks: true enable_tag_filtering: true redis_host: os.environ/REDIS_HOST redis_port: 6379 redis_password: os.environ/REDIS_PASSWORD fallbacks: - chat: [claude-sonnet, cheap] - reasoner: [claude-sonnet] - cheap: [chat] context_window_fallbacks: - chat: [long-context] # 超 128K 自动切 gemini-pro content_policy_fallbacks: - chat: [claude-sonnet] # Azure 审核拦, 走 Claude ############################################################### litellm_settings: drop_params: true set_verbose: false request_timeout: 60 telemetry: false cache: true cache_params: type: redis host: os.environ/REDIS_HOST port: 6379 password: os.environ/REDIS_PASSWORD ttl: 1800 namespace: "prod:llm" success_callback: ["langfuse", "prometheus", "s3"] failure_callback: ["langfuse", "sentry"] s3_callback_params: s3_bucket_name: company-llm-audit s3_region_name: us-east-1 turn_off_message_logging: false # 全文留存 (已有脱敏 callback) ############################################################### general_settings: master_key: os.environ/LITELLM_MASTER_KEY database_url: os.environ/DATABASE_URL database_connection_pool_limit: 100 database_connection_timeout: 60 use_aws_secret_manager: true store_model_in_db: true # 支持 UI 改模型 ui_access_mode: admin_only allow_user_auth: true enforce_user_param: true # 每请求必须带 user alerting: ["slack", "pagerduty"] alerting_threshold: 60 alert_types: - "llm_exceptions" - "llm_too_slow" - "llm_requests_hanging" - "budget_alerts" - "cooldown_deployment" - "daily_reports" environment_variables: LANGFUSE_PUBLIC_KEY: os.environ/LANGFUSE_PK LANGFUSE_SECRET_KEY: os.environ/LANGFUSE_SK LANGFUSE_HOST: https://langfuse.internal SLACK_WEBHOOK_URL: os.environ/SLACK_WEBHOOK_URL
这份配置可以直接用在一个中等规模公司的 AI 网关上——把 Key/URL 替换成你自己的、把 tag 改成贴合你业务的,就能上生产。
Launch checklist:上线前最后一遍核对
- [ ] config.yaml 里没有明文 key,全部
os.environ/。 - [ ] Postgres + Redis 已高可用部署,备份策略已开。
- [ ] Proxy ≥ 3 replica,跨 AZ / HPA 已开。
- [ ] Virtual Keys 已全部发放,Master Key 只在管理员手中。
- [ ] 每个业务的 budget / RPM / TPM / 模型白名单都写死。
- [ ] fallbacks 链验证过(手动 404 主模型测试)。
- [ ] context_window_fallbacks / content_policy_fallbacks 配好。
- [ ] Langfuse / Prometheus / S3 callback 都能收到数据。
- [ ] Slack / PagerDuty 告警测过一次。
- [ ] eval 金标跑过,分数合格。
- [ ] /health/liveliness 和 /health/readiness 都通。
- [ ] Grafana 五图(RPS/cost/p95/error/cooldown)已搭好。
- [ ] 回滚脚本验证过,< 1 分钟能滚。
- [ ] Runbook 已写,含 5 个主要故障场景。
- [ ] 预算报表已 schedule 每日自动发给财务/主管。
常见架构反模式
- 每个业务自己接 OpenAI:key 散、账散、无审计。第一步永远是上 Proxy 统一入口。
- Proxy 和业务混部:一个业务 OOM 把整个 AI 网关带挂,全公司瘫。独立部署。
- 只有 1 个 provider:OpenAI 全球故障那一晚你就知道代价。至少三家。
- 没 fallback 跑生产:任何 provider 抖一下业务全报错。每个关键 model_name 都要有 fallback。
- 没 eval 发 prompt:靠肉眼测几条上线,幻觉率翻倍还不知。自动化 eval 卡发布。
- 不设日预算:月预算可能前 3 天就烧光,后 27 天 429。日/月双限。
- 不做灰度:prompt 改一次全量发,回滚才发现线上掉 20% 质量。永远灰度。
- callback 同步 IO:日志系统慢 500ms,AI 跟着慢 500ms。async + 超时 + drop。
- 把 user 字段省了:出事抓不到人。gateway 强制塞 user。
- 只看 mean 延迟:mean 2s p99 30s,用户体验全看 p99。
写在最后
LiteLLM 不是银弹——它是一把把散装 provider 组装成可运维系统的扳手。这 12 章讲的事情总结成一句话:
业务代码只关心"调 chat 模型回答用户",其他事(路由、容灾、限流、缓存、观测、成本、合规)全部下沉到基础设施。出事时一处调配置、一次灰度、一条回滚——而不是去改 12 个业务仓库。
你可能一开始只会用到其中的 30%——那是好事。不要一上来就把 config.yaml 抄成 300 行。先用 SDK 解决跨 provider 的问题,流量上来了换 Proxy,规模再大加 Virtual Keys 和 Admin UI。按需演进才是工程上的美德。
本章小结
- 秘钥走 KMS(AWS Secrets Manager / GCP Secret Manager / Azure Key Vault),绝不硬编码
- 分层限流 4 层:Ingress / Virtual Key / deployment / provider,缺一不可
- 发布要灰度:tag-based routing + hash 分桶 + 自动 eval + 1 分钟回滚
- 多活容灾:Proxy ≥ 3 replica 跨 AZ,Postgres/Redis 高可用,多 region,多 provider
- 容量规划三件事:峰值 RPS、TPM 消耗、月预算,月度 review
- 每季度故障演练 5 场景:provider 挂 / 配额爆 / Redis 挂 / Postgres 挂 / pod OOM
- 提供一份完整生产 config.yaml 模板,覆盖 fallback / 限流 / 缓存 / 观测 / 告警
- Launch checklist 15 条,上线当天逐一打勾