1. 从一个真实困境说起:为什么传统网关接不住大模型流量
去年帮一个团队做技术咨询,他们的情况很有代表性。后端有七八个微服务,前面挂着一套传统的 API 网关做鉴权、限流、路由转发,跑了一年多一直挺稳。后来产品要加 AI 能力,接入了大模型做智能问答和文档摘要,问题就来了——原本那套网关在大模型面前几乎成了摆设。
具体表现是什么?传统网关的限流是按请求数算的,比如每秒 100 个请求。但大模型的一次调用和一次普通接口调用完全不是一个量级:普通接口可能 50 毫秒返回 2KB 数据,大模型一次流式输出可能持续 30 秒、吐出几千个 token。按请求数限流,10 个并发的大模型请求就能把后端推理服务打满,而网关还觉得“才 10 个请求,远没到 100 的阈值”。这就是典型的计量单位错配。
更麻烦的是流式响应。大模型普遍采用 SSE(Server-Sent Events)做流式输出,让用户看到文字一个个蹦出来。传统网关很多是按“请求-响应”完整周期设计的,遇到长连接流式响应,要么缓冲住整个响应再转发(用户等半天没反应),要么超时断开(回答到一半断了)。再加上 token 计费、多模型路由、提示词安全过滤这些新需求,传统网关的插件体系根本无从下手。
Apache APISIX 的 AI 网关能力就是冲着这些痛点来的。它没有另起炉灶搞一套新东西,而是在原有 APISIX 网关的基础上,通过一系列 AI 相关插件,把大模型流量的特殊性吃透了。这篇文章我会从实际落地角度,把 APISIX AI 网关的核心机制、关键插件、配置细节和踩坑经验完整拆一遍。不管你是正在选型 AI 网关,还是已经在用 APISIX 想接入大模型,都能拿到可以直接参考的东西。
2. APISIX 做 AI 网关的底层逻辑:它凭什么能接住大模型
2.1 不是新网关,而是插件层的定向增强
很多人一听“AI 网关”以为是独立产品,其实 APISIX 的思路很务实:网关该干的活(路由、鉴权、限流、可观测)一样不变,只是针对大模型流量的特性,在插件层做定向增强。这个定位很关键,因为它意味着你不需要为了接大模型把现有网关架构推倒重来。
APISIX 本身基于 NGINX 和 OpenResty,底层用 Lua 做插件扩展,天然支持高并发和长连接。它的插件机制是热加载的,加一个 AI 插件不需要重启网关。这一点在 AI 场景下特别重要——大模型相关的需求变化极快,今天要加个新模型供应商,明天要改提示词过滤规则,如果每次都要重启网关,线上根本受不了。
从架构上看,APISIX 处理 AI 流量的链路是这样的:客户端请求进来,先过常规的路由匹配和鉴权插件,然后进入 AI 专属插件链,包括请求改写(比如统一不同厂商的请求格式)、模型路由(按策略选后端)、流式代理(处理 SSE)、token 计量、响应过滤等,最后转发到实际的大模型服务。整条链路对客户端是透明的,客户端只管按标准格式发请求。
2.2 大模型流量和普通 API 流量的四个本质差异
要理解 APISIX 为什么这么设计,得先搞清楚大模型流量到底特殊在哪。我总结了四个核心差异,这也是选型和配置时最容易踩坑的地方。
第一,响应是流式的、长时的。普通 API 是“请求-响应”瞬时完成,大模型是持续几十秒的流式输出。这要求网关必须支持流式代理,不能缓冲整个响应体。APISIX 通过ai-proxy系列插件配合底层的流式转发能力,能做到边收边转,用户端能实时看到 token 逐个出现。
第二,计量单位是 token 不是请求数。一次请求可能消耗几十个 token,也可能消耗几千个。按请求数限流完全失真。APISIX 的 AI 插件支持在响应流中解析 usage 字段,统计 prompt tokens 和 completion tokens,据此做限流和配额。
第三,请求和响应的格式因厂商而异。OpenAI、Anthropic、国内各家大模型的 API 格式都不一样,字段名、鉴权方式、流式协议细节都有差异。如果每个业务都自己适配,重复劳动巨大。APISIX 的ai-proxy插件做的就是协议归一化——客户端统一按一种格式发,插件负责翻译成目标厂商的格式。
第四,安全边界扩大了。传统 API 的安全主要是鉴权和防注入,大模型还多了提示词注入、敏感信息泄露、模型滥用等风险。这需要在网关层做请求内容检查和响应内容过滤。
2.3 插件协同的工作流:一次 AI 请求在 APISIX 里经历了什么
我把一次典型的大模型请求在 APISIX 里的完整旅程拆一下,这样你能清楚每个插件在哪个环节起作用。
请求进来后,首先是常规的路由匹配,根据 URI 或 Header 找到对应的 Route。然后进入 AI 插件链:ai-proxy或ai-proxy-multi负责把客户端请求转换成目标大模型的格式,同时处理鉴权头(把网关持有的 API Key 注入进去,客户端不需要知道真实 Key)。如果是多模型场景,ai-proxy-multi还会根据负载均衡策略或故障转移规则选一个健康的模型实例。
请求转发出去后,大模型开始流式返回。这时候ai-proxy的流式处理逻辑接管,逐块解析 SSE 数据,一边转发给客户端,一边提取 usage 信息。如果配置了ai-rate-limiting,它会根据累计的 token 消耗判断是否超限。响应结束后,如果有内容过滤插件,会对完整响应做一次检查。
整个过程中,ai-proxy是核心,其他插件围绕它做增强。这种设计的好处是职责清晰,你可以按需组合,不需要的插件不启用,不增加额外开销。
3. 核心插件逐个拆:ai-proxy 系列到底怎么配
3.1 ai-proxy:单模型接入的最小可用配置
ai-proxy是接入单个大模型的基础插件。它的核心作用是请求格式转换 + 鉴权注入 + 流式代理。我拿接入一个 OpenAI 兼容接口的模型举例,配置大概长这样:
plugins: ai-proxy: provider: openai auth: header: Authorization: "Bearer sk-xxxxxxxx" options: model: gpt-4o-mini override: endpoint: "https://api.example.com/v1/chat/completions"这里有几个点值得展开说。provider字段决定了请求和响应的转换规则,APISIX 内置了 openai、anthropic、azure-openai 等常见 provider 的适配。auth.header是网关侧持有的真实密钥,客户端请求里不需要带,这样密钥不会暴露到前端。override.endpoint允许你指向任意兼容 OpenAI 协议的端点,国内很多模型服务都提供 OpenAI 兼容接口,改这个字段就能接。
实测下来,最容易出问题的是model字段的传递。有些客户端会在请求体里自带 model 参数,如果和插件配置的冲突,行为取决于 provider 的实现。我的建议是统一在插件侧配置 model,客户端请求体里不要带,避免歧义。
3.2 ai-proxy-multi:多模型路由与故障转移的实战配置
单模型接入简单,但生产环境很少只用一个模型。可能是为了成本(简单问题走便宜模型,复杂问题走贵模型),可能是为了可用性(主模型挂了自动切备用),也可能是为了合规(不同地区走不同模型)。ai-proxy-multi就是干这个的。
它的配置核心是instances列表,每个实例是一个独立的模型端点,配合balancer做负载策略:
plugins: ai-proxy-multi: balancer: type: chash hash_on: header key: x-model-tier instances: - name: primary provider: openai weight: 1 auth: header: Authorization: "Bearer sk-primary" options: model: gpt-4o - name: fallback provider: openai weight: 1 auth: header: Authorization: "Bearer sk-fallback" options: model: gpt-4o-minibalancer.type支持roundrobin、chash、least_conn等。上面这个例子用chash按请求头x-model-tier做一致性哈希,客户端可以通过这个头指定走哪个档位的模型。如果不指定,就按权重轮询。
故障转移这块要注意:ai-proxy-multi的重试逻辑和普通 upstream 重试不一样。大模型请求重试成本很高(可能已经消耗了 token),所以默认的重试策略要谨慎。我一般会把重试次数设得很低,并且只对连接失败这类明确错误重试,不对超时重试——因为超时可能意味着模型正在生成,重试会导致重复计费。
3.3 流式响应处理:SSE 转发里那些文档没写的细节
流式响应是 AI 网关的命门。APISIX 处理 SSE 的关键在于不缓冲、逐块转发。但实际配置中有几个细节文档里不会重点讲。
首先是proxy_buffering必须关掉。APISIX 底层是 NGINX,如果 buffering 开着,NGINX 会攒够一定大小才转发,用户端就会看到“卡一下蹦一大段”而不是流畅输出。在 Route 或上游配置里要确保proxy_buffering: false。
其次是超时设置。大模型生成慢的时候,单个 chunk 之间可能间隔好几秒。如果proxy_read_timeout设得太短(默认 60 秒),长回答会被中途掐断。我一般会把它设到 300 秒以上,具体看业务的最长回答时长。
还有一个坑是chunk 边界处理。SSE 数据是按\n\n分隔的事件块,但 TCP 传输不保证边界对齐,一个事件块可能被拆到两个 TCP 包里。APISIX 的流式解析器会做缓冲重组,但如果你的自定义插件也要解析流,必须自己处理这种边界情况,不能假设每次收到的都是完整事件。
3.4 token 计量与限流:怎么算准每一次调用的成本
token 计量是 AI 网关区别于普通网关的核心能力之一。APISIX 的做法是在流式响应中解析每个 chunk,从最后一个包含 usage 的 chunk 里提取 token 数。OpenAI 的流式响应默认不在每个 chunk 里带 usage,需要请求时加stream_options: {include_usage: true},APISIX 的 ai-proxy 插件会自动处理这个参数。
拿到 token 数之后,ai-rate-limiting插件可以按 token 维度做限流。配置大概是:
plugins: ai-rate-limiting: limit_strategy: total_tokens limit: 100000 time_window: 3600 rejected_code: 429这表示每小时最多消耗 10 万 token。超过就返回 429。相比按请求数限流,这个粒度准确得多。
但这里有个实测中的坑:如果流式响应中途断开(客户端主动取消或网络问题),usage 可能拿不到,这次调用的 token 就统计不到。APISIX 对这种情况有兜底估算,但估算值和实际值可能有偏差。如果你的计费非常敏感,建议在业务层也做一次对账。
4. 把 AI 网关跑起来:从环境准备到验证的完整链路
4.1 环境准备:版本选择和依赖确认
APISIX 的 AI 插件能力是在较新版本里逐步完善的,我建议至少用 3.9 以上的版本,AI 插件生态比较完整。安装方式看你的习惯,Docker 最快:
docker run -d --name apisix \ -p 9080:9080 -p 9180:9180 \ -v $(pwd)/config.yaml:/usr/local/apisix/conf/config.yaml \ apache/apisix:3.9.0-debian9180是 Admin API 端口,用来动态配置路由和插件,9080是数据面端口,业务流量走这里。生产环境记得把 Admin API 的访问控制做好,默认的 admin key 一定要改。
依赖方面,AI 插件本身不需要额外装什么,但如果要用到一些高级的请求改写能力,可能需要确认lua-resty-*相关库的版本。Docker 镜像里这些都是打包好的,自己编译安装的话要留意。
4.2 配置一个可用的 AI 路由:分步骤操作
第一步,创建一个 Upstream 指向大模型服务。如果你用的是外部 API,其实可以跳过 Upstream,直接在插件里用override.endpoint指定。但如果要做健康检查或负载均衡,还是建一个 Upstream 更规范。
第二步,创建 Route 并挂载 AI 插件。通过 Admin API 操作:
curl http://127.0.0.1:9180/apisix/admin/routes/ai-chat \ -H "X-API-KEY: your-admin-key" \ -X PUT -d ' { "uri": "/v1/chat/completions", "methods": ["POST"], "plugins": { "ai-proxy": { "provider": "openai", "auth": { "header": { "Authorization": "Bearer sk-your-real-key" } }, "options": { "model": "gpt-4o-mini" } } } }'第三步,验证。用 curl 发一个流式请求:
curl http://127.0.0.1:9080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "用一句话解释什么是API网关"}], "stream": true }'如果配置正确,你会看到 SSE 格式的流式输出,每个 chunk 是一段 JSON。注意请求体里不需要带 model 和 Authorization,这些都由网关侧处理了。
4.3 验证清单:怎么确认流式、计量、路由都正常
配完之后别急着上生产,按这个清单逐项验证:
| 验证项 | 方法 | 预期结果 |
|---|---|---|
| 流式转发 | curl 加stream:true,观察输出 | 逐块实时输出,无长时间卡顿 |
| 鉴权注入 | 请求不带 Authorization | 正常返回,说明网关侧密钥生效 |
| 模型路由 | 请求带x-model-tier头 | 按配置路由到对应模型 |
| token 计量 | 查看 APISIX 日志或监控 | 有 usage 统计输出 |
| 限流生效 | 短时间内大量请求 | 超过阈值返回 429 |
| 故障转移 | 故意配错主模型密钥 | 自动切到备用实例 |
这个清单我每次上线前都会过一遍,尤其是故障转移,一定要主动制造故障验证,不能假设它一定生效。
5. 生产环境才会暴露的问题:我踩过的坑和排查思路
5.1 流式响应被缓冲:一个排查了两小时的配置问题
有次上线后用户反馈“AI 回答要等十几秒才一次性出现”,完全不是流式效果。第一反应是插件配置问题,检查了ai-proxy的配置没发现异常。然后怀疑是客户端问题,换了个 curl 测试,还是缓冲。
排查链路是这样的:先确认 APISIX 到上游的请求是不是流式的——抓包看,上游确实在逐块返回。那问题就在 APISIX 到客户端这一段。检查 NGINX 层面的配置,发现 Route 继承的全局配置里proxy_buffering是默认的on。虽然 AI 插件内部有处理,但 NGINX 的 buffering 在更底层生效,把流式数据攒起来了。
修复很简单,在 Route 级别显式关掉:
{ "proxy_buffering": false }这个坑的教训是:AI 插件的流式能力依赖底层 NGINX 配置配合,不能只看插件文档。上线前一定要用真实的长回答测试流式效果。
5.2 token 统计对不上:流式中断和并发场景的边界
另一个坑是 token 统计。运营那边对账发现网关统计的 token 消耗和模型厂商账单对不上,差了大概 5%。排查后发现两个原因。
一是流式中断。用户点了“停止生成”或者网络抖动导致连接断开,这时候最后一个带 usage 的 chunk 可能没收到,这次调用的 token 就漏统计了。APISIX 有估算兜底,但估算基于已收到的内容,和实际生成的可能有差异。
二是并发下的统计聚合。高并发时多个请求的 token 统计如果写同一个计数器,可能有竞争。APISIX 用的是共享内存字典,原子性有保障,但如果你的监控系统拉取频率太高,可能读到中间状态。
应对办法:对计费敏感的场景,在业务层做二次对账,以模型厂商的账单为准,网关统计作为实时参考。不要完全依赖网关的 token 数做最终计费。
5.3 多模型路由的故障转移:为什么备用模型没被触发
配置了主备两个模型,主模型挂了但流量没切到备用,这是很常见的问题。原因通常有几个。
最常见的是健康检查没配。ai-proxy-multi的故障转移依赖上游健康状态,如果你没配主动健康检查,它不知道主模型已经挂了,还会继续往那边发。要配上health_check配置,定期探测。
第二个原因是错误类型判断。有些错误(比如 429 限流)不应该触发故障转移,因为备用模型可能也限流。APISIX 默认的转移策略对错误码有区分,但如果你自定义了重试逻辑,可能覆盖了默认行为。
第三个原因是超时设置。主模型如果只是慢而不是完全不可用,在超时之前不会触发转移。这时候用户会一直等。我的做法是给主模型设一个合理的超时,超过就快速失败切备用,宁可切换也不要让用户干等。
5.4 提示词注入防护:网关层能做什么、不能做什么
安全方面,网关层能做的是基于规则的初步过滤,比如检测请求里有没有明显的注入模式、敏感词。APISIX 可以通过自定义插件或请求改写插件实现。但要说清楚:网关层做不了深度的语义级防护,那需要专门的模型或服务。
我的实践是在网关层做两道:一是长度和格式校验,挡住明显异常的请求;二是关键词黑名单,挡住已知的注入模式。真正的深度防护放在业务层,用专门的提示词安全模型做二次检查。网关层的定位是“快速挡住低级攻击,减轻后端压力”,不要指望它解决所有安全问题。
6. 从能用到好用:性能调优和可观测性建设
6.1 高并发下的连接池和超时调优
大模型请求是长连接、长耗时,连接池配置和普通 API 完全不同。普通 API 可能几百毫秒就释放连接了,大模型一个连接要占几十秒。如果连接池太小,高并发时请求会排队等连接。
关键参数是keepalive_pool的size和idle_timeout。size 要根据你的并发量估,经验值是峰值并发的 1.5 倍左右。idle_timeout 要大于模型的最长响应时间,否则连接还没用完就被回收了。
超时方面,connect_timeout可以短(几秒),但read_timeout和send_timeout要长(几分钟)。这三个要分开设,不能一刀切。
6.2 日志和指标:怎么知道每个模型花了多少钱
可观测性是 AI 网关容易被忽视但极其重要的一环。你至少要知道:每个模型被调用了多少次、消耗了多少 token、平均响应时间多少、错误率多少。
APISIX 的日志插件可以把这些信息打到访问日志里。关键是在日志格式里包含 token 和模型信息。ai-proxy插件会把 usage 信息放到请求上下文里,日志插件可以引用。配合 Prometheus 插件,还能把这些做成指标,接 Grafana 看板。
我一般会建几个核心看板:按模型的 token 消耗趋势、按用户的调用分布、错误率和延迟的 P99。这几个指标能覆盖大部分运营和排障需求。
6.3 成本控制的几个实用手段
最后聊聊成本。大模型调用是真金白银,网关层能做不少成本控制的事。
一是按用户或租户做 token 配额,防止单个用户刷爆。二是模型分级路由,简单请求走便宜模型,复杂请求走贵模型,通过请求特征自动判断。三是缓存,相同或相似的请求直接返回缓存结果,APISIX 有缓存插件可以配合。四是请求合并,把多个小请求合并成一次大请求,减少调用次数。
这些手段组合起来,实测能省下不少成本。但要注意缓存对 AI 场景的适用性——大模型输出有随机性,缓存要谨慎,一般只对确定性强的场景(比如固定问题的标准回答)用。
7. 我对 APISIX AI 网关的真实评价和选型建议
用下来这段时间,我的整体判断是:APISIX 做 AI 网关的思路是对的,它没有为了 AI 把网关搞成一个四不像,而是在成熟的网关能力上做定向增强。插件化的设计让接入成本很低,流式处理和 token 计量这两个核心能力也做得比较扎实。
但它也不是银弹。如果你的场景非常简单,就接一个模型、并发也不高,那直接用官方 SDK 可能更省事,没必要上网关。网关的价值在多模型管理、统一鉴权、集中限流、可观测性这些规模化场景下才体现得明显。
选型时我建议重点看三件事:一是流式处理是否真的无缓冲,这个一定要实测;二是 token 计量的准确性,尤其是异常场景下的兜底;三是多模型路由的故障转移是否可靠。这三点是 AI 网关的核心竞争力,其他都是锦上添花。
最后分享一个我自己的习惯:每次接入新模型,先不配任何高级插件,就用最简配置跑通流式对话,确认基础链路没问题,再逐步加限流、路由、过滤。这样出问题时排查范围小,不会一上来就被一堆插件配置绕晕。AI 网关的配置项比普通网关多不少,循序渐进比一步到位靠谱得多。