Streaming (Reponses en flux continu)
Comment fonctionne le streaming
Sans streaming (mode synchrone), le flux est simple : vous envoyez une requete, le modele genere la totalite de la reponse, puis le serveur vous renvoie le resultat complet en un seul bloc. Si la reponse fait 500 tokens et que le modele genere 50 tokens par seconde, vous attendez 10 secondes sans aucun retour visuel avant de voir apparaitre le texte en entier.
Avec le streaming, le serveur commence a transmettre des que le premier token est genere. Le temps d’attente avant le premier affichage (Time To First Token, ou TTFT) passe de 10 secondes a 200-500 millisecondes. L’utilisateur voit le texte se construire progressivement, ce qui ameliore radicalement la perception de rapidite, meme si le temps total de generation est identique.
Le protocole utilise pour le streaming est le Server-Sent Events (SSE), un standard du web qui permet au serveur d’envoyer des evenements unidirectionnels au client via une connexion HTTP persistante. Chaque evenement contient un fragment de reponse (un « delta ») que le client concatene pour reconstruire la reponse complete.
Server-Sent Events (SSE) en detail
Le SSE est un protocole leger base sur HTTP. Contrairement aux WebSockets qui etablissent une connexion bidirectionnelle, le SSE est unidirectionnel : le serveur envoie des donnees au client, mais pas l’inverse. C’est parfaitement adapte au streaming d’IA ou le flux va dans un seul sens (serveur vers client).
Un flux SSE est constitue d’evenements separes par des doubles sauts de ligne. Chaque evenement commence par « data: » suivi d’un objet JSON contenant le delta (le fragment de texte genere). Le flux se termine par l’evenement special « data: [DONE] » qui signale la fin de la generation.
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"Bon"}}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"jour"}}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":" !"}}]}
data: [DONE]
Le parsing cote client est simple : lisez le flux ligne par ligne, extrayez le JSON apres « data: « , recuperez le champ delta.content et ajoutez-le au texte accumule. Les SDK officiels font tout cela automatiquement et exposent un iterateur ou un callback pour chaque nouveau token.
Implementation pratique
Activer le streaming
Activer le streaming sur les API d’IA se fait en ajoutant un seul parametre a votre requete : stream: true. L’endpoint reste le meme, seul le format de la reponse change. Voici des exemples avec les principaux providers.
# OpenAI - Streaming avec le SDK Python
from openai import OpenAI
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Explique le streaming."}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
# Anthropic - Streaming avec le SDK Python
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Explique le streaming."}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Notez la difference d’API entre OpenAI (parametre stream=True dans create) et Anthropic (methode dediee messages.stream). Le SDK Anthropic offre aussi un context manager (with) qui gere proprement la fermeture de la connexion, meme en cas d’erreur.
Streaming cote frontend
Pour afficher le streaming dans une interface web, vous avez deux approches. L’approche directe : le navigateur appelle l’API d’IA directement (deconseille en production car expose la cle API). L’approche proxy : votre backend consomme le flux SSE de l’API d’IA et le retransmet au navigateur.
Cote navigateur, l’API Fetch avec ReadableStream permet de consommer un flux SSE. Le pattern est le suivant : envoyez une requete fetch, recuperez le body comme ReadableStream, lisez-le chunk par chunk avec un TextDecoder, et parsez les evenements SSE pour extraire le texte.
Des bibliotheques comme eventsource-parser simplifient le parsing SSE cote client. Pour React, la librairie ai de Vercel (AI SDK) offre le hook useChat qui gere tout le streaming automatiquement, du fetch a l’affichage progressif du texte.
Streaming vs mode synchrone
| Critere | Mode synchrone | Mode streaming |
|---|---|---|
| Time To First Token | Egal au temps total | 200-500 ms |
| Experience utilisateur | Attente puis affichage | Texte progressif |
| Complexite code | Simple (un seul objet) | Plus complexe (iterateur) |
| Gestion erreurs | Standard (try/catch) | Erreurs mid-stream possibles |
| Usage tokens | Recu a la fin | Recu dans le dernier chunk |
| Annulation | Impossible une fois envoyee | Possible (fermer la connexion) |
| Cas d’usage ideal | Batch, traitements backend | Chatbots, interfaces live |
Le streaming est recommande pour toutes les applications ou un humain attend la reponse. Le mode synchrone reste preferable pour les traitements batch, les pipelines automatises ou les cas ou vous avez besoin du nombre de tokens avant d’afficher quoi que ce soit.
Gestion des erreurs en streaming
Le streaming introduit une complexite supplementaire dans la gestion des erreurs. En mode synchrone, si une erreur survient, vous recevez un code HTTP d’erreur clair. En streaming, la connexion est deja etablie avec un code 200, et l’erreur peut survenir a mi-parcours de la generation.
Les erreurs mid-stream se manifestent de deux facons. Soit la connexion se ferme brutalement (timeout, erreur serveur), auquel cas vous avez un texte tronque. Soit le serveur envoie un evenement d’erreur dans le flux SSE, que votre code doit detecter et traiter.
En production, implementez une strategie de recuperation. Stockez le texte genere jusqu’au point d’erreur. Si l’erreur est transitoire (timeout, 503), tentez un retry en incluant le contexte deja genere dans un nouveau prompt. Si l’erreur est definitive (contenu filtre, limite de tokens atteinte), informez l’utilisateur avec le texte partiel disponible.
Optimisation des performances
Le TTFT (Time To First Token) est la metrique cle du streaming. Il depend principalement de la taille du prompt : plus le prompt est long, plus le modele met de temps a le traiter avant de commencer a generer. Un prompt de 100 tokens aura un TTFT de 200 ms, tandis qu’un prompt de 50 000 tokens peut atteindre 2-3 secondes.
Pour optimiser le TTFT, reduisez la taille du prompt en eliminant les instructions redondantes. Le prompt caching (disponible chez Anthropic et OpenAI) ameliore significativement le TTFT sur les prompts systeme longs car les tokens mis en cache n’ont pas besoin d’etre retraites. Sur des prompts systeme de 10 000 tokens, le gain de latence peut atteindre 80%.
Le choix du modele impacte aussi le TTFT et la vitesse de generation (tokens par seconde). Les modeles compacts (Claude Haiku, Gemini Flash, GPT-4o-mini) generent 100-200 tokens/seconde, tandis que les grands modeles (Claude Opus, GPT-4o) se situent autour de 30-80 tokens/seconde. Pour une experience fluide dans un chatbot, visez au minimum 30 tokens/seconde.
Techniques avancees
Streaming structure
Une difficulte du streaming est la generation de contenu structure (JSON, tableaux). Quand le modele produit du JSON, vous ne pouvez pas parser chaque token individuellement car le JSON n’est valide qu’une fois complete. Deux solutions existent : accumuler le texte et parser quand un objet JSON est complet (avec une bibliotheque de parsing incremental), ou utiliser les modes de sortie structuree (JSON mode, structured output) qui garantissent la validite du JSON en sortie.
Annulation de la generation
Un avantage majeur du streaming est la possibilite d’annuler la generation en cours. Il suffit de fermer la connexion HTTP cote client. Le serveur detecte la deconnexion et arrete la generation, ce qui evite de consommer des tokens inutiles. Les SDK exposent cette fonctionnalite via des methodes abort() ou cancel().
L’annulation est particulierement utile dans les chatbots ou l’utilisateur envoie un nouveau message avant que la reponse precedente soit terminee, ou quand l’utilisateur clique sur un bouton « Stop » pour interrompre une generation trop longue.
Streaming multimodal
Le streaming s’etend au-dela du texte. Les API de synthese vocale (OpenAI TTS, ElevenLabs) supportent le streaming audio : les chunks audio sont transmis au fur et a mesure de la generation, permettant la lecture instantanee sans attendre la synthese complete. L’API Realtime d’OpenAI combine streaming texte et audio pour des conversations vocales en temps reel.
Questions frequentes sur le streaming
Le streaming coute-t-il plus cher que le mode synchrone ?
Non. Le cout est strictement identique : vous payez le meme nombre de tokens en entree et en sortie, que le streaming soit active ou non. La seule difference est le format de livraison de la reponse, pas le calcul effectue cote serveur.
Tous les modeles supportent-ils le streaming ?
La grande majorite des modeles de generation de texte supportent le streaming. Les exceptions sont rares et concernent principalement certains modeles specialises (embeddings, classification) ou les endpoints batch. Verifiez la documentation du provider pour confirmer le support sur un modele specifique.
Peut-on utiliser le streaming avec le function calling ?
Oui. Quand un modele decide d’appeler un outil (function calling), les arguments de l’appel sont streames progressivement. Vous pouvez commencer a parser les arguments avant que l’appel soit complet, bien que la plupart des SDK attendent la fin de l’appel avant de le transmettre a votre code.
Le streaming est-il compatible avec le mode batch ?
Non. Le batch processing est par nature asynchrone : vous soumettez des requetes et recuperez les resultats plus tard. Le streaming est concu pour le temps reel. Ces deux modes sont mutuellement exclusifs et repondent a des besoins differents.
Comment tester le streaming sans ecrire de code ?
Utilisez curl avec le flag –no-buffer pour voir le flux SSE en temps reel. Les playgrounds des providers (OpenAI Playground, Google AI Studio, Anthropic Console) affichent le streaming nativement. Postman supporte aussi la visualisation des flux SSE depuis la version 11.