AI 网关与 LLM API 治理实战:从单点接入到统一管控

2026-05-20 23:05 AI 网关与 LLM API 治理实战:从单点接入到统一管控已关闭评论

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

选型时我评估了三个方向:

  1. 自建代理 — 用 Nginx/Envoy 做反向代理,自己写限流和鉴权
  2. 托管服务 — Portkey、Helicone 等 SaaS 网关
  3. 开源 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%

费用的下降主要来自三个方向:

  1. 无意识调用被阻断 — 某个 CI 环境每天跑着 2000 次重复调用,网关限流后自动降权,直接省下 $1,200/月
  2. 模型降级策略 — 非关键场景从 GPT-4 降到 3.5,费用下降 80%,质量基本持平
  3. 并发控制 — 避免多个请求同时进入高成本模型,账单曲线从"锯齿状尖峰"变成了"平滑波动"

复盘总结

做对了的事

  • 先治理后优化 — 不要一上来就搞 Prompt 压缩、Cache 之类的优化。先一把锁住 API key,再谈其他
  • 虚拟 key 体系 — 每个服务独立的 key,吊销粒度精确到服务级别
  • 调用前预检 — 在请求发出前检查配额,比事后算账重要得多

踩过的坑

  • SQLite → PostgreSQL — 日志量起来后 SQLite 写锁频繁,生产必须上 PG
  • Fallback 策略要有业务感知 — 不是所有场景都适合自动降级,给每个接口打标签分类处理
  • 审计数据保留期限 — 默认保留全部日志,一个月后 ClickHouse 存储成本超过日志本身价值。设置 90 天自动清理

延伸思考

网关只是第一步。当你的 LLM 调用量再上一个量级,你会遇到新的问题:

  • Prompt 缓存层 — 相似的请求能否在网关层做语义缓存?我们正在试验用 embedding 相似度匹配重复请求,命中率约 15%
  • 多租户隔离 — 每个业务线有自己的预算池,如何在一个网关实例里做隔离?
  • A/B 测试路由 — 网关能否作为 Prompt 实验平台,按比例分发流量到不同 Prompt 版本?

如果你也在搭网关,最想问的问题是什么?欢迎交流。

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://teachcourse.cn/4150.html ,谢谢支持!

资源分享

分类:Android 标签:
初学Android Studio项目结构第一课 初学Android Studio项目结构第
009-wordpress改写文章或页面代码实现Javascript动态加载并渲染防止爬虫 009-wordpress改写文章或页面代码
基于向量数据库的RAG应用开发实战 基于向量数据库的RAG应用开发
ViewPager+FragmentPagerAdapter实现简单新闻客户端 ViewPager+FragmentPagerAd

评论已关闭!