Par défaut, lorsque vous envoyez une requête à l’API OpenAI, le modèle génère toute sa réponse avant que l’API vous la renvoie en une seule réponse HTTP. L’attente peut être longue si le modèle doit générer beaucoup de texte. Avec le streaming, vous pouvez afficher ou traiter le début de la réponse pendant que le modèle en génère la suite.
Ce guide porte sur le streaming HTTP (stream=true) au moyen d’événements envoyés par le serveur (SSE). Pour utiliser une connexion WebSocket persistante et fournir de nouvelles entrées au fur et à mesure avec previous_response_id, consultez le guide sur le mode WebSocket de l’API Responses.
Pour recevoir les réponses en streaming, indiquez stream=True dans votre requête au point de terminaison Responses.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import { OpenAI } from "openai";
const client = new OpenAI();
const stream = await client.responses.create({
model: "gpt-6-astra",
input: [
{
role: "user",
content: "Say 'double bubble bath' ten times fast.",
},
],
stream: true,
});
for await (const event of stream) {
console.log(event);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17from openai import OpenAI
client = OpenAI()
stream = client.responses.create(
model="gpt-6-astra",
input=[
{
"role": "user",
"content": "Say 'double bubble bath' ten times fast.",
},
],
stream=True,
)
for event in stream:
print(event)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package 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",
Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Say 'double bubble bath' ten times fast.")},
})
for stream.Next() {
fmt.Println(stream.Current().Type)
}
if err := stream.Err(); err != nil {
panic(err)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import 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.ResponseStreamEvent;
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-6-astra")
.input("Say 'double bubble bath' ten times fast.")
.build();
try (StreamResponse<ResponseStreamEvent> stream = client.responses().createStreaming(params)) {
stream.stream().forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18using OpenAI.Responses;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
ResponsesClient client = new(key);
var responses = client.CreateResponseStreamingAsync(
"gpt-6-astra",
"Say 'double bubble bath' ten times fast."
);
await foreach (StreamingResponseUpdate response in responses)
{
if (response is StreamingResponseOutputTextDeltaUpdate delta)
{
Console.Write(delta.Delta);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17require "openai"
openai = OpenAI::Client.new
stream = openai.responses.stream(
model: "gpt-6-astra",
input: [
{
role: "user",
content: "Say 'double bubble bath' ten times fast."
}
]
)
stream.each do |event|
puts(event)
end
L’API Responses utilise des événements sémantiques pour le streaming. Chaque type d’événement suit un schéma prédéfini, ce qui vous permet d’écouter les événements qui vous intéressent.
Vous trouverez la liste complète des types d’événements dans la référence de l’API sur le streaming. Voici quelques exemples :
1
2
3
4
5
6
7
8
9for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
} else if (event.type === "response.completed") {
console.log("\nResponse completed.");
} else if (event.type === "error") {
console.error(event.message);
}
}
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
26StreamingEvent = (
ResponseCreatedEvent
| ResponseInProgressEvent
| ResponseFailedEvent
| ResponseCompletedEvent
| ResponseOutputItemAdded
| ResponseOutputItemDone
| ResponseContentPartAdded
| ResponseContentPartDone
| ResponseOutputTextDelta
| ResponseOutputTextAnnotationAdded
| ResponseTextDone
| ResponseRefusalDelta
| ResponseRefusalDone
| ResponseFunctionCallArgumentsDelta
| ResponseFunctionCallArgumentsDone
| ResponseFileSearchCallInProgress
| ResponseFileSearchCallSearching
| ResponseFileSearchCallCompleted
| ResponseCodeInterpreterInProgress
| ResponseCodeInterpreterCallCodeDelta
| ResponseCodeInterpreterCallCodeDone
| ResponseCodeInterpreterCallInterpreting
| ResponseCodeInterpreterCallCompleted
| Error
)
1type StreamingEvent = responses.ResponseStreamEventUnion
1
2
3
4
5
6
7
8
9
10
11
12import 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.ResponseStreamEvent;
ResponseCreateParams params =
ResponseCreateParams.builder().model("gpt-5.5").input("Say hello.").build();
try (StreamResponse<ResponseStreamEvent> stream = client.responses().createStreaming(params)) {
stream.stream().forEach(System.out::println);
}
1
2
3
4
5require "openai"
client = OpenAI::Client.new
stream = client.responses.stream(model: "gpt-5.5", input: "Say hello.")
stream.each { |event| puts(event) }
Il est assez simple de recevoir les réponses de Chat Completions en streaming. Nous vous recommandons toutefois d’utiliser l’API Responses pour le streaming, car nous l’avons conçue pour cet usage. L’API Responses utilise des événements sémantiques pour le streaming et garantit la sûreté des types.
Pour recevoir les réponses en streaming, indiquez stream=True lorsque vous appelez le point de terminaison Chat Completions ou l’ancien point de terminaison Completions. L’appel renvoie un objet qui transmet la réponse sous forme d’événements envoyés par le serveur, chacun contenant uniquement des données.
Le flux d’événements vous transmet la réponse fragment par fragment. Vous pouvez parcourir ce flux avec une boucle for, comme dans cet exemple :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import OpenAI from "openai";
const openai = new OpenAI();
const stream = await openai.chat.completions.create({
model: "gpt-6-astra",
messages: [
{
role: "user",
content: "Say 'double bubble bath' ten times fast.",
},
],
stream: true,
});
for await (const chunk of stream) {
console.log(chunk);
console.log(chunk.choices[0].delta);
console.log("****************");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19from openai import OpenAI
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-6-astra",
messages=[
{
"role": "user",
"content": "Say 'double bubble bath' ten times fast.",
},
],
stream=True,
)
for chunk in stream:
print(chunk)
print(chunk.choices[0].delta)
print("****************")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
func main() {
client := openai.NewClient()
stream := client.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-6-astra",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Say 'double bubble bath' ten times fast."),
},
})
for stream.Next() {
fmt.Println(stream.Current())
}
if err := stream.Err(); err != nil {
panic(err)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.chat.completions.ChatCompletionChunk;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
ChatCompletionCreateParams params =
ChatCompletionCreateParams.builder()
.model("gpt-6-astra")
.addUserMessage("Say hello.")
.build();
try (StreamResponse<ChatCompletionChunk> stream =
client.chat().completions().createStreaming(params)) {
stream.stream().forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15using System.ClientModel.Primitives;
using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-6-astra";
ChatClient client = new(model, key);
await foreach (
StreamingChatCompletionUpdate update in client.CompleteChatStreamingAsync(
new UserChatMessage("Say double bubble bath ten times fast.")
)
)
{
Console.WriteLine(ModelReaderWriter.Write(update));
}
1
2
3
4
5
6
7
8
9
10
11
12require "openai"
client = OpenAI::Client.new
stream = client.chat.completions.stream(
model: "gpt-6-astra", messages: [
{
role: :user,
content: "Say hello."
}
]
)
stream.each { |event| puts(event) }
Si vous utilisez notre SDK, chaque événement est une instance typée. Vous pouvez aussi identifier chaque événement grâce à sa propriété type.
L’API émet certains événements clés du cycle de vie une seule fois et en émet d’autres plusieurs fois pendant la génération de la réponse. Voici les événements couramment écoutés pour recevoir du texte en streaming :
- `response.created`
- `response.output_text.delta`
- `response.completed`
- `error`
Vous trouverez la liste complète des événements que vous pouvez écouter dans la référence de l’API sur le streaming.
Lorsque vous recevez une réponse de Chat Completions en streaming, chaque fragment comporte un champ delta à la place du champ message. Le champ delta peut contenir un token de rôle, un token de contenu ou être vide.
{ role: 'assistant', content: '', refusal: null }
****************
{ content: 'Why' }
****************
{ content: " don't" }
****************
{ content: ' scientists' }
****************
{ content: ' trust' }
****************
{ content: ' atoms' }
****************
{ content: '?\n\n' }
****************
{ content: 'Because' }
****************
{ content: ' they' }
****************
{ content: ' make' }
****************
{ content: ' up' }
****************
{ content: ' everything' }
****************
{ content: '!' }
****************
{}
****************
Pour ne récupérer que le texte de la réponse de Chat Completions en streaming, utilisez le code suivant :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import OpenAI from "openai";
const client = new OpenAI();
const stream = await client.chat.completions.create({
model: "gpt-6-astra",
messages: [
{
role: "user",
content: "Say 'double bubble bath' ten times fast.",
},
],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from openai import OpenAI
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-6-astra",
messages=[
{
"role": "user",
"content": "Say 'double bubble bath' ten times fast.",
},
],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
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"
)
func main() {
client := openai.NewClient()
stream := client.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-6-astra",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Say 'double bubble bath' ten times fast."),
},
})
for stream.Next() {
if len(stream.Current().Choices) > 0 {
fmt.Print(stream.Current().Choices[0].Delta.Content)
}
}
if err := stream.Err(); err != nil {
panic(err)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.chat.completions.ChatCompletionChunk;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
ChatCompletionCreateParams params =
ChatCompletionCreateParams.builder()
.model("gpt-6-astra")
.addUserMessage("Say 'double bubble bath' ten times fast.")
.build();
try (StreamResponse<ChatCompletionChunk> stream =
client.chat().completions().createStreaming(params)) {
stream.stream()
.flatMap(chunk -> chunk.choices().stream())
.flatMap(choice -> choice.delta().content().stream())
.forEach(System.out::print);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-6-astra";
ChatClient client = new(model, key);
await foreach (
StreamingChatCompletionUpdate update in client.CompleteChatStreamingAsync(
new UserChatMessage("Say double bubble bath ten times fast.")
)
)
{
foreach (ChatMessageContentPart part in update.ContentUpdate)
{
Console.Write(part.Text);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13require "openai"
client = OpenAI::Client.new
stream = client.chat.completions.stream(
model: "gpt-6-astra",
messages: [
{
role: :user,
content: "Say 'double bubble bath' ten times fast."
}
]
)
stream.text.each { |text| print(text) }
Pour des cas d’usage plus avancés, comme la réception d’appels d’outils en streaming, consultez les guides suivants :
Dans une application en production, diffuser les réponses du modèle en streaming complique la modération de leur contenu, car une réponse partielle peut être plus difficile à évaluer. Tenez-en compte pour déterminer si votre usage est autorisé.
Si vous demandez des scores de modération dans une requête de génération, vous les recevez une fois que la réponse complète est disponible. Les fragments transmis pendant la génération ne contiennent pas ces scores.