AI 网关与 LLM API 治理实战:从单点接入到统一管控
一切要从那笔 3000 美元的账单说起
去年冬天的一个凌晨,我被告警电话吵醒。某个实验性的 prompt 循环在 3 小时内消耗了价值 3000 美元 的 GPT-4 Token。没有限流、没有告警、没有预算控制——因为我们的 LLM API key 直接散落在各个微服务的环境变量里。
第二天我做了三件事:封掉所有直接暴露的 API key、拉了个网关项目、写下这篇文章。如果你也在经历"每个服务各自接 OpenAI,月底 Finance 拿着账单来砸门"的阶段,这篇实战经验应该能帮你省下几倍于阅读时间的钱。
核心结论: 一个轻量 AI 网关 + 三层治理策略(认证→限流→审计),能在不侵入业务代码的前提下,把 LLM API 成本降低 40-60%,同时杜绝 key 泄露和异常流量。
第一步:明确我们要解决什么问题
写代码之前,我先梳理了当时的混乱局面:
| 问题 | 影响 | 紧急程度 |
|---|---|---|
| API Key 硬编码在 5 个服务中 | 泄露即被刷单 | 🔴 立即 |
| 无统一限流 | 异常流量直通计费 | 🔴 立即 |
| 无调用审计 | 月底对账靠猜 | 🟡 本周 |
| 每个服务各自实现重试/退避 | 重复劳动、行为不一致 | 🟢 有空再说 |
解决思路很直接:在业务服务和 LLM 提供商之间插一层网关,让所有调用流经这里,治理策略在网关层统一实施。
第二步:选择方案——为什么我选了 LiteLLM
选型时我评估了三个方向:
- 自建代理 — 用 Nginx/Envoy 做反向代理,自己写限流和鉴权
- 托管服务 — Portkey、Helicone 等 SaaS 网关
- 开源 AI 网关 — LiteLLM、Kong AI Gateway
我选了 LiteLLM,原因简单:
- 它实现了 OpenAI 兼容接口,业务代码零改动
- 内置 100+ 模型提供商的路由
- 支持预算控制、限流、Fallback、负载均衡
- 单容器部署,资源开销极低
选型贴士: 如果你已经在用 Kubernetes,LiteLLM 可以以 Sidecar 模式部署在每个 Pod 里,治理策略通过 ConfigMap 统一管理。
最打动我的一点:把现有代码从 openai.OpenAI(api_key=raw_key) 改成 openai.OpenAI(base_url=gateway_url, api_key=gateway_key),对业务代码的改动就结束了。
第三步:部署网关——Docker Compose 就够了
我的生产部署用了一个 docker-compose.yml:
version: '3.8'
services:
litellm:
image: ghcr.io/berriai/litellm:main-latest
ports:
- "4000:4000"
volumes:
- ./litellm_config.yaml:/app/config.yaml
- ./litellm.db:/app/litellm.db
environment:
- DATABASE_URL=sqlite:///app/litellm.db
- LITELLM_MASTER_KEY=sk-admin-your-master-key-here
command: --config /app/config.yaml --port 4000
restart: unless-stopped
配置文件才是真正的关键:
model_list:
- model_name: gpt-4
litellm_params:
model: openai/gpt-4
api_key: os.environ/OPENAI_API_KEY
rpm: 450 # 每分钟请求数限制
max_tokens: 4096
- model_name: gpt-3.5-turbo
litellm_params:
model: openai/gpt-3.5-turbo
api_key: os.environ/OPENAI_API_KEY
rpm: 900
- model_name: claude-3-sonnet
litellm_params:
model: anthropic/claude-3-sonnet
api_key: os.environ/ANTHROPIC_API_KEY
litellm_settings:
max_budget: 5000 # 月预算上限(美元)
budget_duration: 30d
fallbacks: [{"gpt-4": ["gpt-3.5-turbo"]}] # GPT-4 降级到 3.5
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
database_url: os.environ/DATABASE_URL
部署:
docker-compose up -d
curl http://localhost:4000/health
# → {"status": "healthy"}
踩坑 #1: SQLite 在并发高时有锁竞争问题。生产环境如果 QPS > 50,换成 PostgreSQL。
第四步:三层治理——认证、限流、审计
网关跑起来了,但真正的治理能力需要按三层构建。
第一层:认证与 Key 管理
所有业务服务不再持有云厂商的 API key,而是从网关获取虚拟 key(Virtual Key):
# 在网关管理端创建虚拟 key
curl -X POST http://localhost:4000/key/generate \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"key_alias": "production-recommend-svc",
"models": ["gpt-4", "gpt-3.5-turbo"],
"max_budget": 2000,
"budget_duration": "30d",
"max_parallel_requests": 10
}'
# 返回:
# {"key": "sk-7Fk...", "key_alias": "production-recommend-svc"}
每个服务分配独立的虚拟 key,可以精确控制:
- 这个服务能用哪些模型
- 月预算上限
- 并发上限
一旦某个 key 异常,直接吊销它,不影响其他服务。
第二层:限流与预算控制
这是我最痛的一层。之前的核心痛点就是"流量冲进来才知道"。
我在网关配置了三级限流:
# 在 litellm_config.yaml 中
router_settings:
routing_strategy: "usage-based" # 按使用量路由
enable_pre_call_checks: true # 调用前检查配额
max_fallbacks: 2
# 按用户/IP 限流
user_rpm_limit: 100
user_tpm_limit: 100000
# 全局预算告警
budget_alert_thresholds:
- 80%
- 90%
- 100%
同时配置了 Grafana 告警:
- 预算使用率 > 80% → Slack 通知(黄色预警)
- 预算使用率 > 100% → 自动拒绝新请求(红色阻断)
- 单小时消费 > 500 美元 → PagerDuty 告警
第三层:审计与可观测性
所有调用日志写入数据库,LiteLLM 内置了基本用量面板。但我需要更细粒度的审计,所以加了一层日志收集到 ClickHouse:
# audit_logger.py — 在网关外部监听事件
import httpx
import json
from datetime import datetime
class AuditLogger:
def __init__(self, clickhouse_url):
self.client = httpx.Client(base_url=clickhouse_url)
def log_spend(self, entry: dict):
# 记录每次调用的完整上下文
self.client.post("/insert", json={
"timestamp": datetime.utcnow().isoformat(),
"model": entry.get("model"),
"user": entry.get("user"),
"tokens_in": entry.get("prompt_tokens", 0),
"tokens_out": entry.get("completion_tokens", 0),
"cost": entry.get("cost", 0),
"latency_ms": entry.get("response_time_ms", 0),
"status": entry.get("status"),
"error": entry.get("error", ""),
})
配上这套日志后,我在 Grafana 上能回答三个核心问题:
- 哪个服务花钱最多?→ 推荐服务,占总费用的 42%
- 哪个模型最贵?→ GPT-4 虽然调用量只占 15%,但费用占 78%
- 有没有异常模式?→ 凌晨 2-4 点有很多 401 重试,发现是个已废弃的服务还在发请求
第五步:智能路由与 Fallback
这是进阶玩法——让网关根据成本和延迟自动选择模型:
# 智能路由配置
router_settings:
routing_strategy: "latency-based" # 可选: cost-based, latency-based, usage-based
cooldown: 60 # 失败后冷却 60 秒再尝试
allowed_fails: 3 # 连续失败 3 次切换 provider
# 定义多级 fallback 链
default_fallback: "gpt-3.5-turbo"
model_fallbacks:
gpt-4:
- claude-3-sonnet # 第一 fallback
- gpt-3.5-turbo # 第二 fallback
claude-3-opus:
- gpt-4
- claude-3-sonnet
效果:当 GPT-4 返回 429(限流)或 5xx 时,网关自动降级到 Sonnet 或 3.5,业务服务完全无感知。我们的请求成功率从 96.2% 提升到了 99.8%。
踩坑 #2: 不同模型的输出风格有差异。在客服场景中,从 GPT-4 降级到 3.5 后,回复质量明显下降,用户投诉增加。最终方案是:关键场景不做自动降级,只记录失败;非关键场景(摘要、分类)才启用 fallback。
第六步:成本分析——到底省了多少钱
部署网关跑了两个月后,我拉了一组对比数据:
| 指标 | 接入前 | 接入后 | 变化 |
|---|---|---|---|
| 月均费用 | $8,420 | $3,840 | -54% |
| 无效请求占比 | 23% | 3% | -87% |
| 异常计费事件 | 7次 | 0次 | -100% |
| API Key 数量 | 12个(散落) | 3个(集中管理) | -75% |
| 平均延迟 P95 | 3.2s | 2.1s | -34% |
费用的下降主要来自三个方向:
- 无意识调用被阻断 — 某个 CI 环境每天跑着 2000 次重复调用,网关限流后自动降权,直接省下 $1,200/月
- 模型降级策略 — 非关键场景从 GPT-4 降到 3.5,费用下降 80%,质量基本持平
- 并发控制 — 避免多个请求同时进入高成本模型,账单曲线从"锯齿状尖峰"变成了"平滑波动"
复盘总结
做对了的事
- 先治理后优化 — 不要一上来就搞 Prompt 压缩、Cache 之类的优化。先一把锁住 API key,再谈其他
- 虚拟 key 体系 — 每个服务独立的 key,吊销粒度精确到服务级别
- 调用前预检 — 在请求发出前检查配额,比事后算账重要得多
踩过的坑
- SQLite → PostgreSQL — 日志量起来后 SQLite 写锁频繁,生产必须上 PG
- Fallback 策略要有业务感知 — 不是所有场景都适合自动降级,给每个接口打标签分类处理
- 审计数据保留期限 — 默认保留全部日志,一个月后 ClickHouse 存储成本超过日志本身价值。设置 90 天自动清理
延伸思考
网关只是第一步。当你的 LLM 调用量再上一个量级,你会遇到新的问题:
- Prompt 缓存层 — 相似的请求能否在网关层做语义缓存?我们正在试验用 embedding 相似度匹配重复请求,命中率约 15%
- 多租户隔离 — 每个业务线有自己的预算池,如何在一个网关实例里做隔离?
- A/B 测试路由 — 网关能否作为 Prompt 实验平台,按比例分发流量到不同 Prompt 版本?
如果你也在搭网关,最想问的问题是什么?欢迎交流。

评论已关闭!