Streaming des réponses
Mis à jour le 30 juillet 2026
Le problème d’expérience utilisateur
Quand vous envoyez une requête à Claude, le modèle peut mettre entre 10 et 30 secondes à générer sa réponse complète. Sans streaming, votre utilisateur fixe un écran vide pendant tout ce temps, sans savoir si quelque chose se passe.
Le streaming résout ce problème : au lieu d’attendre la réponse entière, vous recevez les tokens au fur et à mesure qu’ils sont générés. L’utilisateur voit le texte apparaître progressivement, exactement comme dans l’interface chat de Claude.
Comment ça marche : les événements SSE
Le streaming ne rend pas la génération plus rapide — le dernier token arrive au même moment dans les deux modes. Ce qu’il change, c’est le premier token : l’utilisateur voit la réponse commencer en une seconde au lieu de fixer un écran vide pendant vingt. À vitesse égale, la perception est radicalement différente, et c’est cette perception qui fait la qualité d’une interface conversationnelle.
Techniquement, le streaming utilise le protocole Server-Sent Events (SSE). Le serveur envoie un flux d’événements structurés, chacun contenant une partie de la réponse.
Voici les types d’événements dans l’ordre où ils arrivent :
| Événement | Description |
|---|---|
message_start | Début du message, contient les métadonnées (id, modèle, usage) |
content_block_start | Début d’un bloc de contenu (texte, outil, etc.) |
content_block_delta | Fragment de texte du bloc en cours |
content_block_stop | Fin du bloc de contenu |
message_delta | Métadonnées de fin (stop_reason, usage de sortie) |
message_stop | Fin du message |
Un message typique produit cette séquence :
message_start → content_block_start → content_block_delta (x N) → content_block_stop → message_delta → message_stop
Implémentation basique avec stream=True
La façon la plus directe d’activer le streaming est de passer stream=True à l’appel API :
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Explique le fonctionnement d'un moteur diesel."}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Le paramètre flush=True est important : il force l’affichage immédiat de chaque fragment, sans attendre un saut de ligne.
La méthode simplifiée : client.messages.stream()
Le SDK Python fournit un context manager qui simplifie considérablement le streaming. Plutôt que de gérer chaque événement SSE manuellement, vous utilisez stream.text_stream :
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Écris un court poème sur la mer."}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print() # Saut de ligne final
stream.text_stream est un itérateur qui vous donne uniquement les fragments de texte, sans vous encombrer avec les événements de structure. C’est le bon niveau d’abstraction pour 90 % des usages : la mécanique SSE de la section précédente reste utile à comprendre — elle explique ce que le SDK fait pour vous — mais vous n’aurez presque jamais à la manipuler directement (start, stop, delta).
Récupérer le message complet après streaming
Parfois, vous avez besoin à la fois du streaming (pour l’affichage) et du message complet (pour le traiter ensuite). La méthode get_final_message() vous donne le message reconstitue après la fin du flux :
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Donne-moi 3 idées de projets Python pour débutants."}
]
) as stream:
# Affichage en temps reel
for text in stream.text_stream:
print(text, end="", flush=True)
# Récupération du message complet
message = stream.get_final_message()
print()
print(f"\nTokens d'entree : {message.usage.input_tokens}")
print(f"Tokens de sortie : {message.usage.output_tokens}")
print(f"Raison d'arret : {message.stop_reason}")
Le message retourné est identique à ce que vous auriez obtenu sans streaming — c’est un objet Message complet avec tout le contenu, l’usage de tokens, et les métadonnées.
Gérer les événements individuels
Si vous avez besoin d’un contrôle plus fin (par exemple pour mettre à jour une barre de progression ou détecter le début d’un bloc outil), vous pouvez écouter chaque type d’événement :
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explique la photosynthese."}
]
) as stream:
for event in stream:
if event.type == "content_block_start":
print("[Debut du bloc]")
elif event.type == "content_block_delta":
if event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)
elif event.type == "content_block_stop":
print("\n[Fin du bloc]")
elif event.type == "message_stop":
print("\n[Message termine]")
Quand utiliser le streaming
- Applications interactives : chatbots, assistants, interfaces conversationnelles
- Réponses longues : articles, analyses détaillées, génération de code
- Feedback utilisateur : montrer que le système travaille
Le streaming n’ajoute aucun coût supplémentaire et ne change pas le contenu de la réponse. La seule vraie contrepartie est architecturale : votre code aval doit accepter de travailler avec une réponse incomplète, ou attendre get_final_message(). C’est pourquoi le réflexe utile est de streamer vers l’affichage et de traiter sur le message final — chaque consommateur reçoit la forme qui lui convient. C’est purement une amélioration de l’expérience utilisateur.
Résumé
| Approche | Usage |
|---|---|
client.messages.stream() + text_stream | Cas général, simple et efficace |
Itération sur stream (événements bruts) | Contrôle fin sur chaque événement |
stream.get_final_message() | Récupérer le message complet après streaming |