Melhores Práticas da API de Mensagens
Um conjunto coletado de práticas para estruturar papéis, turnos, blocos de conteúdo e prompts do sistema de forma confiável ao construir contra a API de Mensagens.
Trate isso como uma referência de trabalho para verificar seu código, não como uma leitura única.
Como Usar Esta Lista
- Percorra primeiro os cabeçalhos das categorias e, em seguida, mergulhe na seção relevante para o que você está construindo.
- Cada regra afirma a prática positivamente - faça isso - juntamente com o motivo pelo qual ela é importante.
- Revisite esta lista sempre que estiver depurando um erro 400, uma resposta inconsistente ou custos inesperados de tokens - a maioria dos problemas remonta a um desses pontos.
A - Papéis e Turnos
- Sempre comece o array de mensagens com um papel de "user". A API rejeita qualquer array que comece com
assistant, portanto, construa conversas a partir da primeira entrada do usuário em diante. - Mantenha os papéis estritamente alternados. Nunca envie dois turnos consecutivos de
userouassistant- combine vários pedaços de entrada do usuário em um único conteúdo de turno em vez de dividi-los em entradas de array separadas. - Anexe o
response.contentcompleto, não apenas o texto extraído, como o próximo turno do assistente. Isso preserva os blocostool_usee qualquer outro conteúdo estruturado necessário para que a conversa continue corretamente. - Trate a API como totalmente sem estado. Nunca assuma que Claude se lembra de uma chamada anterior - reenviou o histórico relevante completo em cada solicitação.
- Escopo uma lista de mensagens por conversa. Nunca compartilhe uma única lista mutável entre usuários ou sessões concorrentes; turnos intercalados de conversas diferentes quebrarão a alternância.
B - Prompts do Sistema
- Mantenha o prompt do sistema como uma string separada e estável. Não incorpore instruções permanentes em um turno de
user-systemé o lugar correto para persona, escopo e restrições que se aplicam a toda a conversa. - Estruture prompts do sistema longos em seções claras. Persona, escopo, restrições e formato de saída como seções distintas são mais fáceis de auditar e atualizar do que um único parágrafo indiferenciado.
- Evite interpolar valores dinâmicos no prompt do sistema. Carimbos de data/hora, IDs de solicitação ou IDs de usuário incorporados em
systemo tornam uma string diferente em cada solicitação, quebrando silenciosamente o cache do prompt. - Reenvie o mesmo prompt do sistema em cada solicitação em uma conversa. Ao contrário de
messages,systemnão é cumulativo - passe o valor idêntico cada vez que quiser um comportamento consistente. - Use mensagens do sistema no meio da conversa para atualizações, onde suportado. Em modelos que o suportam, anexar uma mensagem
role: "system"preserva melhor seu prefixo em cache do que reescrever o camposystemde nível superior no meio da conversa.
C - Blocos de Conteúdo
- Corresponda o tipo de bloco de conteúdo ao tipo de conteúdo. Use
textpara prosa,imagepara entrada visual,tool_usepara uma chamada de ferramenta iniciada pelo modelo etool_resultpara a resposta de uma delas - não force tudo em strings simples. - Sempre analise a entrada
tool_usecomo dados estruturados. Leiablock.inputcomo o objeto analisado que é; nunca corresponda a string do JSON serializado, pois o escape exato pode variar. - Retorne todos os
tool_resultjuntos em um único turno do usuário quando um turno do assistente solicitou várias ferramentas. Dividi-los em turnos separados quebra o emparelhamento esperado e pode suprimir futuras chamadas de ferramentas paralelas. - Corresponda cada
tool_usecom seutool_resultportool_use_id. Nunca omita um resultado para uma chamada de ferramenta pendente, mesmo uma falha - useis_error: trueem vez de omiti-lo. - Verifique o tipo de um bloco de conteúdo antes de acessar campos específicos do tipo. Não assuma que cada bloco em uma resposta é
text- ramifique emblock.typeprimeiro, pois os turnos doassistantpodem incluirtool_useao lado ou em vez de texto.
D - Estado e Contexto da Conversa
- Meça o uso de tokens com
count_tokens(), não com estimativas de contagem de caracteres. As contagens de tokens não se mapeiam linearmente ao comprimento da string, especialmente para código ou texto não inglês. - Corte ou resuma proativamente, antes de atingir uma falha na janela de contexto. Verifique o uso em relação a um limite de segurança abaixo do limite real em vez de reagir a um erro em produção.
- Corte em pares correspondentes. Se você omitir um turno do assistente contendo
tool_use, omita também otool_resultdo turno do usuário correspondente - nunca deixe metade de um par órfão. - Use um modelo mais barato e rápido para etapas de sumarização. Resumir turnos mais antigos não precisa da capacidade total do seu modelo principal - Claude Haiku 4.5 geralmente é suficiente e reduz o custo.
- Verifique se um array cortado ou resumido ainda começa com "user" e alterna corretamente. Fatiar um array pode deixá-lo começando com
assistantou com turnos adjacentes do mesmo papel - corrija isso antes de enviar.
E - Erros e Confiabilidade
- Capture as exceções tipadas do SDK, da mais específica para a menos específica. Distinga
RateLimitError,NotFoundErroreAuthenticationErrordeAPIStatusErrormais amplo em vez de capturar uma única classe de exceção genérica. - Sempre verifique
stop_reasonantes de confiar que uma resposta está completa. Umstop_reasondemax_tokenssignifica que a resposta foi cortada, não concluída naturalmente. - Confie no comportamento de retentativa integrado do SDK para erros 429 e 5xx. Não implemente manualmente a lógica de retentativa para falhas transitórias que o cliente já retenta com backoff por padrão.
- Transmita solicitações com um
max_tokensgrande. Solicitações não transmitidas com um alto limite de tokens correm o risco de atingir tempos limite de conexão HTTP do lado do cliente; a transmissão evita esse modo de falha. - Defina
max_tokensdeliberadamente, não como uma reflexão tardia. Muito baixo trunca a saída no meio do pensamento e força uma retentativa; dimensione-o para a tarefa, com margem para pensar ou chamar ferramentas, quando relevante.
FAQs
Qual é a causa mais comum de um erro 400 na API de Mensagens?
Alternância de papéis quebrada - ou o array não começa com user, ou dois turnos do mesmo papel aparecem um após o outro. Verifique a estrutura antes de verificar o conteúdo.
Por que reenviar o prompt do sistema em cada solicitação é importante?
Porque system não é cumulativo como messages - cada solicitação é avaliada independentemente, então omiti-lo ou alterá-lo muda silenciosamente o comportamento e pode invalidar um cache de prompt construído com base no texto anterior.
Devo pular o anexo de um tool_result para um bloco tool_use?
Não - cada bloco tool_use precisa de um tool_result correspondente, mesmo que a chamada da ferramenta tenha falhado. Use is_error: true para uma chamada falha em vez de omitir o resultado completamente.
É seguro estimar o uso de tokens a partir do comprimento da string em vez de chamar count_tokens?
Não - as contagens de tokens não se mapeiam linearmente para contagens de caracteres ou palavras, especialmente para código ou texto não inglês, portanto, as estimativas podem estar significativamente erradas em qualquer direção.
Por que usar um modelo mais barato para resumir turnos de conversa antigos?
Porque a sumarização é uma tarefa comparativamente simples que não requer a capacidade de raciocínio total do seu modelo principal - um modelo mais rápido e barato reduz o custo de corte sem perda de qualidade significativa.
O que devo verificar antes de confiar que uma resposta está completa?
O campo stop_reason - se for max_tokens em vez de end_turn, a resposta foi cortada e pode estar faltando conteúdo que você espera que esteja lá.
Quando devo mudar para streaming em vez de uma solicitação normal?
Sempre que max_tokens for definido alto o suficiente para que uma solicitação não transmitida corra o risco de um tempo limite de conexão HTTP do lado do cliente - a transmissão evita completamente esse modo de falha.
Por que misturar correspondência de string e análise de entrada de tool_use causa bugs?
Porque a serialização exata do JSON da entrada da ferramenta pode variar em escape entre solicitações ou modelos - sempre analise block.input como dados estruturados em vez de corresponder ao padrão do texto bruto.
Está tudo bem compartilhar uma lista de mensagens entre as conversas de vários usuários?
Não - uma lista compartilhada e mutável usada por conversas concorrentes intercalará turnos de diferentes usuários e quebrará a alternância de papéis exigida para todos eles.
Qual é o risco de interpolar um carimbo de data/hora no prompt do sistema?
Isso torna o prompt do sistema uma string diferente em cada solicitação, o que quebra silenciosamente o cache do prompt, pois o cache depende de um prefixo estável e inalterado.
Preciso implementar manualmente a lógica de retentativa para limites de taxa?
Geralmente não - o SDK oficial retenta respostas 429 e 5xx automaticamente com backoff por padrão, portanto, a lógica de retentativa manual geralmente é desnecessária, a menos que você precise de um comportamento personalizado.
Relacionados
- Entendendo Papéis e Turnos na API de Mensagens - a base conceitual por trás das práticas de papéis e turnos aqui.
- Construindo Conversas Multi-Turno com o Array de Mensagens - mecânicas detalhadas por trás das práticas de estado de conversa.
- Gerenciando Histórico de Conversas e Corte para a Janela de Contexto - as estratégias completas de corte e sumarização referenciadas na categoria D.
- Lidando com Blocos de Conteúdo Misto: Texto, Imagem e Resultados de Ferramentas em um Único Turno - exemplos práticos por trás das práticas de blocos de conteúdo na categoria C.
Versões da 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
anthropicpara Python (ú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.