Durante la creazione di un Messaggio, puoi impostare "stream": true
per trasmettere incrementalmente la risposta utilizzando server-sent events (SSE).
Streaming con SDK
I nostri SDK Python e TypeScript offrono diversi modi di gestire lo streaming. L’SDK Python permette stream sia sincroni che asincroni. Consulta la documentazione in ciascun SDK per i dettagli.
Tipi di eventi
Ogni evento server-sent include un tipo di evento nominato e dati JSON associati. Ogni evento utilizzerà un nome evento SSE (es. event: message_stop
), e includerà il corrispondente type
di evento nei suoi dati.
Ogni stream utilizza il seguente flusso di eventi:
message_start
: contiene un oggetto Message
con content
vuoto.
- Una serie di blocchi di contenuto, ciascuno dei quali ha un
content_block_start
, uno o più eventi content_block_delta
, e un evento content_block_stop
. Ogni blocco di contenuto avrà un index
che corrisponde al suo indice nell’array content
finale del Messaggio.
- Uno o più eventi
message_delta
, che indicano modifiche a livello superiore all’oggetto Message
finale.
- Un evento finale
message_stop
.
Eventi ping
Gli stream di eventi possono includere anche un qualsiasi numero di eventi ping
.
Eventi di errore
Occasionalmente potremmo inviare errori nello stream di eventi. Per esempio, durante periodi di alto utilizzo, potresti ricevere un overloaded_error
, che normalmente corrisponderebbe a un HTTP 529 in un contesto non streaming:
Altri eventi
In accordo con la nostra politica di versioning, potremmo aggiungere nuovi tipi di eventi, e il tuo codice dovrebbe gestire i tipi di eventi sconosciuti in modo appropriato.
Tipi di delta
Ogni evento content_block_delta
contiene un delta
di un tipo che aggiorna il blocco content
a un determinato index
.
Delta di testo
Un delta del blocco di contenuto text
appare così:
I delta per i blocchi di contenuto tool_use
corrispondono agli aggiornamenti per il campo input
del blocco. Per supportare la massima granularità, i delta sono stringhe JSON parziali, mentre l’input
finale di tool_use
è sempre un oggetto.
Puoi accumulare le stringhe delta e analizzare il JSON una volta ricevuto un evento content_block_stop
, utilizzando una libreria come Pydantic per l’analisi JSON parziale, o utilizzando i nostri SDK, che forniscono helper per accedere ai valori incrementali analizzati.
Un delta del blocco di contenuto tool_use
appare così:
Nota: I nostri modelli attuali supportano solo l’emissione di una proprietà completa di chiave e valore da input
alla volta. Pertanto, quando si utilizzano gli strumenti, potrebbero esserci ritardi tra gli eventi di streaming mentre il modello sta lavorando. Una volta che una chiave e un valore di input
sono accumulati, li emettiamo come multipli eventi content_block_delta
con json parziale suddiviso in modo che il formato possa automaticamente supportare una granularità più fine nei modelli futuri.
Delta di pensiero
Quando si utilizza il pensiero esteso con lo streaming abilitato, riceverai contenuti di pensiero tramite eventi thinking_delta
. Questi delta corrispondono al campo thinking
dei blocchi di contenuto thinking
.
Per i contenuti di pensiero, un evento speciale signature_delta
viene inviato appena prima dell’evento content_block_stop
. Questa firma viene utilizzata per verificare l’integrità del blocco di pensiero.
Un tipico delta di pensiero appare così:
Il delta della firma appare così:
Risposta HTTP Stream grezza
Raccomandiamo vivamente di utilizzare i nostri SDK client quando si utilizza la modalità streaming. Tuttavia, se stai costruendo un’integrazione API diretta, dovrai gestire questi eventi da solo.
Una risposta stream è composta da:
- Un evento
message_start
- Potenzialmente multipli blocchi di contenuto, ciascuno dei quali contiene:
a. Un evento
content_block_start
b. Potenzialmente multipli eventi content_block_delta
c. Un evento content_block_stop
- Un evento
message_delta
- Un evento
message_stop
Ci possono essere eventi ping
dispersi in tutta la risposta. Vedi Tipi di eventi per maggiori dettagli sul formato.
Richiesta di streaming base
Richiesta di streaming con uso di strumenti
In questa richiesta, chiediamo a Claude di utilizzare uno strumento per dirci il meteo.
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":"Ok"}}
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":" controlliamo"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" il"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" meteo"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" per"}}
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"}
Richiesta di streaming con pensiero esteso
In questa richiesta, abilitiamo il pensiero esteso con lo streaming per vedere il ragionamento passo dopo passo di 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": "Risolviamo questo passo dopo passo:\n\n1. Prima scomponiamo 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"}