Streaming SSE
Réponses en temps réel
En mode normal, vous attendez que le modèle ait fini de générer sa réponse complète avant de la recevoir. Avec le streaming SSE (Server-Sent Events), les tokens arrivent au fur et à mesure de leur génération. C’est indispensable pour les interfaces conversationnelles où l’utilisateur veut voir la réponse apparaître progressivement.

Activer le streaming
Ajoutez "stream": true à votre requête :
curl https://api.x.ai/v1/responses \
-H "Authorization: Bearer $XAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.20-reasoning",
"input": "Écris un poème sur la programmation.",
"stream": true
}'
La réponse arrive sous forme de flux SSE :
data: {"type": "response.created", "response": {...}}
data: {"type": "response.output_item.added", ...}
data: {"type": "response.content_part.added", ...}
data: {"type": "response.output_text.delta", "delta": "La "}
data: {"type": "response.output_text.delta", "delta": "programmation "}
data: {"type": "response.output_text.delta", "delta": "est "}
...
data: {"type": "response.completed", "response": {...}}
Types d’événements
| Événement | Description |
|---|---|
response.created | Début de la génération |
response.output_item.added | Nouvel élément dans la sortie |
response.content_part.added | Nouvelle partie de contenu |
response.output_text.delta | Fragment de texte (le plus fréquent) |
response.output_text.done | Texte complet d’un élément |
response.completed | Réponse finalisée avec usage |
response.failed | Erreur pendant la génération |
Streaming en Python
stream = client.responses.create(
model="grok-4.20-reasoning",
input="Explique le fonctionnement d'un compilateur.",
stream=True
)
full_text = ""
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
full_text += event.delta
elif event.type == "response.completed":
usage = event.response.usage
print(f"\n\nTokens : {usage.total_tokens}")
print(f"Coût : {usage.cost_in_nano_usd / 1e9:.6f} USD")
Le flush=True force l’affichage immédiat de chaque fragment.
Streaming avec les outils
Quand le modèle utilise des outils en mode streaming, vous recevez des événements supplémentaires :
data: {"type": "response.output_item.added", "item": {"type": "web_search_call"}}
data: {"type": "response.web_search_call.in_progress", ...}
data: {"type": "response.web_search_call.completed", ...}
data: {"type": "response.output_text.delta", "delta": "Selon les résultats..."}
Pour les appels de fonctions client, vous recevez les arguments progressivement :
data: {"type": "response.function_call.arguments.delta", "delta": "{\"city\""}
data: {"type": "response.function_call.arguments.delta", "delta": ": \"Paris\"}"}
data: {"type": "response.function_call.arguments.done", ...}
Intégration frontend
Pour une application web, envoyez le flux SSE au navigateur via un endpoint serveur :
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message: userInput })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
outputElement.textContent += text;
}
Streaming et facturation
Le streaming ne change pas la facturation. Le coût est identique qu’il soit activé ou non — seul le mode de livraison diffère. L’objet usage complet est disponible dans l’événement response.completed.
Points clés à retenir
stream: trueactive le streaming SSE — les tokens arrivent au fur et à mesure- L’événement
response.output_text.deltacontient chaque fragment de texte - L’événement
response.completedcontient la réponse finale avec les métadonnées d’usage - Le streaming fonctionne avec les outils (web_search, functions)
- Le coût est identique avec ou sans streaming