登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

OpenAI Responses API 后台任务完成后如何取回结果

来源:17golang原创

时间:2026-09-14 10:05:50 314浏览 收藏

把一个耗时较长的请求交给 OpenAI Responses API 后,服务端不会把完整结果一直挂在创建请求上。正确做法是让请求使用 background=true,先保存返回的 response.id,再通过 Responses 的取回接口读取状态和结果。只要状态仍是 queuedin_progress,就继续等待;离开这两个状态后,才进入成功、失败、取消或不完整的处理分支。

官方地址:https://developers.openai.com/api/docs/guides/background

要点速览
  • 后台任务的关键凭据是 Response ID,而不是创建请求的连接。
  • 轮询条件只覆盖 queuedin_progress,终态不能继续盲轮询。
  • 只有 completed 才适合读取正常输出,其他终态要保留 errorincomplete_details

先把后台响应拆成三个可保存的字段

创建请求返回的是一个 Response 对象,其中最重要的是 idstatus 和后续可取回的输出。业务队列至少应保存 response_id、创建时间和本地任务编号;不要把 Python SDK 对象直接塞进缓存。取回接口是 GET /v1/responses/{response_id},每次返回的状态都应当被视为新的事实。

OpenAI Responses API 后台任务中请求、Response ID、取回接口和输出对象的静态结构示意图
图1:Response ID 结构示意图,展示创建请求、Response 对象、取回接口与输出字段之间的静态关系。
字段或状态用途处理判断
id后续取回的唯一标识创建成功后立即持久化
queued / in_progress任务仍未结束等待后再次 retrieve
completed结果可用读取 output_text 或输出项
其他终态失败、取消或不完整记录诊断,不当作成功

用 SDK 按状态取回结果

下面的最小写法把轮询封装成一个函数。创建阶段只负责拿到 ID;取回阶段只在两个进行态内等待,这样可以避免任务已经结束后继续制造无意义请求。

import os
import time
from openai import OpenAI

def wait_for_response(response_id, timeout_seconds=600):
    # 复用同一个客户端,并给后台任务设置本地总超时。
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    deadline = time.monotonic() + timeout_seconds
    response = client.responses.retrieve(response_id)

    while response.status in {"queued", "in_progress"}:
        # 固定间隔足够演示;生产环境可改为带上限的退避。
        if time.monotonic() >= deadline:
            raise TimeoutError(f"后台响应轮询超时: {response_id}")
        time.sleep(2)
        response = client.responses.retrieve(response_id)

    if response.status != "completed":
        # 非成功终态也要带回服务端诊断,便于重试或人工处理。
        detail = response.error or response.incomplete_details
        raise RuntimeError(f"后台响应结束于 {response.status}: {detail}")
    return response

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
created = client.responses.create(
    model="gpt-6-astra",
    input="整理这份任务的三条执行建议。",
    background=True,
)
result = wait_for_response(created.id)
print(result.output_text)

这里的关键不是把 sleep(2) 当成固定最佳值,而是把“进行态”和“终态”分开。若你使用结构化输出,取回时仍要根据终态判断数据是否完整;不要只判断对象存在就强行解析。

终态处理决定任务是否真的完成

completed 表示可以按成功路径读取输出。failed 应记录 errorincomplete 应检查 incomplete_detailscancelled 则说明任务被取消。把所有非进行态都当成成功,是后台任务最隐蔽的逻辑错误:队列会显示完成,但用户拿不到可用答案。

OpenAI Responses API 后台任务的状态字段、成功输出和失败诊断静态关系示意图
图2:终态关系示意图,展示 status 与 output_text、error、incomplete_details 之间的读取边界。

如果任务需要人工取消,官方指南还提供了 POST /v1/responses/{response_id}/cancel。取消动作应与本地任务状态一起记录,避免取消请求尚未被服务端确认时就把业务单标成成功。

生产轮询要补上超时与保存边界

第一,给每个任务设置本地总超时,超时后进入待重试或人工检查,而不是无限循环。第二,对大量任务采用指数退避并设置最大间隔,减少短时间内的集中取回。第三,响应 ID、当前状态和最后一次错误要落到可靠存储中,进程重启后从 ID 恢复,而不是重新创建任务。

后台响应的保存策略也要看项目配置。官方说明指出,ZDR 项目的后台响应会为异步执行和轮询临时保存大约 10 分钟;在启用 Modified Abuse Monitoring 的项目中,若希望轮询窗口后仍保留后台响应,需要显式设置 store=true。因此,长于这个窗口的业务不要把 Responses 当作永久任务数据库,应该及时取回并写入自己的结果存储。

常见问题

为什么创建请求返回后不能直接读取最终答案?

因为后台模式先返回任务对象,生成仍可能处于 queuedin_progress。必须使用同一个 ID 取回到终态。

轮询什么时候停止?

当状态不再是 queuedin_progress 时停止,再按终态分支处理。

拿不到 output_text 时先查什么?

先看 status,然后检查 errorincomplete_details;不要用空字符串掩盖失败原因。

一句话记忆:创建阶段保存 ID,进行态阶段轮询,终态阶段判定结果,成功输出和失败诊断走不同的数据路径。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>