Messaggi in streaming
Quando crei un Messaggio, puoi impostare "stream": true
per trasmettere incrementalmente la risposta utilizzando server-sent events (SSE).
Streaming con le SDK
Le nostre SDK Python e Typescript offrono diversi modi per lo streaming. L’SDK Python consente sia stream sincroni che asincroni. Consulta la documentazione di ciascuna SDK per i dettagli.
Tipi di evento
Ogni evento inviato dal server include un tipo di evento denominato e dati JSON associati. Ogni evento utilizzerà un nome di evento SSE (ad es. event: message_stop
) e includerà il type
dell’evento corrispondente nei suoi dati.
Ogni stream utilizza il seguente flusso di eventi:
message_start
: contiene un oggettoMessage
concontent
vuoto.- Una serie di blocchi di contenuto, ognuno dei quali ha un evento
content_block_start
, uno o più eventicontent_block_delta
e un eventocontent_block_stop
. Ogni blocco di contenuto avrà unindex
che corrisponde al suo indice nell’arraycontent
finale del Messaggio. - Uno o più eventi
message_delta
, che indicano modifiche di alto livello all’oggettoMessage
finale. - Un evento
message_stop
finale.
Eventi ping
I flussi di eventi possono anche includere un numero qualsiasi di eventi ping
.
Eventi di errore
Occasionalmente potremmo inviare errori nel flusso di eventi. Ad esempio, durante i periodi di utilizzo elevato, potresti ricevere un overloaded_error
, che normalmente corrisponderebbe a un HTTP 529 in un contesto non in streaming:
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Sovraccarico"}}
Altri eventi
In conformità con la nostra politica di versioning, potremmo aggiungere nuovi tipi di eventi e il tuo codice dovrebbe gestire con grazia i tipi di eventi sconosciuti.
Tipi di delta
Ogni evento content_block_delta
contiene un delta
di un tipo che aggiorna il blocco content
a un dato index
.
Delta di testo
Un delta di blocco di contenuto text
ha questo aspetto:
event: content_block_delta
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "iao amic"}}
Delta JSON di input
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 il tool_use.input
finale è sempre un oggetto.
Puoi accumulare i delta di stringa e analizzare il JSON una volta ricevuto un evento content_block_stop
, utilizzando una libreria come Pydantic per eseguire l’analisi JSON parziale, o utilizzando le nostre SDK, che forniscono helper per accedere ai valori incrementali analizzati.
Un delta di blocco di contenuto tool_use
ha questo aspetto:
event: content_block_delta
data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}
Nota: i nostri modelli attuali supportano solo l’emissione di una proprietà chiave e valore completa da input
alla volta. Pertanto, quando si utilizzano gli strumenti, potrebbero esserci ritardi tra gli eventi di streaming mentre il modello è al lavoro. Una volta accumulati una chiave e un valore di input
, li emettiamo come più eventi content_block_delta
con json parziali suddivisi in modo che il formato possa supportare automaticamente una granularità più fine nei modelli futuri.
Risposta di flusso HTTP grezza
Consigliamo vivamente di utilizzare le nostre SDK client quando si utilizza la modalità di streaming. Tuttavia, se stai costruendo un’integrazione API diretta, dovrai gestire questi eventi tu stesso.
Una risposta di flusso è composta da:
- Un evento
message_start
- Potenzialmente più blocchi di contenuto, ognuno dei quali contiene:
a. Un evento
content_block_start
b. Potenzialmente più eventicontent_block_delta
c. Un eventocontent_block_stop
- Un evento
message_delta
- Un evento
message_stop
Potrebbero esserci eventi ping
dispersi in tutta la risposta. Consulta Tipi di evento per ulteriori dettagli sul formato.
Richiesta di streaming di 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-opus-20240229",
"messages": [{"role": "user", "content": "Ciao"}],
"max_tokens": 256,
"stream": true
}'
event: message_start
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-3-opus-20240229", "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": "Ciao"}}
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"}
Richiesta di streaming con utilizzo di strumenti
In questa richiesta, chiediamo a Claude di utilizzare uno strumento per dirci il meteo.
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-opus-20240229",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Ottieni il meteo attuale in una determinata posizione",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "La città e lo stato, ad es. San Francisco, CA"
}
},
"required": ["location"]
}
}
],
"tool_choice": {"type": "any"},
"messages": [
{
"role": "user",
"content": "Com'è il tempo a 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":"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"}