Aller au contenu principal

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énementDescription
message_startDébut du message, contient les métadonnées (id, modèle, usage)
content_block_startDébut d’un bloc de contenu (texte, outil, etc.)
content_block_deltaFragment de texte du bloc en cours
content_block_stopFin du bloc de contenu
message_deltaMétadonnées de fin (stop_reason, usage de sortie)
message_stopFin 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é

ApprocheUsage
client.messages.stream() + text_streamCas 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