Claude Platform Docs
MessagesCapacidades do modelo

Streaming de mensagens

Faça streaming incremental das respostas da Messages API com server-sent events, incluindo text, uso de ferramentas e deltas de pensamento estendido.

Ao criar uma Message, você pode definir "stream": true para fazer streaming incremental da resposta usando server-sent events (SSE).

Streaming com SDKs

O Python SDK e o TypeScript SDK oferecem várias maneiras de fazer streaming. O PHP SDK fornece streaming através de createStream(). O Python SDK permite streams síncronos e assíncronos. Consulte a documentação em cada SDK para mais detalhes.

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
    model="claude-opus-5-5",
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Obter a mensagem final sem tratar eventos

Se você não precisa processar o texto à medida que ele chega, os SDKs fornecem uma maneira de usar streaming internamente enquanto retornam o objeto Message completo, idêntico ao que .create() retorna. Isso é especialmente útil para requisições com valores grandes de max_tokens, onde os SDKs exigem streaming para evitar timeouts de HTTP.

client = anthropic.Anthropic()

with client.messages.stream(
    max_tokens=128000,
    messages=[{"role": "user", "content": "Write a detailed analysis..."}],
    model="claude-opus-5-5",
) as stream:
    message = stream.get_final_message()

for block in message.content:
    if block.type == "text":
        print(block.text)

A chamada .stream() mantém a conexão HTTP ativa com server-sent events, então .get_final_message() (Python) ou .finalMessage() (TypeScript) acumula todos os eventos e retorna o objeto Message completo. Em Go, você chama message.Accumulate(event) dentro do loop do stream para construir o mesmo Message completo. Em Java, use MessageAccumulator.create() e chame accumulator.accumulate(event) em cada evento. Em C#, aguarde o método de extensão .Aggregate() do stream para obter o Message completo, ou passe um MessageContentAggregator para .CollectAsync() para agregar enquanto trata eventos. Em Ruby, chame .accumulated_message no stream. No PHP SDK, você itera sobre os eventos do stream manualmente para acumular a resposta.

Tipos de eventos

Cada server-sent event inclui um tipo de evento nomeado e dados JSON associados. Cada evento usa um nome de evento SSE (por exemplo, event: message_stop), e inclui o type de evento correspondente em seus dados.

Cada stream usa o seguinte fluxo de eventos:

  1. message_start: contém um objeto Message com content vazio. Sob o cabeçalho beta thinking-binding-controls-2026-08-01, este objeto Message também carrega o array input_transformations. Após um fallback do lado do servidor no meio do stream, o evento final message_delta carrega o array novamente com as entradas do modelo de atendimento.
  2. Uma série de blocos de conteúdo, cada um dos quais tem um content_block_start, um ou mais eventos content_block_delta, e um evento content_block_stop. Cada bloco de conteúdo tem um index que corresponde ao seu índice no array content final da Message. Uma exceção: durante respostas de fallback do lado do servidor, um bloco de conteúdo fallback chega em cada limite de modelo como um par content_block_start e content_block_stop sem deltas entre eles.
  3. Um ou mais eventos message_delta, indicando mudanças de nível superior no objeto Message final.
  4. Um evento final message_stop.

Eventos ping

Os fluxos de eventos também podem incluir qualquer número de eventos ping.

Eventos de erro

A API pode ocasionalmente enviar erros no fluxo de eventos. Por exemplo, durante períodos de alto uso, você pode receber um overloaded_error, que normalmente corresponderia a um HTTP 529 em um contexto sem streaming:

Example error
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}

Outros eventos

De acordo com a política de versionamento, novos tipos de eventos podem ser adicionados, e seu código deve tratar tipos de eventos desconhecidos de forma elegante.

Tipos de delta de bloco de conteúdo

Cada evento content_block_delta contém um delta de um tipo que atualiza o bloco content em um determinado index.

Delta de texto

Um delta de bloco de conteúdo text se parece com:

Text delta
event: content_block_delta
data: {"type": "content_block_delta","index": 0,"delta": {"type": "text_delta", "text": "ello frien"}}

Delta de JSON de entrada

Os deltas para blocos de conteúdo tool_use correspondem a atualizações do campo input do bloco. Para suportar granularidade máxima, os deltas são strings JSON parciais, enquanto o tool_use.input final é sempre um objeto.

Você pode acumular os deltas de string e fazer o parse do JSON assim que receber um evento content_block_stop, usando uma biblioteca como Pydantic para fazer o parse parcial de JSON, ou usando os SDKs, que fornecem helpers para acessar valores incrementais já parseados.

Um delta de bloco de conteúdo tool_use se parece com:

Input JSON delta
event: content_block_delta
data: {"type": "content_block_delta","index": 1,"delta": {"type": "input_json_delta","partial_json": "{\"location\": \"San Fra"}}}

Nota: Os modelos atuais só suportam emitir uma propriedade completa de chave e valor de input por vez. Assim, ao usar ferramentas, pode haver atrasos entre os eventos de streaming enquanto o modelo está trabalhando. Uma vez que uma chave e valor de input são acumulados, eles são emitidos como múltiplos eventos content_block_delta com JSON parcial fragmentado para que o formato possa suportar automaticamente granularidade mais fina em modelos futuros.

Delta de pensamento

Ao usar pensamento com streaming habilitado, você receberá conteúdo de pensamento através de eventos thinking_delta. Esses deltas correspondem ao campo thinking dos blocos de conteúdo thinking.

Para conteúdo de pensamento, um evento especial signature_delta é enviado logo antes do evento content_block_stop. Essa assinatura é usada para verificar a integridade do bloco de pensamento.

Quando display: "omitted" é definido na configuração de pensamento, nenhum texto de pensamento é enviado via streaming. O bloco de pensamento é aberto, recebe um thinking_delta com uma string thinking vazia e depois um único signature_delta, e é fechado. Com display: "updates" (beta), os blocos de raciocínio são enviados via streaming da mesma forma, e apenas as atualizações de progresso que alguns modelos escrevem entre chamadas de ferramentas enviam eventos thinking_delta que carregam texto. Consulte Controlando a exibição do pensamento.

Um delta de pensamento típico se parece com:

Thinking delta
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}

O delta de assinatura se parece com:

Signature delta
event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}

Resposta completa de stream HTTP

Use os SDKs de cliente ao usar o modo de streaming. No entanto, se você estiver construindo uma integração direta com a API, precisará tratar esses eventos você mesmo.

Uma resposta de stream consiste em:

  1. Um evento message_start
  2. Potencialmente múltiplos blocos de conteúdo, cada um dos quais contém:
    • Um evento content_block_start
    • Potencialmente múltiplos eventos content_block_delta
    • Um evento content_block_stop
  3. Um ou mais eventos message_delta
  4. Um evento message_stop

Também pode haver eventos ping dispersos ao longo da resposta. Consulte Tipos de eventos para mais detalhes sobre o formato.

Requisição básica de streaming

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-5-5",
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=256,
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
Response
event: message_start
data: {"type": "message_start", "message": {"id": "msg_1nZdL29xx5MUA1yADyHTEsnR8uuvGzszyY", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null, "usage": {"input_tokens": 25, "output_tokens": 1}}}

event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}

event: ping
data: {"type": "ping"}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "Hello"}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "!"}}

event: content_block_stop
data: {"type": "content_block_stop", "index": 0}

event: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence":null}, "usage": {"output_tokens": 15}}

event: message_stop
data: {"type": "message_stop"}

Requisição de streaming com uso de ferramentas

Esta requisição pede ao Claude para usar uma ferramenta para reportar o clima.

client = anthropic.Anthropic()

tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                }
            },
            "required": ["location"],
        },
    }
]

with client.messages.stream(
    model="claude-opus-5",
    max_tokens=1024,
    tools=tools,
    tool_choice={"type": "any"},
    messages=[
        {"role": "user", "content": "What is the weather like in San Francisco?"}
    ],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
Response
event: message_start
data: {"type":"message_start","message":{"id":"msg_014p7gG3wDgGV9EUtLvnow3U","type":"message","role":"assistant","model":"claude-opus-5","stop_sequence":null,"usage":{"input_tokens":472,"output_tokens":2},"content":[],"stop_reason":null}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: ping
data: {"type": "ping"}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Okay"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" let"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'s"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" check"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" weather"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" for"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Francisco"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":","}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" CA"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":":"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01T1x1fJ34qAmk2tNTrN7Up6","name":"get_weather","input":{}}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"location\":"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"San"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" Francisc"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"o,"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" CA\"}"}}

event: content_block_stop
data: {"type":"content_block_stop","index":1}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":89}}

event: message_stop
data: {"type":"message_stop"}

Requisição de streaming com pensamento

Esta requisição habilita o pensamento com streaming. A configuração display: "summarized" faz streaming de um resumo condensado do raciocínio do Claude em vez da cadeia de pensamento completa.

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-5-5",
    max_tokens=20000,
    thinking={"type": "adaptive", "display": "summarized"},
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
) as stream:
    for event in stream:
        if event.type == "content_block_delta":
            delta = event.delta
            match delta.type:
                case "thinking_delta":
                    print(delta.thinking, end="", flush=True)
                case "text_delta":
                    print(delta.text, end="", flush=True)
Response
event: message_start
data: {"type": "message_start", "message": {"id": "msg_01...", "type": "message", "role": "assistant", "content": [], "model": "claude-opus-5-5", "stop_reason": null, "stop_sequence": null}}

event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": "", "signature": ""}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "I need to find the GCD of 1071 and 462 using the Euclidean algorithm.\n\n1071 = 2 × 462 + 147"}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n462 = 3 × 147 + 21"}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\n147 = 7 × 21 + 0"}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": "\nThe remainder is 0, so GCD(1071, 462) = 21."}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "EqQBCgIYAhIM1gbcDa9GJwZA2b3hGgxBdjrkzLoky3dl1pkiMOYds..."}}

event: content_block_stop
data: {"type": "content_block_stop", "index": 0}

event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "text", "text": ""}}

event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "text_delta", "text": "The greatest common divisor of 1071 and 462 is **21**."}}

event: content_block_stop
data: {"type": "content_block_stop", "index": 1}

event: message_delta
data: {"type": "message_delta", "delta": {"stop_reason": "end_turn", "stop_sequence": null}}

event: message_stop
data: {"type": "message_stop"}

Requisição de streaming com uso da ferramenta de busca na web

Esta requisição pede ao Claude para buscar na web informações atuais sobre o clima.

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-5-5",
    max_tokens=1024,
    tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 5}],
    messages=[
        {"role": "user", "content": "What is the weather like in New York City today?"}
    ],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
Response
event: message_start
data: {"type":"message_start","message":{"id":"msg_01G...","type":"message","role":"assistant","model":"claude-opus-5-5","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":2679,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":3}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll check"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the current weather in New York City for you"}}

event: ping
data: {"type": "ping"}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"server_tool_use","id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","name":"web_search","input":{}}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"query"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\":"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" \"weather"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":" NY"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"C to"}}

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"day\"}"}}

event: content_block_stop
data: {"type":"content_block_stop","index":1 }

event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"web_search_tool_result","tool_use_id":"srvtoolu_014hJH82Qum7Td6UV8gDXThB","content":[{"type":"web_search_result","title":"Weather in New York City in May 2025 (New York) - detailed Weather Forecast for a month","url":"https://world-weather.info/forecast/usa/new_york/may-2025/","encrypted_content":"Ev0DCioIAxgCIiQ3NmU4ZmI4OC1k...","page_age":null},...]}}

event: content_block_stop
data: {"type":"content_block_stop","index":2}

event: content_block_start
data: {"type":"content_block_start","index":3,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"Here's the current weather information for New York"}}

event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" City:\n\n# Weather"}}

event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":" in New York City"}}

event: content_block_delta
data: {"type":"content_block_delta","index":3,"delta":{"type":"text_delta","text":"\n\n"}}

...

event: content_block_stop
data: {"type":"content_block_stop","index":17}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":10682,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":510,"server_tool_use":{"web_search_requests":1}}}

event: message_stop
data: {"type":"message_stop"}

Recuperação de erros

Claude 4.5 e anteriores

Para modelos Claude 4.5 e anteriores, você pode recuperar uma requisição de streaming que foi interrompida devido a problemas de rede, timeouts ou outros erros, retomando de onde o stream foi interrompido. Essa abordagem evita que você reprocesse a resposta inteira.

A estratégia básica de recuperação envolve:

  1. Capturar a resposta parcial: Salve todo o conteúdo que foi recebido com sucesso antes de o erro ocorrer.
  2. Construir uma requisição de continuação: Crie uma nova requisição de API que inclua a resposta parcial do assistente como o início de uma nova mensagem do assistente.
  3. Retomar o streaming: Continue recebendo o restante da resposta de onde ela foi interrompida.

Claude 4.6 e posteriores

Para modelos Claude 4.6 e posteriores, a mesma estratégia de captura e retomada se aplica, mas o passo 2 muda: em vez de colocar a resposta parcial em uma mensagem do assistente, adicione uma mensagem do usuário que instrua o modelo a continuar de onde parou.

  1. Capturar a resposta parcial: Salve todo o conteúdo que foi recebido com sucesso antes de o erro ocorrer.
  2. Construir uma requisição de continuação: Crie uma nova requisição de API com uma mensagem do usuário contendo a resposta parcial e uma instrução para continuar, por exemplo:
    Sample prompt
    Your previous response was interrupted and ended with [previous_response]. Continue from where you left off.
  3. Retomar o streaming: Continue recebendo o restante da resposta de onde ela foi interrompida.

Melhores práticas de recuperação de erros

  1. Use recursos do SDK: Aproveite as capacidades integradas de acumulação de mensagens e tratamento de erros do SDK.
  2. Trate tipos de conteúdo: Esteja ciente de que as mensagens podem conter múltiplos blocos de conteúdo (text, tool_use, thinking). Blocos de uso de ferramentas e de pensamento estendido não podem ser recuperados parcialmente. Você pode retomar o streaming a partir do bloco de texto mais recente.

Próximos passos

Trate cada valor de stop_reason assim que um stream for concluído.

Faça streaming do JSON de entrada da ferramenta sem buffering do lado do servidor para menor latência.

Faça streaming da saída de pensamento com eventos thinking_delta e signature_delta.

Use os SDKs oficiais, que tratam streaming, acumulação e reconexão para você.

Processe grandes volumes de requisições de forma assíncrona quando você não precisa de respostas em tempo real.

Was this page helpful?