Phase 19 - Lesson 11
Capstone 11 — Panel de Observabilidad y Evaluación de LLM
Langfuse pasó a ser de código abierto básico (open-core). Arize Phoenix publicó los mapeos semánticos GenAI de 2026. Helicone y Braintrust duplicaron su apuesta en la atribución de costo por usuario. OpenLLMetry de Traceloop se convirtió en la instrumentación de SDK de facto. El diseño de producción consiste en ClickHouse para trazas, Postgres para metadatos, Next.js para la interfaz de usuario (UI) y un pequeño ejército de tareas de evaluación (DeepEval, RAGAS, LLM-judge) ejecutándose sobre trazas muestreadas. Desarrolle un panel autohospedado (self-hosted), consuma datos de al menos cuatro familias de SDK y demuestre la detección de una regresión inyectada en menos de cinco minutos.
Type: Capstone Languages: TypeScript (UI), Python / TypeScript (ingest + evals), SQL (ClickHouse) Prerequisites: Phase 11 (LLM engineering), Phase 13 (tools), Phase 17 (infrastructure), Phase 18 (safety) Phases exercised: P11 · P13 · P17 · P18 Time: 25 horas
Problem
Cada equipo de IA que ejecuta tráfico de producción en 2026 mantiene un plano de observabilidad junto al modelo. Atribución de costos. Detención de alucinaciones. Monitoreo de desviación (drift). Señales de jailbreak. Paneles de SLO. Alertas de filtración de PII. Las referencias de código abierto — Langfuse, Phoenix, OpenLLMetry — convergieron en las convenciones semánticas (semantic conventions) GenAI de OpenTelemetry como el esquema de ingesta. Ahora puede instrumentar OpenAI, Anthropic, Google, LangChain, LlamaIndex y vLLM con un solo SDK y enviar spans compatibles.
Construirá un panel autohospedado que ingiere datos de al menos cuatro familias de SDK, ejecuta un pequeño conjunto de tareas de evaluación sobre trazas muestreadas, detecta desvíos y genera alertas. La meta de medición: dada una regresión inyectada deliberadamente (un prompt que comienza a producir PII), el panel la detecta y dispara una alerta en menos de cinco minutos.
Concept
La ingesta se realiza vía OTLP HTTP. El SDK produce spans con convenciones semánticas de GenAI: gen_ai.system, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.response.id, llm.prompts, llm.completions. Los spans llegan a ClickHouse para análisis columnar; los metadatos (usuarios, sesiones, aplicaciones) se guardan en Postgres.
Las evaluaciones se ejecutan como tareas por lotes (batch jobs) sobre trazas muestreadas. DeepEval evalúa fidelidad (faithfulness), toxicidad y relevancia de la respuesta. RAGAS evalúa métricas de recuperación cuando la traza incluye contexto de recuperación. Los LLM-judges personalizados ejecutan verificaciones específicas del dominio (filtración de PII, respuesta fuera de directiva). Las tareas de evaluación escriben de vuelta en el mismo ClickHouse como spans de evaluación vinculados a la traza padre.
La desviación de datos (drift) monitorea las distribuciones en el espacio de embeddings a lo largo del tiempo (divergencia PSI o KL en embeddings de prompts) más tendencias de puntajes de evaluación. Las alertas alimentan a Prometheus Alertmanager y luego a Slack / PagerDuty. La UI está desarrollada en Next.js 15 con Recharts.
Architecture
aplicaciones de producción:
OpenAI SDK + Anthropic SDK + Google GenAI SDK
LangChain + LlamaIndex + vLLM
|
v
OpenTelemetry SDK con GenAI semconv
|
v OTLP HTTP
colector (ingesta, muestreo, fan-out)
|
+-------------+-----------+
v v v
ClickHouse Postgres archivo S3
(spans) (metadatos) (eventos brutos)
|
+---> jobs de eval (DeepEval, RAGAS, LLM-judge)
| muestreados o todas las trazas
| escribe spans de eval de vuelta
|
+---> detector de desvío (PSI / KL en embeddings de prompt)
|
+---> métricas Prometheus -> Alertmanager -> Slack / PagerDuty
|
v
panel Next.js 15 (Recharts)
Stack
- Ingesta: OpenTelemetry SDKs + convenciones semánticas GenAI; transporte OTLP HTTP
- Colector: OpenTelemetry Collector con procesador de muestreo de cola (tail-sampling) (para control de costos)
- Almacenamiento: ClickHouse para spans, Postgres para metadatos, S3 para archivo de eventos brutos
- Evaluaciones: DeepEval, RAGAS 0.2, paquete evaluador Arize Phoenix, LLM-judge personalizado
- Desvío (Drift): PSI / KL en embeddings de prompts agrupados (sentence-transformers) semanalmente
- Alertas: Prometheus Alertmanager -> Slack / PagerDuty
- UI: Next.js 15 App Router + Recharts + server actions
- SDKs soportados nativamente: OpenAI, Anthropic, Google GenAI, LangChain, LlamaIndex, vLLM
Build It
Configuración del colector. OpenTelemetry Collector con el receptor OTLP HTTP, un muestreador de cola (tail-sampler) que conserva el 100% de las trazas con error y el 10% de las exitosas, y exportadores hacia ClickHouse y S3.
Esquema de ClickHouse. Tabla
spanscon columnas que reflejan GenAI semconv:gen_ai_system,gen_ai_request_model,input_tokens,output_tokens,latency_ms,prompt_hash,trace_id,parent_span_id, más un campo JSON para payloads largos. Agregue índices secundarios poruser_idyapp_id.Prueba de cobertura del SDK. Escriba una pequeña aplicación cliente usando cada SDK (OpenAI, Anthropic, Google, LangChain, LlamaIndex, vLLM) con autoinstrumentación de OpenLLMetry. Verifique que cada uno produzca spans de GenAI canónicos que terminen en ClickHouse.
Tareas de evaluación (eval). Una tarea programada lee las trazas muestreadas de los últimos 15 minutos y ejecuta DeepEval para fidelidad, toxicidad y relevancia de respuesta. Los resultados son spans de evaluación vinculados a la traza padre.
LLM-judge personalizado. Un evaluador de filtraciones de PII: dada una respuesta, llame a una LLM guardiana para calificar la probabilidad de filtración de PII. Las respuestas con puntajes altos pasan a una cola de triaje.
Detección de desvíos. Tarea semanal que calcula el PSI entre los embeddings de prompts agrupados de esta semana y la línea de base de las últimas 4 semanas. Si el PSI está por encima del umbral, dispara una alerta.
Panel. Next.js 15 con las páginas: visión general (spans/seg, costo/usuario, latencia p95), trazas (búsqueda + vista en cascada), evaluaciones (tendencia de fidelidad, toxicidad), desvío (PSI a lo largo del tiempo), alertas.
Cadena de alertas. El exportador de Prometheus lee los agregados de puntaje de evaluación y percentiles de latencia; el Alertmanager los encamina a Slack para advertencias y a PagerDuty para infracciones críticas.
Sonda de regresión. Inyecte un error: el chatbot evaluado comienza a filtrar números de seguridad social falsos el 1% de las veces. Mida el MTTR: desde el despliegue del error hasta la alerta de Slack.
Use It
$ curl -X POST https://my-otel-collector/v1/traces -d @trace.json
[collector] accepted 1 trace, 3 spans
[clickhouse] inserted 3 spans (app=chat, user=u_42)
[eval] DeepEval faithfulness 0.82, toxicity 0.03
[drift] weekly PSI 0.08 (below 0.2 threshold)
[ui] live at https://obs.example.com
Ship It
outputs/skill-llm-observability.md es el entregable. Dada una aplicación de LLM, el panel ingiere sus trazas, ejecuta evaluaciones, alerta sobre desvíos y presenta el desglose de costo/usuario en Next.js.
| Peso | Criterio | Cómo se mide |
|---|---|---|
| 25 | Cobertura del esquema de trazas | Número de familias de SDK que producen spans de GenAI canónicos (meta: 6+) |
| 20 | Corrección de la evaluación | Puntajes de DeepEval / RAGAS frente al conjunto etiquetado a mano |
| 20 | UX del panel | MTTR en la regresión inyectada (meta inferior a 5 minutos) |
| 20 | Costo / escala | Ingesta sostenida a 1k spans/seg sin acumulación de fila |
| 15 | Alertas + detección de desvíos | Cadena Prometheus/Alertmanager ejercitada de extremo a extremo |
| 100 |
Exercises
Agregue instrumentación personalizada para el framework Haystack. Verifique que los spans canónicos terminen en ClickHouse con los atributos
gen_ai.*correctos.Reemplace DeepEval por evaluadores de Phoenix en las mesmas trazas. Mida la desviación del puntaje entre los dos motores de evaluación.
Perfeccione el detector de desvíos: calcule el PSI por app-id en lugar de globalmente. Muestre los históricos de desvío por aplicación.
Agregue una página de "impacto en el usuario": costo por usuario y tasa de fallas por usuario con sparklines.
Construya una política de muestreo de cola (tail-sampling) que conserve el 100% de las trazas con toxicidad > 0.5 más una muestra estratificada del 10% del resto. Mida el sesgo de muestreo introducido.
Key Terms
| Término | Lo que la gente dice | Lo que realmente significa |
|---|---|---|
| GenAI semconv | "Atributos de LLM de OTel" | Especificación OpenTelemetry de 2025 para atributos de span de LLM (sistema, modelo, tokens) |
| Tail sampling | "Muestra post-traza" | El colector decide conservar o descartar una traza después de que finaliza (permite observar errores) |
| PSI | "Índice de estabilidad de la población" | Métrica de desvío que compara dos distribuciones; > 0.2 típicamente indica un desvío significativo |
| LLM-judge | "Evaluación como modelo" | Una LLM que califica la salida de otra LLM sobre una rúbrica (fidelidad, toxicidad, PII) |
| Tail-sampling policy | "Regla de retención" | Regla que decide qué trazas conservar frente a descartar; errores + tasa de muestreo |
| Eval span | "Traza de evaluación vinculada" | Span hijo que contiene un puntaje de evaluación vinculado al span de la llamada original de LLM |
| Cost per user | "Economía unitaria" | Costo en dólares atribuido a un user_id durante una ventana de tiempo; métrica clave de producto |
Further Reading
- Langfuse — la plataforma de observabilidad open-core de referencia
- Arize Phoenix — referencia alternativa con fuerte soporte de desvíos
- OpenLLMetry (Traceloop) — familia de SDK de autoinstrumentación
- OpenTelemetry GenAI semantic conventions — el esquema de ingesta
- Helicone — observabilidad hospedada alternativa
- Braintrust — plataforma de evaluación alternativa enfocada en evals
- ClickHouse documentation — almacén de spans columnar
- DeepEval — biblioteca de evaluación