Volver al blogLLMOps

Construyendo LLMOps custom: Cuando Langfuse no fue suficiente para agentes de IA en producción

500K+ interacciones, 10 agentes, 18 meses en producción. Por qué PostgreSQL + logs estructurados superó a Langfuse, LangSmith y Phoenix.

Alejandro Valencia12 min

He estado operando un sistema de IA de 10 agentes en producción durante 18 meses. Más de 500K interacciones, $67K de ahorros operacionales, operación multilingüe 24/7. Después de evaluar Langfuse, LangSmith y Arize Phoenix, construí mi propio stack de observabilidad.

Esto no se trata del síndrome NIH (Not Invented Here). Se trata de lo que los sistemas multi-agente en producción realmente necesitan.

El problema: sesiones de agente de larga duración

Las herramientas estándar de LLMOps están diseñadas para patrones request-response. Usuario envía mensaje → LLM responde → traza completa.

Mi sistema maneja sesiones de coaching que duran días o semanas. Un solo viaje de usuario involucra:

  • Más de 10 traspasos entre agentes
  • Decisiones de compresión de contexto en cada paso
  • Ejecución de workflow anidado (hasta 5 niveles de profundidad)
  • Lógica de negocio intercalada con decisiones de IA

Las trazas de Langfuse parecían espagueti. Sin correlación entre sesiones. Sin visibilidad de por qué un agente tomó una decisión.

Lo que herramientas comerciales no cubren

1. Seguimiento de decisiones del agente

Langfuse rastrea lo que dijo el LLM. No rastrea lo que tu agente decidió.

Mis agentes toman decisiones estructuradas en cada ejecución:

{
  "agent_decisions": {
    "flow": {
      "challenge_status": "in_progress",
      "significant_moment_detected": true
    },
    "safety": {
      "meta_questions_behavior": "normal"
    },
    "coaching_quality": {
      "intensity_level": "balanced",
      "message_length": 2325,
      "response_structure": {
        "sections": ["ANÁLISIS", "ESTRATEGIA", "CALIBRACIÓN"],
        "section_count": 7
      }
    }
  }
}

Esta es la "mente" del agente. Langfuse no tiene concepto de esto.

2. Observabilidad de compresión de contexto

Uso compresión exponencial de tokens para manejar conversaciones largas. Cada mensaje obtiene un puntaje de compresión basado en significancia.

{
  "context_management": {
    "user_input": {
      "compression_score": 0.1,
      "compression_priority": "preserve_full",
      "significant_moment_detected": true
    },
    "agent_output": {
      "compression_score": 0.15,
      "context_utilization": "high"
    }
  }
}

Cuando significant_moment_detected: true, la compresión es mínima. Los intercambios rutinarios obtienen compresión agresiva. Así es como mantienes relaciones de coaching coherentes durante un mes sin explotar los costos de tokens.

Ninguna herramienta comercial rastrea esto. Porque ninguna herramienta comercial asume que lo estás haciendo.

3. Correlación de workflow multi-nivel

Un solo mensaje de usuario en mi sistema puede desencadenar:

{
  "processes_executed": [
    {"name": "001 Main",               "nesting_level": 0},
    {"name": "  003 Extract message",  "nesting_level": 1},
    {"name": "  014 Process security", "nesting_level": 1},
    {"name": "  005 Process command",  "nesting_level": 1},
    {"name": "  301 Selling process",  "nesting_level": 1},
    {"name": "  202 Agent - Coaching", "nesting_level": 1},
    {"name": "    101 AI Execute LLM", "nesting_level": 2},
    {"name": "    021 Send message",   "nesting_level": 2},
    {"name": "      022 Record exchange", "nesting_level": 3},
    {"name": "  901 Cleanup User Lock", "nesting_level": 1}
  ],
  "created_at": "2025-11-28T21:41:34.752Z",
  "finalized_at": "2025-11-28T21:42:02.129Z"
}

10 workflows, 3 niveles de anidamiento, ~27 segundos total (incluyendo procesamiento LLM). Cada paso correlacionado por execution_id. Cada viaje de usuario rastreable a través de días.

Langfuse puede mostrarte una traza. No puede mostrarte un viaje.

La arquitectura

Cuatro tablas de logs, una clave de correlación:

┌─────────────────────────────────────────────────────────────┐
│                      execution_id                            │
│                           │                                  │
│    ┌──────────────────────┼──────────────────────┐          │
│    │                      │                      │          │
│    ▼                      ▼                      ▼          │
│ logs_execution     logs_user_journey     logs_agent_execution│
│ (workflow trace)   (event sourcing)      (AI decisions)     │
│    │                                            │           │
│    │                                            ▼           │
│    │                                   logs_llm_execution   │
│    │                                   (tokens, costs)      │
│    └────────────────────────────────────────────┘          │
└─────────────────────────────────────────────────────────────┘

logs_execution

Orquestación de workflow. Qué workflows de n8n se dispararon, en qué orden, con qué anidamiento.

logs_user_journey

Event sourcing para interacciones de usuario. Cada mensaje recibido, cada mensaje enviado, cada transición de estado.

{
  "event_type": "user_message_sent_requested",
  "particular_data": {
    "role": "system",
    "text_length": 934,
    "credits_used": 0,
    "is_bot_scope": true,
    "is_coaching_scope": false,
    "is_selling_scope": false
  }
}

Contexto de negocio integrado en cada evento. Puedo consultar "muéstrame todos los mensajes de selling-scope para el usuario X" en una sola sentencia SQL.

logs_agent_execution

Decisiones a nivel de agente. Preparación de contexto, elecciones de compresión, métricas de calidad de coaching.

logs_llm_execution

Llamadas LLM en bruto. Tokens, costos, latencia, hashes de prompts.

{
  "event_type": "llm_valid_execution",
  "model_target": "claude-sonnet-4-20250514",
  "prompt_hash": "# ADVANCED MALE SOCIAL COACHING SYSTEM...43713chars",
  "output_tokens": 1568,
  "processing_time_ms": 25937,
  "output_cost": "0.02352",
  "total_cost": "0.06123"
}

Implementación: n8n + PostgreSQL

La capa completa de observabilidad corre en el mismo stack que la aplicación:

  • n8n: Orquestación de workflow con seguimiento de ejecución integrado
  • PostgreSQL: Logs estructurados con capacidad completa de consulta SQL
  • Redis: Correlación de ejecución entre workflows asíncronos

Sin infraestructura adicional. Sin facturas de SaaS. Sin datos saliendo de mis servidores.

Patrón de inserción de logs

Cada workflow comienza con captura de contexto:

// Pseudocódigo - implementación real en nodos de n8n
const executionLog = {
  execution_id: generateCorrelationId(),
  user_id: context.user.id,
  telegram_id: context.user.telegram_id,
  processes_executed: [],
  user_tier: context.user.tier,
  user_language: context.user.language,
  user_input_type: detectInputType(message),
  created_at: new Date().toISOString()
};

// Pasar a través de todo el workflow, agregar cada proceso
executionLog.processes_executed.push({
  name: currentWorkflow.name,
  timestamp: new Date().toISOString(),
  timestamp_ms: Date.now(),
  nesting_level: context.nestingLevel
});

Patrones de consulta

Encontrar ejecuciones lentas de agente:

SELECT
  execution_id,
  agent_type,
  particular_data->>'event_duration_ms' as duration_ms,
  created_at
FROM logs_agent_execution
WHERE (particular_data->>'event_duration_ms')::int > 20000
ORDER BY created_at DESC;

Análisis de costos por tipo de agente:

SELECT
  agent_type,
  COUNT(*) as executions,
  SUM((total_cost)::numeric) as total_cost,
  AVG((processing_time_ms)::numeric) as avg_latency
FROM logs_llm_execution
WHERE event_type = 'llm_valid_execution'
GROUP BY agent_type;

Reconstrucción de viaje de usuario:

SELECT
  event_type,
  particular_data,
  created_at
FROM logs_user_journey
WHERE user_id = '57'
ORDER BY created_at;

Resultados

18 meses en producción:

MétricaValor
Interacciones totales500K+
Tipos de agentes10
Tiempo de respuesta promedio3-5 segundos
Ahorros operacionales$67K
Downtime0
Costo de observabilidad externa$0

El stack de observabilidad personalizado ha detectado:

  • Bugs de compresión de contexto: Momentos significativos siendo sobre-comprimidos
  • Drift de decisiones del agente: Intensidad de coaching subiendo/bajando demasiado
  • Anomalías de costos: Patrones específicos de usuario desencadenando rutas de ejecución costosas
  • Regresiones de latencia: Nuevas versiones de prompts causando respuestas más lentas

Cuándo construir custom

Construye tu propia observabilidad si:

  1. Tus agentes toman decisiones estructuradas que necesitas rastrear
  2. Las sesiones duran días/semanas, no minutos
  3. El contexto de negocio importa para debugging (tiers, scopes, journeys)
  4. Ya estás corriendo PostgreSQL y no quieres otro SaaS
  5. Necesitas capacidad de consulta SQL, no solo dashboards

Usa Langfuse/LangSmith si:

  1. El patrón request-response se ajusta a tu caso de uso
  2. Quieres configuración rápida sobre personalización
  3. Tu equipo espera una UI familiar
  4. No estás haciendo compresión de contexto u orquestación multi-agente

Conclusión

El mercado de LLMOps asume que estás construyendo chatbots. Si estás construyendo algo más complejo—sesiones de agente de larga duración, gestión de contexto personalizada, orquestación multi-agente—las herramientas te van a dificultar el trabajo.

PostgreSQL + logs estructurados + tu conocimiento de dominio = observabilidad que realmente funciona.

Tiempo total de implementación: ~2 semanas. Costo continuo total: $0. Vendor lock-in total: 0.