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.

import anthropic

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Ciao"}],
    model="claude-3-opus-20240229",
) as stream:
  for text in stream.text_stream:
      print(text, end="", flush=True)

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:

  1. message_start: contiene un oggetto Message con content vuoto.
  2. Una serie di blocchi di contenuto, ognuno dei quali ha un evento 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.
  3. Uno o più eventi message_delta, che indicano modifiche di alto livello all’oggetto Message finale.
  4. 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:

Esempio di errore
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:

Delta di testo
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:

Delta JSON di input
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:

  1. Un evento message_start
  2. Potenzialmente più blocchi di contenuto, ognuno dei quali contiene: a. Un evento content_block_start b. Potenzialmente più eventi content_block_delta c. Un evento content_block_stop
  3. Un evento message_delta
  4. 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

Richiesta
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
}'
Risposta
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.

Richiesta
  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
    }'
Risposta
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"}