为什么越来越多人用AI Gateway?
内容概览: AI Gateway 的价值,不是把一次模型调用多经过一个代理,而是把多模型路由、密钥、配额、成本、安全和可观测性从各个业务系统里收拢出来。本文结合主流实现、配置示例和 Java 接入方式,说明它为什么正在成为 AI 应用的基础设施。
最近缺项目经历想快速提升项目实战能力(包含多个AI项目),或者最近找工作,或者想学习AI的小伙伴,可以看看下面👇🏻的这个链接(或许真的能够帮到你)。
前言
假设一家公司最初只有一个智能客服接入了大模型。
那时候代码很直接:业务服务里放一个 SDK,配置一个 API Key,选一个模型,能回答问题就行了。可是过了半年,推荐系统、知识库、代码助手和内容审核都开始用模型,供应商从一家变成三四家,团队从一个人变成五六个小组,老板还开始追问:每个月到底花了多少 Token?哪个租户用得最多?模型挂了能不能自动切?
这时候再去每个项目里复制一套鉴权、重试、限流和日志逻辑,维护成本会很快失控。
AI Gateway 正是在这个阶段进入视野的。
有些小伙伴第一次听到这个名字,可能会觉得它只是又一层反向代理。
它不是一个突然出现的新协议,也不是把请求转发一下那么简单。它真正解决的是 AI 流量从“单个应用接一个模型”走向“多个团队使用多个模型”之后,缺少统一控制面的问题。
今天这篇文章就专门跟大家一起聊聊 AI Gateway,希望对你会有所帮助。
先看整体位置。业务应用不再直接持有所有厂商密钥,而是通过 AI Gateway 访问主模型和备用模型:
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart LR
subgraph Apps["业务应用"]
A1["客服"]:::primary
A2["推荐"]:::primary
A3["审核"]:::primary
end
Gw["AI网关"]:::warning
subgraph Control["治理能力"]
Key["密钥中心"]:::success
Quota["配额中心"]:::danger
Metric["观测平台"]
end
subgraph Models["模型提供方"]
M1["主模型"]:::success
M2["备用模型"]
M3["本地模型"]:::warning
end
A1 --> Gw
A2 --> Gw
A3 --> Gw
Gw --> Key
Gw --> Quota
Gw --> Metric
Gw --> M1
Gw --> M2
Gw --> M3
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 1:AI Gateway 位于业务应用和模型提供方之间,承担统一接入与治理。
下面咱们从直连为什么失控开始,一层层拆开。
1 直连大模型,最开始为什么没问题?
一个应用只接一家模型时,直连其实很合理。
请求链路短,排查简单,SDK 也足够成熟。为了偶尔出现的供应商故障,提前引入一套网关,反而会增加部署和维护成本。
问题出在规模变化以后。
有些小伙伴可能会说,多加几个 SDK 依赖不就行了?
每多一个模型供应商,就多一套鉴权方式、错误码、流式协议、限流规则和计费口径。每个业务团队再各写一遍超时与重试,最后没人能回答三个基本问题:
- 这次请求到底走了哪个模型?
- 哪个租户消耗的 Token 最多?
- 模型切换后,为什么只有一部分业务表现异常?
直连并没有错,错在把平台级问题分散到了每个业务服务里。
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart TB
subgraph Direct["直连模式"]
A1["客服"]:::primary --> K1["厂商密钥"]:::danger
A2["推荐"]:::success --> K2["另一密钥"]:::warning
A3["审核"]:::warning --> K3["本地SDK"]
end
subgraph Unified["网关模式"]
B1["多个应用"]:::primary --> G["AI网关"]:::warning
G --> P["模型池"]:::success
end
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 2:AI 应用从直连厂商 SDK,逐步演进到统一接入和集中治理。
这也是“越来越多人用”的工程背景。不是因为所有项目都必须上 AI Gateway,而是多模型、多团队和成本治理一旦同时出现,平台层就需要一个统一入口。
2 AI Gateway 到底管什么?
先给一个我比较认可的定义:
AI Gateway 是面向模型调用的流量与治理层,它把供应商差异、访问控制、配额、路由、流式响应和观测数据统一到一个入口。
它和普通 API Gateway 有重叠,但不能简单画等号。
| 维度 | 普通 API Gateway | AI Gateway |
|---|---|---|
| 请求对象 | HTTP API | Chat、Embedding、Rerank、工具调用 |
| 鉴权 | 服务、用户、应用 | 虚拟密钥、租户、模型权限 |
| 配额 | QPS、连接数、请求数 | RPM、TPM、Token 预算、并发数 |
| 路由 | Host、Path、Header | 模型别名、健康度、延迟、成本、能力 |
| 流式处理 | 代理 SSE 字节流 | 识别首字、Token、结束和取消 |
| 可观测性 | 状态码、耗时 | 模型、Token、首字延迟、成本、回退 |
| 内容治理 | 通用 WAF | Prompt 防护、脱敏、审计、缓存作用域 |
普通网关看到的是一个 HTTP 请求。
AI Gateway 还要理解这个请求的模型、Token、流式状态和供应商约束。差异主要在这里。
看到这里,有些小伙伴可能会问:那是不是所有请求都必须经过 AI Gateway?
也不是。后面咱们会单独聊适用边界,先把它的能力看清楚。
一次完整的 AI 请求通常会经过下面这些阶段:
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart LR
A["请求接入"]:::primary --> B["虚拟密钥"]:::warning
B --> C["权限检查"]:::success
C --> D["预算预留"]:::danger
D --> E["模型路由"]
E --> F["模型调用"]:::primary
F --> G["流式返回"]:::warning
G --> H["Token结算"]:::success
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 3:AI Gateway 的请求链路,覆盖鉴权、配额、路由、模型调用、流式返回和计费审计。
需要说明一点:AI Gateway 并不是一个有统一 RFC 的标准协议。LiteLLM、Kong、Envoy AI Gateway、Apache APISIX 等产品的实现重点并不完全一样,选型时不能只看名字。
比如 LiteLLM 重点提供 OpenAI 兼容的多模型代理、路由和预算;Envoy AI Gateway 把模型接入、凭据、回退和 Token 限制放到 Envoy 的流量体系里;Kong AI Gateway 更强调现有 API 网关上的模型路由、语义缓存、内容治理和观测;Apache APISIX 的 AI 插件 则围绕 ai-proxy、缓存、Token 限流和 Prompt 防护展开。
3 多模型路由,才是最主要的动力
业务代码直接写死模型名,会带来一个很现实的问题:换模型等于改代码、重新测试、重新发布。
AI Gateway 通常会在中间加一层“模型别名”。
应用始终请求 chat-default,网关再把别名映射到具体供应商和模型。今天背后是 A 模型,明天换成 B 模型,业务代码不用知道。
路由策略也不只是随机选一个。
真正进入生产后,会同时考虑模型健康度、首字延迟、最近错误率、租户剩余额度、上下文长度、是否支持工具调用、区域合规和单次调用成本。
有小伙伴可能会问,模型别名是不是就能把供应商差异全部抹平?
答案是没有这么简单。下一段就会讲到兼容性的边界。
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart LR
A["健康度"] --> R["评分排序"]:::warning
B["首字延迟"] --> R
C["Token成本"] --> R
R --> S["选择模型"]:::success
S --> M1["主模型"]
S --> M2["备用模型"]:::primary
M1 --> E["统一响应"]:::danger
M2 --> E
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 4:模型别名把业务请求和具体供应商解耦,主模型异常时可以进入备用路径。
下面是一份 LiteLLM 的配置示意。它把多个部署挂在同一个模型别名下,并为整个别名配置备用模型:
model_list:
- model_name: chat-default
litellm_params:
model: openai/gpt-4o-mini
api_key: os.environ/OPENAI_API_KEY
- model_name: chat-default
litellm_params:
model: deepseek/deepseek-chat
api_key: os.environ/DEEPSEEK_API_KEY
- model_name: chat-backup
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY
router_settings:
routing_strategy: simple-shuffle
fallbacks:
- chat-default: [chat-backup]这是一份依赖供应商和模型 ID 的配置示例,不是脱离环境的完整部署文件。实际使用时,还要配置代理密钥、数据库、日志和健康检查。
LiteLLM 官方文档把它定位为统一调用 100+ LLM 的 OpenAI 兼容代理,并提供负载均衡、回退、预算和用量追踪。这个能力组合正好对应多模型应用最头疼的几件事。
但要说清楚:模型别名解决不了所有兼容性问题。
工具调用格式、结构化输出、推理内容、图片输入和多模态返回,在不同供应商之间仍然有差异。网关能做转换,但转换不是免费的,也不保证每个高级能力都能无损互通。
涉及工具调用和严格 JSON Schema 的业务,必须逐个模型做契约测试。
4 Token 配额和成本治理,不能只看请求数
普通接口限制 QPS,通常够用。
大模型不行。
有些小伙伴做限流时,只数每分钟进来了多少个请求。
同样是一次请求,可能只输入几十个 Token,也可能塞进几万字上下文;一次回答可能只有一句话,也可能持续输出几千 Token。只限制请求次数,预算很容易被少量大请求吃光。
AI Gateway 一般会围绕虚拟密钥和租户做多层限制:
最近缺项目经历想快速提升项目实战能力(包含多个AI项目),或者最近找工作,或者想学习AI的小伙伴,可以看看下面👇🏻的这个链接(或许真的能够帮到你)。
- 每分钟请求数。
- 每分钟 Token 数。
- 单次最大输入和输出 Token。
- 每日、每月成本预算。
- 同时在途请求数。
- 指定模型或供应商的访问权限。
这里有个细节很容易做错。
请求开始前,输出 Token 还不知道。网关通常要先预估一个上限,预留预算,等响应结束后再按实际用量结算。流式请求更是如此,直到最后一个事件,网关才可能拿到完整的 usage。
所以“预算检查”不是一次简单计数,而是“预留、结算、释放”三件事。
如果网关只做请求级限流,不做 Token 预算,账单依然可能失控。
5 流式请求,最容易把重试做错
聊天接口和普通 REST 接口最大的区别之一,是长时间保持连接。
有些小伙伴以为流式请求只是把 Content-Type 改成事件流,代理层转发字节流就行了。
用户看到第一个字之前,网关当然可以尝试另一个供应商。可一旦已经向客户端写出了第一段回答,再静默切换模型就很危险。
客户端可能把两个模型的回答拼在一起,用户会看到重复甚至互相矛盾的内容;供应商侧也可能产生两次计费。
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart LR
A["发起请求"]:::primary --> B["等待首字"]:::warning
B -->|"超时"| C["允许重试"]:::success
B -->|"拿到首字"| D["已返回"]:::danger
D -->|"连接中断"| E["禁止静默重试"]
D -->|"正常完成"| F["结束响应"]:::primary
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 5:流式请求的重试边界,在首字返回前后完全不同。
所以 AI Gateway 至少要区分两个时间点:
- 首字之前:连接失败、限流或供应商报错,可以按策略重试或回退。
- 首字之后:不要偷偷重开一次完整回答,应该明确结束、报错或走业务补偿。
除此之外,还要处理客户端取消、网关超时、下游慢消费者和连接背压。用户关闭页面以后,如果网关仍然继续拉取模型输出,既浪费带宽,也浪费 Token。
流式代理不是把字节从 A 转发到 B 就结束了。
6 安全和可观测性,决定它能不能进生产
密钥集中管理是 AI Gateway 最直接的价值之一。
业务服务拿到的是网关虚拟密钥,真正的供应商密钥只存在网关的密钥管理系统中。某个团队离职、密钥泄露或者供应商轮换,不需要修改所有应用。
这里还得提醒小伙伴们一句:密钥集中以后,网关自己的权限边界更重要。
但这里也带来新的责任。
Prompt 和模型回答里可能包含个人信息、业务数据和工具调用参数。把所有 Prompt 原样打进日志,看起来“方便排查”,实际可能变成新的数据泄露入口。
更稳妥的做法是按租户和用途设置采样、脱敏和保留周期,敏感业务默认不记录完整内容。
下面这些指标比单独的“网关 QPS”更有价值:
| 指标 | 用来回答什么问题 |
|---|---|
| 请求量与错误率 | 哪个应用、模型、租户异常 |
| Time to First Token | 用户多久看到第一段回答 |
| 总响应时间 | 流式请求最终持续多久 |
| 输入/输出 Token | 成本主要由哪里产生 |
| 单次调用成本 | 哪个模型或业务最烧钱 |
| 回退次数 | 主模型是否长期不稳定 |
| 配额拒绝数 | 限额是否合理 |
| 客户端取消率 | 用户是否等不下去 |
语义缓存也要谨慎。
重复 Prompt 做缓存确实能省钱,但缓存 key 必须包含租户、模型、Prompt 版本和权限范围。别人的知识库答案、不同用户的数据,不能只因为问题相似就命中同一份缓存。
7 Java 项目怎么接 AI Gateway?
对 Java 业务来说,最大的好处是供应商切换被收进网关,业务代码只面对一个 OpenAI 兼容入口。
有些小伙伴会问,那是不是引入 AI Gateway 之后,Spring AI 的代码就完全不用关心模型了?
业务代码确实可以只认模型别名,但工具调用、结构化输出和流式事件仍要按网关支持的能力做回归测试。
以 Spring AI 2.0 为例,可以把 base-url 指向网关,把模型名写成网关的模型别名:
spring:
ai:
openai:
base-url: ${AI_GATEWAY_URL:http://localhost:4000/v1}
api-key: ${AI_GATEWAY_KEY}
chat:
options:
model: ${AI_MODEL_ALIAS:chat-default}这里的 api-key 是网关签发的虚拟密钥,不是某一家模型供应商的原始 Key。AI_MODEL_ALIAS 也由网关负责映射。
业务代码仍然使用标准的 ChatClient:
package com.example.ai;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
@Service
public final class GatewayChatService {
private final ChatClient chatClient;
public GatewayChatService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public String ask(String question) {
if (question == null || question.isBlank()) {
throw new IllegalArgumentException("question must not be blank");
}
return chatClient.prompt()
.user(question)
.call()
.content();
}
}这是一个完整的业务类,省略的是依赖配置和 Spring Boot 启动类。使用多个模型 Starter 时,可能还需要显式构造 ChatClient Bean,避免注入歧义。
上线前可以先用一次非流式请求验证网关、虚拟密钥和模型别名:
curl --fail-with-body \
"${AI_GATEWAY_URL}/chat/completions" \
-H "Authorization: Bearer ${AI_GATEWAY_KEY}" \
-H "Content-Type: application/json" \
-H "X-Tenant-Id: tenant-a" \
-d '{
"model": "chat-default",
"messages": [
{"role": "user", "content": "只回复:gateway-ok"}
]
}'X-Tenant-Id 是示例租户头,网关必须提前配置对应策略;不是所有产品默认都支持这个请求头。
返回体符合 OpenAI 兼容格式,只能说明基本请求链路通了。工具调用、流式结束事件、错误码和 usage 字段仍要单独验证。
8 什么时候不该用 AI Gateway?
AI Gateway 不是“上了就更先进”。
只有一个小团队、一个模型、没有多租户和合规要求,直连往往更简单。网关会多一个网络跳点,也多一套需要监控、发布和容灾的系统。
如果你没有能力维护高可用网关,却把所有模型流量都压到一个单实例上,它反而会变成新的单点故障。
如果小伙伴们只是做内部工具或者低频批处理,直连的成本往往更低。
%% Draw.io: Arrange > Insert > Advanced > Mermaid
%%{init: {"themeVariables": {"fontSize": "20px", "fontFamily": "PingFang SC, Microsoft YaHei, Noto Sans SC", "edgeLabelBackground": "transparent"}, "flowchart": {"nodeSpacing": 70, "rankSpacing": 90, "padding": 32, "htmlLabels": true, "labelStyle": "color:#2C2C2C;background:transparent;"}}}%%
flowchart LR
A{"多模型?"}:::warning -->|"是"| G["引入网关"]
A -->|"否"| B{"多租户?"}:::primary
B -->|"是"| G
B -->|"否"| C{"强合规?"}:::danger
C -->|"是"| G
C -->|"否"| D{"统一观测?"}:::success
D -->|"是"| G
D -->|"否"| E["继续直连"]:::danger
classDef default fill:#E1D6E8,stroke:#9A86AD,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef primary fill:#D5E5FA,stroke:#7891B2,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef success fill:#CFE4CF,stroke:#7E9F7E,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef warning fill:#FFE6CD,stroke:#C59A68,color:#2C2C2C,stroke-width:1.5px,filter:none
classDef danger fill:#F7CECD,stroke:#C88585,color:#2C2C2C,stroke-width:1.5px,filter:none
linkStyle default stroke:#6E6E6E,stroke-width:1.5px,filter:none图 6:只有多个治理条件同时出现时,引入 AI Gateway 才划算。
我通常用四个条件判断:
- 是否同时接入两个以上供应商,或者需要频繁切换模型?
- 是否有多个团队、应用或租户需要独立配额与权限?
- 是否需要统一的首字延迟、Token、成本和回退观测?
- 是否有内容安全、审计、密钥集中管理或区域合规要求?
满足两项以上,就值得认真评估。
如果决定使用,生产环境至少要考虑双实例、外部状态存储、密钥托管、超时预算、流式取消、告警和降级。网关不是一个进程,而是一套需要长期维护的基础设施。
总结
AI Gateway 越来越常见,本质上不是大家突然喜欢多一层代理。
真正的原因是 AI 应用从 Demo 走向平台以后,模型调用已经变成跨团队、跨供应商、跨租户的基础能力。密钥、配额、成本、路由、流式响应和审计,继续散落在每个业务服务里,迟早会失控。
我建议记住一句话:AI Gateway 的价值不在于“转发请求”,而在于把模型的不确定性关进一个可治理的边界里。
单模型、小团队可以继续直连;多模型、多租户、重成本和强合规的平台,应该把 AI Gateway 当成基础设施认真设计。
你们项目现在是让业务直接调用模型,还是已经有一个统一的 AI 网关?欢迎小伙伴们在评论区聊聊。
相关阅读
最近缺项目经历想快速提升项目实战能力(包含多个AI项目),或者最近找工作,或者想学习AI的小伙伴,可以看看下面👇🏻的这个链接(或许真的能够帮到你)。
