LLM 速率限制:每分钟令牌数、每分钟请求数,以及达到限制时会发生什么

语言模型 API 同时以两种方式限制你的流量:每分钟发送的请求数(RPM)和每分钟使用的令牌数(TPM)。 你的请求数可能远低于请求限制,但仍会被限流,因为几个较长的提示用完了你的令牌预算。 达到任一限制时,API 会返回 429 Too Many Requests,应用必须等待。

OpenAI、Azure OpenAI 和 Anthropic 如何计数

Provider 限制的内容 要了解的事项
OpenAI RPM、每天请求、TPM、每天令牌等,每个组织和项目,每个模型 哪个配额先耗尽,你就会触及相应的限制。 对于令牌限制,请求按 max_tokens 和基于其字符的估计值两者中较高者计算。 失败的请求也计入。
Azure OpenAI 分配给每个部署的 TPM,以及按比例设置的 RPM 限制 RPM 通过 1 或 10 秒的窗口进行检查,因此即使每分钟总数正常,突发也会得到 429。 令牌估计包括 max_tokens。
Anthropic RPM、每分钟输入令牌(ITPM)和每分钟输出令牌(OTPM),每个模型 容量持续补充,60 RPM 可能会以每秒 1 个请求的方式强制执行。 对于大多数模型,缓存的输入令牌不计入 ITPM,且 max_tokens 不计入 OTPM。

如果你将max_tokens设置为 4,000 并收到 200 个令牌,OpenAI 和 Azure OpenAI 仍会将这 4,000 个令牌计入你的配额。 这就是为什么在你的使用量指标看起来远低于配额时仍可能出现 429。

每个提供程序的 429 的含义

并非每个 429 都能通过等待消失。

Provider 等待并重试 停止并告诉某人
OpenAI 请求数或令牌数达到限制时的 429、429 slow_down(你的流量增长过快,即使仍在限制范围内)以及 503 server_is_overloaded。 如果存在Retry-After,请按其指定的时间等待。 在error.code中带credit_balance_exhausted、organization_spend_limit_exceeded、project_spend_limit_exceeded或organization_usage_limit_exceeded的 429。 重试不会还原访问权限。
Azure OpenAI 因部署的 TPM 或 RPM 限制、系统容量限制或速率限制暂时降低而返回的 429。 等待 retry-after-ms。 在生产环境中持续出现 429,而你的使用量低于批准的配额。 检查部署的 TPM 分配,然后打开支持请求。
Anthropic 带retry-after标头的 429 rate_limit_error(包括使用量急剧增加后触发的加速限制)以及 529 overloaded_error。 每月支出上限为 429。 它没有 retry-after 标头,error.details.error_code 是 enforced_spend_limit_reached,它会持续失败,直到访问恢复。

如何处理 LLM 速率限制

  1. 检查你遇到的是哪一种 429 错误。 计费、支出和配额错误需要人工处理,而不是重试。
  2. 按 API 要求等待即可。 OpenAI 和 Anthropic 以秒为单位发送retry-after。 Azure OpenAI 以毫秒为单位发送retry-after-ms。 如果没有提示,使用随机抖动以指数方式退避,并同时限制尝试次数和总时间。
  3. 了解 SDK 已具备哪些功能。 OpenAI 和 Anthropic Python SDK 会对连接错误、408、409、429 以及 5xx 响应默认重试 2 次。 如果添加自己的重试循环,请关闭 SDK 的重试,例如在 Python 中使用 max_retries=0,如 Azure OpenAI 建议,否则重试次数会成倍增加。
  4. 减少计入配额的用量。 在 OpenAI 和 Azure OpenAI 上,将max_tokens设置为接近预期响应大小的值。 在Anthropic上,缓存重复的内容,如系统指令。
  5. 逐步提升。 流量的急剧增加会触发 OpenAI 的slow_down和 Anthropic 的加速限制,即使仍在你的限制范围内。 OpenAI 建议,每分钟达到 100 万个输入令牌后,每 15 分钟增长不超过 50%。
  6. 不要重放你已消费的流。 流启动后的错误可以作为流事件到达,OpenAI 建议不要在已接收输出后自动重播请求。
  7. 当请求因 429 而卡住时告知用户,而不是显示加载指示器。

如何测试你的应用是否能处理 LLM 速率限制

Approach 你找到的内容 您错过的内容
在测试中模拟 SDK 客户端,或让编码智能体编写模拟对象 错误分支是否运行 提供程序的实际状态代码、错误代码和标头,以及 SDK 自己的重试。 你的应用还需要一个仅用于测试的开关来访问该模拟对象。
调用真正的 API,直到它对你进行限流 真实行为 你需要为每个令牌付费,且无法按需触发slow_down、过载或支出上限
截获应用的实际流量并返回提供商的错误,或根据应用使用的令牌进行限流 真实 URL、你的 SDK 的重试策略以及提供程序的错误正文,使用你选择的限制 隔离状态下的你的代码。 保留你的单元测试以验证这一点。

在你的应用中试用

Dev Proxy 会截获应用对语言模型 API 的请求,并返回提供程序自己的错误,而你的应用仍然调用真实 URL。 对于 OpenAI,请下载预设,并使用它启动 Dev Proxy:

devproxy config get openai-throttling
devproxy --config-file "~dataFolder/configs/openai-throttling/.devproxy/devproxyrc.json"

openai-throttling预设向 https://api.openai.com/* 发出的请求中有 90% 会失败,并出现随机错误:TPM 或 RPM 的 rate_limit_exceeded、slow_down、credit_balance_exhausted 或 503 server_is_overloaded。 anthropic-throttling预设对https://api.anthropic.com/*执行相同操作,包括 RPM、输入令牌、输出令牌和加速限制对应的 429,以及 529 overloaded_error。 两个预设都包含RetryAfterPlugin,当你的应用在 429 响应的retry-after所指定的等待时间结束前再次调用 API 时,它会告知你。 它不会检查 503 和 529 响应。

若要根据应用实际使用的令牌数进行限流,请使用 LanguageModelRateLimitingPlugin。 它计算每个响应报告的提示和完成令牌,并在应用超出设置的限制时返回带有 retry-after 的 429。 它适用于 OpenAI 兼容的 API,包括 Azure OpenAI 和本地模型:

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
  "plugins": [
    {
      "name": "LanguageModelRateLimitingPlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
      "configSection": "languageModelRateLimitingPlugin"
    }
  ],
  "urlsToWatch": [
    "https://api.openai.com/*",
    "https://*.openai.azure.com/openai/deployments/*/chat/completions*"
  ],
  "languageModelRateLimitingPlugin": {
    "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/languagemodelratelimitingplugin.schema.json",
    "promptTokenLimit": 1000,
    "completionTokenLimit": 500,
    "resetTimeWindowSeconds": 60
  }
}

插件无法复现 max_tokens 估计值。 其默认的 429 响应正文使用 insufficient_quota 代码。 若要返回应用预期的速率限制错误正文,请将 whenLimitExceeded 设置为 Custom,并将 customResponseFile 指向你自己的响应。 若要安装 Dev Proxy,请参阅“设置 Dev Proxy”。

后续步骤

另请参阅