OpenAI Responses API 怎样让长任务异步运行
来源:17golang原创
时间:2026-10-26 22:03:29 327浏览 收藏
我在接入长耗时 Responses 请求时,最先遇到的不是模型参数,而是连接应该一直等着,还是先把任务交出去。对于可能运行数分钟的任务,Responses API 提供了 background=true:请求先返回一个 Response 对象,客户端保存 response_id,之后再查询状态和结果。这样,业务接口不必把一次 HTTP 连接维持到模型完成。
官方文档:https://developers.openai.com/api/docs/guides/background
核心判断是:长任务用 background 模式异步提交;拿到 response ID 后轮询,只有离开 queued 或 in_progress 等处理中状态,才按终态读取结果。
先判断是否真的需要后台响应
普通的短请求仍然适合同步调用。background 模式更适合耗时不可预测、调用方可能超时,或者需要让前端显示“处理中”的任务。它解决的是连接生命周期,不会自动替你设计任务表、重试策略或业务幂等键。
我通常把它和业务记录绑定起来:提交成功后立刻保存 response_id,同时记录自己的任务状态。这样即使 Web 请求结束,后台 worker 或定时任务仍能根据这个 ID 查询进度。
提交 background 请求并保存 response_id
创建请求时把 background 设为 true。下面用 Python SDK 展示最小骨架;密钥只从环境变量读取,示例不把密钥写进代码。
import os
from openai import OpenAI
# 只从环境变量读取密钥,避免把凭据写入源码或日志。
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# background=True 让长任务异步运行,调用先得到 response 对象。
response = client.responses.create(
model="gpt-6-astra",
input="整理这份长文档的章节要点,并给出结构化摘要。",
background=True,
)
# response.id 是后续查询、取消和业务任务关联所需的标识。
print({"response_id": response.id, "status": response.status})
生产代码应把 response.id 和业务任务一起持久化,而不是只打印后丢弃。第一次返回的状态可能已经变化,也可能仍处于排队或处理中,不能依据一次响应就假设任务完成。

轮询时只把处理中状态当作等待
官方示例把 queued 和 in_progress 视为仍在运行的状态。客户端可以使用 SDK 的 retrieve 方法查询同一个响应;离开这两个状态后,再根据最终状态决定读取、重试或提示失败。
import time
def wait_for_response(client, response_id, interval=2, max_polls=60):
"""轮询后台响应;超出次数时交给上层处理,避免无限等待。"""
for _ in range(max_polls):
# retrieve 查询同一个 response_id,不重新创建模型请求。
current = client.responses.retrieve(response_id)
if current.status not in {"queued", "in_progress"}:
return current
# 轮询间隔应可配置,避免高频查询放大请求量。
time.sleep(interval)
raise TimeoutError("后台响应在轮询窗口内没有进入终态")
final_response = wait_for_response(client, response.id)
if final_response.status == "completed":
# 只有 completed 才把 output_text 当成业务结果保存。
print(final_response.output_text)
else:
# 其它终态交给业务层记录,不能伪装成成功结果。
print("response ended with status:", final_response.status)
这个骨架故意设置了最大轮询次数。到达上限不代表模型失败,只代表当前 worker 的等待窗口结束;业务层可以把任务留在“待继续查询”状态,稍后再恢复。
完成、失败和取消要分开处理
当响应进入 completed,才读取并保存输出内容。若进入其它终态,应该记录原始状态和响应 ID,便于后续排查。取消是另一种主动终止方式,不能用普通 retrieve 查询代替。
# 用已经保存的响应 ID 取消一个仍在运行的后台任务。 # 这里的 ID 应来自业务数据库或安全的任务上下文,而不是用户任意输入。 curl -X POST "https://api.openai.com/v1/responses/resp_123/cancel" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY"
取消动作适合用户主动停止、任务超过业务截止时间,或上游输入已经失效的场景。取消后仍应以 API 返回的最终状态为准,并把业务任务从“运行中”迁移到可解释的终止状态。
background、stream 和同步连接怎么选
这三种方式解决的问题不同。同步调用适合结果很快就能返回的交互;background 适合先提交、后查询;background 加 stream=true 则适合希望边运行边接收事件,同时保留断线后恢复机会的场景。
| 方式 | 适合场景 | 需要保存的东西 | 主要代价 |
|---|---|---|---|
| 同步 | 短请求、调用方能持续等待 | 请求上下文 | 连接超时会影响体验 |
| background | 长任务、异步任务中心 | response_id、业务状态 | 需要轮询与终态处理 |
| background + stream | 需要事件流、允许断线恢复 | response_id、sequence_number | 要管理游标和重连逻辑 |

断线恢复与数据保留要提前设计
如果创建 background 响应时同时启用 stream,客户端可以记录事件中的 sequence_number,连接断开后按游标继续获取事件。这个设计适合事件本身就是业务进度的情况;如果业务只关心最终答案,简单轮询通常更容易维护。
还要注意 store 的取舍。官方文档说明,background 请求需要暂时保存响应数据以支持异步轮询;是否长期保留则与 store 和项目的数据控制策略有关。对敏感数据,不要把“能轮询”误解成“可以永久取回”,应把保留周期、业务副本和删除策略一起设计。
我会采用的最小落地清单
- 提交成功后马上保存
response_id,并写入业务任务表。 - 只把
queued、in_progress当作处理中,其他状态统一进入终态分支。 - 轮询间隔和最大次数配置化,避免 worker 无限占用。
- 用户取消走 cancel 接口,超时不等于自动重发。
- 需要断线续接才启用 stream,并持久化
sequence_number。 - 按数据敏感度选择
store,同时维护业务侧的结果生命周期。
常见问题
background=true 会让模型更快吗?
它主要改变调用方式和连接生命周期,不是性能加速开关。任务仍然要等待模型完成,只是客户端可以先结束当前连接。
轮询拿到 queued 时要重新创建请求吗?
不要重新创建。继续使用原来的 response_id 查询,否则可能产生重复任务。
什么时候值得使用 stream?
当中间事件本身有展示或编排价值,并且团队愿意维护游标、断线和重复事件处理时再使用;只取最终结果时,轮询更直观。
小结
让 OpenAI Responses API 长任务异步运行的关键不是把同步代码包一层线程,而是使用 background=true 建立可查询的响应任务:保存 response_id,轮询处理中状态,按终态读取或结束,再根据是否需要事件流选择 stream。把取消、恢复和数据保留一起纳入设计,后台任务才不会从“连接超时”变成“状态丢失”。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
234 收藏
-
292 收藏
-
378 收藏
-
455 收藏
-
科技周边 · 人工智能 | 54分钟前 | python · 人工智能 · snapshot_download Hugging Face Hub HF_HUB_CACHE HF_HOME 模型缓存 huggingface_hub247 收藏
-
113 收藏
-
174 收藏
-
131 收藏
-
268 收藏
-
349 收藏
-
297 收藏
-
437 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习