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 suportam 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 aquela ferramenta, e omiti-lo fornece o streaming padrão com buffer, no qual a API armazena em buffer e valida cada valor de parâmetro antes de transmiti-lo de volta via streaming. 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 uso de 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 ao Claude um poema longo, para que a entrada da ferramenta seja grande o suficiente para você observá-la chegando via streaming:
client = anthropic.Anthropic()
with client.messages.stream(
max_tokens=65536,
model="claude-opus-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 acumulada completa 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 formando 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 transmiti-lo de volta via streaming, então nada é impresso para um parâmetro grande até que Claude tenha terminado de gerá-lo. Com ele, os fragmentos começam a chegar assim que Claude inicia o parâmetro, e eles são tipicamente mais longos, com menos quebras no meio de palavras.
Acumulando deltas de entrada de ferramentas
O contrato de acumulação é o mesmo do streaming de uso de ferramentas padrão, portanto 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 transmite fragmentos via streaming sem validá-los, então a string acumulada pode não ser 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 placeholder. 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 auxiliar de acumulação (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 auxiliar, 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", anexe: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 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-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 "Tratamento de JSON inválido em respostas de ferramentas" 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?