Lors de la création d’un Message, vous pouvez définir "stream": true
pour diffuser la réponse de manière incrémentielle en utilisant les événements envoyés par le serveur (SSE).
Streaming avec les SDKs
Nos SDKs Python et TypeScript offrent plusieurs façons de faire du streaming. Le SDK Python permet les flux synchrones et asynchrones. Consultez la documentation de chaque SDK pour plus de détails.
Types d’événements
Chaque événement envoyé par le serveur inclut un type d’événement nommé et des données JSON associées. Chaque événement utilisera un nom d’événement SSE (par exemple event: message_stop
), et inclura le type d’événement correspondant dans ses données.
Chaque flux suit le déroulement d’événements suivant :
message_start
: contient un objet Message
avec un content
vide.
- Une série de blocs de contenu, chacun ayant un événement
content_block_start
, un ou plusieurs événements content_block_delta
, et un événement content_block_stop
. Chaque bloc de contenu aura un index
qui correspond à son index dans le tableau final content
du Message.
- Un ou plusieurs événements
message_delta
, indiquant les changements de haut niveau dans l’objet Message
final.
- Un événement final
message_stop
.
Événements ping
Les flux d’événements peuvent également inclure un nombre quelconque d’événements ping
.
Événements d’erreur
Nous pouvons occasionnellement envoyer des erreurs dans le flux d’événements. Par exemple, pendant les périodes de forte utilisation, vous pouvez recevoir une erreur overloaded_error
, qui correspondrait normalement à un HTTP 529 dans un contexte sans streaming :
Autres événements
Conformément à notre politique de versionnement, nous pouvons ajouter de nouveaux types d’événements, et votre code doit gérer les types d’événements inconnus avec élégance.
Types de delta
Chaque événement content_block_delta
contient un delta
d’un type qui met à jour le bloc content
à un index
donné.
Delta de texte
Un delta de bloc de contenu de type text
ressemble à :
Delta JSON d’entrée
Les deltas pour les blocs de contenu tool_use
correspondent aux mises à jour du champ input
du bloc. Pour supporter une granularité maximale, les deltas sont des chaînes JSON partielles, alors que le tool_use.input
final est toujours un objet.
Vous pouvez accumuler les chaînes delta et analyser le JSON une fois que vous recevez un événement content_block_stop
, en utilisant une bibliothèque comme Pydantic pour faire l’analyse JSON partielle, ou en utilisant nos SDKs, qui fournissent des assistants pour accéder aux valeurs incrémentielles analysées.
Un delta de bloc de contenu tool_use
ressemble à :
Note : Nos modèles actuels ne prennent en charge que l’émission d’une propriété complète clé et valeur de input
à la fois. Ainsi, lors de l’utilisation d’outils, il peut y avoir des délais entre les événements de streaming pendant que le modèle travaille. Une fois qu’une clé et une valeur input
sont accumulées, nous les émettons sous forme de plusieurs événements content_block_delta
avec du json partiel fragmenté pour que le format puisse automatiquement supporter une granularité plus fine dans les futurs modèles.
Delta de réflexion
Lors de l’utilisation de la réflexion étendue avec le streaming activé, vous recevrez le contenu de réflexion via des événements thinking_delta
. Ces deltas correspondent au champ thinking
des blocs de contenu thinking
.
Pour le contenu de réflexion, un événement spécial signature_delta
est envoyé juste avant l’événement content_block_stop
. Cette signature est utilisée pour vérifier l’intégrité du bloc de réflexion.
Un delta de réflexion typique ressemble à :
Le delta de signature ressemble à :
Réponse HTTP brute en streaming
Nous recommandons fortement d’utiliser nos SDKs client lors de l’utilisation du mode streaming. Cependant, si vous construisez une intégration API directe, vous devrez gérer ces événements vous-même.
Une réponse en streaming est composée de :
- Un événement
message_start
- Potentiellement plusieurs blocs de contenu, chacun contenant :
a. Un événement
content_block_start
b. Potentiellement plusieurs événements content_block_delta
c. Un événement content_block_stop
- Un événement
message_delta
- Un événement
message_stop
Il peut y avoir des événements ping
dispersés tout au long de la réponse. Voir Types d’événements pour plus de détails sur le format.
Requête de streaming basique
Requête de streaming avec utilisation d’outil
Dans cette requête, nous demandons à Claude d’utiliser un outil pour nous dire la météo.
event: message_start
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-3-haiku-20240307","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: ping
data: {"type": "ping"}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"D'accord"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" vérifions"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" la"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" météo"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" pour"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Francisco"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" CA"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" :"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01T1x1fJ34qAmk2tNTrN7Up6","name":"get_weather","input":{}}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location\":"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"San"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" Francisc"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"o,"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" CA\""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":", "}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\"unit\": \"fah"}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"renheit\"}"}}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":89}}
event: message_stop
data: {"type":"message_stop"}
Requête de streaming avec réflexion étendue
Dans cette requête, nous activons la réflexion étendue avec streaming pour voir le raisonnement étape par étape de Claude.
event: message_start
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-3-7-sonnet-20250219", "stop_reason": null, "stop_sequence": null}}
event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": ""}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "Résolvons cela étape par étape :\n\n1. D'abord décomposons 27 * 453"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n2. 453 = 400 + 50 + 3"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n3. 27 * 400 = 10 800"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n4. 27 * 50 = 1 350"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n5. 27 * 3 = 81"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n6. 10 800 + 1 350 + 81 = 12 231"}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}
event: content_block_stop
data: {"type": "content_block_stop", "index": 0}
event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "text", "text": ""}}
event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "27 * 453 = 12 231"}}
event: content_block_stop
data: {"type": "content_block_stop", "index": 1}
event: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence": null}}
event: message_stop
data: {"type": "message_stop"}