资讯动态

大模型网关实战:从Token感知到成本治理的架构设计

发布时间:2026/9/23 5:24:00 来源:尧图企业网站定制
1. 常规API网关在LLM场景失效的三件事1.1 从“转发请求”到“感知令牌”的角色升级通常我们聊到网关脑子里浮现的是Nginx、Kong、APISIX这类东西它们做路由、限流、鉴权、灰度粒度是HTTP请求。请求到了转发到后端后端返回200或者5xx网关记一条access log收工。这套模型在处理普通微服务时非常成熟但是放到大模型推理场景立刻露出一堆盲区。大模型API的一个核心特征是单次请求的耗时不固定消耗的资源不体现在“次”上而是体现在token上。同样是调用一次对话接口有人问“今天天气怎么样”可能消耗几百个token有人上传一份长文档让模型总结可能一次就消耗几万token。普通网关按QPS做限流打死也挡不住“请求次数不多、但token量爆炸”的调用方式。这就是需要大模型网关的第一个理由它必须看得懂token而不是只看得懂HTTP。另一个关键差异是流式输出。今天几乎所有的对话类模型API都支持流式返回也就是SSEServer-Sent Events客户端可以一个字一个字地看到结果。传统网关在处理流式响应时本质上只是在做字节流的透传如果客户端中途断开网关很多时候并不能及时把上游的连接也断掉导致上游模型服务继续计算、继续产生费用。这个问题的根子在于网关不感知“请求级语义”不知道一个流式会话什么时候才算真正结束。所以大模型网关不是把普通API网关改个名而是要把流量管理从“请求粒度”下沉到“token粒度和流粒度”。这是两者最本质的区别。1.2 模型数量一多协议差异就不是小问题了团队里如果只接一个模型提供方的API那确实不需要网关封装一个SDK就够。但现实情况是稍微大一点的平台团队会同时接入多家模型对话模型、向量化模型、图片生成模型甚至还有自己微调的私有化模型。不同提供方的接口风格不一样有的兼容OpenAI格式有的有自己的SDK有的模型名称版本还在不断变化。这时候如果没有一个统一接入层业务方的代码就会被各种SDK和鉴权方式割裂。今天换个模型供应商所有下游代码都要改明天某个模型要升级版本涉及十几个服务同时改配置。这些问题不是SDK能解决的因为你没办法让业务方统一依赖所有厂商的SDK。所以需要一个网关在协议层做一次统一把“多模型、多供应商、多版本”的差异收敛到一个入口里。这里我想强调一点统一不仅是接口格式的统一还包括错误码语义的统一。不同模型API在触发限流、欠费、内容安全拦截、上下文超长时的返回结构完全不一样。网关要做的是把这些差异翻译成一套业务方都能理解的错误模型最好还能做自动降级。比如主模型返回429限流网关自动把请求转发到备选模型业务方无感知。1.3 成本能算到“部门模型时间”三个维度大模型API的成本结构非常特殊它是按token计费的而且输入token和输出token价格不同不同模型的单价可以差几十倍。如果企业内部有多个业务线同时使用模型能力月底账单出来后根本说不清哪个业务线用了多少钱。普通网关的access log里只有URL、状态码、耗时没有token消耗数据成本归因无从谈起。我在实践中见过最典型的场景公司统一申请了一笔模型API预算一个月跑下来超支了40%但没人能说清楚是哪条业务线烧掉的。后来给网关加上了token计量和成本估算能力才把问题查清楚原来是某个内部工具在循环调模型做数据清洗而且用了高端模型。没有网关层的计量能力这种问题只能等账单出来之后才发现那时候已经晚了。大模型网关需要在每条请求结束后把模型名、输入token数、输出token数、估算成本、归属部门、调用用户这些维度全量记录下来。这样才能支撑起成本分析、预算告警、甚至按部门做配额管理。这也是我认为大模型网关最直接、最核心的价值之一把大模型这种按量计费的新资源纳入到企业已有的精细化治理体系里。2. MAI Gateway的结构设计从请求进入到计量结束的一条完整链路2.1 请求在网关内部要经过哪些节点我习惯把MAI Gateway拆成“控制面”和“数据面”两块来看。控制面负责管理路由规则、模型分组、配额策略、密钥配置、成本报表数据面就是真正跑流量的网关节点每个请求在数据面里要经过一条明确的链路鉴权、限流、路由选择、协议适配、上游转发、流式搬运、计量上报。如果用一个比较实操的说法来描述这条链路用户的请求进来之后网关先检查调用方身份判断这个应用或者这个用户有没有权限访问当前模型接着做一次token级别的配额检查注意这里不只是看QPS还要估算这次请求大概会消耗多少token配额没超就进入路由选择根据请求的模型名和配置的路由策略决定转发到哪个供应商的哪个模型选定目标之后网关把业务方的请求转换成目标API对应格式建立上游连接然后把数据转发出去。响应阶段同样值得细看。如果是普通响应网关拿到完整body后做计量、记日志、返回结果。如果是流式响应网关会一边透传内容块一边累计token数和耗时在流结束时再统一计量。整条链路里鉴权和限流是同步的转发是异步的计量和日志是异步的这样才能保证网关本身的延迟开销足够低。2.2 模型适配层加新供应商不是改代码而是加配置模型适配层是整个MAI Gateway架构里最容易设计过度、也最容易设计不足的部分。装一个模型适配器可太容易了。我看到很多团队直接写if else判断供应商代码里全是switch-case加一个新供应商就得重新发布一次网关这种设计用不了三个月就会变得无法维护。正确的做法是把“模型供应商接入”做成配置驱动的。每个供应商本质上就是一个“端点配置 协议转换模板 参数映射规则”的组合。新接一个供应商时只需要在网关控制面里填写一份配置base_url是什么、鉴权方式是什么、哪些参数的命名和默认值不一样、超时时间怎么设然后调用一次配置热加载业务方就可以用原来的统一接口访问新模型了。代码层面只需要实现一个通用的HTTP适配器真正做到“加模型不改代码”。模型分组是另一个容易被忽略的设计。实际使用中业务方很少关心具体模型名他们关心的是“我需要的是一类能力”。比如“对话摘要类模型”可能这个月供应商A的模型效果更好下个月供应商B出了新版本更便宜。这时候网关可以做模型分组一个组里挂多个真实模型按权重或优先级做路由。业务方只面向分组调用底层模型的切换完全由平台团队在网关控制面完成。2.3 路由策略与降级逻辑路由是网关的大脑。我见过最朴素的实现是“固定路由”——配置里写死模型A然后就是落到模型A。这种实现连网关的一半价值都没发挥出来。更实用的路由策略至少应该包括三种优先级路由、加权路由、故障自动切换。优先级路由适合“主备”场景比如主供应商偏贵但质量好备供应商便宜但质量略差。正常情况主供应商只要有额度和容量就优先走它一旦连续报错或者触发限流就切到备供应商。加权路由适合“容量分摊”场景两个模型各承担50%流量或者按3:1的比例分摊既可以做模型效果对比测试也能分散单点依赖风险。故障自动切换是网关比较容易踩坑的环节。核心问题是什么样的情况算“故障”超时算不算返回429限流算不算返回内容格式不对算不算我的经验是不能只盯着HTTP状态码。比如上游稳定返回200但响应解析失败这种也叫故障。网关判断一次请求失败之后要累计失败次数达到阈值后把该模型标记为熔断状态后续请求直接绕开它。这个过程要有一段时间窗口的自动恢复机制不能熔断了就永远不恢复。3. 流式转发、token限流和语义缓存三个决定体验的细节3.1 流式转发客户端断开时上游连接必须同步断掉流式转发是网关工程里最容易翻车的环节具体技术细节也最枯燥。很多网关刚开始只实现了简单透传客户端那边页面关了HTTP连接断了但是网关到模型API之间的数据还在继续拉取。模型根本不知道客户端已经走了还会一直生成直到max_tokens耗尽笔笔都是成本。处理办法只有一个原则客户端断开的事件必须传导到上游。网关在读取上游流式数据的同时要监听客户端连接的状态。一旦检测到客户端断连马上取消上游的读取操作关闭上游连接。这个逻辑看起来简单但在异步编程模型里需要很小心地处理取消信号的传播凡是忽略取消信号的语言模型通道都会出现这个问题。另一个相关的问题是超时设置。普通HTTP短请求的超时配置在流式场景下完全不适用。一个正常的对话生成可能要30秒甚至几分钟如果网关配了全局“请求超时60秒”用户一个长回答生成到第61秒就被网关掐断了体验极其糟糕。流式场景的超时应该拆成几个不同维度连接建立的超时、首包到达的超时、相邻数据块之间的空闲超时。只要模型还在持续输出内容块网关就认为连接是健康的不打断。3.2 token限流的正确姿态估算滚动窗口有了“按token计费”这个认知之后限流设计也不能再封在QPS上了。一个准确的按token限流模型需要回答一个问题请求还没执行怎么知道它要消耗多少token如果拿不到就没办法精确控制。这个问题无法完美解决但可以用“预估”来逼近。对于对话补全类接口请求体里的prompt输入是已知的可以用tokenizer或长度估算算法算出一个大概的输入token数输出token数可以用请求参数里的max_tokens作为上限估算。那么在请求刚开始时网关就可以按“输入token max_tokens”占用的配额来做预扣。如果这个配额已经超过了用户的剩余额度就直接拒绝不用转发到上游。我一般建议用滑动时间窗口来记录token消耗窗口长度可以是一分钟、一小时或者一天。每次请求结束后再根据实际token消耗修正预扣值。这样做的好处是不会出现某个人在一个瞬间用大max_tokens请求把整月预算打爆的情况同时在请求级就能拦掉一部分超配调用。限流逻辑伪代码async def check_quota(user_id, model_name, estimated_total_tokens): key fquota:{user_id}:{model_name}:{current_time_window()} used await redis.get(key) or 0 if used estimated_total_tokens quota_limit[model_name]: raise QuotaExceeded(该模型小时级配额不足) await redis.incrby(key, estimated_total_tokens)3.3 语义缓存不是所有请求都值得缓存把语义缓存加进网关是我觉得性价比很高但又经常被忽视的能力。它的思路是对用户输入做embedding向量化把向量和之前的请求向量做相似度比对如果相似度超过阈值就直接返回缓存里的响应不再调用上游模型。很多高频问题、固定模板问题、RAG问答里的常见query命中之后可以省掉大量token成本。但语义缓存有几个需要想清楚的点。首先不是所有场景都适合缓存。涉及实时信息、个性化内容、严谨合规要求的请求都不建议走缓存否则返回过时信息会很麻烦。其次相似度阈值需要调试得谨慎一些。阈值太松相似但不相同的输入会命中同一个缓存导致答案不匹配阈值太紧命中率又太低缓存就失去意义。我通常从0.92到0.97这个区间开始调节具体要看业务场景。还有一个容易被忽略的坑缓存结果要和模型版本绑定。同一个问题模型升级之后答案可能完全不同如果缓存里还是旧答案就是在用旧版本能力服务新需求。所以缓存的key里至少要包含模型版本信息和Prompt版本信息。3.4 计量网关的“最后一公里”计量模块看起来不起眼但它直接决定了网关能给企业带来多少治理价值。每完成一次模型调用网关都应该生成一条完整的调用事件字段至少包括调用时间、traceId、业务方标识、用户标识、模型名称、输入token数、输出token数、首包延迟、总延迟、估算成本、返回状态。这里有一个建议不要只记录成功请求失败的请求同样要记录。因为很多成本的“黑洞”恰恰来自失败请求——比如上游超时但实际已经生成了大量token或者因为网络重试导致一次业务请求变成了多次实际调用。如果不记录这些成本归因依然会有很大偏差。计量事件落地之后就可以做成本大盘、部门账单、异常告警、模型效果对比报告。网关的价值在这个环节才算真正闭环。4. 把网关部署到生产环境后最先要解决的四个问题4.1 多实例部署与分布式配额的权衡网关本身必须是无状态、可水平扩展的这是部署的前提。但如果所有实例共享一套配额数据限流检查就会变成一个分布式事务问题。这里要做一个权衡如果对配额精确性的要求很高那就用Redis做集中式计数所有实例读写同一个key。不过redis的incr操作本身在高并发下会成为瓶颈需要给Redis做集群或者分片。如果要求没有这么高可以接受一定程度的超用那就采用“本地桶定期同步”的方案。每个实例维护一份本地配额缓存定期从中心同步总量这样限流大部分时候走本地判断性能很好。坏处是极端情况下瞬时并发可能让实际消耗量短时间超出配额上限。我的建议是正常业务场景下用本地桶方案就够了。4.2 上游连接池和超时参数配置生产环境里模型API通常部署在外部服务上跨网络调用时连接池的管理非常关键。如果每个请求都新建一条上游TCP连接在高并发下很容易把本机端口和上游服务的连接数打爆。要用连接池复用连接但要注意给连接池设置空闲断开时间和最大存活时间。有些模型API的网关会对长时间空闲的连接主动断开结果客户端侧还在用“半死”的连接首个请求就会因为连接被重置而失败。超时参数建议按三个维度分开配置连接超时、读超时、写超时。我用过一组相对安全的初始值连接超时5秒、读空闲超时120秒、写超时60秒。这组值不是说适用所有场景而是给了一个起点具体要根据你的上游模型服务响应速度来调整。如果你发现线上经常出现“上游读取超时”可以先看看是不是读超时配得太短而不是急着给网关扩容。4.3 密钥安全供应商key绝不能落到业务代码里这是一个让我在多个项目里反复强调的治理点。业务方接入网关之后不应该再持有任何模型供应商的API key也没有必要。网关统一保存、统一轮换供应商密钥业务方只需要持有网关颁发的应用级凭证。这样可以避免两个常见问题一是密钥散落在各个服务的环境变量里泄露后无法追踪是谁泄露的二是供应商侧封禁某个key之后所有下游服务全都跟着断。更具体一点网关保存供应商密钥时至少要支持密文存储和密钥轮换。轮换流程应该是新key可以先用“影子模式”验证确认可用之后再切换为正式密钥避免一把key被删掉之后才发现还有服务在用它。4.4 成本归因的一个真实分析案例说一个我处理过的案例。某团队网关上线后发现某个内部数据清洗任务每天消耗的成本占了总预算的一半以上。直接看网关计量的成本报表发现这个任务的调用量并不大但它使用的是旗舰级大模型而且每次输入都是几十页的长文档输入token量巨大。如果把成本维度拆到“部门模型时间”这一问题会立刻暴露。修复方法也很简单用网关的路由配置把这个场景的请求改到便宜得多的中等模型同时限制该业务的最高模型等级。整体成本直接下降到原来的四分之一。如果没有网关的计量和路由能力这个优化基本不可能做得这么干净利落。5. 自研还是买现成另一种“架构设计”是选择5.1 什么情况下必须要有一个大模型网关需要明确的是不是所有团队都需要MAI Gateway这个级别的组件。如果你们只是在一个后端服务里调用两三个模型API封装一个简单的client就够了。真正需要引入独立网关的信号一般包括多个业务团队都要用模型能力、要统一做成本分摊和配额管理、要用到多模型路由和高可用降级、需要统一审计日志和密钥管理。这些信号出现的数量越多建设网关的理由就越充分。独立网关的价值是收敛复杂度业务方对接一个统一入口平台方在一个入口里做治理和保障两边都省事。最怕的是“已经明显需要但一直没做”——业务方的代码里各自写调用逻辑每接一个模型就到处改这种状态越拖越贵因为它们涉及的支付集成问题很复杂会拖慢后续一切产品迭代。5.2 从零搭建一个最小可用网关需要哪些能力如果决定自研我建议第一版不需要贪多求全先做一个最小闭环统一接入鉴权、基础路由转发、token计量、成本报表这四个能力就足够跑通价值了。有了计量数据之后再做限流和配额跑稳之后再加语义缓存、熔断降级、A/B路由这些高阶能力。技术栈选择上网关的核心诉求是高并发代理能力和灵活的插件机制所以优先考虑那些原生支持反向代理、且配置热加载容易的框架。Go系的生态通常比Python系更适合内存管理更可控部署也更轻便。纯Python异步框架也能做但在超高并发和资源占用上需要多做一些优化。再补一个架构建议控制面和数据面从一开始就分开。数据面节点只负责转发和采集控制面负责规则下发和配置管理。否则等规则多了之后你会发现在业务高峰期改配置变成了一件极度高风险的事情。5.3 部署拓扑与容灾注意事项网关本身就是关键路径它挂了所有模型的调用都会受影响。所以部署至少要做到两个节点起步不能只用单实例。如果对可用性要求更高可以按机房或者可用区各部署一组前端用负载均衡把流量分散到多组节点。我还想提醒一点很多团队忽略了“网关依赖外部的Redis和数据库”本身也是一种风险。控制面的配置持久化可以依赖外部存储但数据面的核心转发链路要尽量做到不依赖外部组件也能处理突发流量。就算Redis短暂的抖动也不能让模型调用直接全部失败。这一条是生产级网关和玩具级网关的重要分界线。有一种做法是Redis不可用时限流自动退化成本地计数模式宁可允许少量超额调用也不能让流量全部中断。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价