Biblioteca · Confiabilidad: monitoreo, fallas y respaldos

Observabilidad en producción: qué monitorear cuando tu agente está en vivo

Ingeniero60 minActualizado: octubre de 2026
89 de 105 en la biblioteca

Tiempo: ~25 min de teoría + 35 min de práctica


Lo esencial

"It works on my machine" ("en mi máquina funciona") es la frase más cara de la industria. Desplegaste tu agente, funciona, los clientes lo usan. Y luego llega un mensaje: "se rompió desde ayer en la noche". Y te das cuenta de que no te enteraste por tu sistema, sino por un usuario molesto.

La observabilidad en producción (production observability) son tus ojos y oídos dentro del sistema en marcha. Sin ella eres un piloto ciego: el motor funciona, pero no sabes cuándo se va a sobrecalentar, cuándo se acaba el combustible, cuándo se va a desprender un ala.

En esta lección: 5 métricas que DEBES monitorear, 3 niveles de alertas y 4 herramientas para agentes de IA (lista a octubre de 2026). Sin relleno, con ejemplos de cifras y bocetos de tableros. Los umbrales de la lección son un punto de partida: con el tiempo, ajusta los tuyos con datos reales.

🎨 Imagínalo así: un avión sin tablero de instrumentos. El motor funciona y vuelas. Pero la temperatura del motor sube. El combustible se acaba. La altura baja. Sin instrumentos te enteras solo cuando algo se incendia. La observabilidad es el tablero de instrumentos de tu agente de IA. No es un lujo: es la condición para poder volar.


🎯 El principio principal: no logs, sino señales

Registrar (logging) ≠ observabilidad. Puedes tener gigabytes de logs y no entender qué pasa. La observabilidad es la capacidad de responder preguntas sobre el sistema sin meterte al código.

Los tres pilares clásicos (según el estándar OpenTelemetry https://opentelemetry.io):

  1. Metrics (métricas): números en el tiempo (latencia, costo, errores)
  2. Traces (trazas): el recorrido de una solicitud por todo el sistema
  3. Logs (registros): eventos con contexto

Para los agentes de IA se agrega un cuarto:

  1. Lo específico de los LLM: prompts, respuestas, uso de tokens, aciertos de caché

🎨 Imagínalo así: las métricas son el pulso y la temperatura del paciente (el estado general). Las trazas son la radiografía de un hueso concreto (el recorrido detallado de un problema). Los logs son el expediente con el historial clínico. Lo específico de los LLM es el análisis de sangre con marcadores propios del paciente de IA.


Conceptos clave

  • p50 / p95 / p99: percentiles de latencia: la mitad de las solicitudes es más rápida que p50, el 95% más rápida que p95, el 99% más rápida que p99. El p99 muestra el peor caso que ven tus usuarios peor atendidos
  • Cardinalidad: el número de valores únicos en una métrica. Las métricas de alta cardinalidad (por usuario) son caras de guardar
  • Muestreo (sampling): guardar no el 100% de las trazas, sino 1-10% de las normales + 100% de los errores
  • Fatiga de alertas (alert fatigue): cuando hay tantas alertas que las ignoras todas. Es más peligrosa que no tener alertas
  • SLI / SLO / SLA: Service Level Indicator (la métrica), Objective (la meta interna), Agreement (el contrato con el cliente)
  • Detección de anomalías: desviación respecto a la línea base (el promedio de ayer × 2 = sospechoso)
  • Trace ID: un identificador único de la solicitud que pasa por todos los componentes, para correlacionar
  • Cache hit ratio: el % de solicitudes que aciertan en la caché de prompts. Afecta directamente el costo

Teoría

Las 5 métricas obligatorias

Es el mínimo. Sin ellas no entiendes qué pasa con tu agente en producción.


Métrica 1: latencia (tiempo de respuesta)

Qué medir: el tiempo de respuesta p50, p95 y p99 por solicitud

Metas 2026:

Tipo de agente p50 p95 p99
Chat (texto) <3s <8s <15s
Voz (tiempo real) <500ms <1s <2s
Batch (segundo plano) OK 1-24h OK 1-24h OK 1-24h
API (integración B2B) <1s <3s <5s

Por qué el p99 es más crítico que el p50: si tienes 1000 solicitudes al día y p99 = 30s, significa que 10 usuarios al día esperan medio minuto. Se van. Un p50 = 2s se ve bonito en el reporte, pero esconde el problema.

Herramientas de seguimiento:

  • LangSmith (https://www.langchain.com/langsmith): trazas de las llamadas al LLM; tiene plan gratuito (límites en su sitio)
  • Helicone (https://www.helicone.ai/): un proxy de LLM con métricas; en marzo de 2026 la empresa fue comprada por Mintlify y el servicio está en modo mantenimiento, sin funciones nuevas
  • Prometheus/Grafana propio: autoalojado, gratis, pero se come tu tiempo en la configuración

🎨 Imagínalo así: el p50 es el tiempo promedio en el tráfico para la mayoría de los conductores. El p99 es cuánto espera el más desafortunado. Si en promedio son 5 minutos pero el 1% de los conductores se queda una hora, hay un semáforo descompuesto que nadie te reporta porque "en general está bien".


Métrica 2: costo por interacción

Qué medir:

  • $/conversación (una sesión de un usuario)
  • $/usuario (acumulado del mes)
  • $/función (a dónde se va el dinero)
  • Gasto mensual total (la cuenta completa)

Umbral de anomalía: un pico de más de 2x el promedio diario → alerta. Si ayer gastaste $20 y hoy a mediodía ya vas en $80, algo anda mal. Puede ser que:

  • Un error metió un ciclo infinito de llamadas
  • Alguien encontró cómo abusar (prompt injection, solicitudes repetidas)
  • En el código se cambió por accidente el modelo de Haiku a Opus

Herramientas:

  • Anthropic Console (https://platform.claude.com): tablero de facturación integrado
  • LangSmith / Helicone: el costo de cada llamada, desglosado por usuario y por función
  • Registro propio en KV: un contador hecho por ti en Cloudflare KV / Redis

Señales de ahorro que se ven con el monitoreo:

  • Cache hit ratio bajo (<30%) → revisa la estructura del prompt
  • Los tokens de salida crecen más rápido que los de entrada → el agente se volvió más platicador (revisa el prompt de sistema)
  • Las llamadas a Opus son >20% del total → revisa si usas Opus donde bastaría Sonnet

Métrica 3: tasa de errores

Qué medir (4 categorías):

  1. Errores de la API: 4xx, 5xx de Anthropic/OpenAI
  2. Fallas de herramientas: timeouts de MCP, esquemas que no coinciden, excepciones de herramientas
  3. Fallas de validación: la salida del LLM no coincide con el esquema JSON esperado
  4. Errores reportados por usuarios: comentarios explícitos de "no funciona"

Meta: <1% de errores en estado estable, <5% en un pico

Umbrales de alerta:

  • Tasa de errores >5% en 5 minutos → avisa a quien está de guardia (algo se rompió ahora)
  • Tasa de errores >2% en 1 hora → advertencia (tendencia a degradarse)
  • Un mismo código de error >50 eventos por hora → investigar (problema sistémico)

Categorizar importa: cada error pide una reacción distinta:

Tipo de error Acción
529 overloaded_error (Anthropic) Reintentar con backoff; no es culpa nuestra
400 invalid_request_error Error en el código; corregir de inmediato
429 rate_limit_error Subir de nivel o limitar el ritmo
tool_use schema mismatch El LLM es inestable; agregar validación
JSON parse error Revisar el prompt de sistema

🎨 Imagínalo así: la tasa de errores es la temperatura del enfermo. 37° (1%): normal. 38° (2%): resfriado. 39° (5%): al doctor de inmediato. Y no basta con ver el número: hay que entender si es gripe, alergia o apendicitis.


Métrica 4: uso de tokens

Qué medir:

  • Tokens de entrada / de salida (por solicitud + acumulado)
  • Cache hit ratio (% que aciertan en la caché de prompts)
  • Desglose por modelo (% Haiku / % Sonnet / % Opus)
  • Distribución de la longitud del contexto (ves cuándo la gente choca con el límite)

Señales de anomalía:

Señal Qué significa
Tokens de entrada >5x el promedio para un usuario Error de ciclo, scraping, ataque de prompt injection
Cache hit <20% La estructura del prompt no está optimizada
La salida promedio crece durante una semana El prompt de sistema se está degradando; el agente se volvió más platicador
Contexto >150K de forma constante Hora de una estrategia de compactación

El cache hit ratio es una métrica crítica: leer de la caché de prompts cuesta alrededor del 10% del precio normal de los tokens de entrada (a octubre de 2026; condiciones vigentes: Lo vigente). Si el cache hit es alto, buena parte de la entrada sale varias veces más barata. Si el cache hit = 0%, pagas la tarifa completa.

python
# Seguimiento del cache hit ratio
def log_request(response):
    cache_tokens = response.usage.cache_read_input_tokens or 0
    total_input = response.usage.input_tokens + cache_tokens
    cache_ratio = cache_tokens / total_input if total_input > 0 else 0

    metrics.record("cache.hit_ratio", cache_ratio)
    metrics.record("tokens.input", response.usage.input_tokens)
    metrics.record("tokens.output", response.usage.output_tokens)

Métrica 5: métricas de negocio

Las métricas técnicas muestran que el sistema funciona. Las de negocio muestran que el sistema trabaja para el negocio.

Qué medir:

Métrica Descripción Meta
Conversation completion rate % de sesiones que lograron su objetivo >70%
CSAT (satisfacción del cliente) Calificación explícita de 1 a 5 estrellas >4.0
Escalation rate % de casos de "llamar a una persona" <15%
Conversion rate Para IA de ventas/marketing Variable
Time-to-resolution Cuántos turnos hasta resolver <5
Retención % de usuarios que regresan >30% en la semana 2

Herramientas:

  • PostHog (https://posthog.com): analítica de producto; tiene un límite mensual gratuito (tamaño vigente en su página de precios)
  • Mixpanel (https://mixpanel.com): análisis de embudos; planes en su sitio

Por qué las métricas de negocio importan más que las técnicas: puedes tener p95 = 1s y 0.5% de errores, pero si la tasa de conversaciones completadas es 20%, tu agente no ayuda a los usuarios. Técnicamente sano, en la práctica inútil.


3 niveles de alertas

Las alertas son la causa más común de errores en sistemas de IA en producción. O hay demasiadas (fatiga de alertas) o muy pocas (te enteras por el cliente).


Nivel 1: Info (canal de Slack, sin despertar a nadie)

Qué: resumen diario, reportes semanales, telemetría general Canal: #ai-prod-info o un resumen por email Tiempo de respuesta: cuando haya tiempo

Ejemplos:

  • Diario a las 09:00: "Ayer: 1247 solicitudes, $12.40 de gasto, 0.3% de errores, p95 = 4.2s"
  • Los lunes: "En la semana: tendencia de costo +12%, error principal: tool timeout (43 eventos)"
  • Mensual: "Reporte mensual de optimización de precios"

Objetivo: contexto y tendencias, no monitoreo reactivo.


Nivel 2: Warning (mención en Slack, respuesta en menos de 1 hora)

Qué: señales de degradación, problemas que pueden volverse críticos Canal: #ai-prod-alerts + @here Tiempo de respuesta: 1 hora

Ejemplos:

  • Pico de costo de 2x el promedio diario
  • Tasa de errores >2% en 15 minutos
  • Latencia p95 >2x el SLA
  • El cache hit ratio bajó de 30%
  • Un usuario con >100 solicitudes en una hora (posible abuso)

Herramienta: webhook entrante de Slack + mensaje estructurado

python
# Ejemplo de envío de una advertencia
def send_warning(metric, value, threshold):
    slack_webhook = os.getenv("SLACK_WARNING_WEBHOOK")
    payload = {
        "text": f"@here Warning: {metric} = {value} (threshold: {threshold})",
        "attachments": [{
            "color": "warning",
            "fields": [
                {"title": "Metric", "value": metric, "short": True},
                {"title": "Current", "value": str(value), "short": True},
                {"title": "Threshold", "value": str(threshold), "short": True},
                {"title": "Dashboard", "value": "https://enlace-a-tu-tablero", "short": True}
            ]
        }]
    }
    requests.post(slack_webhook, json=payload)

Nivel 3: Critical (avisar a quien está de guardia, respuesta en 5 min)

Qué: afecta a clientes, sistema caído, incidentes de seguridad Canal: PagerDuty / llamada / SMS Tiempo de respuesta: 5 minutos

Ejemplos:

  • Sistema caído (>50% de errores)
  • Pico de costo >5x el diario (posible brecha o ciclo infinito)
  • Alerta de seguridad (patrón de acceso inusual, sospecha de clave filtrada)
  • Caída reportada por clientes y confirmada por las métricas
  • Incumplimiento crítico del SLA

Herramientas:

🎨 Imagínalo así: los tres niveles son como una alarma contra incendios. Un poco de humo en la cocina (Info): enterarte, no entrar en pánico. Olor a quemado en el pasillo (Warning): revisar y apagar. Fuego en el piso (Critical): llamar al 911, evacuar. Si cada humito despierta a los bomberos, al incendio de verdad llegarán cansados y de malas.


4 herramientas de observabilidad en 2026: comparación

Herramienta Plan gratuito Mejor para
LangSmith Sí; límites en su sitio Trazas avanzadas, comparar prompts
Helicone Sí; desde marzo de 2026 el servicio está en modo mantenimiento (lo compró Mintlify), sin funciones nuevas Específico de LLM, seguimiento de costos, configuración rápida
Sentry Sí; límites en su sitio Seguimiento de errores, no específico de LLM
PostHog Sí, un límite mensual (tamaño vigente en su página de precios) Analítica de usuarios, no trazas

Los precios de los planes de pago de las cuatro cambian: revísalos en sus sitios.

Recomendación por etapa:

  • Personal / inicial (<1K usuarios): el plan gratuito de LangSmith o PostHog más Anthropic Console: alcanza para los primeros meses
  • Equipo (1K-10K usuarios): LangSmith + Sentry
  • Producción (con ingresos): LangSmith + Sentry + PostHog + una herramienta de guardias (PagerDuty o similar)
  • Enterprise: Datadog (https://www.datadoghq.com/) + tableros propios

Además:


Patrón de implementación: un proxy, con Helicone como ejemplo

Una de las formas más rápidas de tener observabilidad es envolver el SDK de Anthropic con un proxy, por ejemplo Helicone. Se configura en 5 minutos.

⚠️ A octubre de 2026, Helicone está en modo mantenimiento (ver arriba), así que tómalo como ejemplo del enfoque: un proxy entre tu código y la API, más etiquetas en los encabezados. Para un proyecto nuevo, compáralo con LangSmith (lección MLOps para indie) y con gateways como el AI Gateway de Cloudflare. Revisa la dirección del proxy y los nombres de los encabezados en la documentación del servicio que elijas.

Antes (sin observabilidad):

python
from anthropic import Anthropic

client = Anthropic()
response = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hola"}]
)

Después (envuelto con Helicone):

python
from anthropic import Anthropic
import os

client = Anthropic(
    base_url="https://anthropic.helicone.ai",  # Proxy a través de Helicone
    default_headers={
        "Helicone-Auth": f"Bearer {os.getenv('HELICONE_KEY')}",
        "Helicone-User-Id": user_id,                    # Seguimiento por usuario
        "Helicone-Property-Feature": "chat-bot",        # Desglose por función
        "Helicone-Property-Environment": "production",  # Etiqueta de entorno
        "Helicone-Cache-Enabled": "true",               # Extra: caché
        "Helicone-Property-Tier": user_tier             # Dimensión propia
    }
)

response = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hola"}]
)
# Ahora en el tablero ves: latencia, costo, tokens, usuario, función, entorno

Qué aparece en el tablero de inmediato:

  • Cada solicitud con su trace ID
  • Costo por solicitud con desglose
  • Latencia p50/p95/p99
  • Los usuarios que más gastan
  • Las funciones más usadas
  • Cache hit ratio

Estructura del tablero: qué debe haber en la pantalla principal

Un buen tablero de producción lo miras una vez al día, 30 segundos, y entiendes todo.

Código
┌──────────────────────────────────────────────────────────┐
│ My App Production Dashboard             [Last 24h ▼]     │
├──────────────────────────────────────────────────────────┤
│                                                           │
│  📊 LAST 24H OVERVIEW                                     │
│  ┌─────────┬─────────┬─────────┬─────────┐               │
│  │ 1,247   │ $12.40  │  0.3%   │  4.2s   │               │
│  │ requests│  spend  │ errors  │   p95   │               │
│  └─────────┴─────────┴─────────┴─────────┘               │
│                                                           │
│  📈 TREND (7 days)                                        │
│  Cost:    ▁▂▃▃▄▅▆  +12% wow                              │
│  Errors:  ▁▁▂▁▁▁▁  stable                                │
│  p95:     ▃▃▃▃▃▃▃  stable                                │
│                                                           │
│  🚨 ACTIVE ALERTS                                         │
│  • [WARN] Cache hit ratio 24% (target >30%)              │
│                                                           │
│  🐢 TOP ISSUES                                            │
│  1. Slowest endpoint: /api/research (p95 = 18s)          │
│  2. Most errors: tool_timeout (43 events)                │
│  3. Biggest spender: user_42 ($3.20 today, 25% of total) │
│                                                           │
│  😊 USER SATISFACTION                                     │
│  CSAT: 4.3 / 5.0  (n=87)                                 │
│  Escalation rate: 12%                                     │
│                                                           │
└──────────────────────────────────────────────────────────┘

Reglas de un buen tablero:

  • Los números principales arriba, en una sola pantalla, sin scroll
  • Tendencias visuales (sparklines), no tablas
  • Las alertas activas se ven de inmediato, en rojo
  • Los problemas principales te dicen dónde escarbar
  • La métrica de negocio (CSAT) al mismo nivel que las técnicas

Flujo de depuración: de la queja a la corrección

Escenario: un usuario escribe "la IA respondió mal a las 14:30"

Paso 1: Localizar: encuentra en los logs las trazas alrededor de las 14:30 para ese usuario

Escribe esto en el chat
# En el tablero de trazas: filtro user_id = user_42, hora 14:25 — 14:35

Paso 2: Reproducir: cuál fue la entrada, cuál el contexto, cuál la salida

  • Toma el prompt exacto de la traza
  • Ejecútalo en el playground de Anthropic Console con los mismos parámetros
  • Obtén el mismo resultado (o uno distinto)

Paso 3: Correlacionar: con las métricas del sistema en ese momento

  • ¿Hubo un pico de latencia? (lento = menos tiempo para pensar)
  • ¿Hubo un pico de errores en la API? (servicio degradado)
  • ¿Hubo un pico de costo? (un ciclo infinito en ese periodo)
  • ¿Hubo un fallo de caché? (caché fría → comportamiento distinto)

Paso 4: Plantear la causa: opciones:

  • ¿Desbordamiento de contexto (>180K tokens)? → estrategia de compactación
  • ¿Datos malos (entrada corrupta)? → validación de entradas
  • ¿Un error en el sistema (race condition)? → prueba unitaria
  • ¿Degradación del LLM (actualización del modelo)? → revisar con la suite de evals
  • ¿Deriva del prompt (algo cambió)? → control de versiones de los prompts

Paso 5: Corregir + prevenir

  • La corrección mínima
  • Agrega un caso de prueba a la suite de evals (ver la lección Evals: skills que se mejoran solos)
  • Agrega una regla de alerta si es un patrón que se repite
  • Documéntalo en el runbook

🎨 Imagínalo así: depurar es como un diagnóstico médico. Síntoma (la queja) → historia clínica (las trazas) → análisis (las métricas) → diagnóstico (la causa) → tratamiento (la corrección) + recomendaciones (la prevención). Sin observabilidad eres un médico sin análisis: adivinas.


Buenas prácticas de registro

✅ Qué registrar:

  • Todas las solicitudes/respuestas del LLM (entrada, salida, tokens, latencia, costo)
  • Todas las llamadas a herramientas (nombre, argumentos, resultado, duración)
  • Todos los errores con el stack trace completo
  • Las acciones del usuario (sin datos personales: seudonimiza)
  • Los eventos del sistema (despliegue, cambio de configuración, reinicio)

❌ Qué NO registrar:

  • Contraseñas / claves de API en texto plano
  • Datos personales completos (emails → hash, nombre → "User_42")
  • Números de tarjeta
  • Datos de salud con su contenido completo
  • IP internas / rutas del sistema (seguridad)

Estrategia de muestreo:

  • 100% de los errores (siempre)
  • 5-10% de las trazas normales (equilibrio de costo)
  • 100% de las solicitudes lentas (>2x el p95)
  • 100% de las solicitudes caras (>$0.50)

Política de conservación:

Tipo de log Guardar
Errores 90 días
Trazas normales 30 días
Trazas muestreadas (para tendencias) 1 año
Logs de auditoría (cumplimiento) 7 años (ejemplo: el plazo depende del país y la industria; confírmalo con un abogado)

Registro estructurado: obligatoriamente en JSON:

python
import json
import time

def log_llm_call(request, response, duration_ms):
    log_entry = {
        "ts": time.time(),
        "level": "INFO",
        "event": "llm_call",
        "trace_id": request.headers.get("X-Trace-ID"),
        "user_id_hash": hash_user_id(request.user_id),
        "model": response.model,
        "tokens_input": response.usage.input_tokens,
        "tokens_output": response.usage.output_tokens,
        "cache_read_tokens": response.usage.cache_read_input_tokens or 0,
        "duration_ms": duration_ms,
        "cost_usd": calculate_cost(response.usage, response.model),
        "feature": request.feature_tag,
        "success": True
    }
    print(json.dumps(log_entry))  # → stdout → agregador de logs

Antipatrones (qué no hacer)

❌ Agregar el registro "después": normalmente cuando algo ya se rompió. Para entonces no hay datos para depurar el incidente de ayer.

❌ Una alerta por cada error: ruido, fatiga de alertas. En una semana el equipo silencia el canal. Filtra por gravedad y frecuencia.

❌ Solo seguir errores, sin seguir costos: despiertas con una cuenta sorpresa de $5000. Al principio, monitorear costos es más crítico que monitorear errores.

❌ Registrar sin user_id: imposible depurar los reportes de usuarios. "A mí no me funciona" → no puedes encontrar su traza.

❌ "Yo todo lo tengo en console.log": no es persistente, no se puede buscar, no se correlaciona. Los logs deben ir a un agregador (Helicone / Datadog / uno propio).

❌ Muestrear siempre al 100%: pagas por guardarlo todo. Muestrea con criterio: errores al 100%, normales al 5%.

❌ Alertas sin runbook: se disparó la alerta y quien está de guardia no sabe qué hacer. Cada alerta crítica debe enlazar a un runbook.

❌ Un tablero que nadie mira: si lo abres una vez al mes, te enteras de los problemas con un mes de retraso. El ritual diario importa.


Cuánto cuesta la observabilidad

La pregunta más frecuente es "¿y cuánto cuesta?". La respuesta honesta:

Categoría Costo
Herramientas (inicial) Muchas veces bastan los planes gratuitos (LangSmith, Sentry, PostHog)
Herramientas (producción) Planes de pago de varios servicios: calcúlalo con sus precios actuales
Tiempo de configuración (inicial) 4-8 horas
Mantenimiento 1-2 horas al mes (actualizar alertas, ajustar umbrales)
Almacenamiento (si es autoalojado) Depende del volumen de logs y del plan de almacenamiento (S3, R2)

Cálculo de retorno: un solo pico de costo que se te escape (por ejemplo, un ciclo infinito de llamadas) puede costar más que todas las herramientas de observación de un año. Una caída que afecta a clientes y que no detectas suele costar todavía más.

🎨 Imagínalo así: la observabilidad es el seguro del auto. Si no pasa nada, parece de más. Un solo accidente paga 10 años de primas. Solo que, a diferencia del seguro, aquí puedes evitar el accidente viendo el problema antes.


Recomendaciones según tu madurez

Principiante (sin ingresos, aprendiendo):

  • Solo Anthropic Console (integrado) + revisiones manuales semanales
  • Sin herramientas extra
  • Logs en la consola / en un archivo
  • Meta: entender qué está pasando

Intermedio (primeros usuarios, plan gratuito):

  • Plan gratuito de LangSmith o PostHog
  • Webhook de Slack para las alertas críticas
  • Revisión semanal del tablero
  • Meta: atrapar los problemas antes que los usuarios

Profesional (producción con ingresos):

  • LangSmith (plan de pago) + Sentry + PostHog
  • PagerDuty o similar para las alertas críticas
  • Tableros propios con métricas de negocio
  • Ritual de revisión diaria
  • Meta: cumplir los SLA, optimizar de forma proactiva

Enterprise (escala, cumplimiento):

  • Datadog o New Relic de stack completo
  • Pipeline propio de OpenTelemetry
  • Observabilidad multirregión
  • Meta: no enterarte nunca de un problema por un cliente

Revisión trimestral de la observabilidad

Una vez por trimestre, dedica 2 horas a revisar tu sistema de observabilidad.

Qué agregar:

  • Endpoints / funciones nuevas → métricas nuevas
  • SLO nuevos de clientes → alertas nuevas
  • Aparecieron tipos de error nuevos → categorizarlos y seguirlos

Qué quitar:

  • Tableros sin uso (nadie los vio en 90 días)
  • Alertas con falsos positivos (se disparan, pero no es crítico)
  • Métricas que nunca se usaron para decidir nada

Qué optimizar:

  • Las alertas más ruidosas → ajustar umbrales
  • Oportunidades para revertir la tendencia de costos (dónde se puede ahorrar)
  • Consultas / endpoints lentos

Qué rotar:

  • Claves de acceso (tokens de API de las herramientas de observabilidad)
  • Lista de subencargados (cumplimiento)
  • URL de los runbooks (si algo se movió)

Práctica

Paso 1: configura Helicone (5 minutos)

Aquí Helicone es un ejemplo del enfoque con proxy: desde marzo de 2026 está en modo mantenimiento. Si no quieres atarte a un servicio así, cambia este paso por la integración de LangSmith de la lección MLOps para indie.

bash
# 1. Regístrate en helicone.ai (tiene plan gratuito)
# 2. Obtén la clave de API en el tablero
# 3. Guárdala en .env

echo "HELICONE_API_KEY=sk-helicone-xxx" >> .env
echo "ANTHROPIC_API_KEY=sk-ant-xxx" >> .env
python
# helicone_setup.py — integración mínima
import os
from dotenv import load_dotenv
from anthropic import Anthropic

load_dotenv()

# Cliente a través del proxy de Helicone
client = Anthropic(
    api_key=os.getenv("ANTHROPIC_API_KEY"),
    base_url="https://anthropic.helicone.ai",
    default_headers={
        "Helicone-Auth": f"Bearer {os.getenv('HELICONE_API_KEY')}",
        "Helicone-Property-Environment": "production",
        "Helicone-Property-App": "my-agent"
    }
)

# Solicitud de prueba
response = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=100,
    messages=[{"role": "user", "content": "Saluda"}],
    extra_headers={
        "Helicone-User-Id": "test_user_001",
        "Helicone-Property-Feature": "greeting"
    }
)

print("".join(b.text for b in response.content if b.type == "text"))
print(f"\nRevisa el tablero: https://www.helicone.ai/dashboard")
print(f"Costo: se ve en tiempo real")

Paso 2: configura las alertas de Slack (15 minutos)

python
# alerts.py — alertas de tres niveles
import os
import requests
from enum import Enum

class AlertLevel(Enum):
    INFO = "good"        # verde
    WARNING = "warning"  # amarillo
    CRITICAL = "danger"  # rojo

def send_alert(level: AlertLevel, title: str, message: str, dashboard_url: str = None):
    """Envía una alerta a Slack según su nivel de gravedad."""

    webhook_map = {
        AlertLevel.INFO: os.getenv("SLACK_INFO_WEBHOOK"),
        AlertLevel.WARNING: os.getenv("SLACK_WARNING_WEBHOOK"),
        AlertLevel.CRITICAL: os.getenv("SLACK_CRITICAL_WEBHOOK"),
    }

    webhook = webhook_map[level]
    mention = "@here" if level == AlertLevel.WARNING else ("@channel" if level == AlertLevel.CRITICAL else "")

    payload = {
        "text": f"{mention} *{title}*",
        "attachments": [{
            "color": level.value,
            "text": message,
            "fields": [
                {"title": "Severity", "value": level.name, "short": True},
                {"title": "Dashboard", "value": dashboard_url or "N/A", "short": True}
            ]
        }]
    }

    response = requests.post(webhook, json=payload)
    response.raise_for_status()

# Ejemplos de uso
send_alert(
    AlertLevel.INFO,
    "Daily Summary",
    "Ayer: 1247 solicitudes, $12.40 de gasto, 0.3% de errores"
)

send_alert(
    AlertLevel.WARNING,
    "Cost spike detected",
    "Hoy ya van $40 (2x los $20 de ayer). Revisa los logs de la última hora.",
    "https://enlace-a-tu-tablero"
)

send_alert(
    AlertLevel.CRITICAL,
    "System degradation",
    "Tasa de errores del 12% en los últimos 5 minutos. Latencia p99 de 30s.",
    "https://enlace-a-tu-tablero"
)

Paso 3: un proceso que vigila los costos

python
# cost_monitor.py — revisión de anomalías de costo
import os
import time
from datetime import datetime, timedelta
from anthropic import Anthropic

# Supongamos que tienes una función get_daily_cost() que lee de la API de tu servicio de trazas
def get_daily_cost(date):
    """Regresa los $ gastados en el día. Es un marcador: conecta la API de tu servicio de trazas."""
    # Implementación real: una consulta a la API del servicio de trazas para esa fecha
    return 12.40  # placeholder

def get_baseline(days_back=7):
    """Costo promedio de los últimos N días."""
    costs = []
    for i in range(1, days_back + 1):
        date = datetime.now() - timedelta(days=i)
        costs.append(get_daily_cost(date))
    return sum(costs) / len(costs)

def check_cost_anomaly():
    today_cost = get_daily_cost(datetime.now())
    baseline = get_baseline(days_back=7)

    ratio = today_cost / baseline if baseline > 0 else 0

    if ratio > 5.0:
        send_alert(
            AlertLevel.CRITICAL,
            "🚨 Cost spike >5x baseline",
            f"Today: ${today_cost:.2f}, baseline: ${baseline:.2f} ({ratio:.1f}x)"
        )
    elif ratio > 2.0:
        send_alert(
            AlertLevel.WARNING,
            "⚠️ Cost spike 2x baseline",
            f"Today: ${today_cost:.2f}, baseline: ${baseline:.2f} ({ratio:.1f}x)"
        )

# Se ejecuta con cron cada hora
if __name__ == "__main__":
    check_cost_anomaly()
bash
# crontab -e
# Revisar anomalías de costo cada hora
0 * * * * cd /path/to/project && python cost_monitor.py

# Resumen diario a las 09:00
0 9 * * * cd /path/to/project && python daily_summary.py

Paso 4: registro estructurado

python
# structured_logging.py — logs en JSON listos para agregarse
import json
import time
import hashlib
from contextlib import contextmanager

def hash_user_id(user_id: str) -> str:
    """Seudonimiza el user_id para los logs."""
    return hashlib.sha256(user_id.encode()).hexdigest()[:16]

@contextmanager
def trace_llm_call(user_id: str, feature: str, model: str):
    """Context manager que registra la llamada al LLM en JSON estructurado."""
    trace_id = f"trace_{int(time.time()*1000)}"
    start = time.time()

    log_data = {
        "ts": time.time(),
        "trace_id": trace_id,
        "user_id_hash": hash_user_id(user_id),
        "feature": feature,
        "model": model,
    }

    try:
        yield log_data
        log_data["success"] = True
    except Exception as e:
        log_data["success"] = False
        log_data["error"] = str(e)
        log_data["error_type"] = type(e).__name__
        raise
    finally:
        log_data["duration_ms"] = int((time.time() - start) * 1000)
        print(json.dumps(log_data))  # → stdout → agregador de logs

# Uso
with trace_llm_call(user_id="user_42", feature="chat", model="claude-sonnet-5-5") as log:
    response = client.messages.create(
        model="claude-sonnet-5-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hola"}]
    )
    log["tokens_input"] = response.usage.input_tokens
    log["tokens_output"] = response.usage.output_tokens
    # Precios por millón de tokens a octubre de 2026 (Sonnet 5.5); vigentes: ../actual.html
    PRICE_IN, PRICE_OUT = 2.0, 10.0
    log["cost_usd"] = response.usage.input_tokens * PRICE_IN / 1_000_000 + \
                     response.usage.output_tokens * PRICE_OUT / 1_000_000

Paso 5: crear tu propio tablero (opcional)

python
# simple_dashboard.py — un tablero HTML mínimo
from flask import Flask, render_template_string
import time

flask_app = Flask(__name__)

DASHBOARD_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
    <title>AI Agent Dashboard</title>
    <meta http-equiv="refresh" content="60">
    <style>
        body { font-family: monospace; background: #1a1a1a; color: #00ff00; padding: 20px; }
        .metric { display: inline-block; padding: 20px; border: 1px solid #00ff00; margin: 10px; }
        .big { font-size: 32px; }
        .alert { color: #ff0000; }
        .warn { color: #ffaa00; }
        .ok { color: #00ff00; }
    </style>
</head>
<body>
    <h1>📊 AI Agent Production Dashboard</h1>
    <p>Last refresh: {{ ts }}</p>

    <div>
        <div class="metric">
            <div>Requests (24h)</div>
            <div class="big">{{ requests }}</div>
        </div>
        <div class="metric">
            <div>Cost (24h)</div>
            <div class="big ok">${{ cost }}</div>
        </div>
        <div class="metric">
            <div>Error rate</div>
            <div class="big {{ 'alert' if error_rate > 5 else 'warn' if error_rate > 1 else 'ok' }}">{{ error_rate }}%</div>
        </div>
        <div class="metric">
            <div>p95 latency</div>
            <div class="big">{{ p95 }}s</div>
        </div>
    </div>

    {% if alerts %}
    <h2>🚨 Active alerts</h2>
    <ul>{% for a in alerts %}<li class="warn">{{ a }}</li>{% endfor %}</ul>
    {% endif %}
</body>
</html>
"""

# Registramos la ruta con add_url_rule para que el tablero muestre los datos
def render_dashboard():
    # Pon aquí los datos reales de la API de Helicone / de tu base de datos
    return render_template_string(
        DASHBOARD_TEMPLATE,
        ts=time.strftime("%Y-%m-%d %H:%M:%S"),
        requests=1247,
        cost="12.40",
        error_rate=0.3,
        p95=4.2,
        alerts=["Cache hit ratio 24% (target >30%)"]
    )

flask_app.add_url_rule("/", "dashboard", render_dashboard)

if __name__ == "__main__":
    flask_app.run(port=8080)
bash
# Abres http://localhost:8080 y ves el tablero
python simple_dashboard.py

Checklist de preparación para producción (✅)

Antes de dejar que usuarios reales usen tu agente:

Si tienes menos de 7 marcas, no estás listo para producción. Termínalo.


Herramientas y recursos

  • LangSmith: observabilidad de LangChain, trazas avanzadas; tiene plan gratuito
  • Helicone: proxy de LLM con métricas (a octubre de 2026, en modo mantenimiento)
  • Sentry: seguimiento de errores, de uso general
  • PostHog: analítica de producto, métricas de negocio
  • PagerDuty: alertas de guardia, el estándar de la industria
  • Datadog: observabilidad enterprise de stack completo
  • Grafana Cloud IRM: guardias e incidentes (la versión de código abierto de OnCall se archivó en marzo de 2026)
  • Anthropic Console: seguimiento de uso integrado
  • OpenTelemetry: estándar de observabilidad independiente del proveedor

Conclusiones clave

La observabilidad no es "para después, cuando crezcamos". Es la condición para poder trabajar en producción. Un solo pico de costo que se te escape puede costar más que la suscripción anual a un servicio de monitoreo. Pon algo, lo que sea: hasta un simple webhook de Slack es mejor que "me entero por los clientes".

Las 5 métricas obligatorias: latencia (¡el p95!), costo (detección de picos), tasa de errores (categorizada), uso de tokens (cache ratio) y negocio (conversaciones completadas). Sin cualquiera de las cinco hay un punto ciego que te va a morder.

Los 3 niveles de alertas te salvan de la fatiga de alertas. Info: resumen diario. Warning: mención en Slack. Critical: avisar a quien está de guardia. Si cada error despierta a alguien en la noche, en una semana el equipo silencia el canal y se le pasa el incidente de verdad.

El flujo de depuración siempre es el mismo: localizar la traza → reproducir → correlacionar con las métricas → plantear la causa → corregir + agregar una prueba a los evals. Sin observabilidad, adivinas. Con ella, diagnosticas.


Siguiente lección

→ La arquitectura final: el stack completo de IA de un negocio

Para saber qué hacer cuando todo se rompió, ve la lección Backup & Disaster Recovery para el stack de IA.

La marca se guarda solo en este navegador y no se envía a ningún sitio. Mi progreso