LLM 网关与多模型路由:统一入口、策略分流与故障转移

当业务同时接 GPT、Claude、开源模型与自托管推理,直连每个后端会让限流、鉴权、成本核算散落各处。LLM 网关把「多模型调用」收敛成统一入口:协议适配、策略路由、限流配额、故障转移、可观测性一站式解决。本文讲清网关的职责边界、四类路由策略、统一 API 设计、成本与配额治理,以及高可用与灰度实践。

一个中型 AI 应用,后端常常同时挂着 OpenAI、Anthropic、自研微调模型、自托管 vLLM 四五个来源。业务代码里散落着各家 SDK、各自的密钥、各自的限流处理——改一个模型要动十几个文件,某个供应商挂了才发现没有兜底。LLM 网关(Model Gateway) 的作用就是把这一切收敛到一个统一入口:业务只对着一个 API 说话,网关负责协议适配、路由、限流、故障转移与成本核算。本文讲清网关该做什么、怎么路由、怎么不成为新的故障点。

前置:LLM 推理服务架构设计 、LLM 服务可观测性 、推理引擎终极对比 。

一、网关的职责边界

先明确网关该管和不该管的事:

职责说明归属
协议适配OpenAI/Anthropic/Gemini 格式互转网关
路由分流按策略选后端模型网关
鉴权与配额密钥、租户、限流网关
故障转移重试、降级、熔断网关
成本归因token 计费、按租户分摊网关
缓存精确/语义缓存命中网关(或旁路)
模型推理真正的计算❌ 后端引擎
业务逻辑提示词组装、结果解析❌ 应用层
网关不做的事(避免「胖网关」反模式):
□ 不做提示词工程(那是应用的职责)
□ 不做模型推理(只转发到后端引擎)
□ 不做重业务逻辑(会变成难维护的中间层)
□ 尽量无状态(状态外置到 Redis 等)

工程要点:网关的价值在于**「收敛横切关注点」**——鉴权、限流、路由、计费这些「每个请求都要做一遍」的事,与其在每个业务服务里重复实现,不如收敛到网关一处。但别让它膨胀成「什么都管」的胖网关:提示词组装、结果后处理这类业务逻辑必须留在应用层,否则网关会成为迭代瓶颈与故障放大器。

二、四类路由策略

路由是网关的核心。不同业务场景需要不同的分流依据:

2.1 静态路由(按模型名/规则)

最基础:请求里指定模型名,网关映射到具体后端。

# 路由配置示例
routes:
  - match: { model: "gpt-4o" }
    backend: openai
    upstream: "gpt-4o-2024-08-06"
  - match: { model: "fast" }
    backend: self-hosted
    upstream: "http://vllm-fast:8000"
  - match: { model: "claude-*" }
    backend: anthropic

2.2 成本/性能路由

按「便宜优先」「快优先」自动选型,把简单请求导向小模型:

成本路由示例:
□ 输入 < 500 token 且无工具调用 → 小模型(7B)
□ 需要长上下文(> 32K)         → 长上下文模型
□ 命中缓存                       → 直接返回,不走模型
□ 其余                          → 主力大模型

性能路由示例:
□ 延迟敏感(交互)→ 低 TTFT 后端
□ 吞吐敏感(批处理)→ 高吞吐后端
□ 无 SLA 约束 → 排队到最空闲的副本

2.3 语义路由(Semantic Routing)

用嵌入(Embedding)判断请求意图,再分流到最合适的模型或提示词模板:

# 概念示意:用 embedding 相似度选路由
routes = {
    "code":    embed("写代码、调试、编程问题"),
    "math":    embed("数学计算、证明、公式"),
    "chat":    embed("闲聊、问答、通用对话"),
}
def route(query):
    q = embed(query)
    best = max(routes, key=lambda k: cosine(q, routes[k]))
    return model_for(best)   # code→强代码模型,chat→小模型

语义路由能显著降本:把大量简单闲聊请求拦在便宜模型上,只在真正需要时才路由到大模型。

2.4 负载/健康路由

在多个等价副本间做负载均衡,并剔除不健康实例:

负载策略:
□ 轮询 / 加权轮询:简单,适合同构副本
□ 最少连接:适合长流式请求(避免某副本堆积)
□ 一致性哈希:带会话亲和(多轮对话复用 KV cache)
□ 优先级:付费租户优先

健康检查:
□ 主动探活(/health)→ 剔除故障副本
□ 被动熔断(错误率/超时率超阈值)→ 临时摘除
□ 半开恢复(试探性放量)→ 恢复后回归
路由决策的组合顺序(典型):
1. 鉴权 + 配额检查(超限直接拒)
2. 缓存命中检查(命中直接返回)
3. 显式模型指定?(有 → 静态路由)
4. 策略路由(成本/语义/性能)
5. 负载均衡选副本(含健康过滤)
6. 转发 + 记录成本与指标

工程要点:路由策略要**「可配置、可观测、可回滚」**。别把路由逻辑硬编码进代码——配置化(YAML/DB)才能让运营侧快速调整。每条路由决策都应记录「为什么选了这个后端」,否则线上成本异常时无从追查。相关成本治理思路见 LLM 成本优化 与 FinOps 成本智能 。

三、统一 API 与协议适配

网关对外暴露一套统一 API(通常对齐 OpenAI 的 /v1/chat/completions),对内适配各家差异。

3.1 差异适配表

差异点OpenAIAnthropic自托管 vLLM
请求格式messagesmessages + system 独立兼容 OpenAI
系统提示role: system顶层 system 字段role: system
流式格式SSE data:SSE event: 类型SSE data:
工具调用tools/tool_callstools/tool_usetools
停止条件stopstop_sequencesstop
Token 计数usageusageusage
# 网关内部:把统一请求翻译成各家格式
def to_anthropic(req):
    system = [m["content"] for m in req["messages"] if m["role"] == "system"]
    msgs = [m for m in req["messages"] if m["role"] != "system"]
    return {
        "model": req["model"],
        "system": system[0] if system else None,
        "messages": msgs,
        "max_tokens": req.get("max_tokens", 1024),
        "stop_sequences": req.get("stop", []),
    }

3.2 流式转发的坑

流式(SSE)转发比非流式难得多:

流式转发的关键点:
□ 逐块转发,别缓冲整个响应(否则失去流式意义)
□ 统一 SSE 事件格式(各家 event 名不同)
□ 客户端断连时及时取消上游请求(省算力)
□ 计费:流式下 token 数从 usage 或累计块推算
□ 超时:流式请求的超时应是「首块超时 + 空闲超时」双阈值

工程要点:统一 API 的难点不在「转发」,而在**「语义对齐」**——工具调用、流式事件、停止条件这些细节各家不一致,适配层要仔细处理边界。流式转发尤其要防「缓冲放大」:网关一旦把整个响应缓起来再发,就退化成非流式了。客户端断连要能及时取消上游,否则白烧 GPU。

四、限流、配额与成本归因

网关是执行「谁用多少、花多少」的天然位置。

4.1 多级限流

限流维度(从粗到细):
□ 全局:保护整个网关不被打爆
□ 租户/API Key:防单租户挤占
□ 模型:某模型的总并发上限
□ 请求级:单请求 max_tokens 上限(防超长生成)

限流算法:
□ 令牌桶:允许突发,适合交互
□ 漏桶:平滑输出,适合保护后端
□ 滑动窗口:精确计数,适合配额
□ 并发信号量:限制同时在飞请求数(LLM 最常用)
# 配额配置示例
tenants:
  - id: team-a
    rpm: 600          # 每分钟请求
    tpm: 200000       # 每分钟 token
    concurrent: 32    # 最大并发
    models: ["gpt-4o", "fast"]
    monthly_budget_usd: 2000

4.2 成本归因

网关天然掌握「谁、用了哪个模型、多少 token」,是成本归因的最佳采集点:

归因维度用途
按租户/团队内部结算、预算控制
按模型选型评估、路由优化
按接口/功能找出「烧钱大户」
按缓存命中量化缓存节省
成本计算(网关侧):
cost = input_tokens × 单价_in + output_tokens × 单价_out
按租户累加 → 与预算对比 → 超限告警/限流
→ 单位经济学($/1K 请求、$/用户)可反推定价

工程要点:限流要**「多级 + 按并发」**。LLM 请求耗时长、并发数比 QPS 更能反映后端压力,所以「并发信号量」是最有效的限流手段。成本归因要在网关做,因为只有这里同时知道「调用方」和「token 消耗」;缺少这层,成本永远是笔糊涂账。

五、高可用与故障转移

网关本身不能成为单点。它承载着「所有 AI 流量」,挂了就是全站 AI 不可用。

高可用设计要点:
□ 网关无状态化 → 多副本水平扩展 + 负载均衡
□ 配置外置(DB/配置中心)→ 副本共享路由规则
□ 优雅重启 → 在飞请求不中断
□ 依赖隔离 → 缓存/计费挂了不阻塞主链路

故障转移策略:
□ 重试:同后端换副本重试(幂等前提下)
□ 降级:大模型不可用 → 路由到小模型兜底
□ 熔断:错误率超阈值 → 摘除该后端,定期半开试探
□ 超时分层:连接超时 / 首块超时 / 总超时
# 熔断器概念示意
class Breaker:
    def __init__(self, threshold=0.5, window=60):
        self.fail, self.total, self.state = 0, 0, "closed"
    def call(self, fn):
        if self.state == "open":
            raise BackendUnavailable()
        try:
            r = fn(); self._ok(); return r
        except Exception:
            self._fail()
            if self.fail / max(self.total, 1) > self.threshold:
                self.state = "open"      # 熔断,走降级
            raise
降级链示例:
主模型(GPT-4o) → 备用(Claude) → 小模型(本地 7B) → 静态兜底话术
每一级都设超时与熔断,避免「降级也超时」拖垮整体

工程要点:故障转移的核心是**「预设降级链 + 快速熔断」**。别指望「重试就能解决」——供应商整体故障时重试只是浪费超时时间。熔断要「快」(几秒内摘除)+「会恢复」(半开试探)。降级链要提前配置并演练,线上第一次遇到故障才现想降级方案必然手忙脚乱。

六、可观测性与灰度

网关是所有 AI 请求的必经之路,天然是观测的最佳埋点位置。

网关侧必采指标:
□ 请求量 / 错误率 / 延迟(按模型、租户、路由规则分维度)
□ 各后端健康度(成功率、P99 延迟、熔断状态)
□ 缓存命中率(精确 + 语义)
□ token 消耗与成本(按租户/模型)
□ 路由分布(各后端承接了多少流量)
□ 限流触发次数(谁被限了、限了多少)
灰度发布:
□ 新模型/新提示词按流量比例灰度(如 5%)
□ 对比新旧版本的质量与成本指标
□ 支持按租户/用户定向放量
□ 出问题一键回滚(路由配置切回旧版本)

这些指标应接入统一的 LLM 服务可观测性 体系,与后端引擎的 GPU 指标形成端到端视图。网关的多租户与配额设计,与 多 LoRA 推理服务 的多租户隔离思路一致。

七、速查表与一句话记忆

问题一句话答案
网关做什么收敛鉴权/路由/限流/计费/故障转移等横切关注点
网关不做什么提示词工程、模型推理、重业务逻辑
路由策略静态 / 成本性能 / 语义 / 负载健康,四类组合
统一 API对齐 OpenAI 格式,适配层处理各家差异
流式难点逐块转发、统一事件格式、断连取消上游
限流多级 + 按并发(并发信号量最有效)
成本归因网关采集(同时知道调用方与 token 消耗)
高可用无状态多副本 + 配置外置 + 优雅重启
故障转移重试 → 降级链 → 快速熔断 + 半开恢复
观测埋点网关是所有 AI 流量的必经之路

一句话记忆:LLM 网关 = 统一入口(协议适配)+ 四类路由(静态/成本/语义/负载)+ 多级限流与成本归因 + 降级链与熔断 + 全程可观测——「收敛横切关注点,别做成胖网关」。

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「ai」更多文章

  1. 排序学习与搜索召回排序系统
  2. 数据版本控制与血缘:DVC 与 LakeFS
  3. 模型可解释性:SHAP、LIME 与注意力归因