问题出现得很突然,日志倒是留得挺全。长报告生成总是撞上网关 60 秒超时,改成 background=true 后拿到 status=queued 的响应,客户端不知道按什么节奏查,直接 while True 猛轮询,十分钟后开始返回 429。

刚开始盯着「轮询间隔太密,几秒一次直接吃满每分钟请求数」,折腾了半个多小时,排掉了。

这类报错背后常见的原因有几处,逐个排除就行。后台任务要按 id 调 GET /v1/responses/{id},重复发起创建会生成多份任务。少数情况下是状态有 queued、in_progress、completed、failed 四档,只判 completed 会漏掉失败。

少数情况下是客户端超时后自动重发创建请求,一份任务变成三份在计费。

创建任务时打开 background 并把 id 存下来

curl -s https://api.openai.com/v1/responses -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-5-mini","input":"写一份报告","background":true}' | jq -r '.id'

接着按指数退避节奏查状态

for i in 1 2 4 8 16; do sleep $i; curl -s https://api.openai.com/v1/responses/resp_abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq -r '.status'; done

完成后把各段正文拼出来

curl -s https://api.openai.com/v1/responses/resp_abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq -r '.output[]?.content[]?.text'

失败分支单独取 error 内容

curl -s https://api.openai.com/v1/responses/resp_abc -H "Authorization: Bearer $OPENAI_API_KEY" | jq '.status,.error'

怎么算真的好了,看的是同一批现象。轮询次数控制在十次以内拿到 completed,output 段落完整,日志里没有新的 429,失败任务能在 error 字段看到具体原因而不是空对象。

容易忽略的是,后台任务一样会占配额,超时重发前先查已有任务 id,否则一次点击在账单上会出现三份同样的推理费用。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189