Claude Platform Docs
MessagesInfrastruttura degli strumenti

Streaming granulare degli strumenti

Trasmetti in streaming gli input degli strumenti senza buffering JSON lato server per applicazioni sensibili alla latenza.

Il "fine-grained tool streaming" (streaming granulare degli strumenti) consegna l'input di uno strumento al tuo client man mano che Claude lo genera, senza buffering lato server né validazione JSON. Saltare la fase di buffering riduce il tempo necessario per ricevere il primo frammento di un parametro di grandi dimensioni, come un documento o un blocco di codice, e i frammenti arrivano attraverso gli stessi eventi di Streaming dei messaggi dell'uso degli strumenti standard.

Come usare lo streaming granulare degli strumenti

Tutti i modelli supportano lo streaming granulare degli strumenti sulla Claude API, su Amazon Bedrock, Claude Platform on AWS, Google Cloud e Microsoft Foundry. Per usarlo, imposta eager_input_streaming su true su qualsiasi strumento definito dall'utente per il quale desideri abilitare lo streaming granulare, e abilita lo streaming nella tua richiesta.

Il campo eager_input_streaming è facoltativo. Impostarlo su true attiva lo streaming granulare per quello strumento, mentre ometterlo ti fornisce lo streaming standard con buffering, in cui l'API esegue il buffering e valida ogni valore di parametro prima di ritrasmetterlo in streaming. L'eccezione è una richiesta che invia ancora l'header beta legacy fine-grained-tool-streaming-2025-05-14, che attiva lo streaming granulare per gli strumenti che lasciano il campo non impostato. Il campo per singolo strumento sostituisce quell'header, e un false esplicito mantiene lo streaming con buffering per uno strumento anche quando una richiesta lo invia ancora. L'header legacy non può essere combinato con una voce di toolset computer use o browser use: l'API rifiuta una richiesta che invia entrambi, quindi rimuovi l'header e imposta eager_input_streaming sugli strumenti definiti dall'utente che ne hanno bisogno. Consulta il Riferimento degli strumenti per la definizione del campo.

L'esempio seguente attiva lo streaming granulare per uno strumento make_file e chiede a Claude una lunga poesia, in modo che l'input dello strumento sia abbastanza grande da poterlo osservare mentre arriva in streaming:

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=65536,
    model="claude-opus-5-5",
    tools=[
        {
            "name": "make_file",
            "description": "Write text to a file",
            "eager_input_streaming": True,
            "input_schema": {
                "type": "object",
                "properties": {
                    "filename": {
                        "type": "string",
                        "description": "The filename to write text to",
                    },
                    "lines_of_text": {
                        "type": "array",
                        "description": "An array of lines of text to write to the file",
                    },
                },
                "required": ["filename", "lines_of_text"],
            },
        }
    ],
    messages=[
        {
            "role": "user",
            "content": "Can you write a long poem and make a file called poem.txt?",
        }
    ],
) as stream:
    for event in stream:
        if event.type == "input_json":
            print(event.partial_json, end="", flush=True)
    final_message = stream.get_final_message()

print()
for block in final_message.content:
    if block.type == "tool_use":
        print(f"Complete tool input: {block.input}")

Ogni scheda attiva lo streaming granulare per lo strumento make_file. Le schede degli SDK stampano ogni frammento di input nel momento in cui arriva, quindi stampano l'input completo accumulato una volta terminato lo stream. La scheda cURL mostra lo stream di eventi grezzo, e la scheda CLI usa jq per stampare solo i frammenti. Poiché i frammenti stampati si uniscono a formare l'input completo dello strumento, la poesia riempie il tuo terminale man mano che Claude la scrive:

{"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", "", "I.", "", "Beneath the vast and star-strewn sky,", "Where silver moonbeams softly lie,", ...
Complete tool input: {"filename": "poem.txt", "lines_of_text": ["The Wanderer's Journey", ...]}

Senza eager_input_streaming, l'API esegue il buffering e valida ogni valore di parametro prima di ritrasmetterlo in streaming, quindi per un parametro di grandi dimensioni non viene stampato nulla finché Claude non ha finito di generarlo. Con esso, i frammenti iniziano ad arrivare non appena Claude inizia il parametro, e sono tipicamente più lunghi, con meno interruzioni a metà parola.

Accumulare i delta dell'input degli strumenti

Il contratto di accumulo è lo stesso dello streaming standard dell'uso degli strumenti, quindi questa sezione si applica con e senza eager_input_streaming. Consulta Input JSON delta in Streaming dei messaggi per il formato degli eventi. Lo streaming granulare degli strumenti cambia ciò che puoi presumere sul risultato: il server trasmette i frammenti in streaming senza validarli, quindi la stringa accumulata potrebbe non essere JSON valido.

Quando un blocco di contenuto tool_use viene trasmesso in streaming, l'evento iniziale content_block_start contiene input: {} (un oggetto vuoto). Si tratta di un segnaposto. L'input effettivo arriva come una serie di eventi input_json_delta, ciascuno dei quali trasporta un frammento di stringa partial_json. Per assemblare l'input completo, concatena questi frammenti e analizza il risultato quando il blocco si chiude.

Laddove il tuo SDK fornisce un helper di accumulo (come fanno le schede Python, TypeScript, Go, Java e Ruby nell'esempio precedente), questo se ne occupa per te. Il pattern manuale è per gli SDK senza helper, o per quando desideri il pieno controllo su come viene assemblato l'input.

Il contratto di accumulo:

  1. Su content_block_start con type: "tool_use", inizializza una stringa vuota: input_json = ""
  2. Per ogni content_block_delta con type: "input_json_delta", aggiungi: input_json += event.delta.partial_json
  3. Su content_block_stop, analizza la stringa accumulata

Proteggi il parsing, come fanno i seguenti esempi degli SDK. Una risposta può anche fermarsi a max_tokens a metà di un parametro. Controlla lo stop reason e decidi se ritentare la richiesta con un max_tokens più alto o riparare l'input parziale.

La discrepanza di tipo tra l'input: {} iniziale (oggetto) e partial_json (stringa) è intenzionale. L'oggetto vuoto contrassegna la posizione nell'array del contenuto. Le stringhe delta costruiscono il valore reale.

client = anthropic.Anthropic()

tool_inputs: dict[int, str] = {}  # index -> accumulated JSON string

with client.messages.stream(
    model="claude-opus-5-5",
    max_tokens=1024,
    tools=[
        {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "eager_input_streaming": True,
            "input_schema": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        }
    ],
    messages=[{"role": "user", "content": "Weather in Paris?"}],
) as stream:
    for event in stream:
        match event.type:
            case "content_block_start" if event.content_block.type == "tool_use":
                tool_inputs[event.index] = ""
            case "content_block_delta" if event.delta.type == "input_json_delta":
                tool_inputs[event.index] += event.delta.partial_json
            case "content_block_stop" if event.index in tool_inputs:
                raw_input = tool_inputs[event.index]
                try:
                    parsed = json.loads(raw_input)
                except json.JSONDecodeError:
                    # Non è garantito che la stringa accumulata sia JSON valido.
                    # Vedi "Handling invalid JSON in tool responses" in questa pagina.
                    print(f"Invalid tool input: {raw_input}")
                else:
                    print(f"Tool input: {parsed}")

Gestione del JSON non valido nelle risposte degli strumenti

Con lo streaming granulare degli strumenti, l'input accumulato per una chiamata a uno strumento potrebbe essere JSON non valido o incompleto. Quando lo è, non puoi eseguire lo strumento, quindi segnala invece l'errore a Claude. Il content di un risultato di strumento non deve necessariamente essere JSON, ma racchiudere la stringa grezza in un oggetto JSON sotto una singola chiave rende inequivocabile per Claude che hai ricevuto JSON non valido, e preserva l'input originale per il debugging:

{
  "INVALID_JSON": "<the unparseable input you received>"
}

Restituisci il wrapper, serializzato in una stringa, come content di un blocco di contenuto tool result con is_error impostato su true:

{
  "type": "tool_result",
  "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
  "is_error": true,
  "content": "{\"INVALID_JSON\": \"<the unparseable input you received>\"}"
}

Prossimi passi

Comprendi come funziona la finestra di contesto, come il ragionamento esteso e l'uso degli strumenti vengono conteggiati al suo interno, e come gestire il contesto man mano che le conversazioni crescono.

Trasmetti in streaming le risposte della Messages API in modo incrementale con server-sent events, inclusi i delta di testo, uso degli strumenti e ragionamento esteso.

Analizza i blocchi tool_use, formatta le risposte tool_result e gestisci gli errori con is_error.

Elenco degli strumenti forniti da Anthropic e riferimento per le proprietà facoltative di definizione degli strumenti.

Was this page helpful?