Messages en streaming
Lors de la création d’un Message, vous pouvez définir "stream": true
pour diffuser progressivement la réponse en utilisant les événements envoyés par le serveur (SSE).
Streaming avec les SDK
Nos SDK Python et Typescript offrent plusieurs façons de streamer. Le SDK Python permet à la fois les streams 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 comprend 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 utilise le déroulement d’événements suivant :
message_start
: contient un objetMessage
avec uncontent
vide.- Une série de blocs de contenu, chacun ayant un événement
content_block_start
, un ou plusieurs événementscontent_block_delta
et un événementcontent_block_stop
. Chaque bloc de contenu aura unindex
qui correspond à son index dans le tableaucontent
final du Message. - Un ou plusieurs événements
message_delta
, indiquant les changements de haut niveau dans l’objetMessage
final. - Un événement
message_stop
final.
É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 overloaded_error
, qui correspondrait normalement à un HTTP 529 dans un contexte non streaming :
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Surchargé"}}
Autres événements
Conformément à notre politique de versionnage, nous pouvons ajouter de nouveaux types d’événements, et votre code doit gérer avec souplesse les types d’événements inconnus.
Types de deltas
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 text
ressemble à :
event: content_block_delta
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "alut les a"}}
Delta JSON d’entrée
Les deltas pour les blocs de contenu tool_use
correspondent aux mises à jour du champ input
du bloc. Pour prendre en charge 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 deltas de chaîne et analyser le JSON une fois que vous recevez un événement content_block_stop
, en utilisant une bibliothèque comme Pydantic pour faire une analyse JSON partielle, ou en utilisant nos SDK, qui fournissent des aides pour accéder aux valeurs incrémentielles analysées.
Un delta de bloc de contenu tool_use
ressemble à :
event: content_block_delta
data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}
Remarque : Nos modèles actuels ne prennent en charge que l’émission d’une propriété clé et valeur complète 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 un JSON partiel fragmenté afin que le format puisse automatiquement prendre en charge une granularité plus fine dans les futurs modèles.
Réponse de flux HTTP brut
Nous vous recommandons fortement d’utiliser nos SDK clients lorsque vous utilisez le mode streaming. Cependant, si vous construisez une intégration d’API directe, vous devrez gérer ces événements vous-même.
Une réponse de flux 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énementscontent_block_delta
c. Un événementcontent_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 de base
curl https://api.anthropic.com/v1/messages \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--data \
'{
"model": "claude-3-5-sonnet-20240620",
"messages": [{"role": "user", "content": "Bonjour"}],
"max_tokens": 256,
"stream": true
}'
event: message_start
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-3-5-sonnet-20240620", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}
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": "Bonjour"}}
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: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence":null}, "usage": {"output_tokens": 15}}
event: message_stop
data: {"type": "message_stop"}
Requête de streaming avec utilisation d’outil
Dans cette requête, nous demandons à Claude d’utiliser un outil pour nous donner la météo.
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-3-5-sonnet-20240620",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Obtenir la météo actuelle pour un lieu donné",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "La ville et l'état, par ex. San Francisco, CA"
}
},
"required": ["location"]
}
}
],
"tool_choice": {"type": "any"},
"messages": [
{
"role": "user",
"content": "Quel temps fait-il à San Francisco ?"
}
],
"stream": true
}'
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"}