Claude Platform Docs
MessagesInfraestrutura de ferramentas

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:

  1. Em content_block_start com type: "tool_use", inicialize uma string vazia: input_json = ""
  2. Para cada content_block_delta com type: "input_json_delta", anexe: input_json += event.delta.partial_json
  3. 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?