ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI网关实战:基于Apache APISIX实现大模型流量治理与MCP代理

AI网关实战:基于Apache APISIX实现大模型流量治理与MCP代理 1. 当网关开始“理解”语义AI 网关到底在解决什么问题1.1 从“转发管道”到“智能调度层”的定位转变传统 API 网关的核心职责用一句话概括就是把请求准确地送到后端再把响应准确地送回来。路由匹配、限流熔断、鉴权认证、日志埋点这些能力围绕的都是“流量治理”。在这个阶段网关不需要理解请求体里到底写了什么它只关心 Header、Path、Method 这些元数据。但大模型应用一上来这套逻辑就不够用了。一个典型的 LLM 应用请求体里可能包含几千个 token 的提示词、多轮对话历史、工具调用定义、结构化输出约束。网关如果还是只做“盲转发”就会面临几个很现实的问题成本失控不同请求消耗的 token 数量差异巨大按请求数限流毫无意义必须按 token 计量。模型路由僵化简单问答和复杂推理用同一个模型要么浪费钱要么效果差。安全盲区提示词注入、敏感信息泄露、模型滥用这些风险在传统网关里根本看不见。可观测性缺失只知道请求成功或失败不知道模型返回了什么、消耗了多少、延迟花在哪里。AI 网关要做的就是在传统网关的能力之上增加一层对“语义”的理解和治理。它不再只是转发管道而是变成了大模型流量的智能调度层。1.2 Apache APISIX 为什么适合做这件事Apache APISIX 本身是一个云原生、高性能、可扩展的 API 网关基于 etcd 做配置中心支持动态加载插件底层用 Radixtree 做路由匹配性能在同类产品里属于第一梯队。这些特性让它天然适合作为 AI 网关的底座插件机制成熟APISIX 的插件体系非常灵活可以在请求生命周期的各个阶段插入逻辑。AI 相关的 token 计量、内容审核、模型路由都可以做成插件。多协议支持除了 HTTPAPISIX 还支持 WebSocket、gRPC 等协议。大模型流式输出SSE和 MCP 协议通信都需要网关具备处理长连接和流式数据的能力。动态配置etcd 的 watch 机制让路由和插件配置可以秒级生效不需要重启网关。这对于快速迭代的 AI 应用来说非常关键。生态开放APISIX 社区活跃插件市场里有大量现成能力可以复用同时支持多语言编写插件Lua、Java、Go、Python、Wasm。换句话说APISIX 提供了“网关该有的所有基础能力”而 AI 网关要做的是在这个基础上补齐大模型场景特有的治理逻辑。1.3 一个具体的场景多模型混合调度假设你有一个智能客服系统后端接了三个模型一个便宜但能力一般的小模型一个贵但推理能力强的大模型还有一个专门做意图识别的轻量模型。用户的问题进来后你希望先用轻量模型判断意图简单问题走小模型复杂问题走大模型每个模型的 token 消耗单独计量方便成本核算如果某个模型响应超时自动降级到备用模型所有请求和响应都要做敏感词过滤。这套逻辑如果写在业务代码里会非常臃肿而且每个应用都要重复实现。放在 AI 网关里就变成了几个插件的组合意图识别插件、模型路由插件、token 计量插件、降级插件、内容审核插件。业务代码只需要调用统一的网关入口剩下的交给网关处理。这就是 AI 网关的核心价值把大模型调用的通用治理逻辑从业务代码里抽离出来下沉到网关层。2. 拆开看APISIX AI 网关的核心能力模块2.1 模型代理与协议适配大模型服务商提供的 API 协议并不统一。OpenAI 有一套格式Anthropic 有一套国内各家厂商也各有差异。如果业务代码直接对接多个厂商切换模型时就要改代码。APISIX AI 网关的做法是在网关层做协议适配对外暴露统一的 API 格式。业务代码只需要按照一种格式调用网关根据配置把请求转换成对应厂商的格式再把响应转换回来。具体实现上通常会用到ai-proxy这类插件。它的核心逻辑是解析请求体提取model、messages、temperature等字段根据路由配置把请求转发到对应的上游OpenAI、Anthropic、通义千问等在转发前做 Header 替换比如把统一的 API Key 换成厂商特定的 Key在响应返回时把厂商格式转换成统一格式。这里有一个关键细节流式响应SSE的处理。大模型返回是逐 token 推送的网关不能等整个响应结束再转发必须边收边转。APISIX 基于 OpenResty 的流式处理能力可以在body_filter_by_lua阶段逐块处理响应数据实现真正的流式透传。注意流式场景下token 计量不能等响应结束再统计需要在流式过程中实时累加。这要求插件在body_filter阶段维护状态对性能有一定要求。2.2 Token 计量与成本控制按 token 计费是大模型服务的核心商业模式也是 AI 网关必须解决的问题。传统网关按请求数限流一个请求可能只消耗 10 个 token也可能消耗 10000 个 token粒度太粗。APISIX AI 网关的 token 计量通常分两步请求侧估算在请求转发前对messages内容做 token 估算。不同模型的 tokenizer 不一样但可以用近似算法比如按字符数除以 4快速估算。这一步用于实时限流和配额检查。响应侧精确统计大模型返回的响应里通常包含usage字段里面有精确的prompt_tokens、completion_tokens、total_tokens。网关在响应阶段提取这些数据写入日志或上报到监控系统。基于 token 计量可以实现更精细的限流策略限流维度传统网关AI 网关请求数支持支持Token 数不支持支持并发连接数支持支持模型维度不支持支持用户维度支持支持实际配置时可以用limit-count插件做请求数限流用自定义插件做 token 限流。两者结合既能防止突发流量打垮后端又能控制成本不超预算。2.3 内容安全与提示词防护大模型应用面临的安全风险比传统 API 更复杂。传统 API 的安全主要是鉴权、防重放、防注入SQL 注入等。大模型应用还要面对提示词注入用户输入里包含恶意指令试图覆盖系统提示词。敏感信息泄露模型在响应中输出了不该输出的内容。模型滥用用大模型生成垃圾内容、钓鱼邮件等。APISIX AI 网关可以在请求和响应两个阶段做内容审核请求阶段检查用户输入是否包含敏感词、是否试图注入提示词、是否超出主题范围。可以用正则匹配也可以调用专门的内容审核服务。响应阶段检查模型输出是否包含敏感信息、是否符合合规要求。如果发现违规可以直接拦截并返回预设的兜底话术。这里有一个实操心得内容审核插件不要做成同步阻塞的。如果每次请求都要调用外部审核服务延迟会很高。更好的做法是异步审核 事后拦截或者用本地轻量模型做快速初筛可疑内容再送外部服务精审。2.4 MCP 协议支持与工具调用MCPModel Context Protocol是最近大模型领域的热门话题。简单来说它是一套让大模型能够调用外部工具的协议标准。通过 MCP模型可以访问数据库、调用 API、操作文件系统从而完成更复杂的任务。APISIX AI 网关对 MCP 的支持主要体现在两个方面MCP Server 代理网关可以作为 MCP Server 的统一入口把多个 MCP Server 注册到网关由网关做路由和鉴权。这样模型只需要连接网关就能访问所有工具。工具调用治理模型发起工具调用时网关可以拦截请求做权限校验、参数校验、调用限流。比如某个工具只允许特定用户调用或者某个工具每分钟最多调用 10 次。MCP 协议通常基于 SSE 或 WebSocket 做传输这对网关的长连接处理能力有要求。APISIX 在这块有天然优势它的websocket和sse支持都比较成熟。提示MCP 工具调用的参数校验非常重要。模型生成的参数可能不符合预期如果直接透传给后端服务可能引发错误甚至安全问题。网关层做一层参数 schema 校验能挡掉大部分低级错误。3. 动手搭一个最小可用的 AI 网关3.1 环境准备与 APISIX 安装先准备一台 Linux 机器Ubuntu 22.04 或 CentOS 7 都可以内存建议 4GB 以上因为要跑 etcd 和 APISIX。安装方式用 Docker 最省事也方便清理。# 拉取 APISIX 镜像 docker pull apache/apisix:3.9.0 # 拉取 etcd 镜像 docker pull bitnami/etcd:3.5 # 创建网络 docker network create apisix-net启动 etcddocker run -d \ --name etcd \ --network apisix-net \ -p 2379:2379 \ -e ALLOW_NONE_AUTHENTICATIONyes \ -e ETCD_ADVERTISE_CLIENT_URLShttp://etcd:2379 \ bitnami/etcd:3.5启动 APISIXdocker run -d \ --name apisix \ --network apisix-net \ -p 9080:9080 \ -p 9180:9180 \ -v $(pwd)/config.yaml:/usr/local/apisix/conf/config.yaml \ apache/apisix:3.9.0config.yaml里需要配置 etcd 地址和 Admin API 的 Keydeployment: role: traditional role_traditional: config_provider: etcd admin: admin_key: - name: admin key: edd1c9f034335f136f87ad84b625c8f1 role: admin etcd: host: - http://etcd:2379 prefix: /apisix timeout: 30启动完成后用 curl 测试 Admin API 是否可用curl http://127.0.0.1:9180/apisix/admin/routes \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1如果返回路由列表可能是空的说明网关已经跑起来了。3.2 配置第一个 AI 路由假设我们要代理 OpenAI 的 Chat Completions API。先创建一个上游curl http://127.0.0.1:9180/apisix/admin/upstreams/1 \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -X PUT -d { type: roundrobin, nodes: { api.openai.com:443: 1 }, scheme: https, pass_host: node }然后创建路由绑定ai-proxy插件curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -X PUT -d { uri: /v1/chat/completions, methods: [POST], upstream_id: 1, plugins: { ai-proxy: { provider: openai, auth: { header: { Authorization: Bearer sk-你的APIKey } }, options: { model: gpt-4o-mini } } } }这里有几个关键点pass_host设为node表示转发时 Host 头用上游节点的域名而不是客户端请求的 Host。ai-proxy插件里配置了 OpenAI 的 API Key这样客户端就不需要自己带 Key 了。网关统一管理 Key避免泄露。options.model可以强制指定模型也可以不指定让客户端自己传。测试一下curl http://127.0.0.1:9080/v1/chat/completions \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 用一句话解释什么是API网关}] }如果返回了模型响应说明 AI 网关的基本代理功能已经通了。3.3 加上 Token 限流和内容审核在路由的plugins里追加插件配置{ plugins: { ai-proxy: { ... }, limit-count: { count: 100, time_window: 60, rejected_code: 429, key_type: var, key: remote_addr }, ai-prompt-guard: { deny_patterns: [忽略之前的指令, ignore previous instructions], action: reject } } }limit-count做请求数限流每个 IP 每分钟最多 100 次。ai-prompt-guard做提示词注入防护匹配到可疑模式直接拒绝。如果要按 token 限流需要自己写一个插件或者用 APISIX 的serverless-pre-function做快速实现。核心逻辑是在请求阶段估算 token 数累加到 Redis 计数器超过阈值就拒绝。实操心得token 估算不要追求绝对精确误差控制在 20% 以内就够用了。精确计算需要加载 tokenizer性能开销太大。用字符数除以 4 的粗略估算配合响应侧的精确统计做校准是性价比最高的方案。3.4 接入 MCP ServerMCP Server 通常以 SSE 方式暴露接口。在 APISIX 里配置一个 MCP 代理路由curl http://127.0.0.1:9180/apisix/admin/routes/2 \ -H X-API-KEY: edd1c9f034335f136f87ad84b625c8f1 \ -X PUT -d { uri: /mcp/*, methods: [GET, POST], upstream: { type: roundrobin, nodes: { 127.0.0.1:3000: 1 } }, plugins: { proxy-rewrite: { regex_uri: [^/mcp/(.*), /$1] } } }这里假设 MCP Server 跑在本地 3000 端口。proxy-rewrite插件把/mcp/前缀去掉转发给实际的 MCP Server。MCP 的 SSE 连接需要保持长连接APISIX 默认支持。但要注意调整超时时间避免连接被过早断开{ upstream: { timeout: { connect: 60, send: 600, read: 600 } } }read超时设大一些因为 MCP 工具调用可能耗时较长。4. 踩过的坑和排查技巧4.1 流式响应被缓冲现象客户端调用网关模型响应不是逐字返回而是等全部生成完才一次性返回。原因Nginx/OpenResty 默认会缓冲上游响应。proxy_buffering开启时网关会等缓冲区满或响应结束才转发。解决在路由或上游配置里关闭缓冲{ plugins: { proxy-control: { request_buffering: false } } }或者在config.yaml里全局关闭nginx_config: http: proxy_buffering: off注意关闭缓冲会增加内存占用因为每个连接都要维护一个缓冲区。高并发场景下要评估内存是否够用。4.2 Token 统计不准现象网关统计的 token 数和 OpenAI 账单对不上。原因请求侧估算用的是近似算法响应侧提取usage字段时可能因为流式响应被截断而丢失。解决请求侧估算只用于限流不作为计费依据。响应侧统计要确保在流式结束后能拿到完整的usage。如果流式响应里没有usage可以在请求里加stream_options: {include_usage: true}OpenAI 支持这个参数。对于不支持usage的模型用响应内容的字符数做二次估算和请求侧估算取较大值。4.3 MCP 连接频繁断开现象MCP Server 的 SSE 连接每隔几十秒就断一次。原因Nginx 的keepalive_timeout默认是 65 秒如果 MCP Server 没有及时发送心跳连接会被网关主动关闭。解决调大keepalive_timeout比如设为 600 秒。在 MCP Server 侧实现心跳机制定期发送空事件保持连接活跃。网关侧配置proxy_read_timeout大于 MCP Server 的心跳间隔。4.4 常见问题速查表问题可能原因排查方向解决方案请求返回 401API Key 配置错误检查ai-proxy插件里的 Key更新 Key重启插件响应延迟高上游模型慢或网络差看网关日志里的 upstream_response_time切换模型或优化网络流式输出中断缓冲区或超时问题检查proxy_buffering和read_timeout关闭缓冲调大超时Token 限流不生效插件顺序或 Key 配置错误检查插件执行顺序和 Redis 连接调整插件优先级MCP 工具调用失败参数校验不通过看网关日志里的请求体检查工具 schema 定义5. 一些个人体会和扩展思路APISIX AI 网关最吸引我的地方是它把大模型调用的治理逻辑做成了“可插拔”的。你不需要一次性把所有能力都加上可以先用ai-proxy做基础代理跑通之后再逐步加 token 限流、内容审核、模型路由。这种渐进式的落地方式对团队来说压力小很多。另一个感受是AI 网关的很多问题本质上是传统网关问题的变种。流式响应对应长连接治理token 限流对应精细化限流MCP 代理对应协议转换。APISIX 在这些基础能力上积累很深所以做 AI 网关时不用从零造轮子更多是在现有能力上做组合和扩展。后续如果继续深入我觉得有几个方向值得探索模型路由的智能化根据请求内容自动选择模型而不是靠静态规则。可以用一个小分类模型做意图识别网关根据识别结果动态路由。缓存与去重相似请求复用模型响应降低成本和延迟。语义缓存是个有意思的方向但要做好相似度阈值控制。多租户隔离不同团队共用网关时需要做资源隔离和配额管理。APISIX 的 consumer 机制可以扩展出租户维度的限流和计量。这些方向目前社区里都有一些实践但还没有特别成熟的标准化方案。如果你也在做类似的事情欢迎一起交流踩坑经验。
返回列表