Troubleshooting & Reliability Basics
10 exemplos para você começar com Troubleshooting & Reliability - 7 básicos e 3 intermediários.
Pré-requisitos
- Instale o SDK oficial:
pip install anthropic. - Defina
ANTHROPIC_API_KEYem seu ambiente antes de executar qualquer exemplo. - O módulo
loggingintegrado do Python é usado em todo o material; nenhuma biblioteca de logging adicional é necessária. - Uma familiaridade básica com
try/excepte o clienteanthropicé assumida; nada mais é necessário para acompanhar.
Exemplos Básicos
1. Registrar Cada Chamada da API Claude
Envolva a chamada do cliente para que cada requisição e resposta sejam registradas antes que qualquer outra coisa aconteça.
import logging
import time
import anthropic
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("claude_client")
client = anthropic.Anthropic()
def call_claude(prompt: str) -> anthropic.types.Message:
started = time.monotonic()
logger.info("claude.request", extra={"prompt_len": len(prompt)})
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": prompt}],
)
elapsed_ms = (time.monotonic() - started) * 1000
logger.info(
"claude.response",
extra={"elapsed_ms": elapsed_ms, "stop_reason": response.stop_reason},
)
return response- Registrar tanto a requisição quanto a resposta fornece um rastro antes que um erro ocorra, não apenas depois.
elapsed_msé o campo mais útil para identificar o aumento da latência antes que ela se torne uma interrupção.extra={}mantém campos estruturados separados da mensagem de log para que possam ser consultados posteriormente.- Este wrapper é a junção sobre a qual todos os exemplos posteriores são construídos.
Relacionado: Understanding Why Claude Agents Fail in Production - a taxonomia de falhas para a qual este logging alimenta
2. Capturar os Tipos de Exceção Principais do SDK
O SDK anthropic levanta exceções tipadas; capturar apenas a classe base oculta detalhes úteis.
import anthropic
client = anthropic.Anthropic()
try:
client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
messages=[{"role": "user", "content": "Summarize this incident."}],
)
except anthropic.RateLimitError as e:
print("rate limited:", e.status_code)
except anthropic.APITimeoutError as e:
print("timed out:", e)
except anthropic.APIStatusError as e:
print("api error:", e.status_code, e.response)
except anthropic.APIConnectionError as e:
print("connection error:", e)RateLimitErroré uma subclasse deAPIStatusError, então a ordem importa: capture-a antes da classe mais geral.APITimeoutErroreAPIConnectionErrorsão ambos de nível de transporte, não de nível de API, falhas.e.status_codeemAPIStatusErrorinforma exatamente qual status HTTP foi retornado.- Capturar a
Exceptionbase aqui ocultaria em qual família de falha você está lidando.
3. Extrair IDs de Requisição para Suporte e RCAs
Cada resposta da API carrega um ID de requisição que o suporte da Anthropic (e seu próprio modelo de RCA) solicitará.
import anthropic
client = anthropic.Anthropic()
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
messages=[{"role": "user", "content": "Hello"}],
)
request_id = response._request_id
except anthropic.APIStatusError as e:
request_id = e.request_id
print(f"request {request_id} failed with status {e.status_code}")- O ID da requisição está presente tanto em respostas bem-sucedidas quanto em exceções
APIStatusErrorlevantadas. - Registre-o junto com cada chamada, é a maneira mais rápida de correlacionar uma reclamação de usuário com um rastreamento do lado do servidor.
- Sem um ID de requisição capturado, você muitas vezes não consegue obter mais detalhes de uma falha passada após o ocorrido.
- Este único campo transforma "quebrou mais cedo" em um ticket de suporte acionável.
4. Classificar um Erro em uma Família de Falhas
Transforme uma exceção bruta em uma das famílias de falhas da página de modelo mental da seção.
import anthropic
def classify_error(exc: Exception) -> str:
if isinstance(exc, anthropic.RateLimitError):
return "capacity"
if isinstance(exc, (anthropic.APITimeoutError, anthropic.APIConnectionError)):
return "lifecycle"
if isinstance(exc, anthropic.APIStatusError) and exc.status_code >= 500:
return "capacity"
if isinstance(exc, anthropic.APIStatusError):
return "contract"
return "unknown"- Classificar no ponto de captura significa que seus logs e dashboards são consultáveis por família de falhas desde o primeiro dia.
- Respostas 5xx são agrupadas com capacidade porque geralmente indicam saturação transitória do lado do servidor.
- Qualquer
APIStatusErrorque não seja limitação de taxa ou 5xx é tratado como um problema de contrato, como um formato de requisição incorreto. - Esta função é intencionalmente pequena; estenda-a conforme novas assinaturas de falha aparecerem em produção.
Relacionado: Diagnosing 429 Rate-Limit Errors and Quota Exhaustion Under Load - mergulho profundo na família de capacidade
5. Rastrear Uso de Tokens por Chamada
As contagens de tokens estão em cada resposta e são seu primeiro sinal de problemas de custo ou contexto.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Explain vector clocks briefly."}],
)
usage = response.usage
print(f"input_tokens={usage.input_tokens} output_tokens={usage.output_tokens}")usage.input_tokenseusage.output_tokensestão sempre presentes em uma resposta bem-sucedida.- Registrar estes por chamada permite construir uma linha do tempo de gastos de tokens sem esperar por uma fatura mensal.
- Um salto repentino em
input_tokenspara a mesma requisição lógica geralmente sinaliza crescimento de prompt ou contexto. - Campos de uso relacionados ao cache também existem e importam quando você está perseguindo picos de custo especificamente.
Relacionado: Prompt Cache Miss Storms: Diagnosing Sudden Cost and Latency Spikes - o que fazer quando o uso de tokens aumenta inesperadamente
6. Escrever um Ping Mínimo de Verificação de Integridade
Uma chamada barata e com poucos tokens que você pode executar em um cronograma para confirmar que o caminho da API está íntegro de ponta a ponta.
import anthropic
client = anthropic.Anthropic()
def health_check() -> bool:
try:
client.messages.create(
model="claude-haiku-4-5",
max_tokens=1,
messages=[{"role": "user", "content": "ping"}],
)
return True
except anthropic.APIError:
return False- Use o modelo mais barato disponível e um
max_tokensminúsculo para manter esta chamada quase gratuita para executar com frequência. anthropic.APIErroré a classe base compartilhada para erros de status e erros de conexão, útil para uma verificação booleana simples.- Executar isso a cada minuto a partir de sua infraestrutura fornece um sinal independente da taxa de erro do seu tráfego real.
- Uma verificação de integridade falhando, juntamente com uma taxa de erro de tráfego real falhando, confirma que o problema está acima, não local.
7. Registrar Blocos de Uso de Ferramentas Antes de Analisá-los
Quando um agente usa ferramentas, registre o bloco bruto de uso de ferramentas antes de tentar analisar seus argumentos.
import json
import logging
logger = logging.getLogger("claude_client")
def log_tool_use(response) -> None:
for block in response.content:
if block.type == "tool_use":
logger.info(
"claude.tool_use",
extra={"tool_name": block.name, "raw_input": json.dumps(block.input)},
)- Registrar o bloco bruto de uso de ferramentas antes da análise significa que você ainda tem a evidência se a análise falhar posteriormente.
block.inputdo SDK já é um dicionário analisado para chamadas bem formatadas, mas capturá-lo como JSON mantém o formato do log consistente.- Esta é a primeira linha de defesa antes da lógica de reparo mais profunda coberta no artigo sobre JSON de uso de ferramentas malformado.
- Pular esta etapa é o motivo mais comum pelo qual uma chamada de ferramenta malformada é indiagnosticável após o ocorrido.
Relacionado: Handling Malformed Tool-Use JSON and Schema Validation Failures - capturando e corrigindo a saída de chamadas de ferramentas incorretas
Exemplos Intermediários
8. Combinar Logging, Tempo e Classificação
Um único wrapper que une as peças anteriores em um único local de chamada de diagnóstico.
import logging
import time
import anthropic
logger = logging.getLogger("claude_client")
client = anthropic.Anthropic()
def diagnostic_call(prompt: str) -> anthropic.types.Message | None:
started = time.monotonic()
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": prompt}],
)
except anthropic.APIError as e:
elapsed_ms = (time.monotonic() - started) * 1000
family = classify_error(e)
request_id = getattr(e, "request_id", None)
logger.error(
"claude.failure",
extra={"family": family, "elapsed_ms": elapsed_ms, "request_id": request_id},
)
return None
elapsed_ms = (time.monotonic() - started) * 1000
logger.info(
"claude.success",
extra={"elapsed_ms": elapsed_ms, "tokens": response.usage.output_tokens},
)
return response- Este wrapper é o formato que a maioria dos locais de chamada de produção converge: cronometre-o, tente-o, classifique as falhas, registre qualquer resultado.
classify_error(exemplo 4) é reutilizado aqui em vez de duplicado, mantendo a taxonomia consistente em toda a base de código.- Retornar
Noneem caso de falha, em vez de relançar, é uma escolha deliberada para locais de chamada que podem degradar graciosamente. - Troque o
return Nonepor um relançamento se o chamador precisar falhar ruidosamente em vez disso.
9. Acumular um Contador Mínimo de Taxa de Erro
Rastreie uma taxa de erro rolante na memória como um primeiro sinal de monitoramento, antes de conectar um backend de métricas real.
from collections import deque
import time
class RollingErrorRate:
def __init__(self, window_seconds: int = 300):
self.window_seconds = window_seconds
self.events: deque[tuple[float, bool]] = deque()
def record(self, success: bool) -> None:
now = time.monotonic()
self.events.append((now, success))
cutoff = now - self.window_seconds
while self.events and self.events[0][0] < cutoff:
self.events.popleft()
def error_rate(self) -> float:
if not self.events:
return 0.0
failures = sum(1 for _, success in self.events if not success)
return failures / len(self.events)- Uma janela rolante na memória é suficiente para capturar um pico em um único processo antes que você tenha integrado uma pilha de métricas real.
record(success)é chamado do wrapper de diagnóstico no exemplo 8, uma vez por chamada.- Isso deliberadamente não é um substituto para ferramentas de observabilidade reais, apenas uma ponte para a primeira versão de um aplicativo.
- Observe
error_rate()cruzar um limite (por exemplo, 5%) como seu primeiro sinal automatizado de que algo mudou.
10. Reproduzir uma Requisição Falha com Logging Detalhado
Um script mínimo para o primeiro passo de qualquer incidente: reproduzir a falha com visibilidade completa da requisição e resposta.
import logging
import anthropic
logging.basicConfig(level=logging.DEBUG)
client = anthropic.Anthropic()
def replay(prompt: str, model: str = "claude-sonnet-5") -> None:
try:
response = client.messages.create(
model=model,
max_tokens=512,
messages=[{"role": "user", "content": prompt}],
)
print("SUCCESS:", response.stop_reason, response.usage)
except anthropic.APIStatusError as e:
print("FAILED:", e.status_code, e.request_id, e.response.text)
if __name__ == "__main__":
replay("The prompt that was reported as failing")- Definir
logging.DEBUGno logger da própria SDK expõe a requisição e resposta HTTP brutas, que é muitas vezes a maneira mais rápida de identificar um cabeçalho ou payload malformado. - Executar isso como um script autônomo, fora da sua aplicação normal, isola se a falha é ambiental ou específica do código.
- Este é o primeiro passo concreto no fluxo de diagnóstico no qual o restante desta seção se baseia.
- Uma vez que você possa reproduzir confiavelmente uma falha desta forma, você estará pronto para passar para o artigo específico da família de falhas que a corresponde.
Relacionado: Retry and Exponential Backoff Strategies for Transient Claude API Failures - o que construir assim que você puder reproduzir confiavelmente uma falha transitória Relacionado: Troubleshooting & Reliability Best Practices - a lista de verificação a ser aplicada assim que seus fundamentos estiverem no lugar
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, preços e versões de SDK mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.