速率限制感知 AI API 网关:在 429 到达之前调整 RPM、TPM、突发和租户公平性
用于防止级联 LLM API 429 的实用网关架构:标准化提供商限制、在调度前估计代币压力、按租户保留配额、平滑流量斜坡并使节流可审核。
来自 LLM 提供商的 429 不仅仅是一个重试信号。在生产中,通常有证据表明您的应用程序已经失去了对准入、租户公平性、延迟或特定于提供商的配额核算的控制。
常见的修复方法——指数退避——是必要的,但并不完整。退避在提供商拒绝流量后做出反应。具有速率限制意识的AI API网关应该在请求离开系统之前调整流量:估计令牌压力、保留配额、隔离租户、对正确的工作进行排队、拒绝错误的工作以及在提供商限制发生变化时进行调整。
本文介绍了一种实用的网关配额管理器,供团队通过统一的 API 将生产工作负载发送到多个 LLM 提供商。
读者问题:429 是多维的
许多团队将速率限制视为每分钟的单个请求数。 LLM API 很快就打破了这一假设。
当前提供商文档中的事实:
- OpenAI 记录表明,可能会在比宣传的每分钟限制更短的窗口内强制执行限制,因此即使平均分钟看起来安全,短突发也可能会失败。
- Azure OpenAI 配额按订阅、区域、模型和部署类型(以每分钟令牌数为单位)分配。将 TPM 分配给部署还会确定强制推理 RPM 限制,并且 RPM 与 TPM 的比率因模型而异。
- Azure OpenAI 还指出,速率限制令牌计算是在收到请求时估算的,与最终计费令牌计数不同。
- 人性记录了每分钟的请求数、每分钟的输入令牌数和每分钟的输出令牌数限制。超出限制会返回 429,并带有重试后标头。
- Anthropic 警告称,流量急剧增加可能会达到加速极限,并建议逐步增加流量。
- 对于大多数 Claude 模型,缓存读取输入令牌的人择文档不计入每分钟输入令牌限制,这意味着即时缓存可能会改变有效空间。
- Google Gemini API 费率限制与项目使用级别相关,较高级别取决于结算设置、累计支出以及付款里程碑后的经过时间。
操作经验很明确:与 OpenAI 兼容的请求形状并不意味着与 OpenAI 兼容的配额行为。多提供商网关需要比“重试 429”更丰富的内部配额模型。
设计目标:让准入控制成为网关的职责
速率限制感知网关在发送请求之前应回答五个问题:
- 哪个提供商、模型、部署、区域、项目或工作区将收到请求?
- 可能消耗多少请求、输入令牌、输出令牌和并发容量?
- 哪些租户、团队、API 密钥、客户或工作负载类别应根据共享容量付费?
- 应该立即接受该请求、短暂排队、降级、路由到其他地方还是拒绝?
- 提供商返回实际使用情况后,应如何对预订进行核对?
网关成为配额管理器。它不会取代提供商的限制。它使提供商的限制在您自己的系统中可见、可预测且公平。
构建规范化配额模型
首先定义可以代表主要提供商的内部限制器维度,而不会强迫他们进入一个误导性的范围。
推荐的限制器尺寸
- RPM: 每分钟请求数。
- 输入 TPM:每分钟提示、消息、工具和上下文令牌。
- 输出 TPM:每分钟完成令牌数,单独为流式生成和长生成保留。
- 总体 TPM:对于暴露组合令牌压力的提供商或部署很有用。
- 并发:活动请求、活动流或正在进行的作业。
- 流持续时间:即使 RPM 较低,长期流也可能占用连接和输出令牌余量。
- 特定于提供商的范围:Azure 订阅/区域/部署、Anthropic 工作区/模型类、Google 项目/层或 OpenAI 组织/项目/模型组。
不要隐藏提供商特定的维度。将它们标准化为通用模式,但保留足够的细节以便稍后解释拒绝。
<前><代码>{ “提供商”:“provider_a”, "model_profile": "快速聊天", “provider_scope”:{ “项目”:“产品”, “地区”:“美国东部”, “部署”:“聊天-大-01” }, “限制”:{ “转数”:1200, “输入tpm”:800000, “输出tpm”:250000, “并发”:200 } }这个内部对象应该显式配置,而不是单独从模型名称推断。提供商仪表板、帐户层、区域部署和工作区设置都可以更改同一模型系列的有效容量。
调度前估算代币压力
提供商端速率限制通常发生在最终计费使用情况已知之前。您的网关应该在发送流量之前进行同样的保守估计。
飞行前预订输入
- 序列化提示和消息长度。
- 角色、工具、图像或结构化输出指令的模型特定标记化和开销。
max_completion_tokens或同等输出上限。- 此端点、租户、模型配置文件和请求类别的历史完成率。
- 如果提示缓存可用且可衡量,则预期的缓存读取令牌。
- 流媒体标志和预期流媒体持续时间。
一个简单的预订规则通常足以开始:
estimated_input_tokens = tokenize(request_messages) + model_overhead
估计输出令牌 = 分钟(
最大完成令牌数,
p95_historical_output_tokens_for_route
)
保留_总_令牌 = 估计_输入_令牌 + 估计_输出_令牌
对于未知路由,请使用保守的默认值。为了稳定生产路线,根据实际使用情况不断更新估算。
预留,然后协调
配额预留不应成为永久性费用。将它们视为保留:
- 引用:估计输入和输出压力。
- 预留:调度前从相关令牌桶中扣除。
- 解决:用提供商报告的使用情况(如果可用)替换估算值。
- 退款或借记:如果需要,将未使用的预留容量或超额费用退回到下一个窗口。
这对于长上下文和流式调用最为重要。如果您仅在分派之前检查输入 TPM,则流可以成功启动,然后会遇到输出令牌压力。单独保留输出余量可减少中流故障和失速风险。
使用分层令牌桶实现租户公平
单个全局限制器可以保护提供商帐户,但不能保护租户彼此。一项长上下文批处理作业可能会消耗共享 TPM,并导致其他团队的交互式请求失败。
使用分层令牌桶:
<前><代码>组织 └── 租户 └── 团队 └── api_key └── 模型_配置文件 └──provider_deployment请求必须传递每个相关的存储桶。这使您可以同时执行多个策略:
- 组织不能超出提供商的容量。
- 租户的消费不能超过其合同份额。
- API 密钥不能超出其预期环境或应用程序限制。
- 批量模型配置文件不能让交互式模型配置文件缺乏。
- 即使另一个部署有空闲配额,提供程序部署也不能超载。
公平共享与利用
建议:使用加权公平共享和受控突发借贷。
严格的每租户上限很容易解释,但可能会浪费未使用的容量。突发借用允许租户临时使用共享池中的空闲配额,从而提高利用率。代价是复杂性:仪表板必须显示担保的内容、借用的内容以及借用的时间。
实用规则:
- 为每个租户提供有保证的基线。
- 允许从未使用的共享容量中突发借用。
- 出现更高优先级或有保证的流量时回收借用的容量。
- 切勿让借用的流量创建提供商级 429 以保证流量。
在竞争之前将流量类别分开
并非所有请求都应具有相同的队列行为。将流量放入具有单独队列和配额池的模型配置文件中。
<表> <标题>排队提高了成功率,但增加了尾部延迟。网关应该明确这种权衡。例如,交互式请求可能会等待长达 300 毫秒的配额,然后回退或失败。每晚的批处理作业可能会等待 20 分钟,但仍被视为成功。
将 429 标准化为单个错误模式
即使有良好的准入控制,提供商 429 仍然会发生。限制可能会发生变化,提供商的估计可能与您的不同,并且流量可能会比预期的激增。
将每个提供者 429 标准化为网关错误对象:
<前><代码>{ “错误”:{ “类型”:“速率限制”, “限制器”:“output_tpm”, “提供商”:“provider_a”, "model_profile": "快速聊天", "provider_model": "模型-x", “毫秒后重试”:2400, “tenant_id”:“tenant_123”, "api_key_id": "key_456", "request_class": "交互式", “估计输入令牌”:4200, “估计输出令牌”:800, "gateway_decision": "admited_then_provider_rejected", “fallback_allowed”:假, “trace_id”:“trace_abc” } }关键字段是gateway_decision。网关承认该请求后的 429 与网关在分派之前在本地拒绝的请求不同。第一个表明限制器校准问题。第二个表示有意保护。
根据提供者标头进行调整,但不依赖于它们
一些提供程序返回有用的标头,例如重试后或剩余容量指示器。可用时使用它们。
建议:提供商标头应调整您的本地调控器,而不是替换它。
原因:
- 标头可用性因提供商和端点而异。
- 标头不得公开每个限制器维度。
- Retry-after 告诉您何时重试,而不是下一个租户应该获得容量。
- 提供商方令牌估算可能与您的结算或内部会计不同。
强大的实现会根据标头更新本地存储桶填充率和冷却时间,同时仍然在网关内强制执行租户、API 密钥、流量类别和提供程序部署限制。
为迁移和预定作业添加斜坡调速器
许多速率限制事件发生在计划更改期间:从一种模型迁移到另一种模型、更换提供商、启用新的代理工作流程或启动预定的评估运行。
建议:将流量增长视为可控的部署。
- 按租户、路线或流量百分比进行功能标记模型迁移。
- 为新的提供商部署设置每分钟的增长上限。
- 在数小时内逐渐预热流量,而不是立即切换所有流量。
- 当 429 速率、降级速率、队列深度或 p95 延迟超过阈值时暂停推出。
- 保留具有兼容性政策的紧急回滚路线,而不仅仅是备用型号。
预测:随着提供商路由模式、优先级和工作区级别控制变得更加普遍,斜坡治理将成为标准网关功能,而不是事件响应脚本。
回退是一项政策决定,而不仅仅是容量决定
当一个提供商返回 429 时,路由到另一提供商可能是正确的答案。它也可能不安全。
回退可以改变:
- 输出质量和指令遵循。
- 上下文长度。
- 工具调用行为。
- 结构化输出可靠性。
- 数据保留和驻留状态。
- 成本和延迟。
配额管理器应该询问兼容层是否允许该请求类回退。如果不是,它应该排队或失败,并带有明确的本地速率限制响应,而不是默默地改变语义。
公开解释决策的配额仪表板
没人能理解的配额制度将被绕过。围绕运营问题构建仪表板:
- 哪些租户消耗的 RPM、输入 TPM 和输出 TPM 最多?
- 哪些模型配置文件正在排队、拒绝或回退?
- 哪个提供商范围是瓶颈:项目、区域、部署、工作区、模型类还是帐户层?
- 网关估算值与提供商使用情况之间的差异有多大?
- 按提供商和限制器类型划分的重试后分配是什么?
- 提示缓存读取会创建多少有效空间?
- 哪些流量类别正在借用突发容量?
对于面向客户或面向合作伙伴的产品,公开安全控制:
- 每键速率限制。
- 每个团队的突发限制。
- 每位客户的每日上限。
- 租户或钥匙紧急暂停。
- 针对 429 峰值、队列增长和异常令牌压力发出警报。
- 用于转销商配额管理的合作伙伴 API 端点。
这将速率限制从神秘的提供者错误转变为团队 API 治理的可审计部分。
实施清单
第一阶段:观察和分类
- 记录每次调用的提供程序、模型、部署、区域、工作区、项目、租户、API 密钥和请求类。
- 通过重试后和原始错误元数据捕获提供商 429。
- 分别记录估计和实际的输入/输出标记。
- 分离遥测中的交互式、批量、评估和后台流量。
阶段 2:本地准入控制
- 为 RPM、输入 TPM、输出 TPM、总 TPM 和并发性创建内部限制器对象。
- 添加预检令牌估计。
- 在调度前预留配额,并在提供商使用量到达后进行协调。
- 当请求无法容纳其租户或提供商存储桶时,会在本地拒绝。
第 3 阶段:公平和队列
- 添加从组织到提供商部署的分层存储桶。
- 分配有担保的租户份额并控制突发借款。
- 按流量类别创建单独的队列。
- 设置特定类别的最长等待时间和后备规则。
第 4 阶段:适应和运营
- 使用提供程序标头来调整冷却时间和重新填充假设。
- 为迁移和预定作业添加坡道调速器。
- 公开配额仪表板和警报。
- 每周检查估算错误和搁浅配额。
可行的结论
如果您的网关仅重试 429 秒,则表示故障后网关正在运行。生产级AI API网关应通过决定允许谁发送什么内容、何时发送以及针对哪个提供商配额来防止大多数速率限制失败。
从标准化限制器模型、预检令牌预留和流量级别队列开始。然后添加分层租户公平性、提供商标头适应和斜坡调节器。结果不仅仅是减少 429。您的工程、财务和客户支持团队可以实际解释更清晰的容量分配、更可预测的延迟、更安全的迁移以及速率限制行为。