Evals antes que prompts. Por qué tu LLM no mejora sin golden set.
Simple, si no puedes medir cuándo tu sistema responde bien, no estás iterando: estás adivinando.
01. El mito del prompt engineering
La narrativa dominante del 2024-2025 fue “cambia el prompt, mejora el sistema”. Funciona mientras el sistema cabe en la cabeza de una persona. El día que el prompt pasa a producción, recibe mil variantes de inputs reales y se enchufa a un retriever no determinista, el mito se rompe.
Lo he visto repetidamente: un equipo desplegando 40 cambios de prompt en dos semanas, sin un solo eval, debuggeando respuestas incorrectas una por una. Cada merge es una apuesta, cada rollback es un acto de fe.
El orden correcto es al revés. Primero evals, después prompts.
Cambiar un prompt sin evals es como afinar la guitarra en plena canción antes del solo: a veces resulta impecable, otras, te adaptas.
02. Qué es un golden set (y qué tamaño necesitas)
Un golden set es un conjunto de pares (input, respuesta_esperada) validados por alguien que entiende el dominio. Es el dataset canónico contra el que mides cualquier cambio.
No es un dataset de entrenamiento. Nadie aprende de él. Solo existe para decir “¿mi sistema responde como debería a esta pregunta?”.
Tamaño mínimo defendible
El número que mejor funciona en práctica es 80 pares. Por debajo de eso, el ruido estadístico se come cualquier señal. Por encima de 200, la mantención del dataset empieza a ser un proyecto en sí mismo.
Distribución recomendada:
- 60% casos esperados (el happy path de tu dominio).
- 25% casos edge conocidos (preguntas ambiguas, datos viejos, formatos raros).
- 15% casos adversariales (intentos de jailbreak, inputs que deberían rechazarse).
Cómo se construye sin morir en el intento
La gente se bloquea porque piensa que hay que validar 80 pares en una tarde con un experto de dominio disponible full-time. No es así.
- Extrae 20 pares de los logs de los últimos 30 días — los más frecuentes.
- Escribe 20 pares tú mismo pensando en qué deberías contestar si fueras el sistema.
- Pídele a tu experto de dominio que valide los 40 en una sesión de 90 minutos. No más.
- Añade 40 pares más en el siguiente sprint, iterando sobre errores reales.
Total: dos semanas para tener un golden set usable. Suficiente para CI.
03. Tres métricas automatizables
Una vez tienes el dataset, necesitas métricas que se corran sin humanos en el loop. Tres bastan para el 90% de sistemas RAG:
Faithfulness
Mide si la respuesta está anclada en el contexto recuperado. Si tu RAG recupera tres documentos y la respuesta incluye afirmaciones que no están en ninguno de los tres, faithfulness baja.
Umbral operativo: > 0,85. Debajo, estás alucinando.
Answer relevancy
Mide si la respuesta aborda la pregunta — independiente de si es correcta. Una respuesta correcta pero tangencial puntúa bajo.
Umbral operativo: > 0,80.
Context precision
Mide si los chunks relevantes están rankeados al principio del contexto recuperado. Es una métrica de ranking quality: dos sistemas pueden recuperar la misma proporción de chunks útiles y puntuar distinto si uno los pone arriba y el otro los pone al final. La distinción importa porque la acción correctiva es distinta — si baja context precision, revisas reranker; si lo que baja es la relevancia agregada del contexto, revisas el retriever o los embeddings.
Umbral operativo: > 0,75.
# evals/run.py — pseudocódigo. En producción usa Ragas o DeepEval.
def evaluate(dataset, system):
results = []
for input_, expected in dataset:
answer, ctx = system(input_)
results.append({
"faithfulness": score_faithfulness(answer, ctx),
"relevancy": score_relevancy(answer, input_),
"precision": score_context_precision(input_, ctx, expected),
})
return aggregate(results)
En la práctica, score_* las implementas con un LLM evaluador (gpt-4.1-mini, claude-haiku-4-5) usando prompts validados — o usas Ragas o DeepEval, que ya vienen con estas tres y más.
Caveat importante: los evaluadores LLM tienen sesgos conocidos — position bias, length bias, self-enhancement (un modelo prefiere outputs similares a los suyos) y reproducibilidad pobre entre llamadas. Para producción seria, calibra el evaluador contra juicios humanos al menos una vez por trimestre con una muestra de 30-50 casos. Si la correlación con humanos baja de 0,7, cambias de evaluador o de prompt.
04. CI que bloquea merges con regresiones
Tener métricas que nadie mira es teatro de ingeniería. La única razón por la que un eval sirve es porque bloquea un merge.
Regla: un PR que baja cualquiera de las tres métricas más de 5% respecto a main no puede mergearse sin aprobación explícita. Importa que el bloqueo sea por métrica individual, no por agregado — un PR que mejora el retriever 8% pero degrada el generador 6% no debería mergear silenciosamente porque el promedio queda neutro.
El 5% es razonable para sistemas en early stage. Para un sistema en producción con SLAs, baja el umbral a 1-2%. Para un POC interno, súbelo a 10%. La regla es: el umbral mínimo es el cambio más pequeño que tu negocio puede tolerar antes de necesitar una conversación.
Implementación mínima en un .github/workflows/evals.yml:
name: Evals
on: [pull_request]
jobs:
evals:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run evals vs main
run: python evals/run.py --baseline=main --threshold=0.05 --out=results.json
- name: Block if regression
run: python evals/gate.py --in=results.json
El gate.py lee results.json y sale con exit code 1 si alguna métrica cae más del umbral. GitHub Checks bloquea el merge automáticamente.
El primer día que esto bloquea un PR “trivial” de cambio de prompt, el equipo entiende por qué existe.
05. Cuándo tu golden set miente
Los evals no son neutrales. Son un artefacto que puede envejecer, sesgarse o ser interpretado de forma que dé la respuesta que queremos oír. Tres síntomas que he visto:
- Drift — El mundo real cambia, el golden set no. Preguntas que hace tres meses eran del 5% ahora son del 40% del tráfico, y ningún par del dataset las cubre.
- Bias de construcción — El set se escribió pensando en lo que el sistema ya sabe responder. Las preguntas donde falla nunca entran, así que las métricas dan verde mientras los usuarios se enfadan.
- Staleness del experto — El experto que validó hace seis meses no sabe que la política cambió la semana pasada. Las “respuestas esperadas” están desactualizadas.
Contramedida: re-auditar el golden set cada trimestre. Muestrea 10 pares al azar, preséntalos al experto actual, pregunta si la respuesta esperada sigue siendo correcta. Si más de 2 de 10 están desactualizados, toca refresh completo.
06. Checklist para evals
- ☑ Golden set de 80+ pares con distribución 60/25/15
- ☑ Tres métricas automatizadas (faithfulness, relevancy, context precision)
- ☑ Umbrales operativos documentados por métrica
- ☑ CI que bloquea merges con regresión por métrica individual (no por agregado)
- ☑ Calibración trimestral del evaluador LLM contra juicios humanos
- ☑ Re-auditoría trimestral del golden set
- ☑ Dashboard con evolución histórica por release
- ☑ Runbook claro para “fallaron los evals — qué hago”
07. Preguntas que me hacen todas las semanas
¿80 pares bastan de verdad?
Bastan para empezar. El punto del golden set no es cubrir todo — es tener señal reproducible. Con 80 pares detectas regresiones del 10%. Para señales del 2% necesitas 400+, y ahí ya estamos en territorio de ML infrastructure, no de evals.
¿Ragas o DeepEval?
Las dos funcionan. Ragas es más adoptado en equipos que ya usan LangChain; DeepEval tiene mejor ergonomía en pytest y mejores reportes. Si arrancas hoy, DeepEval.
¿Cada cuánto re-evalúo?
En CI, por PR. En batch, diario contra producción. Trimestral para refresh del dataset y calibración del evaluador.
¿Y si mi caso de uso no es RAG?
Las métricas cambian, el principio no. Si es clasificación, usa accuracy + F1 por clase. Si es generación libre, añade métricas semánticas (BERTScore, rouge-L). Si es agentic, mide success rate por tarea. La pregunta es siempre la misma: ¿puedo medir sin humanos?
Lo que vendrá después en este blog, en orden: observabilidad LLM para que los evals no sean tu única fuente de verdad, y cuándo no usar RAG para que no pagues la complejidad de evals cuando no los necesitas.
Si estás montando esto en tu equipo y no quieres tropezar con las mismas piedras que tropecé yo cinco veces, hablemos. Y si vas a dejar un tab abierto para después, al menos quédate con esto:
Sin evals no estás iterando. Estás esperando a que alguien se queje.