Streaming de ferramentas de granularidade fina
Faça streaming de entradas de ferramentas sem buffer de JSON no lado do servidor para aplicações sensíveis à latência.
O "fine-grained tool streaming" (streaming de ferramentas de granularidade fina) entrega a entrada de uma ferramenta ao seu cliente à medida que Claude a gera, sem buffer no lado do servidor nem validação de JSON. Pular a etapa de buffer 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 usar o streaming de ferramentas de granularidade fina
Todos os modelos oferecem suporte ao streaming de ferramentas de granularidade fina na Claude API, no Amazon Bedrock, na Claude Platform on AWS, 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ê queira habilitar o streaming de granularidade fina e habilite o streaming na sua requisição.
O campo eager_input_streaming é opcional. Defini-lo como true ativa o streaming de granularidade fina para essa ferramenta, e omiti-lo oferece o streaming padrão com buffer, no qual a API armazena em buffer e valida cada valor de parâmetro antes de fazer o streaming 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 de granularidade fina para ferramentas que deixam o campo sem definição. O campo por ferramenta substitui esse cabeçalho, e um false explícito mantém o streaming com buffer para uma ferramenta mesmo quando uma requisição ainda o envia. O cabeçalho legado não pode ser combinado com uma entrada de conjunto de ferramentas de uso de computador ou de uso do navegador: a API rejeita uma requisição que envia ambos, então remova o cabeçalho e defina eager_input_streaming nas ferramentas definidas pelo usuário que precisam dele. Consulte a Referência de ferramentas para a definição do campo.
O exemplo a seguir ativa o streaming de granularidade fina para uma ferramenta make_file e pede a Claude um poema longo, para que a entrada da ferramenta seja grande o suficiente para você acompanhar o 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}")Todas as abas ativam o streaming de granularidade fina para a ferramenta make_file. As abas de SDK imprimem cada fragmento de entrada no momento em que ele chega e, em seguida, imprimem a entrada completa acumulada quando 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 a entrada completa da ferramenta, o poema preenche seu terminal à medida que 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 fazer o streaming de volta, então nada é impresso para um parâmetro grande até que Claude termine de gerá-lo. Com ele, os fragmentos começam a chegar assim que Claude inicia o parâmetro, e eles costumam ser mais longos, com menos quebras no meio de palavras.
Acumulando deltas de entrada de ferramentas
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 Delta de JSON de entrada em Streaming de mensagens para o formato do evento. O streaming de ferramentas de granularidade fina muda o que você pode presumir sobre o resultado: o servidor faz o streaming dos fragmentos sem validá-los, então a string acumulada pode não ser um JSON válido.
Quando um bloco de conteúdo tool_use é transmitido via streaming, o evento inicial content_block_start contém input: {} (um objeto vazio). Isso é um espaço reservado. A entrada real chega como uma série de eventos input_json_delta, cada um carregando um fragmento de string partial_json. Para montar a entrada completa, concatene esses fragmentos e analise o 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 para quando você quer controle total sobre como a entrada é montada.
O contrato de acumulação:
- Em
content_block_startcomtype: "tool_use", inicialize uma string vazia:input_json = "" - Para cada
content_block_deltacomtype: "input_json_delta", concatene:input_json += event.delta.partial_json - Em
content_block_stop, analise a string acumulada
Proteja a análise, 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 motivo de parada e decida se deve repetir a requisição com um max_tokens maior ou reparar a entrada parcial.
A incompatibilidade de tipos entre o input: {} inicial (objeto) e partial_json (string) é intencional. O objeto vazio marca a posição no array de conteúdo. As strings delta constroem o valor real.
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:
# Não há garantia de que a string acumulada seja um JSON válido.
# Consulte "Handling invalid JSON in tool responses" nesta página.
print(f"Invalid tool input: {raw_input}")
else:
print(f"Tool input: {parsed}")Tratando JSON inválido em respostas de ferramentas
Com o streaming de ferramentas de granularidade fina, a entrada acumulada de uma chamada de ferramenta pode ser JSON inválido ou incompleto. Quando for, 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 a entrada 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 de resultado de ferramenta 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>\"}"
}Próximos passos
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.
Faça streaming das respostas da Messages API de forma incremental com server-sent events, incluindo deltas de texto, uso de ferramentas e pensamento estendido.
Analise 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?