Streaming na API do Claude: respostas em tempo real (Python, TypeScript e cURL)
Sem streaming, a API só devolve a resposta quando ela termina. Para textos longos, isso significa vários segundos olhando para uma tela parada. Com streaming, o texto chega aos pedaços, enquanto o modelo escreve, e o usuário começa a ler na hora.
Neste guia você vê como fazer streaming com o Claude Opus 5 em Python, TypeScript e cURL.
Quando usar streaming
- Interfaces de chat, em que o usuário espera ver a resposta aparecendo.
- Respostas longas. O Claude Opus 5 aceita até 128 mil tokens de saída, e os SDKs exigem streaming para valores altos de
max_tokens, para evitar que a requisição estoure o tempo limite. - Entradas longas, em que a resposta pode demorar para terminar.
Para respostas curtas e processamento em segundo plano, a chamada normal (messages.create) continua ótima.
Python
O SDK tem um atalho, text_stream, que entrega só os pedaços de texto:
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_BASE_URL=https://api.open33.tech
with client.messages.stream(
model="claude-opus-5",
max_tokens=64000,
messages=[{"role": "user", "content": "Explique o que é um índice em banco de dados."}],
) as stream:
for texto in stream.text_stream:
print(texto, end="", flush=True)
mensagem = stream.get_final_message() # a resposta completa, com usage
print()
print(mensagem.usage)
get_final_message() devolve a mensagem inteira no fim, igual ao que o messages.create devolveria. Use quando precisar do texto completo, do stop_reason ou do consumo de tokens.
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // ANTHROPIC_BASE_URL=https://api.open33.tech
const stream = client.messages.stream({
model: "claude-opus-5",
max_tokens: 64000,
messages: [{ role: "user", content: "Explique o que é um índice em banco de dados." }],
});
for await (const evento of stream) {
if (evento.type === "content_block_delta" && evento.delta.type === "text_delta") {
process.stdout.write(evento.delta.text);
}
}
const mensagem = await stream.finalMessage();
console.log("\n", mensagem.usage);
cURL e os eventos SSE
Pela API HTTP, basta mandar "stream": true. A resposta chega como Server-Sent Events (SSE):
curl https://api.open33.tech/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"max_tokens": 64000,
"stream": true,
"messages": [{"role": "user", "content": "Escreva um haicai sobre deploy na sexta."}]
}'
A sequência de eventos é esta:
| Evento | O que traz |
|---|---|
message_start |
O início da mensagem, com o id |
content_block_start |
O início de um bloco (texto, raciocínio ou chamada de ferramenta) |
content_block_delta |
Um pedaço do bloco. No texto, o tipo do delta é text_delta |
content_block_stop |
O fim do bloco |
message_delta |
O stop_reason e o consumo de tokens de saída |
message_stop |
O fim da mensagem |
Se você não usa um SDK, junte os text_delta de cada bloco de texto para montar a resposta.
Outros tipos de bloco no stream
A resposta do Claude Opus 5 pode ter blocos além do texto, como os de raciocínio. No stream eles aparecem como blocos próprios, com deltas próprios. Por isso os exemplos acima filtram só os deltas de texto (text_delta): o resto não vai para a tela do usuário.
Streaming para o navegador
O caminho seguro é: navegador → seu servidor → API. O servidor guarda a chave, faz o streaming com a API e repassa o texto para o navegador. O guia de TypeScript tem um exemplo de rota que faz isso.
Nunca coloque a chave da API no código que roda no navegador.
Perguntas frequentes
Streaming custa mais caro?
Não. Os tokens são cobrados igual, com ou sem streaming. Muda só a forma de entrega.
Qual max_tokens usar com streaming?
Com streaming o tempo limite deixa de ser um problema, então você pode dar folga ao modelo, por exemplo 64000. O máximo do Claude Opus 5 é 128 mil tokens de saída.
Dá para usar streaming com tool use?
Sim. As chamadas de ferramenta chegam como blocos no stream, e no fim você pega a mensagem completa com get_final_message() (Python) ou finalMessage() (TypeScript). Veja o guia de tool use.
O streaming funciona na open33?
Sim. É o mesmo formato da API da Anthropic, com https://api.open33.tech como URL base.