OpenAI 后台模式
Codex和深度研究等智能体说明,推理模型可能需要数分钟处理复杂问题。后台模式允许GPT-5.2、GPT-5.2 Pro等模型异步执行长任务,减少长连接超时或断开对结果获取的影响。
设置background=true启动后台生成,随后轮询响应对象查看状态。
零数据保留(ZDR)项目的后台请求使用store=false,但仍会将响应数据临时写入磁盘约10分钟,支持异步执行和轮询。这不是完全不落盘的保证。
对使用修改后的滥用监控(MAM)及增强MAM的项目:前台请求在省略store或设为true时按标准保留;后台响应只有显式store=true才会在轮询期后继续保留。后台请求省略store或设为false,响应约10分钟后删除。
来源示例 1(bash):
## [中文] 异步生成关于太空水獭的长篇小说,background=true,先取得响应状态。
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-6-astra",
"input": "Write a very long novel about otters in space.",
"background": true
}'
来源示例 2(javascript):
// [中文] 异步生成关于太空水獭的长篇小说,background=true,先取得响应状态。
import OpenAI from "openai";
const client = new OpenAI();
const resp = await client.responses.create({
model: "gpt-6-astra",
input: "Write a very long novel about otters in space.",
background: true,
});
console.log(resp.status);
来源示例 3(python):
## [中文] 异步生成关于太空水獭的长篇小说,background=true,先取得响应状态。
from openai import OpenAI
client = OpenAI()
resp = client.responses.create(
model="gpt-6-astra",
input="Write a very long novel about otters in space.",
background=True,
)
print(resp.status)
来源示例 4(go):
// [中文] 异步生成关于太空水獭的长篇小说,background=true,先取得响应状态。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Background: openai.Bool(true),
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("Write a very long novel about otters in space."),
},
})
if err != nil {
panic(err)
}
fmt.Println(response.Status)
}
来源示例 5(java):
// [中文] 异步生成详细市场分析,background=true,先取得响应状态。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Write a detailed market analysis.")
.background(true)
.build();
var response = client.responses().create(params);
System.out.println(response.status().orElseThrow());
来源示例 6(csharp):
// [中文] 异步生成关于太空水獭的长篇小说,background=true,先取得响应状态。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
CreateResponseOptions options = new()
{
Model = "gpt-6-astra",
BackgroundModeEnabled = true,
};
options.InputItems.Add(
ResponseItem.CreateUserMessageItem("Write a very long novel about otters in space.")
);
ResponseResult response = await client.CreateResponseAsync(options);
Console.WriteLine(response.Status);
来源示例 7(ruby):
## [中文] 异步生成详细市场分析,background=true,先取得响应状态。
require "openai"
client = OpenAI::Client.new
response = client.responses.create(
model: "gpt-6-astra",
input: "Write a detailed market analysis.",
background: true
)
puts(response.status)
轮询后台响应
使用Responses的GET端点读取状态。处于queued或in_progress时继续轮询;离开这些状态后已进入终态,仍应查看是成功、失败还是其他终态。
来源示例 8(bash):
## [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
curl https://api.openai.com/v1/responses/resp_123 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"
来源示例 9(javascript):
// [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
import OpenAI from "openai";
const client = new OpenAI();
let resp = await client.responses.create({
model: "gpt-6-astra",
input: "Write a very long novel about otters in space.",
background: true,
});
while (resp.status === "queued" || resp.status === "in_progress") {
console.log("Current status: " + resp.status);
await new Promise((resolve) => setTimeout(resolve, 2000)); // wait 2 seconds
resp = await client.responses.retrieve(resp.id);
}
console.log("Final status: " + resp.status + "\nOutput:\n" + resp.output_text);
来源示例 10(python):
## [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
from openai import OpenAI
from time import sleep
client = OpenAI()
resp = client.responses.create(
model="gpt-6-astra",
input="Write a very long novel about otters in space.",
background=True,
)
while resp.status in {"queued", "in_progress"}:
print(f"Current status: {resp.status}")
sleep(2)
resp = client.responses.retrieve(resp.id)
print(f"Final status: {resp.status}\nOutput:\n{resp.output_text}")
来源示例 11(go):
// [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
package main
import (
"context"
"fmt"
"time"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Background: openai.Bool(true),
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("Write a very long novel about otters in space."),
},
})
if err != nil {
panic(err)
}
for response.Status == "queued" || response.Status == "in_progress" {
fmt.Println("Current status:", response.Status)
time.Sleep(2 * time.Second)
response, err = client.Responses.Get(context.Background(), response.ID, responses.ResponseGetParams{})
if err != nil {
panic(err)
}
}
fmt.Printf("Final status: %s\nOutput:\n%s\n", response.Status, response.OutputText())
}
来源示例 12(java):
// [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseStatus;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Write a very long novel about otters in space.")
.background(true)
.build();
var response = client.responses().create(params);
while (response.status().filter(ResponseStatus.QUEUED::equals).isPresent()
|| response.status().filter(ResponseStatus.IN_PROGRESS::equals).isPresent()) {
System.out.println("Current status: " + response.status().orElseThrow());
Thread.sleep(1000);
response = client.responses().retrieve(response.id());
}
System.out.println("Final status: " + response.status().orElseThrow());
response.output().stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.text()));
来源示例 13(csharp):
// [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
CreateResponseOptions options = new()
{
Model = "gpt-6-astra",
BackgroundModeEnabled = true,
};
options.InputItems.Add(
ResponseItem.CreateUserMessageItem("Write a very long novel about otters in space.")
);
ResponseResult response = await client.CreateResponseAsync(options);
while (response.Status is ResponseStatus.Queued or ResponseStatus.InProgress)
{
await Task.Delay(TimeSpan.FromSeconds(1));
response = await client.GetResponseAsync(response.Id);
}
if (response.Status != ResponseStatus.Completed)
{
throw new InvalidOperationException($"Background response ended with status: {response.Status}");
}
Console.WriteLine($"Status: {response.Status}");
Console.WriteLine(response.GetOutputText());
来源示例 14(ruby):
## [中文] 轮询queued或in_progress状态,离开等待态后还需检查最终状态。
require "openai"
client = OpenAI::Client.new
response = client.responses.create(
model: "gpt-6-astra",
input: "Write a very long novel about otters in space.",
background: true
)
while [:queued, :in_progress].include?(response.status)
puts("Current status: #{response.status}")
sleep(2)
response = client.responses.retrieve(response.id)
end
puts("Final status: #{response.status}")
puts("Output:")
puts(response.output_text)
取消后台响应
可取消正在执行的响应:
来源示例 15(bash):
## [中文] 按已有响应ID取消后台任务;重复取消幂等。
curl -X POST https://api.openai.com/v1/responses/resp_123/cancel \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"
来源示例 16(javascript):
// [中文] 按已有响应ID取消后台任务;重复取消幂等。
import OpenAI from "openai";
const client = new OpenAI();
const resp = await client.responses.cancel("resp_123");
console.log(resp.status);
来源示例 17(python):
## [中文] 按已有响应ID取消后台任务;重复取消幂等。
import os
from openai import OpenAI
response_id = os.environ["OPENAI_RESPONSE_ID"]
client = OpenAI()
resp = client.responses.cancel(response_id)
print(resp.status)
来源示例 18(go):
// [中文] 按已有响应ID取消后台任务;重复取消幂等。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
func main() {
client := openai.NewClient()
canceled, err := client.Responses.Cancel(context.Background(), "resp_123")
if err != nil {
panic(err)
}
fmt.Println(canceled.Status)
}
来源示例 19(java):
// [中文] 按已有响应ID取消后台任务;重复取消幂等。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
String responseId = "resp_123";
var response = client.responses().cancel(responseId);
System.out.println(response.status());
来源示例 20(csharp):
// [中文] 按已有响应ID取消后台任务;重复取消幂等。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
// Replace this illustrative ID with the background response to cancel.
string responseId = "resp_123";
ResponseResult response = await client.CancelResponseAsync(responseId);
Console.WriteLine(response.Status);
来源示例 21(ruby):
## [中文] 按已有响应ID取消后台任务;重复取消幂等。
require "openai"
client = OpenAI::Client.new
response = client.responses.cancel("resp_123")
puts(response.status)
重复取消具有幂等性,后续调用返回最终Response对象。
流式读取后台响应
同时设置background=true和stream=true,可以立即读取事件,并在客户端断开后尝试续流。保存与事件sequence_number对应的游标。
当前来源说明后台请求的首词元延迟高于同步请求,并计划缩小差距,不应把这一计划当成已经实现的延迟保证。
来源示例 22(bash):
## [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 Python现也记录响应ID并过滤keepalive;Java示例设置请求超时并从已保存游标恢复一次,Ruby确保关闭流并保留续流提示。各语言恢复路径仍须分别验证。
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-6-astra",
"input": "Write a very long novel about otters in space.",
"background": true,
"stream": true
}'
// To resume:
curl "https://api.openai.com/v1/responses/resp_123?stream=true&starting_after=42" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"
来源示例 23(javascript):
// [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 当前JavaScript版排除keepalive游标,并从事件取得responseId,用retrieve续流。
import OpenAI from "openai";
const client = new OpenAI();
const stream = await client.responses.create({
model: "gpt-6-astra",
input: "Write a very long novel about otters in space.",
background: true,
stream: true,
});
let cursor = null;
let responseId = null;
for await (const event of stream) {
console.log(event);
// Keepalives use connection counters, not stored-event resume positions.
if (String(event.type) !== "keepalive") cursor = event.sequence_number;
if ("response" in event && event.response?.id) responseId = event.response.id;
}
// If the connection drops, resume streaming from the last stored-event cursor:
// const resumedStream = await client.responses.retrieve(responseId, {
// stream: true,
// starting_after: cursor,
// });
// for await (const event of resumedStream) { ... }
来源示例 24(python):
## [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 各语言的keepalive处理和恢复路径按当前示例分别说明。
from openai import OpenAI
client = OpenAI()
## Fire off an async response but also start streaming immediately
stream = client.responses.create(
model="gpt-6-astra",
input="Write a very long novel about otters in space.",
background=True,
stream=True,
)
cursor = None
response_id = None
for event in stream:
print(event)
if event.type == "response.created":
response_id = event.response.id
# Keepalives use connection counters, not stored-event resume positions.
if event.type != "keepalive":
cursor = event.sequence_number
# If your connection drops, the response continues running and you can reconnect:
# with client.responses.stream(response_id=response_id, starting_after=cursor) as resumed:
# for event in resumed:
# print(event)
if event.type == "response.created":
response_id = event.response.id
来源示例 25(go):
// [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 Python现也记录响应ID并过滤keepalive;Java示例设置请求超时并从已保存游标恢复一次,Ruby确保关闭流并保留续流提示。各语言恢复路径仍须分别验证。
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
stream := client.Responses.NewStreaming(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Background: openai.Bool(true),
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String("Write a very long novel about otters in space."),
},
})
defer stream.Close()
var cursor int64
var responseID string
for stream.Next() {
event := stream.Current()
fmt.Println(event.Type)
// Keepalives use connection counters, not stored-event resume positions.
if event.Type != "keepalive" {
cursor = event.SequenceNumber
}
if event.Response.ID != "" {
responseID = event.Response.ID
}
}
if err := stream.Err(); err != nil {
panic(err)
}
fmt.Printf("response %s last cursor %d\n", responseID, cursor)
// If the connection drops, resume streaming from the last cursor:
// resumed := client.Responses.GetStreaming(
// context.Background(),
// responseID,
// responses.ResponseGetParams{StartingAfter: openai.Int(cursor)},
// )
// for resumed.Next() {
// fmt.Println(resumed.Current().Type)
// }
}
来源示例 26(java):
// [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 Python现也记录响应ID并过滤keepalive;Java示例设置请求超时并从已保存游标恢复一次,Ruby确保关闭流并保留续流提示。各语言恢复路径仍须分别验证。
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.RequestOptions;
import com.openai.core.http.StreamResponse;
import com.openai.errors.OpenAIIoException;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseRetrieveParams;
import com.openai.models.responses.ResponseStreamEvent;
import java.time.Duration;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Write a very long novel about otters in space.")
.background(true)
.build();
AtomicLong lastSequenceNumber = new AtomicLong(-1);
AtomicReference<String> responseId = new AtomicReference<>("");
AtomicBoolean streamCompleted = new AtomicBoolean(false);
JsonMapper json = new JsonMapper();
// This long-running response can exceed the SDK's default request deadline.
RequestOptions streamOptions = RequestOptions.builder().timeout(Duration.ofMinutes(30)).build();
try (StreamResponse<ResponseStreamEvent> stream =
client.responses().createStreaming(params, streamOptions)) {
stream.stream()
.forEach(
event -> {
if (event.failed().isPresent()
|| event.incomplete().isPresent()
|| event.error().isPresent()) {
throw new IllegalStateException("Background response did not complete");
}
var data = json.valueToTree(event);
// Keepalives count connection traffic, not stored response events.
if (data.path("type").asText().startsWith("response.")
&& data.path("sequence_number").isIntegralNumber()) {
lastSequenceNumber.set(data.path("sequence_number").asLong());
}
event
.created()
.ifPresent(
created -> {
responseId.set(created.response().id());
System.out.println("response.created");
});
event
.outputTextDelta()
.ifPresent(
delta -> {
System.out.println("response.output_text.delta");
});
event
.completed()
.ifPresent(
completed -> {
streamCompleted.set(true);
System.out.println("response.completed");
});
});
} catch (OpenAIIoException error) {
// Resume an interrupted stream once, from its stored-event checkpoint.
if (Thread.currentThread().isInterrupted()
|| streamCompleted.get()
|| responseId.get().isBlank()
|| lastSequenceNumber.get() < 0) {
throw error;
}
}
System.out.println(
"Response " + responseId.get() + "; last sequence number " + lastSequenceNumber.get());
if (!streamCompleted.get()) {
if (Thread.currentThread().isInterrupted()
|| responseId.get().isBlank()
|| lastSequenceNumber.get() < 0) {
throw new IllegalStateException("Stream ended without a resumable checkpoint");
}
try (StreamResponse<ResponseStreamEvent> resumed =
client
.responses()
.retrieveStreaming(
ResponseRetrieveParams.builder()
.responseId(responseId.get())
.startingAfter(lastSequenceNumber.get())
.build(),
streamOptions)) {
resumed.stream()
.forEach(
event -> {
if (event.failed().isPresent()
|| event.incomplete().isPresent()
|| event.error().isPresent()) {
throw new IllegalStateException("Resumed response did not complete");
}
event.outputTextDelta().ifPresent(delta -> System.out.println(delta.delta()));
event.completed().ifPresent(completed -> streamCompleted.set(true));
});
}
if (!streamCompleted.get()) {
throw new IllegalStateException("Resumed response did not complete");
}
}
来源示例 27(csharp):
// [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 Python现也记录响应ID并过滤keepalive;Java示例设置请求超时并从已保存游标恢复一次,Ruby确保关闭流并保留续流提示。各语言恢复路径仍须分别验证。
using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
CreateResponseOptions options = new()
{
Model = "gpt-6-astra",
BackgroundModeEnabled = true,
StreamingEnabled = true,
};
options.InputItems.Add(
ResponseItem.CreateUserMessageItem("Write a very long novel about otters in space.")
);
string? responseId = null;
int lastSequenceNumber = -1;
bool completed = false;
void HandleUpdate(StreamingResponseUpdate update)
{
lastSequenceNumber = update.SequenceNumber;
switch (update)
{
case StreamingResponseCreatedUpdate created:
responseId = created.Response.Id;
break;
case StreamingResponseOutputTextDeltaUpdate text:
Console.Write(text.Delta);
break;
case StreamingResponseCompletedUpdate:
completed = true;
break;
case StreamingResponseFailedUpdate:
throw new InvalidOperationException("The background response failed.");
case StreamingResponseIncompleteUpdate:
throw new InvalidOperationException("The background response was incomplete.");
case StreamingResponseErrorUpdate error:
throw new InvalidOperationException($"The response stream failed: {error.Message}");
}
}
try
{
await foreach (
StreamingResponseUpdate update in client.CreateResponseStreamingAsync(options)
)
{
HandleUpdate(update);
}
}
catch (Exception error)
when (error is HttpRequestException or IOException && responseId is not null)
{
// The background response continues after its streaming connection is interrupted.
}
if (!completed)
{
if (responseId is null)
{
throw new InvalidOperationException("The response stream ended before providing its ID.");
}
GetResponseOptions resumeOptions = new(responseId)
{
StartingAfter = lastSequenceNumber,
StreamingEnabled = true,
};
await foreach (StreamingResponseUpdate update in client.GetResponseStreamingAsync(resumeOptions))
{
HandleUpdate(update);
}
if (!completed)
{
throw new InvalidOperationException(
"The resumed response stream ended before the background response completed."
);
}
}
来源示例 28(ruby):
## [中文] 同时开启background与stream,读取事件并记录续流游标;示例任务为太空水獭长篇小说。 各语言的keepalive处理和恢复路径按当前示例分别说明。
require "openai"
## An uncapped background novel can run beyond the SDK's default ten minutes.
client = OpenAI::Client.new(timeout: 30 * 60)
stream = client.responses.stream(
model: "gpt-6-astra",
input: "Write a very long novel about otters in space.",
background: true
)
last_sequence_number = -1
response_id = ""
begin
stream.each do |event|
puts(event.type)
# The SDK filters transport keepalives before yielding stored events.
last_sequence_number = event.sequence_number || last_sequence_number
if event.is_a?(OpenAI::Models::Responses::ResponseCreatedEvent)
response_id = event.response.id
end
end
ensure
stream.close
end
puts("response #{response_id} last cursor #{last_sequence_number}")
## If the connection drops, resume from the last sequence number:
## client.responses.stream(response_id: response_id, starting_after: last_sequence_number).each do |event|
## puts(event.type)
## end
2026-10-27的JavaScript示例已更新续流处理:keepalive使用连接计数,不是持久化事件的恢复位置,因此不据其更新游标;从携带响应的事件保存响应ID,之后用responses.retrieve配合stream:true与starting_after续流。
限制
- 后台请求可用
store=false,但仍会临时保存响应以支持异步执行和轮询。 - 取消同步响应应终止连接。
- 只有创建时设置
stream=true的后台响应,才能再启动新的读取流。

TRAE-AI编程


更多建议: