Melhores Práticas de Streaming
Streaming é inerentemente não confiável - conexões de longa duração caem, proxies bufferizam a saída e clientes desconectam no meio da resposta.
Esta página coleta as práticas que mantêm uma integração de streaming sólida quando ela sai de uma demonstração e atinge tráfego de produção.
Como Usar Esta Lista
- Trate os grupos com letras como camadas: confiabilidade do transporte primeiro, depois correção do estado acumulado, depois UX e custo.
- Cada regra se relaciona a um modo de falha concreto - se você não consegue visualizar a falha, a regra provavelmente ainda não se aplica à sua superfície.
- Revise esta lista sempre que adicionar um novo consumidor de um stream (uma nova interface de usuário, um novo endpoint de retransmissão), pois cada um reintroduz os mesmos modos de falha independentemente.
A - Confiabilidade da Conexão
- Envolva cada stream em um
try/exceptque cubra toda a iteração, não apenas a chamada que a abre.anthropic.APIStatusErrore suas subclasses (comoRateLimitError,APIConnectionError) podem surgir no meio do consumo do stream, não apenas quando ele é aberto pela primeira vez. - Defina um timeout explícito de requisição distinto de sua política de retentativas. Um stream que fica silencioso (sem novos eventos) por mais tempo do que uma janela razoável deve ser tratado como falho e retentado, não esperado indefinidamente.
- Retente com backoff exponencial em erros transitórios, não em todos os erros. Retente
APIConnectionErroreAPIStatusErrorde classe 5xx; não retente erros 4xx como uma requisição malformada, que falhará identicamente todas as vezes. - Nunca retente uma resposta parcialmente transmitida retomando no meio do stream. O endpoint de streaming da API Messages não suporta a retomada de uma conexão interrompida de onde parou - uma retentativa significa reenviar a requisição completa e iniciar um novo stream.
- Limite o número total de tentativas de retentativa e apresente uma falha clara ao usuário após o limite. Um loop de retentativa ilimitado contra um backend persistentemente falho apenas gasta tempo e chamadas de API.
B - Bufferização e Estado
- Bufferize os deltas de cada bloco de conteúdo independentemente, com chave pelo
index. Uma resposta pode conter múltiplos blocos (texto, tool_use, thinking) intercalados por índice; um buffer global único corrompe o estado no momento em que mais de um bloco é transmitido. - Nunca analise fragmentos de
input_json_deltaindividualmente. Acumule a string completa para um bloco e analise uma vez, emcontent_block_stop- veja Tratando JSON Parcial Durante Chamadas de Ferramenta Transmitidas. - Trate
text_deltacomo um fragmento opaco, nunca como um limite de token ou palavra. Lógica de detecção de sentenças, filtragem de profanidade ou análise de markdown deve ser executada na string acumulada, não em deltas individuais. - Agrupe atualizações de UI em vez de re-renderizar a cada delta. Descarregar texto acumulado para a UI a cada 25-50ms (em vez de por delta) reduz substancialmente a sobrecarga de renderização sem custo perceptível de latência.
- Chame
get_final_message()apenas após o stream ter sido completamente iterado. Chamá-la cedo pode retornar um objetoMessageincompleto.
C - Tratamento de Erros
- Distinga um
message_stoplimpo de um stream que apenas ficou silencioso. Se seu loop sair sem nunca ter vistomessage_stop, trate isso como uma condição de falha e registre-o distintamente de uma conclusão bem-sucedida. - Trate o tipo de evento
errorexplicitamente, não apenas exceções. Um eventoerrorno meio do stream (por exemplo, de um modelo sobrecarregado) é uma parte normal do vocabulário de eventos, não sempre levantado como uma exceção Python dependendo da versão do SDK - verifique ambos os caminhos. - Falhe ruidosamente em valores inesperados de
stop_reasonem caminhos de código que assumem a conclusão. Se seu código espera"end_turn"mas recebe"max_tokens", a resposta foi truncada - não a trate silenciosamente como completa. - Registre o conteúdo parcial acumulado em caso de falha, não apenas a mensagem de erro. Uma resposta parcial é frequentemente útil para depuração (e às vezes recuperável para o usuário) mesmo quando o stream falhou por fim.
- Valide o JSON da chamada de ferramenta após a análise, não apenas que ele foi analisado. JSON analisado com sucesso que está faltando um campo obrigatório do
input_schemada ferramenta ainda é uma chamada malformada que seu código de execução precisa rejeitar de forma limpa.
D - Estratégia de Reconexão
- Reenvie a requisição completa na reconexão em vez de tentar uma retomada parcial. Como a API não tem capacidade de retomada, sua "reconexão" é na verdade "retentar a requisição inteira" - projete seu loop de retentativa com essa suposição desde o início.
- Decida antecipadamente se uma reconexão reinicia a mensagem visível ao usuário ou a anexa a ela. Reiniciar silenciosamente uma bolha de chat meio mostrada parece um bug; limpe-a e mostre um indicador de retentativa em vez disso.
- Use lógica de aplicação segura contra idempotência em torno da execução da ferramenta antes de uma retentativa. Se uma chamada de ferramenta foi transmitida completamente e executada antes da conexão cair em um bloco posterior, uma retentativa ingênua da requisição inteira pode re-executar essa ferramenta uma segunda vez - proteja ferramentas com efeitos colaterais de acordo.
- Limite as tentativas de reconexão com o mesmo backoff e cap das retentativas de conexão (Grupo A). Um loop de reconexão é um loop de retentativa; não mantenha políticas separadas e inconsistentes para os dois.
E - Custo e Observabilidade
- Feche o stream explicitamente quando um cliente desconecta. Uma aba de navegador abandonada que não é detectada no lado do servidor continua consumindo (e cobrando) tokens de saída para uma resposta que ninguém verá.
- Registre
usagedemessage_delta, não uma estimativa. Contagens de tokens só são exatas quando a API as reporta - contar caracteres ou palavras no lado do cliente não é um proxy confiável para faturamento ou contabilidade de limites de taxa. - Monitore a distribuição de
stop_reasonem métricas de produção. Uma taxa crescente de paradas"max_tokens"geralmente significa que seumax_tokenscap é muito baixo para o tráfego real, não que as respostas estão naturalmente ficando mais longas. - Alerta sobre uma taxa crescente de eventos
errorou reconexões falhas, não apenas sobre falhas de requisição diretas. Falhas de streaming podem se esconder dentro de um HTTP 200 "bem-sucedido" que nunca atingemessage_stop.
FAQs
Qual é a prática de maior prioridade nesta lista?
Envolver toda a iteração de streaming - não apenas a chamada inicial - em tratamento de erros. A maioria dos bugs de streaming de produção vêm de um erro que surge no meio do stream e que o código nunca esperou capturar lá.
Posso retomar um stream interrompido de onde ele parou?
Não. O endpoint de streaming da API Messages não tem capacidade de retomada - uma "reconexão" é na verdade reenviar a requisição completa e iniciar um novo stream.
Como diferencio um stream bem-sucedido de um que falhou silenciosamente?
O loop de um stream bem-sucedido sai após observar message_stop. Se seu loop sair (ou a conexão fechar) sem nunca ter visto message_stop, trate como uma falha, registre e considere uma retentativa.
Devo retentar todos os erros da mesma forma?
Não. Retente erros transitórios como APIConnectionError ou APIStatusError 5xx com backoff. Não retente erros 4xx (como uma requisição inválida) - eles falharão identicamente todas as vezes.
É seguro re-renderizar todo o texto acumulado em cada delta individual?
Funciona, mas em escala é desperdício. Agrupar atualizações de UI em um intervalo curto (25-50ms) em vez de por delta reduz o custo de renderização sem impacto perceptível na experiência do usuário.
O que acontece se um usuário fechar a aba do navegador no meio do stream?
Nada para automaticamente no lado do Claude, a menos que seu backend detecte a desconexão do cliente e feche seu próprio stream - caso contrário, você continuará pagando por tokens de saída que ninguém verá.
Como devo lidar com uma chamada de ferramenta que executou parcialmente antes de uma queda de conexão?
Tenha cuidado com a idempotência: se a ferramenta já executou e teve um efeito colateral antes da queda, retentar cegamente a requisição inteira pode re-ativar esse efeito colateral. Proteja ferramentas com efeitos colaterais com chaves de idempotência ou lógica de dedup.
O que uma taxa crescente de razões de parada `max_tokens` geralmente indica?
Seu cap max_tokens é muito baixo para as respostas que seu tráfego está realmente gerando - é um sinal para aumentar o cap ou investigar por que as respostas estão mais longas do que o esperado, não algo para ignorar silenciosamente.
Preciso de lógica de retentativa diferente para requisições de streaming versus não-streaming?
A lógica de decisão de retentativa (quais erros retentar, estratégia de backoff, caps) é a mesma. A diferença é apenas que uma falha de streaming pode ocorrer após a requisição já ter parecido ter sucesso (no meio do stream), então a detecção requer observar toda a iteração, não apenas a resposta inicial.
Devo registrar todo o texto acumulado quando um stream falha?
Sim - o conteúdo parcial até o ponto da falha é valioso para depuração e, em algumas UIs, pode ser mostrado ao usuário com um aviso de "resposta interrompida" em vez de ser descartado inteiramente.
Relacionado
- Como Server-Sent Events Potencializam as Respostas de Streaming do Claude - o modelo de eventos sobre o qual essas práticas operam.
- Tratando JSON Parcial Durante Chamadas de Ferramenta Transmitidas - o padrão de bufferização referenciado no Grupo B.
- Combinando Streaming com o Loop de Uso de Ferramentas - considerações de idempotência para execução de ferramentas referenciadas no Grupo D.
- Referência de Configuração de Retentativa e Timeout do SDK Python - as configurações de nível de SDK por trás do Grupo A.
- Tipos de Exceção do SDK Python em Destaque - quais exceções são seguras para retentar.
Versões de Stack: Escrito contra a linha de modelos Claude atual em ~junho de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (o padrão), e Claude Haiku 4.5 - e o SDK oficial
anthropicPython (última versão 0.x). Nomes de modelos, versões de SDK e preços mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.