Codex 和深度研究等智能体表明,推理模型可能需要数分钟才能解决复杂问题。后台模式让您能够使用 GPT-5.2 和 GPT-5.2 Pro 等模型可靠地执行耗时较长的任务,无需担心超时或其他连接问题。
后台模式会异步启动这些任务,开发者可以轮询响应对象,持续查看状态。要在后台生成响应,请发起 API 请求,并将 background 设置为 true:
零数据保留(ZDR)项目的后台请求以
store=false 运行。响应数据会临时存储在磁盘上约 10 分钟,
以支持异步执行和轮询。
对于使用调整后的滥用
监控的项目,包括
使用增强型调整后滥用监控的项目,如果省略 store 或将其设置为 true,前台请求会遵循标准的
保留规则。只有显式提供 store=true,后台响应才会在
轮询期结束后继续保留。
如果后台请求省略了 store 或将其设置为 false,响应
会在约 10 分钟后被删除。
1
2
3
4
5
6
7
8curl 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
}'1
2
3
4
5
6
7
8
9
10import 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);1
2
3
4
5
6
7
8
9
10
11from 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)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package 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)
}1
2
3
4
5
6
7
8
9
10
11
12
13import 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());1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17using 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);1
2
3
4
5
6
7
8
9
10require "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 状态时,请持续轮询。当请求离开这些状态时,就表示已进入最终状态(终态)。
1
2
3curl https://api.openai.com/v1/responses/resp_123 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import 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);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17from 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}")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36package 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())
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import 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()));1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28using 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 created = await client.CreateResponseAsync(options);
ResponseResult response = await client.GetResponseAsync(created.Id);
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());1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17require "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(response.output_text)取消后台响应
您也可以按以下方式取消正在处理的响应:
1
2
3curl -X POST https://api.openai.com/v1/responses/resp_123/cancel \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"1
2
3
4
5
6import OpenAI from "openai";
const client = new OpenAI();
const resp = await client.responses.cancel("resp_123");
console.log(resp.status);1
2
3
4
5
6
7
8
9
10import os
from openai import OpenAI
response_id = os.environ["OPENAI_RESPONSE_ID"]
client = OpenAI()
resp = client.responses.cancel(response_id)
print(resp.status)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package 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)
}1
2
3
4
5
6
7
8import 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());1
2
3
4
5
6
7
8
9
10
11using 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);1
2
3
4
5require "openai"
client = OpenAI::Client.new
response = client.responses.cancel("resp_123")
puts(response.status)重复取消是幂等的:后续调用只会返回最终的 Response 对象。
流式传输后台响应
您可以创建后台 Response,并立即开始流式接收其中的事件。如果您预计客户端可能断开流连接,并希望稍后能够恢复,这种方式可能会有帮助。为此,请创建一个 Response,并将 background 和 stream 都设置为 true。您需要持续记录一个“游标”,其值对应于每个流式事件中收到的 sequence_number。
目前,接收后台响应的首个 Token 所需的时间 比同步响应更长。我们正在努力,争取在未来几周内 缩小这一延迟差距。
1
2
3
4
5
6
7
8
9
10
11
12
13
14curl 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"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import 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;
for await (const event of stream) {
console.log(event);
cursor = event.sequence_number;
}
// If the connection drops, you can resume streaming from the last cursor (SDK support coming soon):
// const resumedStream = await client.responses.stream(resp.id, { starting_after: cursor });
// for await (const event of resumedStream) { ... }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from 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
for event in stream:
print(event)
cursor = event.sequence_number
# If your connection drops, the response continues running and you can reconnect:
# SDK support for resuming the stream is coming soon.
# for event in client.responses.stream(resp.id, starting_after=cursor):
# print(event)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45package 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."),
},
})
var cursor int64
var responseID string
for stream.Next() {
event := stream.Current()
fmt.Println(event.Type)
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)
// }
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseRetrieveParams;
import com.openai.models.responses.ResponseStreamEvent;
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();
try (StreamResponse<ResponseStreamEvent> stream = client.responses().createStreaming(params)) {
stream.stream()
.forEach(
event -> {
lastSequenceNumber.set(json.valueToTree(event).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");
});
});
}
System.out.println(
"Response " + responseId.get() + "; last sequence number " + lastSequenceNumber.get());
if (!streamCompleted.get()) {
try (StreamResponse<ResponseStreamEvent> resumed =
client
.responses()
.retrieveStreaming(
ResponseRetrieveParams.builder()
.responseId(responseId.get())
.startingAfter(lastSequenceNumber.get())
.build())) {
resumed.stream()
.forEach(
event ->
event.outputTextDelta().ifPresent(delta -> System.out.println(delta.delta())));
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82using 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."
);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25require "openai"
client = OpenAI::Client.new
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 = ""
stream.each do |event|
puts(event.type)
last_sequence_number = event.sequence_number || last_sequence_number
if event.is_a?(OpenAI::Models::Responses::ResponseCreatedEvent)
response_id = event.response.id
end
end
puts("Response #{response_id}; last sequence number #{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限制
- 后台请求可以使用
store=false,但响应数据仍会临时存储, 以支持异步执行和轮询。 - 要取消同步响应,请终止连接
- 只有在创建后台响应时使用了
stream=true,您才能从该响应启动新的流。