OpenAI Python SDK 遇到 502/503 怎么排?先看自动重试、request_id 与 timeout

调用 OpenAI API 或 OpenAI-compatible 网关时,日志里出现 502、503 或超时,最常见的误判是"我的代码只调用了一次,所以服务端只收到一次请求"。OpenAI Python SDK 本身有自动重试;如果业务层、任务队列或反向代理又各自重试,一次用户操作可能被放大成多次上游请求。

排查这类问题,先不要立刻把重试次数从 2 改成 10。应该先记录 SDK 版本、异常类型、request ID、实际请求次数和每次耗时,再决定 5xx 是否值得重试。本文锁定官方 `openai==2.48.0`,用只监听 `127.0.0.1` 的 fixture 复现三组行为:默认重试两次后成功、禁用重试后首次 503 即失败、极短 timeout 触发 `APITimeoutError`。没有请求线上 OpenAI 或第三方 provider。

先跑这 5 步

1. 固定 SDK 版本

```bash

python3 -m venv /tmp/openai-sdk-check

source /tmp/openai-sdk-check/bin/activate

python -m pip install 'openai==2.48.0'

python -c 'import openai; print(openai.version)'

```

本文实测版本是 `2.48.0`。先固定版本,是因为"默认重试哪些状态、默认 timeout 多长、异常类叫什么"属于 SDK 行为,不能只凭旧文章或另一个语言 SDK 推断。

2. 先知道默认重试了什么

官方 README 写明:连接错误、408、409、429 和 `>=500` 默认自动重试 2 次,并使用短指数退避。这里的"2 次"是首次请求失败后最多再试两次,因此最坏情况下可能看到 3 次请求。

```python

from openai import OpenAI

client = OpenAI(

api_key="<YOUR_API_KEY>",

base_url="https://your-endpoint.example/v1",

)

```

如果业务代码外层还有三次重试,不能把两个数字简单理解成总共五次;嵌套重试可能形成乘法。先用服务端 request ID、访问日志或本地计数器确认真实次数。

3. 诊断时可临时关闭 SDK 重试

```python

client = OpenAI(

api_key="<YOUR_API_KEY>",

base_url="https://your-endpoint.example/v1",

max_retries=0,

)

```

`max_retries=0` 适合做一次受控诊断:让第一次 503 原样暴露,确认错误体、响应头和 request ID。它不等于"生产环境永远不重试"。生产策略还要考虑请求是否幂等、用户能否接受重复执行、上游是否给出 `Retry-After`,以及业务层是否已有队列重试。

4. 捕获异常并记录 request ID

```python

import openai

try:

response = client.chat.completions.create(

model="your-model-id",

messages={"role": "user", "content": "reply with OK"},

)

print(response._request_id)

except openai.APIStatusError as exc:

print(type(exc).name)

print(exc.status_code)

print(exc.request_id)

```

成功响应的公开 `_request_id` 来自 `x-request-id` 头;失败状态则从 `APIStatusError.request_id` 读取。第三方兼容网关不一定提供这个头,缺失时应如实记 `missing_request_id`,不要自己生成一个值冒充上游 ID。

5. 把 timeout 与 5xx 分开

```python

import httpx

from openai import OpenAI

client = OpenAI(

api_key="<YOUR_API_KEY>",

base_url="https://your-endpoint.example/v1",

max_retries=0,

timeout=httpx.Timeout(20.0, connect=2.0, read=10.0, write=10.0),

)

```

官方 SDK 默认请求超时是 10 分钟,可以传一个秒数,也可以用 `httpx.Timeout` 分开设置连接、读取和写入。客户端等待超时通常抛 `APITimeoutError`;它不等同于服务端返回 HTTP 504,也不等同于 502/503。三者的观测点和修复动作不同。

本地实测:默认 3 次请求,关闭重试后 1 次

本地 fixture 按请求头分三种场景:

  • `retry`:前两次返回 503,第三次返回 200。

  • `no-retry`:始终返回 503,并携带 `x-request-id`。

  • `timeout`:延迟响应,超过客户端极短读取时间。

执行:

```bash

python 06-evidence/probe_openai_sdk_5xx.py

```

本次输出:

```text

OPENAI_VERSION=2.48.0

DEFAULT_RETRY_REQUESTS=3

DEFAULT_RETRY_FINAL_HTTP=200

DEFAULT_RETRY_TEXT=SDK_RETRY_OK

NO_RETRY_REQUESTS=1

NO_RETRY_ERROR=InternalServerError

NO_RETRY_HTTP=503

NO_RETRY_REQUEST_ID=req_no_retry_1

TIMEOUT_REQUESTS=1

TIMEOUT_ERROR=APITimeoutError

ONLINE_PROVIDER_REQUEST=NO

```

这组结果证明,在本文锁定版本和本地夹具下,默认配置把两次 503 重试成第三次成功;`max_retries=0` 让第一次 503 直接暴露,并从响应头读回 request ID;极短 timeout 得到单独的超时异常。它不能证明线上 provider 的恢复率,也不能说明所有 503 都应该重试。

502/503 的排查顺序

第一步:确认错误来自哪一层

记录最终请求 URL 的主机、状态码、响应 `Content-Type`、错误类型和 request ID。502 常见于代理没有拿到有效上游响应,503 常见于服务暂不可用或过载,但不同网关会重写状态;最终仍要看目标服务的错误体和链路日志。

第二步:确认 SDK 已经请求了几次

不要只看业务函数调用次数。对同一次逻辑操作,用稳定的本地 trace ID 关联每次下游请求,再分别记录上游 request ID。若业务层一次、SDK 三次、队列再重跑一次,就已经存在明显放大。

第三步:决定哪些请求允许重试

纯文本推理通常可以在明确边界下重试,但带工具执行、写数据库、发消息或扣费的 Agent 任务可能产生外部副作用。即使 API 本身幂等,工具调用也未必幂等。重试前要确认请求是否已被上游接受,以及业务是否有幂等键。

第四步:给重试设总预算

总预算至少包括最大次数、总耗时和退避上限。不要让 SDK、代理、任务队列和页面按钮各自无限等待。若 503 持续存在,应停止重试并保留最后一个 request ID、错误体摘要和时间窗口,交给服务端排查。

一张检查清单

```text

openai SDK 版本已固定

记录异常类型、HTTP 状态和 request ID

确认默认 max_retries 与业务外层重试是否叠加

诊断时用 max_retries=0 暴露第一次错误

区分 502、503、504 与 APITimeoutError

记录实际请求次数和总耗时

对工具调用和写操作设置幂等边界

日志中没有完整 Key、Cookie 或用户数据

```

总结

OpenAI Python SDK 遇到 502/503 时,先还原真实请求次数,再谈增加重试。`openai==2.48.0` 默认会对 `>=500` 再试两次;`max_retries=0` 能让第一次错误原样暴露;失败的 `APIStatusError` 可读取 request ID;timeout 则是另一条异常路径。把这些信号记录完整,才能判断是短暂上游波动、代理路径错误、客户端等待超时,还是多层重试已经放大了故障。

相关推荐
全栈弄潮儿10 小时前
让 AI 帮你拆分一个功能需求:页面、接口、数据和测试任务怎么分
aigc·openai·ai编程
jeffer_liu10 小时前
OpenAI把Codex开源了?
openai·deepseek·harness·openai开源
怕浪猫1 天前
2026年为什么我推荐你学DeepSeek Harness?AI Agent开发入门指南
openai·agent·ai编程
怕浪猫1 天前
从 pre-execute 到 post-execute:AI Agent 调用工具时背后发生了什么
aigc·openai·ai编程
爱吃的小肥羊1 天前
ChatGPT Pro 额度被爆缩水 77%,OpenAI 被喷惨了!
openai
全栈弄潮儿1 天前
一周总结:把 AI 当助手,而不是答案机器
aigc·openai·ai编程
明航咨询_贾老师2 天前
ChatGPT全球宕机12+ API接口异常:事件复盘与AI从业者的架构启示
openai
怕浪猫2 天前
一行行拆解 agent-loop:AI Agent 的"思考循环"到底是怎么转的
aigc·openai·agent
9i编程2 天前
4. AI编写的SKILL,坑我一一试过,这次我自己改写:换个工具,照样不按SKILL写文档
人工智能·openai·ai编程
掘金酱2 天前
Vibe作品广场首发挑战来啦!发布作品,赢富士拍立得等千元好礼
openai·ai编程·vibecoding