多租户 LLM 应用的配额与路由工程 2026
当一千个企业租户共用一个 OpenAI 兼容网关时,配额、优先级、模型路由、成本归因被压缩成同一个调度决策面——本文把 token bucket 公平调度、cost-aware model cascading、namespace 抢占语义、跨区域配额复制一次拆开。
约 26 分钟阅读7,531 字9 次阅读博主

当一千个企业租户共用一个 OpenAI 兼容网关时,配额、优先级、模型路由、成本归因被压缩成同一个调度决策面——本文把 token bucket 公平调度、cost-aware model cascading、namespace 抢占语义、跨区域配额复制一次拆开。

当一千个企业租户共用一个 OpenAI 兼容网关时,配额、优先级、模型路由、成本归因被压缩成同一个调度决策面——本文把 token bucket 公平调度、cost-aware model cascading、namespace 抢占语义、跨区域配额复制一次拆开。
2026 年的企业级 LLM 应用,几乎都走向"一个推理网关背靠多个模型、多租户共享底座"的形态。这种形态在产品上看起来像 SaaS——客户登录、调用、按量付费;但在内部,它是一场每秒钟都在发生的资源战争:免费试用租户的 prompt 突发可能把付费租户的 latency 推上 SLA 红线;某条客户业务线的工具调用风暴会瞬间吃光整批 GPT-5 配额;一个跨区域故障切换后,区域 B 的预留配额若没有同步,A 区租户的请求会被无声地限速到错误级别。
更隐蔽的是成本面:当一个应用同时接入 GPT-5、Claude Opus 4、Gemini 2.5 Pro、DeepSeek、自托管 Qwen3-Max、第三方托管的 Llama 4 Maverick 时,单次请求究竟应该走哪个模型、计费应当归到哪个租户、配额在三个供应商之间如何滚动——这些问题如果不在网关层一次性回答清楚,就会在每个业务线重复发明一遍。
本文要回答的核心问题是:多租户 LLM 应用的资源治理,应该在网关层一次性解决哪些问题,才能让上层业务不再为"谁用了多少""这次请求该走哪个模型""配额耗尽时降级到哪一档"这些决策反复重写? 我们把答案拆成四个主体:token 配额治理、成本感知路由、多租户隔离、跨区域容灾与边端降级,再在第六节统一为一张决策面,最后给出六条可执行的工程推论与一份给 AI 应用架构师的演进路线。
为了让后文每一段都能落到具体决策,我们先把"多租户 LLM 资源治理"抽象成一个四元组 ,并把目标写成一条带约束的优化问题:
治理目标可以写为:
这条公式的工程含义是:对每一次请求同时优化"成本—延迟—质量"三维,并把租户的 SLO 优先级编码为权重。我们后文展开的所有机制——token bucket、cascading、namespace 抢占、跨区域配额复制——都是这条公式在某个维度的可执行投影。
配额治理的第一性问题是:如何让一千个租户既不被免费租户的突发挤爆,又不会被机械的"每租户 1/N 平均"误杀。我们采用三层 token bucket 的分层结构:
/v1/chat/completions、/v1/embeddings、/v1/responses)一个突发桶,秒级响应突发。这一层回答"这次请求能不能立刻放行"。图表加载中…
公平调度的关键不在 bucket 本身,而在桶之间的优先级仲裁。我们采用"加权赤字公平队列"(Weighted Deficit Fair Queueing, WDFQ)——它把每个租户当前欠的 token 数记为赤字 ,每次请求按 排序,其中 是租户的 tier 权重。这样既避免了"先到先得"导致的低优先级租户饿死,也避免了"按权重排序"导致的低权重租户永远排队。
工程实现上,WDFQ 的状态完全可以用 Redis 的 sorted set 维护:score = ,每次请求 zadd + zpopmin,单次 O(log N)。当 N=10000 时,10ms 内可以完成仲裁;当 N=100000 时,建议升级到分层仲裁(按 tier 分桶、桶内 WDFQ)。
配额治理回答的是"能不能调",成本感知路由回答的是"调哪个模型最划算"。我们采用 model cascading 的多阶段决策:先用轻量模型(如 GPT-5-mini、Haiku 4.5、Qwen3-Flash)试答,再用 confidence score 决定是否升级。
cascading 不是简单的"便宜先试"——它必须同时考虑三类信号:
图表加载中…
成本感知路由的隐藏陷阱是短请求反而更贵:当 prompt 只有 50 tokens 但要求高质量时,cascading 走完 L1 + L2 + L3 反而比直接调 L3 多花 1.5 倍成本。我们用一条简单的规则解决:若 prompt < 200 tokens 且 task_class ∈ {summarization, classification, extraction},直接跳到 L2 起步,避免"轻量试答"本身成为浪费。
另一个常被忽视的点是缓存信号必须参与路由:当 prompt 命中 semantic cache(参见 id=732)时,应直接短路返回,连 L1 都不调用——这把单次推理成本打到接近零,但配额仍要记一笔"虚拟调用",避免缓存命中率被人为刷高。
我们再展开 cascading 决策的两类高频陷阱:
陷阱一:把 confidence threshold 写死。 多数 cascading 实现把 L1→L2 的升级阈值设为 0.7,但 0.7 在数学推理任务上太低、在闲聊任务上太高。正确的姿势是按 (tenant, endpoint, task_class) 三元组动态查表,阈值表本身也是 namespace 配置的一部分,跟着 GitOps 走。
陷阱二:忽视 cascading 决策的延迟贡献。 一次 L1→L2 升级意味着串行两次推理,p99 latency 直接翻倍。在 latency-sensitive 的 endpoint 上,应当使用"双轨并行"模式:L1 与 L2 同时启动(前者快速返回,后者作为后备),谁的 confidence 高就用谁的结果——这要求 L1 与 L2 的 prompt 准备可以并行,且双倍推理成本可被接受。双轨并行适合 SLO < 800ms 的场景,不适合 cost-sensitive 的批量任务。
配额和路由是决策面,namespace 与抢占是隔离机制。一个企业级 LLM 网关至少要支持四种隔离粒度:
{
"namespace": "acme-corp",
"tier": "enterprise",
"priority": 8,
"quotas": {
"steady_state": { "rate_tokens_per_sec": 50000, "burst_tokens": 200000, "period_sec": 3600 },
"endpoint_burst": { "chat": 5000, "embeddings": 10000, "responses": 8000 },
"global_safety": { "fraction_of_provider_reserved": 0.35 }
},
"preemption": { "can_preempt": true, "max_preempt_per_min": 60 },
"borrowing": { "allow_borrow_within_tier": true, "rebalance_interval_sec": 300 },
"reserved": { "provider": "openai", "tpm": 1200000, "rpm": 6000 }
}
抢占语义必须区分两种:位置抢占(让排队中的低优先级请求让出队首)和预算抢占(让已被分配但尚未发出的 token 退还)。前者用 priority queue 实现,后者需要租户级的"in-flight token counter"——每个进入网关的请求先在 counter 里预占 token,响应完成(含 streaming 结束)后再释放。当抢占发生时,按 排序选出可抢占的低优先级请求,把它的 counter 退回,让高优先级请求"插队"进入。
配额和路由在单区域已经够复杂,但生产环境必须考虑跨区域。一个典型的容灾场景是:A 区 OpenAI 配额耗尽或网络中断,业务要切到 B 区 Anthropic Claude 或自托管集群——此时 A 区的租户配额数据如何同步到 B 区?切换过程中谁先谁后?
我们把跨区域配额治理拆成三个子问题:
图表加载中…
边端降级是配额治理在客户端的延伸。当租户的配额耗尽且无法借到额度时,网关应当返回的不只是 HTTP 429 + Retry-After,还应当告知客户端应当降级到哪个本地模型:例如"切换到端侧 Qwen3-1.5B-Q4_K_M"。这种"治理即降级"的契约让客户端可以在 200ms 内完成 fallback,无需自己重新探测。
边端降级的实际收益巨大:当 prompt 主要消费是 RAG 检索结果 + 短回答生成时,端侧 1.5B 模型已经够用,token 成本从 0——这把 SLO 压力从网关完全卸载到客户端设备。
把前四节的机制落到工程实践,可以提炼出六条可执行清单:
X-Degrade-To-Model)返回,客户端 SDK 直接消费。我们额外给一条反模式清单:① 不要在网关层实现"按租户计费的实时账单"——那是计费系统的事,网关只输出 usage event;② 不要把"用户可以无限切换模型"作为产品功能开放给最终用户——这等于把模型路由决策权下放到不懂成本结构的客户端;③ 不要用同一个 token bucket 同时承载"流式输出"和"非流式输出"——它们的 token 消费速率差异巨大,必须分桶;④ 不要把"租户优先级"硬编码在网关代码里——优先级是 namespace 的元数据,应当随配置热加载;⑤ 不要让 cascading 决策绕过"成本硬上限"——一旦 prompt 被识别为高 token 消耗(如长文档摘要),应当直接跳到 L2/L3 起步,不走 L1 试答;⑥ 不要把"预留容量"和"动态配额"放在同一个治理面板里——它们的计费语义、扩容节奏、故障模型完全不同;⑦ 不要在 cascading 决策里忽略 prompt 的语言特征——中文 prompt 与英文 prompt 在不同模型上的 cost-quality 比差异巨大,必须按语言分桶统计;⑧ 不要把"降级模型"写死在客户端——降级目标应当由网关在 429 响应头里告知,客户端只能消费,不能预设。
我们再展开两条容易被忽视的边界情况:
边界一:流式输出的 token 计量时机。 在 SSE / WebSocket 流式协议下,token 是逐 token 产生的,但配额扣减发生在 token 离开网关时——这意味着配额扣减与模型推理存在时间错位。若按"开始时预扣、结束时结算",则突发桶的瞬时占用率会被高估;若按"逐 token 实扣",则上游供应商的 RPM 限制可能因为 jitter 而被低估。我们推荐"开始时预扣 80%、结束时按真实用量结算"的双段策略,中间多余预扣的 20% 作为突发缓冲返还给租户桶,避免被 jitter 反复吃光。
边界二:长上下文请求的配额倍增。 当 prompt 长度 > 32k 时,多数模型的单价会发生跃迁(如 Gemini 1.5 Pro 128k context 单价是 8k context 的 4 倍),配额消耗也按四倍计费。网关必须按"实际单价"而非"列表价"扣减配额,否则会出现"配额还剩 50%,但实际已无 budget 调用 128k 上下文"的奇怪局面。
本文刻意把范围限制在"配额—路由—隔离—容灾"四件套,但这套机制不是孤立的,它与可观测性、反馈闭环、成本归因的关系需要明确:
本文也有几条明确的局限:① 未涉及"租户间模型微调的隔离"——当租户要求私有 fine-tuned 模型时,namespace 与模型权重如何耦合是个独立议题;② 未涉及"跨供应商的 token 标准化"——OpenAI 的 token 与 Anthropic 的 token 不是同一回事,跨供应商的 quota accounting 需要归一化层;③ 未讨论"突发桶的反压传播"——当第三层桶耗尽时,反压信号如何快速传到第一层和第二层,避免请求在网关内堆积。这三条都值得后续独立文章展开。
最后给一份给 AI 应用架构师的演进路线,建议分四阶段:
阶段一(0-3 个月):单租户网关 + 静态配额。 用一个 OpenAI 兼容代理(如 LiteLLM、OpenRouter 自托管版、Portkey)做协议归一,配额先用配置文件静态写。这一阶段的目标是把"模型路由从业务代码里剥出来"。
阶段二(3-6 个月):多租户 token bucket + WDFQ。 引入 Redis + sorted set 实现 WDFQ,三层桶结构跑通,namespace 配置走 GitOps。这一阶段的目标是把"配额治理从运维脚本里抽出来"。
阶段三(6-12 个月):cost-aware cascading + 降级契约。 上 model cascading,confidence 评分用自托管的 reward model 或第三方评估 API;降级契约写进 API header;事件流同步跨区域配额。这一阶段的目标是把"成本治理从财务对账里挪出来"。
阶段四(12+ 个月):自适应配额 + 全局优化。 用历史数据训练一个租户级 cost-quality Pareto 前沿模型,让路由决策在 SLO 约束下自动取 Pareto 最优点;跨供应商的 token 标准化层落地。这一阶段的目标是把"治理决策从规则系统进化为学习系统"。
需要提醒的是,演进路线不是升上去就不能降下来——很多公司在阶段三才发现阶段二的 WDFQ 调度参数没调好,导致高优先级租户的体验反而下降,回到阶段二重新校准权重。这是正常的工程节奏,不是失败。
最后一句给读者的建议:多租户 LLM 应用的治理问题,本质上是一次"把决策面从代码里抽到网关层"的重构。早做比晚做好——因为每晚一个月,就多一个业务线把配额逻辑写在它自己的 if-else 里,多一个 if-else 就多一份治理债务。
附录:常见配置陷阱 12 条速查。 ① 把 RPM 和 TPM 用同一个桶管理——这两者的限速来源不同,应分桶;② 忽略 cache hit 的 token 计费差异——多数供应商对 cached input token 单价更低,扣减应按 cache 命中与否分档;③ 用浮点数计费——累计误差会导致月度账单偏差 1-3%;④ namespace 名字带空格或全角字符——会导致日志聚合时不可搜索;⑤ 不区分"试用租户"和"已转化租户"——试用租户应在独立 burst bucket 内,不能消耗付费租户的额度;⑥ streaming 和 non-streaming 走同一个 endpoint 配额——前者的瞬时并发远高于后者,必须分桶;⑦ fail-open 策略——配额耗尽时直接放行请求而不降级,会导致上游供应商超售;⑧ fail-closed 策略——配额耗尽时硬拒绝所有请求,会让边缘租户体验极差;正确的姿势是 fail-degrade(降级到本地轻量模型);⑨ 配置漂移——namespace 配置改完没有审计 trail,事故复盘时找不到"谁改的";⑩ quota 数据用同步 RPC 复制——单 region 故障会拖垮全局;⑪ cascading 决策里没考虑 cache 命中——已经命中 semantic cache 的请求不应再走 cascading;⑫ 把"模型路由策略"写死在 SDK 里——策略必须由网关下发,客户端 SDK 只负责消费。
附录:评估指标速查。 网关层的治理质量应当用以下五类指标评估,而非仅看 latency:① 跨租户公平性指数(Jain's Fairness Index,目标 ≥ 0.85);② 单租户配额利用率中位数(过低说明配额分配过松,过高说明频繁耗尽);③ cascading 升级率(按 tier 分桶统计,目标 ≤ 35%);④ 降级契约触发率(429 + X-Degrade-To-Model 头占总请求比例);⑤ 跨区域配额偏差(reconciler 收敛后的最大差额 / 总配额,目标 ≤ 0.5%)。这五条指标独立于业务 SLO,应当作为治理 SLO 单独跟踪。
Conversation
0 条