Questa funzionalità è idonea per la Zero Data Retention (ZDR). Quando la tua organizzazione dispone di un accordo ZDR, i dati inviati tramite questa funzionalità non vengono conservati dopo che la risposta dell'API è stata restituita.
Lo "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 il passaggio 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.
Poiché l'API non esegue il buffering né valida l'input di uno strumento prima di trasmetterlo in streaming, potresti ricevere JSON parziale o non valido. Una risposta che termina con lo stop reason max_tokens può anche troncare un parametro a metà. Accumula i frammenti, proteggi il parsing e consulta Gestione di JSON non valido nelle risposte degli strumenti per sapere come restituire a Claude un input non analizzabile.
Tutti i modelli supportano lo streaming granulare degli strumenti sull'API di Claude, Claude Platform su AWS, Amazon Bedrock, Google Cloud e Microsoft Foundry. Per usarlo, imposta eager_input_streaming su true su qualsiasi strumento definito dall'utente per cui desideri abilitare lo streaming granulare, e abilita lo streaming sulla tua richiesta.
Il campo eager_input_streaming è opzionale. 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. 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 viene trasmesso in streaming:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-4-8",
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 non viene stampato nulla per un parametro di grandi dimensioni 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.
Il contratto di accumulazione è 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 assumere riguardo al 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). Questo è un segnaposto. L'input effettivo arriva come una serie di eventi input_json_delta, ciascuno contenente un frammento di stringa partial_json. Per assemblare l'input completo, concatena questi frammenti e analizza il risultato quando il blocco si chiude.
Dove il tuo SDK fornisce un helper di accumulazione (come fanno le schede Python, TypeScript, Go, Java e Ruby nell'esempio precedente), questo gestisce l'operazione per te. Il pattern manuale è per gli SDK senza un helper, o quando desideri il pieno controllo su come viene assemblato l'input.
Il contratto di accumulazione:
content_block_start con type: "tool_use", inizializza una stringa vuota: input_json = ""content_block_delta con type: "input_json_delta", aggiungi: input_json += event.delta.partial_jsoncontent_block_stop, analizza la stringa accumulataProteggi il parsing, come fanno i seguenti esempi SDK. Una risposta può anche fermarsi a max_tokens a metà di un parametro. Controlla lo stop reason e decidi se riprovare la richiesta con un max_tokens più alto o riparare l'input parziale.
La discrepanza di tipo tra l'iniziale input: {} (oggetto) e partial_json (stringa) è intenzionale. L'oggetto vuoto segna la posizione nell'array di 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-4-8",
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.
# Consulta "Gestione di JSON non valido nelle risposte degli strumenti" in questa pagina.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Reagire ai frammenti e assemblarli sono due aspetti separati. Il primo esempio reagisce a ogni frammento man mano che arriva e delega comunque l'assemblaggio all'SDK nelle schede che usano un helper di accumulazione. Usa il pattern manuale quando non stai usando un helper di accumulazione o quando desideri il pieno controllo sull'assemblaggio.
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 il fallimento 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 debug:
{
"INVALID_JSON": "<the unparseable input you received>"
}Restituisci il wrapper, serializzato come 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>\"}"
}Costruisci il wrapper con la tua libreria JSON anziché concatenando stringhe, in modo che le virgolette e altri caratteri speciali nell'input non valido vengano correttamente sottoposti a escape.
Comprendi come funziona la finestra di contesto, come il pensiero 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 dell'API Messages in modo incrementale con server-sent events, inclusi i delta di testo, uso degli strumenti e pensiero esteso.
Analizza i blocchi tool_use, formatta le risposte tool_result e gestisci gli errori con is_error.
Directory degli strumenti forniti da Anthropic e riferimento per le proprietà opzionali di definizione degli strumenti.
Was this page helpful?