错误排查

OpenAI API 429 Too Many Requests 怎么处理

区分请求频率、并发、账号额度、模型繁忙和重试放大导致的 429,使用 Retry-After、有上限的指数退避、并发控制和排队机制恢复 OpenAI Compatible API。

更新于 2026-07-18已核对 2026-07-18预计阅读 10 分钟适用于 OpenAI SDK、批处理、Agent、Dify 工作流与 OpenAI Compatible API
配置字段已按公开文档核对;模型、价格和可用能力会变化,请以控制台与接口实时返回为准。
所属专题:OpenAI Compatible API 接入与排错中心

429 Too Many Requests 不只表示“请求太快”。在大模型 API 中,它还可能来自并发过高、Token 速率、账号额度、单模型繁忙,或者应用与 SDK 的双重重试。

先保存完整错误证据

至少记录以下字段:

发生时间:
模型 ID:
HTTP 状态:429
错误 type / code:
Retry-After:
请求 ID:
当时并发数:
输入 Token 估算:
重试次数:

错误正文里如果明确出现余额、配额或账号状态,就先处理账户问题;如果出现 rate limit、requests per minute 或 tokens per minute,再调整请求节奏。

429 的五种常见来源

来源 典型现象 正确动作
请求频率 短请求密集时触发 限速、排队、读取 Retry-After
Token 速率 长上下文更容易触发 缩短输入、控制批量大小
并发过高 单请求成功,并发任务失败 设置并发上限和队列
余额或配额 低频请求仍持续 429 检查余额、账号和模型权限
重试放大 故障后请求量突然增加 关闭重复重试层,增加抖动

先用同一模型发送一个短、非流式请求。如果单请求也持续 429,优先检查额度和模型状态;如果只有并发时失败,优先检查队列与限速。

正确的退避策略

服务端返回 Retry-After 时优先按该值等待。该请求头既可能是秒数,也可能是 HTTP 日期;应先解析成等待秒数。没有该字段时,再使用带随机抖动的指数退避:

第 1 次:约 1 秒
第 2 次:约 2 秒
第 3 次:约 4 秒
达到最大尝试次数后停止并返回明确错误

不要让所有实例在同一秒重试。随机抖动能减少同步重试造成的第二次流量峰值。

from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
import random
import time

MAX_WAIT_SECONDS = 60.0

def parse_retry_after(value: str | None) -> float | None:
    if not value:
        return None
    try:
        return max(0.0, float(value))
    except ValueError:
        try:
            retry_at = parsedate_to_datetime(value)
            if retry_at.tzinfo is None:
                retry_at = retry_at.replace(tzinfo=timezone.utc)
            return max(0.0, (retry_at - datetime.now(timezone.utc)).total_seconds())
        except (TypeError, ValueError, OverflowError):
            return None

def backoff(attempt: int, retry_after_header: str | None = None) -> None:
    retry_after = parse_retry_after(retry_after_header)
    if retry_after is not None and retry_after > MAX_WAIT_SECONDS:
        raise TimeoutError("Retry-After 超过当前任务允许的等待时间")
    if retry_after is not None:
        delay = retry_after
    else:
        delay = min(8.0, 2 ** attempt) + random.uniform(0, 0.5)
    time.sleep(delay)

这段代码只负责解析等待时间和暂停;attempt0 开始。是否重试还要根据错误类型、请求幂等性、业务截止时间和最大尝试次数决定。

避免 SDK 与业务层重复重试

OpenAI Python SDK 默认会在初次请求后自动重试 2 次,即每次 SDK 调用最多尝试 3 次。如果业务层总共调用 SDK 4 次,最坏可能发出 12 次上游请求。

自建重试器时应明确只保留一层:

import os

from openai import OpenAI

client = OpenAI(
    base_url="https://www.aifast.club/v1",
    api_key=os.environ["AIFAST_API_KEY"],
    max_retries=0,
)

如果使用 SDK 默认重试,则业务层不要对同一个异常再无条件循环。

批处理和 Agent 怎么限并发

批处理

  • 把任务放入队列;
  • 设置固定并发上限;
  • 每次只提高一个档位并观察 429;
  • 记录成功量、429 数量和 Token,而不是只看任务数。

Agent 与工具调用

一个用户任务可能触发多轮模型请求和工具回传。限制“用户并发”并不等于限制“模型请求并发”。应同时设置:

  • 单任务最大模型轮次;
  • 单任务最大工具调用次数;
  • 全局模型请求并发;
  • 失败后的最大重试次数;
  • 单任务预算上限。

什么时候不应该重试

  • 错误正文说明余额不足或账号不可用;
  • 请求已经达到业务截止时间;
  • 有副作用的操作无法确认是否已执行;
  • 同一模型持续失败且已达到最大尝试次数;
  • 业务层没有幂等键,重试可能产生重复任务或重复扣费。

修复完成的验收标准

  1. 单请求和目标并发分别完成至少一轮验证;
  2. 429 会读取 Retry-After 或进入有上限的退避;
  3. SDK 与业务层只有一套明确的重试责任;
  4. 监控能区分请求数、Token、并发和重试次数;
  5. 达到重试上限后能快速失败,不会无限等待。

如果短请求也持续 429,先查看当前模型与价格并核对账号状态;如果错误变成 502、断流或读取超时,继续查看502 与 stream disconnected 排查

已核对来源

参考与核对来源

下一步

先核对模型与价格,再创建独立测试 Key

模型 ID、开放状态和价格会变化;小规模验证通过后再接入生产。

查看模型与价格注册使用 查看 API 文档