Des agents comme Codex et Recherche approfondie montrent que les modèles de raisonnement peuvent prendre plusieurs minutes pour résoudre des problèmes complexes. Le mode en arrière-plan vous permet d’exécuter des tâches de longue durée avec des modèles comme GPT-5.2 et GPT-5.2 Pro de manière fiable, sans vous soucier des délais d’expiration ou d’autres problèmes de connexion.
Le mode en arrière-plan lance ces tâches de manière asynchrone. Les développeurs peuvent ensuite interroger régulièrement les objets de réponse pour suivre leur état. Pour lancer la génération d’une réponse en arrière-plan, envoyez une requête API avec background défini sur true :
Les requêtes en arrière-plan des projets soumis à la politique de non-conservation des données (ZDR) s’exécutent avec
store=false. Les données de réponse sont temporairement stockées sur disque pendant environ 10
minutes pour permettre l’exécution asynchrone et l’interrogation périodique.
Pour les projets utilisant la surveillance modifiée
des abus, y compris
sa version renforcée, les requêtes au premier plan suivent les règles standard
de conservation lorsque store est omis ou défini sur true. Les réponses en arrière-plan sont
conservées après la période d’interrogation uniquement lorsque store=true est explicitement fourni.
Si store est omis ou défini sur false pour une requête en arrière-plan, la réponse
est supprimée après environ 10 minutes.
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)
Pour vérifier l’état des requêtes en arrière-plan, utilisez le point de terminaison GET de l’API Responses. Continuez à l’interroger tant que la requête est à l’état queued ou in_progress. Lorsqu’elle quitte ces états, elle a atteint un état final (terminal).
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)
Vous pouvez également annuler une réponse en cours de génération de la manière suivante :
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)
L’annulation est idempotente : si vous la demandez plusieurs fois, les appels suivants renvoient simplement l’objet Response final.
Vous pouvez créer un objet Response en arrière-plan et commencer immédiatement à recevoir ses événements en streaming. Cela peut être utile si vous prévoyez que le client interrompe le flux et souhaitez pouvoir le reprendre plus tard. Pour cela, créez un objet Response avec background et stream tous deux définis sur true. Veillez à conserver un « curseur » correspondant au sequence_number reçu dans chaque événement du flux.
Actuellement, le délai de réception du premier token d’une réponse en arrière-plan est
plus long que celui d’une réponse synchrone. Nous travaillons à réduire
cet écart de latence dans les semaines à venir.
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
- Les requêtes en arrière-plan peuvent utiliser
store=false, mais les données de réponse sont temporairement
stockées pour permettre l’exécution asynchrone et l’interrogation périodique.
- Pour annuler une réponse synchrone, fermez la connexion
- Vous ne pouvez démarrer un nouveau flux à partir d’une réponse en arrière-plan que si vous l’avez créée avec
stream=true.