Fundamentos de Solución de Problemas y Fiabilidad
10 ejemplos para empezar con Solución de Problemas y Fiabilidad: 7 básicos y 3 intermedios.
Prerrequisitos
- Instala el SDK oficial:
pip install anthropic. - Configura
ANTHROPIC_API_KEYen tu entorno antes de ejecutar cualquier ejemplo. - Se utiliza el módulo
loggingintegrado de Python; no se requiere ninguna biblioteca de registro adicional. - Se asume una familiaridad básica con
try/excepty el clienteanthropic; no se necesita nada más para seguir el ejemplo.
Ejemplos Básicos
1. Registrar cada llamada a la API de Claude
Envuelve la llamada al cliente para que cada solicitud y respuesta se registre antes de que ocurra cualquier otra cosa.
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 la solicitud como la respuesta te proporciona un rastro antes de que ocurra un error, no solo después.
elapsed_mses el campo más útil para detectar el aumento de la latencia antes de que se convierta en una interrupción.extra={}mantiene los campos estructurados separados del mensaje de registro para que puedan consultarse más tarde.- Este envoltorio es la unión sobre la que se construyen todos los ejemplos posteriores.
Relacionado: Comprender por qué fallan los agentes de Claude en producción - la taxonomía de fallos a la que se alimenta este registro
2. Capturar los Tipos de Excepción Principales del SDK
El SDK anthropic genera excepciones tipificadas; capturar solo la clase base oculta detalles útiles.
import anthropic
client = anthropic.Anthropic()
try:
client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
messages=[{"role": "user", "content": "Resume este incidente."}],
)
except anthropic.RateLimitError as e:
print("límite de tasa:", e.status_code)
except anthropic.APITimeoutError as e:
print("tiempo de espera agotado:", e)
except anthropic.APIStatusError as e:
print("error de api:", e.status_code, e.response)
except anthropic.APIConnectionError as e:
print("error de conexión:", e)RateLimitErrores una subclase deAPIStatusError, por lo que el orden importa: captúrala antes que la clase más general.APITimeoutErroryAPIConnectionErrorson ambos de nivel de transporte, no de nivel de API.e.status_codeenAPIStatusErrorte dice exactamente qué estado HTTP se devolvió.- Capturar la
Exceptionbase aquí ocultaría qué familia de fallos estás tratando.
3. Extraer IDs de Solicitud para Soporte y RCA
Cada respuesta de la API lleva un ID de solicitud que el soporte de Anthropic (y tu propia plantilla de RCA) te pedirá.
import anthropic
client = anthropic.Anthropic()
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
messages=[{"role": "user", "content": "Hola"}],
)
request_id = response._request_id
except anthropic.APIStatusError as e:
request_id = e.request_id
print(f"solicitud {request_id} falló con estado {e.status_code}")- El ID de solicitud está presente tanto en las respuestas exitosas como en las excepciones
APIStatusErrorgeneradas. - Regístralo junto con cada llamada, es la forma más rápida de correlacionar una queja de usuario con un rastreo del lado del servidor.
- Sin un ID de solicitud capturado, a menudo no puedes obtener más detalles de un fallo pasado después del hecho.
- Este único campo convierte "se rompió antes" en un ticket de soporte procesable.
4. Clasificar un Error en una Familia de Fallos
Convierte una excepción en bruto en una de las familias de fallos de la página del modelo mental de la sección.
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"- Clasificar en el punto de captura significa que tus registros y paneles de control se pueden consultar por familia de fallos desde el primer día.
- Las respuestas 5xx se agrupan con capacidad porque generalmente indican saturación transitoria del lado del servidor.
- Cualquier
APIStatusErrorque no sea de límite de tasa o 5xx se trata como un problema de contrato, como una forma de solicitud incorrecta. - Esta función es intencionalmente pequeña; extiéndela a medida que aparezcan nuevas firmas de fallos en producción.
Relacionado: Diagnóstico de errores de límite de tasa 429 y agotamiento de cuotas bajo carga - análisis en profundidad de la familia de capacidad
5. Rastrear el Uso de Tokens por Llamada
Los recuentos de tokens están en cada respuesta y son tu primera señal de problemas de costos o contexto.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Explica brevemente los relojes vectoriales."}],
)
usage = response.usage
print(f"input_tokens={usage.input_tokens} output_tokens={usage.output_tokens}")usage.input_tokensyusage.output_tokensestán siempre presentes en una respuesta exitosa.- Registrar estos por llamada te permite construir una línea de tiempo de gasto de tokens sin esperar una factura mensual.
- Un salto repentino en
input_tokenspara la misma solicitud lógica a menudo indica un crecimiento del prompt o del contexto. - También existen campos de uso relacionados con la caché que importan una vez que persigues específicamente los picos de costos.
Relacionado: Tormentas de Fallos de Caché de Prompts: Diagnóstico de Picos Repentinos de Costos y Latencia - qué hacer cuando el uso de tokens aumenta inesperadamente
6. Escribir un Ping Mínimo de Comprobación de Estado
Una llamada barata y con pocos tokens que puedes ejecutar de forma programada para confirmar que la ruta de la API está en buen estado de principio a fin.
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- Utiliza el modelo más barato disponible y un
max_tokenspequeño para que esta llamada sea casi gratuita de ejecutar con frecuencia. anthropic.APIErrores la clase base compartida tanto para errores de estado como para errores de conexión, útil para una simple comprobación booleana.- Ejecutar esto cada minuto desde tu infraestructura te da una señal independiente de la tasa de error de tu tráfico real.
- Una comprobación de estado fallida junto con una tasa de error de tráfico real fallida confirman que el problema está en el nivel superior, no en el local.
7. Registrar Bloques de Uso de Herramientas Antes de Analizarlos
Cuando un agente utiliza herramientas, registra el bloque de uso de herramientas en bruto antes de intentar analizar sus 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 el bloque de uso de herramientas en bruto antes de analizar significa que todavía tienes la evidencia si el análisis posterior falla.
block.inputdel SDK ya es un diccionario analizado para llamadas bien formadas, pero capturarlo como JSON mantiene el formato del registro consistente.- Esta es la primera línea de defensa antes de la lógica de reparación más profunda cubierta en el artículo sobre JSON de uso de herramientas mal formado.
- Omitir este paso es la razón más común por la que una llamada a herramienta mal formada no se puede diagnosticar después del hecho.
Relacionado: Manejo de JSON de Uso de Herramientas Mal Formado y Fallos de Validación de Esquema - captura y reparación de salidas de llamadas a herramientas incorrectas
Ejemplos Intermedios
8. Combinar Registro, Temporización y Clasificación
Un único envoltorio que une las piezas anteriores en un único punto de llamada 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 envoltorio tiene la forma que adoptan la mayoría de los puntos de llamada de producción: temporízalo, pruébalo, clasifica los fallos, registra el resultado.
classify_error(ejemplo 4) se reutiliza aquí en lugar de duplicarse, manteniendo la taxonomía consistente en toda la base de código.- Devolver
Noneen caso de fallo, en lugar de volver a lanzar, es una elección deliberada para los puntos de llamada que pueden degradarse con gracia. - Cambia
return Nonepor unraisesi el llamador necesita fallar de forma ruidosa en su lugar.
9. Acumular un Contador Mínimo de Tasa de Errores
Rastrea una tasa de error rodante en memoria como una primera señal de monitorización, antes de conectar un 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)- Una ventana rodante en memoria es suficiente para detectar un pico en un solo proceso antes de haber integrado una pila de métricas real.
record(success)se llama desde el envoltorio de diagnóstico en el ejemplo 8, una vez por llamada.- Esto no es deliberadamente un reemplazo para las herramientas de observabilidad reales, solo un puente para la primera versión de una aplicación.
- Observa cómo
error_rate()cruza un umbral (por ejemplo, 5%) como tu primera señal automatizada de que algo ha cambiado.
10. Reproducir una Solicitud Fallida con Registro Detallado
Un script mínimo para el primer paso de cualquier incidente: reproducir el fallo con visibilidad completa de la solicitud y la respuesta.
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("ÉXITO:", response.stop_reason, response.usage)
except anthropic.APIStatusError as e:
print("FALLO:", e.status_code, e.request_id, e.response.text)
if __name__ == "__main__":
replay("El prompt que se reportó como fallido")- Establecer
logging.DEBUGen el propio logger del SDK muestra la solicitud y respuesta HTTP en bruto, que a menudo es la forma más rápida de detectar una cabecera o carga útil mal formada. - Ejecutar esto como un script independiente, fuera de tu aplicación normal, aísla si el fallo es ambiental o específico del código.
- Este es el primer paso concreto en el flujo de trabajo de diagnóstico en el que se basa el resto de esta sección.
- Una vez que puedas reproducir de manera confiable un fallo de esta manera, estarás listo para pasar al artículo específico de la familia de fallos que coincida.
Relacionado: Estrategias de Reintento y Backoff Exponencial para Fallos Transitorios de la API de Claude - qué construir una vez que puedas reproducir de manera confiable un fallo transitorio Relacionado: Mejores Prácticas de Solución de Problemas y Fiabilidad - la lista de verificación para aplicar una vez que tus fundamentos estén en orden
Versiones de la Pila: Escrito contra la línea de modelos de Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado) y Claude Haiku 4.5 - y el SDK oficial de Python
anthropic(última versión 0.x). Los nombres de los modelos, los precios y las versiones del SDK cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.