Este recurso é elegível para Zero Data Retention (ZDR). Quando sua organização possui um acordo de ZDR, os dados enviados por meio deste recurso não são armazenados após a resposta da API ser retornada.
O "fine-grained tool streaming" (streaming granular de ferramentas) entrega o input de uma ferramenta ao seu cliente à medida que o Claude o gera, sem buffering no lado do servidor nem validação de JSON. Pular a etapa de buffering reduz o tempo até o primeiro fragmento de um parâmetro grande, como um documento ou um bloco de código, e os fragmentos chegam por meio dos mesmos eventos de Streaming de mensagens que o uso de ferramentas padrão.
Como a API não faz buffering nem valida o input de uma ferramenta antes de transmiti-lo, você pode receber JSON parcial ou inválido. Uma resposta que termina com o stop reason max_tokens também pode cortar um parâmetro no meio. Acumule os fragmentos, proteja o parsing e consulte Tratando JSON inválido em respostas de ferramentas para saber como retornar ao Claude um input que não pode ser parseado.
Todos os modelos suportam streaming granular de ferramentas na API do Claude, no Claude Platform on AWS, no Amazon Bedrock, no Google Cloud e no Microsoft Foundry. Para usá-lo, defina eager_input_streaming como true em qualquer ferramenta definida pelo usuário na qual você deseja habilitar o streaming granular, e habilite o streaming na sua requisição.
O campo eager_input_streaming é opcional. Defini-lo como true ativa o streaming granular para aquela ferramenta, e omiti-lo fornece o streaming padrão com buffering, no qual a API armazena em buffer e valida cada valor de parâmetro antes de transmiti-lo de volta. A exceção é uma requisição que ainda envia o cabeçalho beta legado fine-grained-tool-streaming-2025-05-14, que ativa o streaming granular para ferramentas que deixam o campo não definido. O campo por ferramenta substitui esse cabeçalho, e um false explícito mantém o streaming com buffering para uma ferramenta mesmo quando uma requisição ainda o envia. Consulte Referência de ferramentas para a definição do campo.
O exemplo a seguir ativa o streaming granular para uma ferramenta make_file e pede ao Claude um poema longo, de modo que o input da ferramenta seja grande o suficiente para você observá-lo sendo transmitido:
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}")Cada aba ativa o streaming granular para a ferramenta make_file. As abas de SDK imprimem cada fragmento de input no momento em que ele chega e, em seguida, imprimem o input completo acumulado assim que o stream termina. A aba cURL mostra o stream de eventos bruto, e a aba CLI usa jq para imprimir apenas os fragmentos. Como os fragmentos impressos se juntam para formar o input completo da ferramenta, o poema preenche seu terminal à medida que o Claude o escreve:
{"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", ...]}Sem eager_input_streaming, a API armazena em buffer e valida cada valor de parâmetro antes de transmiti-lo de volta, então nada é impresso para um parâmetro grande até que o Claude tenha terminado de gerá-lo. Com ele, os fragmentos começam a chegar assim que o Claude inicia o parâmetro, e eles são tipicamente mais longos, com menos quebras no meio de palavras.
O contrato de acumulação é o mesmo do streaming padrão de uso de ferramentas, então esta seção se aplica com e sem eager_input_streaming. Consulte Input JSON delta em Streaming de mensagens para o formato do evento. O streaming granular de ferramentas muda o que você pode assumir sobre o resultado: o servidor transmite fragmentos sem validá-los, então a string acumulada pode não ser JSON válido.
Quando um bloco de conteúdo tool_use é transmitido, o evento inicial content_block_start contém input: {} (um objeto vazio). Isso é um placeholder. O input real chega como uma série de eventos input_json_delta, cada um carregando um fragmento de string partial_json. Para montar o input completo, concatene esses fragmentos e faça o parsing do resultado quando o bloco for fechado.
Quando seu SDK fornece um helper acumulador (como fazem as abas Python, TypeScript, Go, Java e Ruby no exemplo anterior), ele cuida disso para você. O padrão manual é para SDKs sem um helper, ou quando você quer controle total sobre como o input é montado.
O contrato de acumulação:
content_block_start com type: "tool_use", inicialize uma string vazia: input_json = ""content_block_delta com type: "input_json_delta", concatene: input_json += event.delta.partial_jsoncontent_block_stop, faça o parsing da string acumuladaProteja o parsing, como fazem os exemplos de SDK a seguir. Uma resposta também pode parar em max_tokens no meio de um parâmetro. Verifique o stop reason e decida se deve tentar a requisição novamente com um max_tokens maior ou reparar o input parcial.
A incompatibilidade de tipo entre o input: {} inicial (objeto) e partial_json (string) é intencional. O objeto vazio marca o slot no array de conteúdo. As strings de delta constroem o valor real.
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:
# A string acumulada não tem garantia de ser JSON válido.
# Consulte "Lidando com JSON inválido em respostas de ferramentas" nesta página.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Reagir a fragmentos e montá-los são preocupações separadas. O primeiro exemplo reage a cada fragmento à medida que ele chega e ainda delega a montagem ao SDK nas abas que usam um helper acumulador. Use o padrão manual quando você não estiver usando um helper acumulador ou quando quiser controle total sobre a montagem.
Com o streaming granular de ferramentas, o input acumulado para uma chamada de ferramenta pode ser JSON inválido ou incompleto. Quando isso acontece, você não pode executar a ferramenta, então reporte a falha de volta ao Claude. O content de um resultado de ferramenta não precisa ser JSON, mas envolver a string bruta em um objeto JSON sob uma única chave deixa inequívoco para o Claude que você recebeu JSON inválido, e preserva o input original para depuração:
{
"INVALID_JSON": "<the unparseable input you received>"
}Retorne o wrapper, serializado como string, como o content de um bloco de conteúdo tool result com is_error definido como true:
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"is_error": true,
"content": "{\"INVALID_JSON\": \"<the unparseable input you received>\"}"
}Construa o wrapper com sua biblioteca JSON em vez de concatenar strings, para que aspas e outros caracteres especiais no input inválido sejam escapados corretamente.
Entenda como a janela de contexto funciona, como o pensamento estendido e o uso de ferramentas contam para ela, e como gerenciar o contexto à medida que as conversas crescem.
Transmita respostas da Messages API incrementalmente com server-sent events, incluindo deltas de texto, uso de ferramentas e pensamento estendido.
Faça o parsing de blocos tool_use, formate respostas tool_result e trate erros com is_error.
Diretório de ferramentas fornecidas pela Anthropic e referência para propriedades opcionais de definição de ferramentas.
Was this page helpful?