速率限制是我们的 API 对用户或客户端在指定时间内访问我们服务的次数所施加的限制。
为什么要设置速率限制?
设置速率限制是 API 的常见做法,主要有以下几个原因:
- 帮助防止 API 被滥用或误用。 例如,恶意行为者可能向 API 发送大量请求,试图使其过载或导致服务中断。通过设置速率限制,OpenAI 可以防止此类行为。
- 速率限制有助于确保每个人都能公平地使用 API。 如果某个用户或组织发送过多请求,可能会拖慢其他所有用户的 API 使用速度。通过限制单个用户可以发送的请求数量,OpenAI 确保尽可能多的人有机会使用 API,而不会遇到响应变慢的情况。
- 速率限制可以帮助 OpenAI 管理基础设施的总体负载。 如果 API 请求量急剧增加,可能会给服务器带来过大压力,导致性能问题。通过设置速率限制,OpenAI 可以帮助所有用户保持流畅、一致的使用体验。
请完整阅读本文,以便更好地了解 OpenAI 速率限制系统的运作方式。本文提供了代码示例以及处理常见问题的可行方案。下方的用量层级部分还详细介绍了您的速率限制如何自动提高。
这些速率限制如何运作?
速率限制采用的指标包括 RPM (每分钟请求数)、 RPD (每天请求数)、 TPM (每分钟 Token 数)、 TPD (每天 Token 数)、 IPM (每分钟图像数),以及适用于部分流式音频模型的每分钟音频时长(以分钟计)。任何一项指标先达到上限,都会触发速率限制。例如,您可能向 ChatCompletions 端点发送了 20 个请求,仅包含 100 个 Token。如果您的 RPM 上限为 20,这就会触发限制,即使这 20 个请求的 Token 数尚未达到 150k(假设您的 TPM 上限为 150k)。
Batch API 的队列限制按指定模型队列中的输入 Token 总数计算。待完成批处理作业中的 Token 会计入您的队列限额。批处理作业完成后,其 Token 将不再计入该模型的限额。
还需注意以下要点:
- 速率限制在组织级别和项目级别设置,而非用户级别。
- 速率限制因所使用的模型而异。
- 对于 GPT-5.5 等长上下文模型,长上下文请求有单独的速率限制。您可以在开发者控制台中查看这些限制。
- OpenAI 会为每个组织设定经核准的每月用量上限。这与您可以为组织或项目配置的支出限额不同。
- 部分模型系列共享速率限制。在您的组织限额页面中,列在同一“共享限额”下的所有模型共享一个速率限制。例如,如果列出的共享 TPM 为 3.5M,那么对该“共享限额”列表中任意模型的所有调用都会计入这 3.5M 的限额。
- 向量存储的数据摄取也按向量存储 ID 实施速率限制。对于每个向量存储,
/vector_stores/{vector_store_id}/files和/vector_stores/{vector_store_id}/file_batches共享每分钟 300 个请求的限额。摄取较大数据量时,请优先使用/vector_stores/{vector_store_id}/file_batches。
用量层级
您可以在账户设置的限额部分查看组织的速率限制和用量上限。随着您在我们 API 上的支出增加,我们会自动将您提升到下一个用量层级。这通常会提高大多数模型的速率限制。
| 层级 | 资格条件 | 用量上限 |
|---|---|---|
| 免费 | 用户必须位于受支持的地区 | $100/月 |
| 层级 1 | 已支付 $5 | $100/月 |
| 层级 2 | 已支付 $50 | $500/月 |
| 层级 3 | 已支付 $100 | $1,000/月 |
| 层级 4 | 已支付 $250 | $5,000/月 |
| 层级 5 | 已支付 $1,000 | $200,000/月 |
要查看各模型的速率限制概览,请访问模型页面。
响应标头中的速率限制
除了在账户页面查看速率限制,您还可以在 HTTP 响应标头中查看与速率限制有关的重要信息,例如剩余请求数、剩余 Token 数以及其他元数据。
响应可能包含以下标头字段:
| 字段 | 示例值 | 说明 |
|---|---|---|
| Retry-After | 56 | 如果存在此字段,其值表示遇到临时速率限制错误后,重试前至少需要等待的秒数。 |
| x-ratelimit-limit-requests | 60 | 速率限制允许的最大请求数。 |
| x-ratelimit-limit-tokens | 150000 | 速率限制允许的最大 Token 数。 |
| x-ratelimit-remaining-requests | 59 | 达到速率限制前还可发送的请求数。 |
| x-ratelimit-remaining-tokens | 149984 | 达到速率限制前剩余可用的 Token 数。 |
| x-ratelimit-reset-requests | 1s | 基于请求数的速率限制重置为初始状态前的剩余时间。 |
| x-ratelimit-reset-tokens | 6m0s | 基于 Token 数的速率限制重置为初始状态前的剩余时间。 |
| x-ratelimit-limit-project-tokens | 60000 | 项目的 Token 限额。 |
| x-ratelimit-remaining-project-tokens | 57000 | 达到项目级 Token 速率限制前剩余可用的 Token 数。 |
| x-ratelimit-reset-project-tokens | 3s | 项目级 Token 速率限制重置为初始状态前的剩余时间。 |
当项目级 Token 限额适用时,响应中可能包含项目 Token 相关响应头。临时速率限制导致的 429 响应和模型暂时过载导致的 503 响应中可能包含 Retry-After。这并不意味着配额、计费或其他需要用户采取措施的错误可以通过重试解决。
微调速率限制
您也可以在控制台中查看组织的微调速率限制,或通过 API 获取:
curl https://api.openai.com/v1/fine_tuning/model_limits \
-H "Authorization: Bearer $OPENAI_API_KEY"缓解错误
处理流量快速增长和模型过载
当您的请求速率增长过快时,API 可能返回 slow_down;当请求的模型暂时过载时,可能返回 server_is_overloaded。请检查 HTTP 状态和 error.code,以区分这两种情况:
| HTTP 状态 | 错误类型 | 错误代码 | 含义 | 处理方法 |
|---|---|---|---|---|
429 | rate_limit_error | slow_down | 您的请求速率增长过快。 | 如果响应中包含 Retry-After,请按其指定的时间等待,降低请求速率,然后逐步提高。 |
503 | service_unavailable_error | server_is_overloaded | 请求的模型暂时过载。 | 如果响应中包含 Retry-After,请按其指定的时间等待后重试。如果错误持续出现,请延长重试间隔。 |
如果响应中没有 Retry-After,请延长重试间隔,并额外增加一小段随机延迟。
即使您的流量未超出每分钟请求数和每分钟 Token 数限制,也可能出现 slow_down 错误。该错误反映的是流量增长速度,而非是否已用尽这些限额。
根据经验,当流量达到每分钟 100 万个输入 Token(TPM)后,每 15 分钟的增幅应不超过 50%。触发增长速率限制的具体阈值可能因模型和流量状况而异。
如果企业客户的按量付费流量经常触发增长速率限制,可以考虑使用规模层级,以获得适用模型更可预测的容量。对于 GPT-5.6 及后续模型,请参阅预留层级。容量层级不会改变 slow_down 响应的处理方式:如果响应中包含 Retry-After,请按其指定的时间等待,降低流量,然后逐步增加。
更新现有错误处理程序
如果您的应用已针对之前的限流和过载响应做了处理,请同时检查 HTTP 状态和 error.code:
- 某些端点之前在这两种情况下都会返回
503,并使用slow_down错误代码。现在,流量快速增长时会返回429,并使用slow_down错误代码。模型过载时仍返回503,但错误代码改为server_is_overloaded。 - 对于在创建作业前因这两种情况而被拒绝的视频请求,之前会返回
429,错误类型为invalid_request_error,错误代码为rate_limit_exceeded。现在,流量快速增长时会返回429,错误类型为rate_limit_error,错误代码为slow_down;模型过载时会返回503,错误类型为service_unavailable_error,错误代码为server_is_overloaded。视频作业状态中报告的错误属于另一种情况。
请在 SDK 错误处理程序中同时处理 429 和 503。例如,Python、TypeScript 和 Ruby 使用 RateLimitError 表示 429,使用 InternalServerError 表示 503;Java 则使用 RateLimitException 和 InternalServerException。只要您的应用仍可能收到之前的响应代码,就应继续支持它们。其他错误也可能使用相同的 HTTP 状态,因此请先检查错误响应体,再选择恢复措施。
对于流式传输请求,这些 HTTP 错误响应适用于流开始之前。流式传输开始后发生的错误可能以流事件的形式返回;读取输出后,请勿自动重新发送请求。
可以采取哪些措施来缓解这些问题?
OpenAI Cookbook 提供了一个 Python 笔记本,介绍如何避免速率限制错误,还提供了一个 Python 脚本示例,说明如何在批量处理 API 请求时保持在速率限制以内。
在提供程序化访问、批量处理功能和社交媒体自动发布功能时,您也应谨慎,考虑仅向可信客户开放这些功能。
为防止自动化和大规模滥用,请为单个用户设置指定时间段内(每天、每周或每月)的用量限额。可以考虑设置硬性上限,或对超出限额的用户启动人工审查流程。
使用指数退避重试
当请求超出临时速率限制时,API 会返回 429 错误。响应中可能包含 Retry-After 响应头,告知您再次尝试前需要等待的秒数。请将此值视为最短等待时间:至少等待这么长时间,并额外增加一小段随机延迟,以免多个客户端同时重试。
每个官方 OpenAI SDK 都会根据其重试设置,对符合条件的 429 和 503 响应自动重试。对 Retry-After 的处理方式,尤其是较长等待时间的处理方式,会因 SDK 版本和配置而异。请检查您已安装版本的重试行为,不要假定它支持服务器指定的所有等待时间。
如果服务器指定的有效等待时间超过受支持或配置的最大重试等待时间,请停止重试并推迟请求,不要提前重试。当 SDK 不接受超出其上限的等待时间时,可能会返回原始 HTTP 错误。请继续单独处理取消和超时错误:请求被取消或截止时间已过,都可能导致重试停止,且不返回该 HTTP 错误。每次尝试的超时时间不一定就是整个操作的时间上限。
如果您使用自己的 HTTP 客户端,且响应中包含值有效的 Retry-After 响应头,请按其指定的时间等待。如果该响应头缺失或值无效,请改用带随机抖动的指数退避。同时限制尝试次数和重试总耗时。如果您在应用中管理重试,请禁用 SDK 重试,或将其计入这些限制,以免嵌套的重试循环成倍增加请求数。对于配额、计费或其他需要您采取措施的错误,请勿重试。
指数退避是指请求失败后先短暂等待,之后每次重试失败都延长等待时间,直到请求成功或达到配置的重试限制。
这种方法有许多好处:
- 自动重试可让您从速率限制错误中恢复,避免程序崩溃或数据丢失
- 指数退避可让您迅速进行最初的几次重试;如果这些重试失败,后续重试仍可受益于更长的等待时间
- 在等待时间中加入随机抖动,有助于避免所有重试同时发生。
请注意,失败的请求也会计入每分钟限额,因此不停地重新发送请求并不能解决问题。
以下 Python 示例演示了作为备用方案的退避机制。它们不会检查 Retry-After:使用前,请添加对服务器有效重试提示的处理,确保封装函数不会早于服务器要求的时间重试。请禁用 SDK 重试,或将其计入应用的重试限制。
调低 max_tokens,使其与补全内容的长度相匹配
计算您的速率限制时,会取 max_tokens 与根据请求字符数估算的 Token 数中的较大值。请尽量将 max_tokens 设为接近预期响应长度的值。
批量处理请求
如果您的使用场景不需要即时响应,可以使用 Batch API 更轻松地提交和执行大量请求,而不影响同步请求的速率限制。
对于 确实 需要同步响应的使用场景,OpenAI API 分别对 每分钟请求数 和 每分钟 Token 数设有限制。
如果您已达到每分钟请求数限制,但每分钟 Token 数仍有余量,可以将多个任务合并到每个请求中,以提高吞吐量。这样可以让您每分钟处理更多 Token,尤其是在使用我们较小的模型时。
批量发送提示与普通 API 调用的方式完全相同,唯一的区别是向 prompt 参数传入字符串列表,而不是单个字符串。请参阅 Batch API 指南了解详情。