<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Promptfoo on lo0 — Blog Técnico</title><link>https://blog.lo0.es/tags/promptfoo/</link><description>Recent content in Promptfoo on lo0 — Blog Técnico</description><generator>Hugo -- gohugo.io</generator><language>es</language><lastBuildDate>Mon, 25 May 2026 07:30:00 +0200</lastBuildDate><atom:link href="https://blog.lo0.es/tags/promptfoo/index.xml" rel="self" type="application/rss+xml"/><item><title>Evals para LLMs: la capa después del tracing que decide si tu modelo rinde o sólo parece rendir</title><link>https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/</link><pubDate>Mon, 25 May 2026 07:30:00 +0200</pubDate><guid>https://blog.lo0.es/posts/evals-llm-la-capa-despues-de-tracing/</guid><description>&lt;blockquote>
&lt;p>Esta es la &lt;strong>etapa 3&lt;/strong> del pipeline LLMOps. Si llegas sin contexto del recorrido completo, el &lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">pipeline LLMOps de seis etapas&lt;/a> describe dónde encaja Eval entre Tune y Deploy, y la &lt;a href="https://blog.lo0.es/posts/anatomia-request-llm-mayo-2026/">anatomía de una petición LLM en producción&lt;/a> muestra una eval real bloqueando la promoción de un adapter.&lt;/p>
&lt;/blockquote>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Tracing no es evaluación. &lt;strong>Tracing te dice qué pasó; eval te dice si lo que pasó está bien.&lt;/strong> Las dos capas viven en herramientas que se solapan visualmente (Langfuse hace ambas), pero la disciplina es distinta: tracing es captura continua sobre tráfico real; eval es ejecución controlada contra un dataset estable, con métricas que tienen que &lt;strong>fallar el CI&lt;/strong> si caen por debajo de un umbral. Sin eval, el ciclo &lt;code>Tune → Deploy&lt;/code> se cierra a ciegas: el adapter v8 va a producción porque el ingeniero &amp;ldquo;vio que respondía bien&amp;rdquo; en cinco ejemplos. Con eval bien hecha, el v8 sólo entra si supera al v7 en una batería de 500 casos curados, evaluados por una mezcla de heurísticos, embeddings, un judge LLM calibrado contra humanos, y una muestra de tráfico real con anotación humana. Este post desmonta el mecanismo, las matemáticas para no engañarse, las herramientas reales en 2026 y las trampas que lo convierten en teatro.&lt;/p>
&lt;h2 id="la-analogía-el-tribunal-académico">La analogía: el tribunal académico&lt;/h2>
&lt;div class="diagram" style="max-width:760px;margin:1.5rem auto;">
&lt;svg viewBox="0 0 760 320" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Eval como tribunal académico">
&lt;style>
.tbox{fill:#f8f8f8;stroke:#444;stroke-width:1.4;rx:8}
.thead{fill:#7aafff;stroke:#444;stroke-width:1.4;rx:8}
.tlbl{font:600 13px sans-serif;fill:#222}
.tsub{font:400 11px sans-serif;fill:#555}
.tarr{stroke:#666;stroke-width:1.5;fill:none;marker-end:url(#me1)}
.tgate{fill:#ffd76b;stroke:#444;stroke-width:1.6;rx:6}
&lt;/style>
&lt;defs>&lt;marker id="me1" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">&lt;path d="M0,0 L10,5 L0,10 z" fill="#666"/>&lt;/marker>&lt;/defs>
&lt;rect x="20" y="20" width="160" height="60" class="thead"/>
&lt;text x="100" y="44" text-anchor="middle" class="tlbl">Candidato&lt;/text>
&lt;text x="100" y="62" text-anchor="middle" class="tsub">modelo + adapter + prompt&lt;/text>
&lt;text x="100" y="76" text-anchor="middle" class="tsub">(la "tesis" que se defiende)&lt;/text>
&lt;rect x="240" y="20" width="200" height="60" class="tbox"/>
&lt;text x="340" y="44" text-anchor="middle" class="tlbl">Temario fijado&lt;/text>
&lt;text x="340" y="62" text-anchor="middle" class="tsub">golden dataset versionado&lt;/text>
&lt;text x="340" y="76" text-anchor="middle" class="tsub">(500 preguntas con respuesta esperada)&lt;/text>
&lt;rect x="500" y="20" width="240" height="60" class="tbox"/>
&lt;text x="620" y="44" text-anchor="middle" class="tlbl">Tribunal mixto&lt;/text>
&lt;text x="620" y="62" text-anchor="middle" class="tsub">heurísticos + embeddings + judge LLM&lt;/text>
&lt;text x="620" y="76" text-anchor="middle" class="tsub">+ muestra humana (panel calibrado)&lt;/text>
&lt;path class="tarr" d="M180,50 L240,50"/>
&lt;path class="tarr" d="M440,50 L500,50"/>
&lt;rect x="40" y="130" width="180" height="60" class="tbox"/>
&lt;text x="130" y="154" text-anchor="middle" class="tlbl">Notas por categoría&lt;/text>
&lt;text x="130" y="172" text-anchor="middle" class="tsub">faithfulness, relevancy,&lt;/text>
&lt;text x="130" y="186" text-anchor="middle" class="tsub">format, toxicity, latency&lt;/text>
&lt;rect x="270" y="130" width="220" height="60" class="tbox"/>
&lt;text x="380" y="154" text-anchor="middle" class="tlbl">Agregación + segmentación&lt;/text>
&lt;text x="380" y="172" text-anchor="middle" class="tsub">media global, por idioma,&lt;/text>
&lt;text x="380" y="186" text-anchor="middle" class="tsub">por tenant, por tipo de pregunta&lt;/text>
&lt;rect x="540" y="130" width="200" height="60" class="tgate"/>
&lt;text x="640" y="154" text-anchor="middle" class="tlbl">Eval gate (nota de corte)&lt;/text>
&lt;text x="640" y="172" text-anchor="middle" class="tsub">faithfulness ≥ 0.85 ∧ tox &amp;lt; 0.02&lt;/text>
&lt;text x="640" y="186" text-anchor="middle" class="tsub">∧ regresión vs baseline &amp;lt; 2 pp&lt;/text>
&lt;path class="tarr" d="M620,86 L130,124"/>
&lt;path class="tarr" d="M620,86 L380,124"/>
&lt;path class="tarr" d="M620,86 L640,124"/>
&lt;rect x="40" y="240" width="320" height="60" class="tbox"/>
&lt;text x="200" y="264" text-anchor="middle" class="tlbl">Aprobado → promoción a producción&lt;/text>
&lt;text x="200" y="282" text-anchor="middle" class="tsub">label `production` se mueve al candidato&lt;/text>
&lt;rect x="400" y="240" width="320" height="60" class="tbox"/>
&lt;text x="560" y="264" text-anchor="middle" class="tlbl">Suspenso → vuelve a Tune&lt;/text>
&lt;text x="560" y="282" text-anchor="middle" class="tsub">incidente o regresión queda en lineage&lt;/text>
&lt;path class="tarr" d="M580,196 L200,236"/>
&lt;path class="tarr" d="M700,196 L560,236"/>
&lt;/svg>
&lt;/div>
&lt;p>Un candidato a doctor defiende una tesis. No la defiende ante un solo profesor distraído: la defiende ante un &lt;strong>tribunal mixto&lt;/strong>, con un &lt;strong>temario fijado por adelantado&lt;/strong> (no improvisado el día del acto), y con una &lt;strong>nota de corte explícita&lt;/strong> que separa aprobado de suspenso. El tribunal no es un único experto: es un panel que combina lectores rápidos (los heurísticos: ¿tiene el formato pedido?, ¿incluye la cita?), revisores semánticos (los embeddings: ¿se parece a la respuesta esperada?), un evaluador externo formado para el tema (el judge LLM: ¿es fiel al contexto, es relevante, suena coherente?), y miembros humanos del jurado en una &lt;strong>muestra de los casos más sensibles&lt;/strong>. Si el candidato no llega a la nota, no se promociona: vuelve a preparar la defensa.&lt;/p>
&lt;p>Esa analogía tiene tres aristas que conviene retener desde el primer minuto:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>El temario es fijo&lt;/strong>, pero &lt;strong>se actualiza activamente cuando aparece un tema nuevo en el mundo real&lt;/strong> que el candidato debe saber. Si no se actualiza, el examen mide algo cada vez más alejado de lo que pasa fuera.&lt;/li>
&lt;li>&lt;strong>El tribunal hay que formarlo&lt;/strong>: un juez LLM sin calibrar contra humanos es un examinador que se inventa los criterios.&lt;/li>
&lt;li>&lt;strong>La nota de corte se publica antes&lt;/strong>: no se decide después de ver el resultado, porque entonces no es nota de corte, es justificación.&lt;/li>
&lt;/ol>
&lt;p>Estas tres ideas atraviesan el resto del post. Cada herramienta y cada matemática que sigue es, en el fondo, un modo de operacionalizarlas.&lt;/p>
&lt;h2 id="el-mecanismo-en-sí-cuatro-capas-de-evaluadores">El mecanismo en sí: cuatro capas de evaluadores&lt;/h2>
&lt;p>Una suite de evals en 2026 se compone de cuatro capas que coexisten. Ninguna sustituye a las otras; cada una mide lo que las demás no pueden medir bien y deja sin medir lo que sí miden bien las demás.&lt;/p>
&lt;p>&lt;strong>Capa 1 — Heurísticos deterministas.&lt;/strong> Reglas que devuelven &lt;code>true&lt;/code> o &lt;code>false&lt;/code> sin ambigüedad: el output coincide con un regex, contiene una entidad concreta, no excede una longitud, sigue un esquema JSON válido, respeta un formato pedido (markdown, función &lt;code>tool_call&lt;/code>, citación obligatoria). Son baratos, rapidísimos, no necesitan judge ni embeddings, y atrapan el tipo de bug más frecuente: el modelo respondió en el formato equivocado. Su límite es obvio — no saben si la respuesta es &lt;strong>correcta&lt;/strong>, sólo si es &lt;strong>bien formada&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Capa 2 — Métricas semánticas con embeddings.&lt;/strong> Comparan el output del modelo con una respuesta esperada calculando similitud coseno entre sus embeddings, o midiendo si una afirmación del output está implicada por el contexto recuperado. Son baratos, deterministas dado el modelo de embedding, y muy útiles para detectar respuestas que se desvían en sentido pero no en forma. Su límite también es claro: dos respuestas pueden tener alto coseno y decir lo contrario una de otra (&amp;ldquo;el cliente puede cancelar en cualquier momento&amp;rdquo; vs &amp;ldquo;el cliente no puede cancelar en cualquier momento&amp;rdquo; comparten 80% de tokens).&lt;/p>
&lt;p>&lt;strong>Capa 3 — LLM-as-judge.&lt;/strong> Un modelo —o un ensemble— evalúa el output del modelo bajo prueba con un prompt diseñado para producir un score en una rúbrica. Los métodos canónicos en 2026 son &lt;strong>G-Eval&lt;/strong> (chain-of-thought prompting con score numérico calibrado), &lt;strong>Prometheus&lt;/strong> (judge open-source entrenado específicamente para evals, reporta correlación 0.897 con humanos en su release v2.5 de finales de 2025), y los &lt;strong>panel-of-judges&lt;/strong> que promedian votos de tres modelos heterogéneos para reducir sesgo. Esta capa captura matices que las dos anteriores no ven: ¿es fiel al contexto? ¿es útil? ¿es seguro? ¿está completo? Su límite es el coste y la necesidad de calibración —tratada como sección entera más abajo—.&lt;/p>
&lt;p>&lt;strong>Capa 4 — Humanos.&lt;/strong> Anotadores formados que evalúan una &lt;strong>muestra&lt;/strong> del eval set, no toda. Son la única capa con autoridad última sobre la rúbrica: el judge LLM se calibra contra ellos, no al revés. Son caros (≈ 0,50–2,00 € por muestra anotada cuando el dominio es técnico) y lentos (un anotador competente hace 60–120 anotaciones de calidad por jornada). El error que los equipos cometen una y otra vez es prescindir de esta capa &amp;ldquo;porque tenemos judge LLM&amp;rdquo;; sin humanos, no hay calibración, y sin calibración el judge mide lo que le da la gana.&lt;/p>
&lt;p>La operación normal de un eval gate combina las cuatro: heurísticos eliminan los outputs malformados antes de gastar judge, los embeddings filtran lo manifiestamente irrelevante, el judge puntúa el resto, y los humanos anotan una muestra cada N runs para mantener el judge calibrado.&lt;/p>
&lt;h2 id="el-golden-dataset-temario-versionado">El golden dataset: temario versionado&lt;/h2>
&lt;p>El golden dataset es el artefacto más infravalorado del pipeline. Es &lt;strong>el examen&lt;/strong>. Si está mal construido, todo lo demás —el judge mejor calibrado del mundo, los gates más estrictos, la suite más rápida— mide ruido. Cubierto a primer nivel en el &lt;a href="https://blog.lo0.es/posts/data-versioning-dvc-lakefs/">post de data versioning&lt;/a> como uno de los cuatro artefactos a versionar diferenciadamente; aquí entramos al detalle desde la perspectiva de Eval.&lt;/p>
&lt;p>Las tres propiedades que un golden dataset tiene que cumplir son:&lt;/p>
&lt;p>&lt;strong>Representatividad estratificada.&lt;/strong> El dataset tiene que cubrir el espacio real de inputs del sistema en proporciones que reflejen producción. Si el 30% del tráfico real es en alemán, el 30% del golden tiene que ser en alemán; si el 12% de las preguntas son sobre cancelación de suscripción, esa categoría no puede ser el 60% del eval set sólo porque era fácil de anotar. La estratificación se mantiene auditable: cada ejemplo lleva tags (&lt;code>lang=de&lt;/code>, &lt;code>category=cancellation&lt;/code>, &lt;code>tenant_type=enterprise&lt;/code>, &lt;code>difficulty=hard&lt;/code>) y la suite reporta métricas por segmento, no sólo el agregado.&lt;/p>
&lt;p>&lt;strong>Holdout estricto, no contaminación con training.&lt;/strong> Esta regla es tan obvia que casi todos los equipos creen que la cumplen, y casi todos la rompen sin darse cuenta. Si el golden eval set se mezcla con el dataset de fine-tuning —porque alguien hizo un &lt;code>random_split&lt;/code> mal hecho, porque un dataset comprado lo usa para entrenar otros vendors, porque el judge LLM lo vio durante su pretraining— la métrica deja de medir generalización y pasa a medir memorización. El hash del eval set se versiona aparte (cubierto en el &lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">post de fine-tuning continuo&lt;/a>) y se ejecuta un check rutinario de leakage: si un ejemplo del golden coincide token-a-token con uno del training, alerta.&lt;/p>
&lt;p>&lt;strong>Sample size razonado, no aspiracional.&lt;/strong> ¿Cuántos ejemplos hacen falta? Hay un mínimo matemático para distinguir dos modelos con confianza. Si el modelo A acierta el 80% y el modelo B el 85% sobre el mismo set, el intervalo de confianza al 95% para esa diferencia de proporciones (sin pareo) es:&lt;/p>
&lt;p>[
\Delta p \pm 1{,}96 \cdot \sqrt{\frac{p_A(1-p_A) + p_B(1-p_B)}{n}}
]&lt;/p>
&lt;p>Para distinguir 80% vs 85% con confianza 95% (intervalo que no cruce cero), necesitas n ≈ 700 ejemplos. Para distinguir 90% vs 91% bajo el mismo criterio, el cálculo da n ≈ 6.500. Los &amp;ldquo;tenemos 50 ejemplos en el golden y vemos que el adapter v8 saca 90%&amp;rdquo; no significan nada estadísticamente: el intervalo de confianza es ±8 puntos. La regla práctica del campo en 2026 es &lt;strong>mínimo 300 ejemplos para detectar diferencias gruesas, idealmente 500–1.500 si quieres detectar mejoras finas&lt;/strong>, y empezar por estratificar bien antes de obsesionarse con sample size.&lt;/p>
&lt;p>A esto se suma el &lt;strong>mantenimiento activo&lt;/strong>: el golden se enriquece con los &lt;strong>incidentes de producción&lt;/strong> (cubierto en detalle en el &lt;a href="https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/">post de retrain&lt;/a>), de manera que cada queja real terminada en bug se convierte en un ejemplo curado que el siguiente candidato a deploy tendrá que aprobar. El golden no es estático: es un &lt;strong>registro vivo de errores que el sistema ya ha cometido y no debe volver a cometer&lt;/strong>.&lt;/p>
&lt;h2 id="llm-as-judge-cómo-se-calibra-un-examinador">LLM-as-judge: cómo se calibra un examinador&lt;/h2>
&lt;p>La capa 3 es la que más equipos malusan. El error típico es: &amp;ldquo;usamos GPT-4 como judge porque es el más capaz&amp;rdquo;. El judge no se elige por capacidad nominal; se elige por &lt;strong>agreement con los humanos&lt;/strong> sobre la rúbrica concreta que estás midiendo. Un judge con 60% agreement no sirve aunque sea GPT-5; un Prometheus 7B fine-tuneado para tu dominio con 88% agreement vale más.&lt;/p>
&lt;p>La métrica estándar para medir agreement entre dos anotadores (humano vs judge, o dos humanos entre sí) es el &lt;strong>kappa de Cohen&lt;/strong>, que corrige por el agreement esperado por azar:&lt;/p>
&lt;p>[
\kappa = \frac{p_o - p_e}{1 - p_e}
]&lt;/p>
&lt;p>donde (p_o) es la proporción de acuerdo observada y (p_e) es la proporción esperada por casualidad bajo las distribuciones marginales de cada anotador. Las interpretaciones aceptadas en la literatura son:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>κ &amp;lt; 0,40&lt;/strong>: agreement pobre. El judge dice lo que le da la gana.&lt;/li>
&lt;li>&lt;strong>κ ∈ [0,40, 0,60]&lt;/strong>: moderado. Aceptable para señales gruesas (¿es tóxico?), pésimo para matices (¿es fiel al contexto?).&lt;/li>
&lt;li>&lt;strong>κ ∈ [0,60, 0,80]&lt;/strong>: substancial. Útil en producción para la mayoría de métricas.&lt;/li>
&lt;li>&lt;strong>κ &amp;gt; 0,80&lt;/strong>: casi perfecto. El judge se puede tratar como sustituto del humano para ese tipo de juicio concreto.&lt;/li>
&lt;/ul>
&lt;p>Numéricamente, considera una rúbrica binaria (faithful / not faithful) sobre 200 ejemplos anotados por humano y por judge. Si el humano dijo &amp;ldquo;faithful&amp;rdquo; en 150 casos y el judge en 140, y coinciden en 175 de los 200, entonces (p_o = 0{,}875); las marginales son (p_h = 0{,}75), (p_j = 0{,}70), y (p_e = 0{,}75 \cdot 0{,}70 + 0{,}25 \cdot 0{,}30 = 0{,}600). Kappa sale &lt;strong>0,6875&lt;/strong>: substancial pero no excelente — utilizable, con vigilancia sobre la rúbrica.&lt;/p>
&lt;p>Calibrar el judge implica un proceso explícito:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Construir un calibration set&lt;/strong> — 100–300 ejemplos anotados por humanos formados, con guidelines escritas. La inter-anotador kappa entre los humanos también se mide; si los propios humanos no se ponen de acuerdo, la rúbrica está mal redactada antes de hablar de judge.&lt;/li>
&lt;li>&lt;strong>Iterar el prompt del judge&lt;/strong> hasta que el judge agreement con los humanos supere el umbral aceptado (típicamente κ ≥ 0,7 para métricas sensibles).&lt;/li>
&lt;li>&lt;strong>Fijar la versión del judge&lt;/strong> (&lt;code>claude-3-5-sonnet-20251022&lt;/code>, &lt;code>gpt-4o-2024-11&lt;/code>, &lt;code>prometheus-2-7b@sha256:…&lt;/code>): cualquier cambio invalida la calibración.&lt;/li>
&lt;li>&lt;strong>Re-calibrar periódicamente&lt;/strong> — cada vez que cambia el judge, el prompt del judge, o la rúbrica. La frecuencia recomendada por el campo en 2026 es trimestral mínimo, mensual si la rúbrica es nueva.&lt;/li>
&lt;li>&lt;strong>Persistir todo en lineage&lt;/strong> — un score &amp;ldquo;faithfulness 0,87&amp;rdquo; sin trazabilidad de qué judge, qué prompt, qué calibration set y qué humano lo validó, es decorativo.&lt;/li>
&lt;/ol>
&lt;p>El &lt;a href="https://blog.lo0.es/posts/prompt-versioning-langfuse-mlflow/">post sobre prompt versioning&lt;/a> cubre cómo se materializa el versionado del prompt del judge. La consecuencia práctica es que &lt;strong>el judge se versiona como cualquier otro modelo&lt;/strong>: tu eval suite tiene &lt;code>judge_id = prometheus-2.5@v3&lt;/code> igual que tiene &lt;code>adapter_id = customer_support_v7&lt;/code>.&lt;/p>
&lt;h2 id="las-dos-cadencias-ci-gate-y-platform-regression">Las dos cadencias: CI gate y platform regression&lt;/h2>
&lt;p>Las suites de eval viven en dos sitios y se ejecutan con dos cadencias distintas. Los equipos que confunden ambas convierten una de las dos en teatro.&lt;/p>
&lt;p>&lt;strong>CI gate (pre-merge, bloqueante).&lt;/strong> Se ejecuta en cada pull request que modifica prompts, adapters, configuración de RAG, o cualquier artefacto que pueda mover la salida del modelo. Se ejecuta contra el golden dataset versionado al hash que está en &lt;code>main&lt;/code>. El gate falla el merge si:&lt;/p>
&lt;ul>
&lt;li>la métrica crítica cae &lt;strong>más de X puntos porcentuales&lt;/strong> absolutos respecto al baseline (típicamente X = 2);&lt;/li>
&lt;li>alguna métrica de seguridad (toxicidad, leakage de PII) cruza un umbral duro (típicamente tox &amp;gt; 0,02);&lt;/li>
&lt;li>algún segmento estratégico (un idioma, un tenant tipo enterprise) cae más de Y puntos aunque el agregado mejore.&lt;/li>
&lt;/ul>
&lt;p>Esta cadencia tiene que ser &lt;strong>rápida&lt;/strong> (idealmente &amp;lt; 10 minutos sobre 500 ejemplos) y &lt;strong>barata&lt;/strong> (judge LLM batch-mode, embeddings cacheados, heurísticos en local). El CI gate no es exhaustivo: es la línea de defensa baja-latencia.&lt;/p>
&lt;p>&lt;strong>Platform regression (post-deploy, continua).&lt;/strong> Se ejecuta de manera programada (típicamente nightly o weekly) sobre &lt;strong>tráfico de producción muestreado&lt;/strong>, no sobre el golden estático. Detecta drift: el modelo no ha cambiado, el golden no ha cambiado, pero los usuarios sí han cambiado, y la calidad sobre tráfico real cae. Esta cadencia es más cara (judge sobre miles de samples, anotación humana sobre cientos), tolera latencias de horas, y su consumidor principal no es CI sino el dashboard de &lt;a href="https://blog.lo0.es/posts/agentsight-tracing-llm/">observabilidad&lt;/a> y los humanos del equipo de producto que deciden si abrir un ciclo de &lt;a href="https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/">retrain&lt;/a>.&lt;/p>
&lt;p>Ambas cadencias persisten resultados en el mismo store (Langfuse, MLflow, o equivalente) y los conectan por &lt;code>model_id&lt;/code>, &lt;code>prompt_id&lt;/code>, &lt;code>dataset_hash&lt;/code> y &lt;code>judge_id&lt;/code>. Sin ese pegamento de identificadores, la métrica que pasa CI no se puede correlacionar con la que falla en producción tres semanas después.&lt;/p>
&lt;h2 id="las-matemáticas-mínimas-que-importan">Las matemáticas mínimas que importan&lt;/h2>
&lt;p>Más allá del kappa y del intervalo para la diferencia de proporciones —los dos ya cubiertos arriba— hay otras tres piezas matemáticas que cualquier equipo que opere evals en serio acaba usando.&lt;/p>
&lt;p>&lt;strong>Intervalo de confianza para una métrica continua.&lt;/strong> Si tu métrica es un score continuo (faithfulness ∈ [0, 1]) y mides la media muestral (\bar{x}) sobre n ejemplos con desviación s, el intervalo de confianza al 95% para la media poblacional es:&lt;/p>
&lt;p>[
\bar{x} \pm 1{,}96 \cdot \frac{s}{\sqrt{n}}
]&lt;/p>
&lt;p>Para n = 300 y s ≈ 0,2 (típico de un score 0-1 con varianza no degenerada), el margen es ±0,023. Esto significa que diferencias por debajo de 2 puntos centesimales &lt;strong>no se distinguen&lt;/strong> del ruido con ese sample size. Si tu equipo persigue mejoras de &amp;ldquo;+0,5 pp&amp;rdquo; sobre 100 ejemplos, está optimizando ruido.&lt;/p>
&lt;p>&lt;strong>Coste del judge en función del sample size y la rúbrica.&lt;/strong> El coste de una pasada de eval con LLM-as-judge sobre n ejemplos, con m métricas evaluadas en una sola llamada por ejemplo, y precio por token (c_{in}, c_{out}) en el modelo judge, es:&lt;/p>
&lt;p>[
C \approx n \cdot (t_{in} \cdot c_{in} + t_{out} \cdot c_{out})
]&lt;/p>
&lt;p>donde (t_{in}) es el número de tokens de entrada (incluye contexto, output del modelo bajo prueba, rúbrica completa) y (t_{out}) el de salida (incluye CoT del judge + score). Para n = 500, (t_{in}) ≈ 4.000, (t_{out}) ≈ 300, judge GPT-4o con precios de mayo 2026, una pasada cuesta del orden de &lt;strong>8–15 USD por suite&lt;/strong>. Si la pasada se dispara en cada PR y hay 30 PRs/día, son 240–450 USD/día sólo en CI gates. Multiplicado por la regression continua, los equipos que no controlan esto se gastan cuatro cifras al mes en judge sin darse cuenta. La mitigación canónica es &lt;strong>mezcla de capas&lt;/strong>: heurísticos y embeddings filtran primero, judge sólo se invoca sobre lo que las capas baratas no pueden resolver, y para platform regression se usa un judge open-source self-hosted (Prometheus 7B sobre el plano GPU propio) en lugar de un modelo comercial.&lt;/p>
&lt;p>&lt;strong>Distinción entre métrica agregada y métrica por segmento.&lt;/strong> La falacia clásica del eval es la media oculta. Si tu suite reporta &lt;code>faithfulness = 0,87&lt;/code> y el equipo lo lee como &amp;ldquo;sube 2 puntos respecto al adapter anterior&amp;rdquo;, puede estar pasando esto: el adapter nuevo sube 4 puntos en inglés (donde está el 70% del eval set) y baja 6 puntos en alemán (donde está el 30%). La media agregada mejora, la experiencia en alemán empeora. Cualquier suite seria reporta &lt;strong>breakdown por segmento estratégico&lt;/strong> (idioma, tipo de tenant, categoría de pregunta, longitud del contexto). El gate de CI también puede tener thresholds por segmento, no sólo agregados.&lt;/p>
&lt;h2 id="el-stack-2026-herramientas-dominantes">El stack 2026: herramientas dominantes&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Herramienta&lt;/th>
&lt;th>Capa principal&lt;/th>
&lt;th>Licencia&lt;/th>
&lt;th>Mantenedor&lt;/th>
&lt;th>Cuándo elegirla&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>DeepEval&lt;/strong>&lt;/td>
&lt;td>CI gate&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>Confident AI&lt;/td>
&lt;td>&amp;ldquo;Evals como pytest&amp;rdquo; — assertions en código Python, integración trivial con GitHub Actions. Default razonable.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Promptfoo&lt;/strong>&lt;/td>
&lt;td>CI gate&lt;/td>
&lt;td>MIT&lt;/td>
&lt;td>Promptfoo Inc.&lt;/td>
&lt;td>YAML declarativo, matriz prompts × providers × assertions, diff vs baseline. DevOps-friendly.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>RAGAS&lt;/strong>&lt;/td>
&lt;td>Métricas RAG-specific&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>Exploding Gradients&lt;/td>
&lt;td>Faithfulness, context relevancy, answer relevancy. La pieza canónica si tu sistema es RAG.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Inspect AI&lt;/strong>&lt;/td>
&lt;td>Safety/capability evals&lt;/td>
&lt;td>MIT&lt;/td>
&lt;td>UK AI Safety Institute&lt;/td>
&lt;td>Suite con foco en safety y capability. Útil para gates regulatorios bajo EU AI Act.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Langfuse Evals&lt;/strong>&lt;/td>
&lt;td>Platform regression&lt;/td>
&lt;td>MIT (OSS) / EE&lt;/td>
&lt;td>Langfuse GmbH&lt;/td>
&lt;td>Integrado con tracing — datasets, runs y scores en la misma UI que las trazas de producción.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>MLflow GenAI Evals&lt;/strong>&lt;/td>
&lt;td>Registry + evals&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>Databricks/LF AI&lt;/td>
&lt;td>Bueno cuando ya tienes MLflow para modelos clásicos; &amp;ldquo;GenAI dashboard&amp;rdquo; desde 3.10.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Phoenix (Arize)&lt;/strong>&lt;/td>
&lt;td>Eval + drift visual&lt;/td>
&lt;td>Elastic License 2.0&lt;/td>
&lt;td>Arize AI&lt;/td>
&lt;td>Foco en debugging visual de embeddings y drift; complemento, no sustituto, de Langfuse.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Prometheus 2.5&lt;/strong>&lt;/td>
&lt;td>Judge OSS self-hosted&lt;/td>
&lt;td>Apache 2.0&lt;/td>
&lt;td>KAIST + LG AI&lt;/td>
&lt;td>Judge fine-tuneado, alta correlación con GPT-4 a coste cero por token cuando se hostea.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>G-Eval / JudgeLM&lt;/strong>&lt;/td>
&lt;td>Métodos de prompting&lt;/td>
&lt;td>— (técnicas)&lt;/td>
&lt;td>académica&lt;/td>
&lt;td>Frameworks de prompting para LLM-as-judge — se aplican sobre cualquier modelo judge.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>El &lt;a href="https://blog.lo0.es/posts/catalogo-herramientas-oss-llmops/">catálogo OSS por etapas&lt;/a> entra al detalle ficha-a-ficha; el &lt;a href="https://blog.lo0.es/posts/oss-vs-hyperscalers-llmops/">catálogo paralelo OSS vs hyperscalers&lt;/a> compara con Bedrock Evaluations, Vertex AI Eval Service y Azure AI Evaluation.&lt;/p>
&lt;p>El patrón canónico en 2026 es híbrido: &lt;strong>DeepEval o Promptfoo para CI gates + Langfuse Evals para platform regression + Prometheus 2.5 como judge self-hosted + anotación humana sobre Argilla o Label Studio para el calibration set&lt;/strong>. Sustituir cualquiera de estos pilares por equivalentes (W&amp;amp;B Weave en lugar de Langfuse, Inspect en lugar de DeepEval) es estilo, no funcionalidad — lo importante es que las cuatro funciones estén presentes y conectadas.&lt;/p>
&lt;h2 id="aplicado-a-hardware-on-premise-típico">Aplicado a hardware on-premise típico&lt;/h2>
&lt;p>Para un despliegue on-premise que quiera evitar enviar outputs sensibles a un judge LLM comercial (por soberanía de datos, ENS, NIS2 o equivalentes), el judge se hostea sobre el propio plano GPU. Las cifras de referencia para mayo 2026, sobre la base de &lt;strong>Prometheus 2.5 (Llama-3.1-8B fine-tuneado como judge)&lt;/strong> servido en vLLM:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>RTX 4090 (24 GB, Ada Lovelace)&lt;/strong>: viable para suites pequeñas (&amp;lt; 200 ejemplos) y para correr el judge en modo offline durante desarrollo. Latencia por evaluación ≈ 1,5–3 s con BF16; throughput agregado del orden de 25–40 evaluations/min con batching. Útil para CI gates locales del desarrollador, no para platform regression.&lt;/li>
&lt;li>&lt;strong>Configuración genérica 4×H100 SXM (320 GB total, NVLink)&lt;/strong>: ejecuta el judge en paralelo en TP=2 sobre dos GPUs, dejando dos libres para servir el modelo bajo prueba. Throughput agregado del orden de 200–350 evaluations/min, suite completa de 500 ejemplos en 2–3 min. Esto permite gates de PR sin esperas perceptibles y platform regression nightly sobre miles de samples sin coste por token.&lt;/li>
&lt;/ul>
&lt;p>Las cuentas del coste comparado son tozudas: hostear Prometheus 2.5 amortiza una H100 en aproximadamente 6 meses &lt;strong>si el equipo dispara ≥ 30 PRs/día con gates de eval&lt;/strong>. Por debajo de ese volumen, el judge comercial sigue ganando salvo que la soberanía sea requisito —y en ENS / NIS2 lo es—.&lt;/p>
&lt;h2 id="las-siete-trampas-que-matan-esta-etapa">Las siete trampas que matan esta etapa&lt;/h2>
&lt;p>&lt;strong>Trampa 1 — Golden dataset envejecido.&lt;/strong> No se enriquece con incidentes de producción. Al cabo de meses, mide un mundo que ya no existe. La métrica sube tranquilamente mientras los usuarios reales se quejan más.&lt;/p>
&lt;p>&lt;strong>Trampa 2 — Judge contaminado o no calibrado.&lt;/strong> El judge LLM evalúa con criterios que se inventa él. Sin calibration set humano de referencia, no hay forma de saber si su 0,89 es generoso, severo o aleatorio.&lt;/p>
&lt;p>&lt;strong>Trampa 3 — Sample size insuficiente.&lt;/strong> Suite de 50 ejemplos, diferencias de 1 punto que el equipo trata como significativas. El intervalo de confianza es ±10 puntos. Están midiendo ruido y tomando decisiones reales sobre él.&lt;/p>
&lt;p>&lt;strong>Trampa 4 — Coste runaway.&lt;/strong> Judge con GPT-4 batch-mode disparado en cada PR sobre 1.000 ejemplos, sin filtrado previo con capas baratas. La factura del eval pasa la del serving en producción. Ocurre con más frecuencia de la que se admite.&lt;/p>
&lt;p>&lt;strong>Trampa 5 — Métrica agregada que oculta segmentos.&lt;/strong> Media global mejora 2 puntos, alemán cae 6, tenants enterprise caen 3. Sin breakdown explícito por segmento, el gate aprueba lo que no debería.&lt;/p>
&lt;p>&lt;strong>Trampa 6 — Judge con versión flotante.&lt;/strong> Modelo judge actualizado sin recalibrar la rúbrica. Los thresholds pierden significado estadístico. Las regresiones del último mes no son comparables con las de hace dos.&lt;/p>
&lt;p>&lt;strong>Trampa 7 — Eval gate que no se aplica.&lt;/strong> El gate existe en la documentación pero no en el workflow real: la suite tarda 30 minutos, los desarrolladores la skippean con &lt;code>--no-verify&lt;/code>, los managers piden excepciones puntuales que se vuelven la norma. El eval gate sin aplicación es ornamento.&lt;/p>
&lt;p>Las siete son operacionales, no técnicas. La capa de Eval no se rompe porque las matemáticas estén mal: se rompe porque la disciplina se relaja. Es lo mismo que ocurre con los tests unitarios en cualquier proyecto que crece — sólo que aquí, sin la disciplina, el sistema &lt;strong>mejora sus métricas mientras empeora&lt;/strong>, y eso convierte la degradación en invisible hasta que ya es ingobernable.&lt;/p>
&lt;h2 id="lo-que-no-hemos-cubierto-próximos-posts">Lo que no hemos cubierto (próximos posts)&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Guardrails y safety online&lt;/strong>: la capa de eval &lt;strong>inline&lt;/strong> que filtra outputs en tiempo real, no en CI. Conceptualmente prima de Eval, pero con restricciones de latencia muy distintas. Cubierto en el &lt;a href="https://blog.lo0.es/posts/guardrails-safety-llm/">post sobre guardrails&lt;/a> cuando se publique.&lt;/li>
&lt;li>&lt;strong>Judge ensembles y agreement entre múltiples judges&lt;/strong>: cómo reducir sesgo combinando tres modelos heterogéneos como panel, qué función de agregación funciona (mayoría simple, media trimmed, judge calibrado meta-judge).&lt;/li>
&lt;li>&lt;strong>Meta-eval&lt;/strong>: cómo se evalúa la propia suite. Si el eval mejora del adapter v7 al v8 no se traduce en mejora real para el usuario, la suite está mal — y eso también se mide, con correlación métrica-eval vs métricas-producto.&lt;/li>
&lt;li>&lt;strong>Metamorphic testing&lt;/strong>: evaluar robustez frente a perturbaciones del input (typos, paraphrasing, idioma alternativo) como gate adicional. Más allá del agreement nominal, mide consistency.&lt;/li>
&lt;li>&lt;strong>Evals adversariales con red teaming&lt;/strong>: introducir ataques de prompt injection y jailbreak como parte del gate.&lt;/li>
&lt;li>&lt;strong>Privacidad en el judge&lt;/strong>: cómo evitar que outputs sensibles del modelo bajo prueba viajen a un judge externo cuando la regulación lo prohíbe — judge homomorphic, judge en TEE, o sencillamente judge self-hosted.&lt;/li>
&lt;/ul>
&lt;h2 id="ver-también">Ver también&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.lo0.es/posts/pipeline-llmops-seis-etapas/">El pipeline LLMOps de seis etapas&lt;/a> — el mapa maestro donde Eval encaja entre Tune y Deploy. La sección &amp;ldquo;Etapa 3 — Eval&amp;rdquo; da el resumen estructurado que este post desarrolla.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/anatomia-request-llm-mayo-2026/">Anatomía de una petición LLM en producción, mayo 2026&lt;/a> — el tour forense de una request que cruza las seis etapas; el momento en que se invoca la suite de evals para promocionar el adapter v7→v8 es la materialización del gate descrito aquí.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/prompt-versioning-langfuse-mlflow/">Prompt versioning: el contrato que evita que un cambio de cinco palabras hunda tu sistema&lt;/a> — los prompts del judge se versionan con los mismos mecanismos que cualquier otro prompt. El &lt;code>prompt_id&lt;/code> viaja en lineage.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/data-versioning-dvc-lakefs/">Data versioning: DVC, lakeFS y el reto del golden dataset reproducible&lt;/a> — el golden eval set es uno de los cuatro artefactos a versionar diferenciadamente. Sin holdout estricto, la métrica mide memorización.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/fine-tuning-continuo-produccion/">Fine-tuning continuo en producción&lt;/a> — las eval gates que en aquel post aparecen como predicados SQL son la materialización concreta del framework descrito aquí.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/retrain-cerrar-el-bucle-feedback-dataset-adapter/">Retrain: cerrar el bucle entre el incidente en producción y el adapter que lo arregla&lt;/a> — el golden se enriquece con incidentes que vienen del bucle Retrain; sin ese flujo el dataset envejece y las trampas 1 y 5 se activan solas.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/catalogo-herramientas-oss-llmops/">El catálogo OSS para LLMOps en seis etapas&lt;/a> — fichas ficha-a-ficha de DeepEval, Promptfoo, RAGAS, Langfuse, Phoenix.&lt;/li>
&lt;li>&lt;a href="https://blog.lo0.es/posts/oss-vs-hyperscalers-llmops/">El catálogo paralelo: OSS vs AWS / GCP / Azure&lt;/a> — cómo se traduce la etapa Eval a Bedrock Evaluations, Vertex AI Eval Service y Azure AI Evaluation.&lt;/li>
&lt;/ul>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>G-Eval&lt;/strong>: Liu et al., &amp;ldquo;G-Eval: NLG Evaluation using GPT-4 with Better Human Alignment&amp;rdquo; — el paper de referencia del método de judge LLM con chain-of-thought.&lt;/li>
&lt;li>&lt;strong>Prometheus&lt;/strong>: Kim et al., &amp;ldquo;Prometheus 2: An Open Source Language Model Specialized in Evaluating Other Language Models&amp;rdquo; — judge OSS con correlación reportada 0.897 vs humanos.&lt;/li>
&lt;li>&lt;strong>RAGAS&lt;/strong>: Es et al., &amp;ldquo;RAGAS: Automated Evaluation of Retrieval Augmented Generation&amp;rdquo; — el paper que estandariza faithfulness, context relevancy y answer relevancy.&lt;/li>
&lt;li>&lt;strong>Cohen&amp;rsquo;s kappa&lt;/strong>: Cohen, J. (1960). &amp;ldquo;A Coefficient of Agreement for Nominal Scales.&amp;rdquo; Educational and Psychological Measurement — la métrica clásica para inter-anotador agreement, todavía la referencia operativa.&lt;/li>
&lt;li>&lt;strong>DeepEval docs&lt;/strong>: &lt;a href="https://docs.confident-ai.com/">https://docs.confident-ai.com/&lt;/a>&lt;/li>
&lt;li>&lt;strong>Promptfoo docs&lt;/strong>: &lt;a href="https://promptfoo.dev/docs/">https://promptfoo.dev/docs/&lt;/a>&lt;/li>
&lt;li>&lt;strong>Langfuse Evals&lt;/strong>: &lt;a href="https://langfuse.com/docs/scores">https://langfuse.com/docs/scores&lt;/a>&lt;/li>
&lt;li>&lt;strong>Inspect AI&lt;/strong>: &lt;a href="https://inspect.ai-safety-institute.org.uk/">https://inspect.ai-safety-institute.org.uk/&lt;/a>&lt;/li>
&lt;li>&lt;strong>EU AI Act&lt;/strong>, artículos relevantes sobre evaluación obligatoria de sistemas de alto riesgo — pendiente de publicación de los technical standards de CEN/CENELEC sobre conformity assessment para GenAI.&lt;/li>
&lt;/ul></description></item></channel></rss>