Cómo evaluar LLMs en producción: guía práctica de evals para equipos de desarrollo
"Parece que funciona" no es una estrategia de testing. La guía de buenas prácticas de evaluación de OpenAI lo nombra como antipatrón explícito: los vibe-based evals, es decir, evaluar a ojo o esperar a estar en producción para empezar a medir. El problema es que los modelos de lenguaje son no deterministas: la misma entrada puede producir salidas distintas, y los tests tradicionales de "input X, output Y" no alcanzan.
Los evals son la respuesta a ese problema. Y en un mercado donde los precios y los modelos cambian cada pocas semanas, son también lo que te permite migrar de modelo con datos en lugar de intuiciones.
Qué es (y qué no es) un eval
La palabra "evals" se usa para tres cosas distintas, y la guía de OpenAI las separa:
- Benchmarks de la industria (MMLU, DeepSWE, etc.) para comparar modelos en abstracto.
- Métricas numéricas estándar (ROUGE, BERTScore) que podés usar como piezas.
- Tests específicos de tu aplicación, que miden si tu sistema resuelve tu caso de uso.
Este artículo es sobre el tercer tipo. Un benchmark te dice qué modelo vale la pena probar; solo tus evals te dicen cuál funciona para tu producto.
El proceso en cinco pasos
La guía de OpenAI propone un flujo que sirve para cualquier proveedor:
- Definir el objetivo. ¿Cuál es el criterio de éxito? "Que el resumen incluya todas las decisiones de la reunión" es evaluable; "que el resumen sea bueno" no.
- Armar el dataset. Casos reales de producción, históricos, curados por expertos o sintéticos.
- Definir las métricas. ¿Cómo se verifica automáticamente que se cumplió el criterio?
- Correr y comparar. Cada cambio de prompt, modelo o parámetro se mide contra el mismo set.
- Evaluar de forma continua. Correr los evals en cada cambio, monitorear producción y hacer crecer el dataset con los casos nuevos.
Cómo armar el dataset
El error más común es construir un dataset que no se parece al tráfico real. OpenAI lo lista como antipatrón: biased design. Algunas reglas prácticas:
- Empezá con 50 a 100 casos reales (anonimizados) antes que con 1.000 sintéticos.
- Incluí los casos difíciles a propósito: entradas ambiguas, fuera de dominio, en otro idioma, con errores de tipeo, con intentos de manipulación.
- Etiquetá la respuesta esperada o el criterio de aprobación, no solo la entrada.
- Registrá todo desde el día uno. La recomendación de la guía es log everything: los logs de producción son la mejor mina de casos nuevos.
- Cada bug reportado se convierte en un caso del dataset, como un test de regresión.
Tres tipos de evaluadores y cuándo usar cada uno
| Tipo | Ejemplos | Ventajas | Límites |
|---|---|---|---|
| Basados en métricas / código | Coincidencia exacta, validación de JSON, precisión de function calling, ejecutar el SQL generado | Baratos, deterministas, ideales para CI | No capturan matices |
| Humanos | Revisión ciega, ranking de respuestas, notas de 1 a 5 | La mayor calidad | Lentos, caros, con desacuerdo entre revisores |
| LLM-as-a-judge | Comparación de a pares, calificación con rúbrica, comparación contra una respuesta de referencia | Escalables y más baratos que humanos | Sesgos de posición y de longitud |
La regla general: todo lo que se pueda verificar con código, verificalo con código. Si la salida tiene que ser un JSON con cierto esquema, un validador es mejor juez que cualquier modelo.
LLM-as-a-judge sin engañarte
Usar un modelo para evaluar a otro es poderoso, pero tiene trampas conocidas. La guía de OpenAI recomienda:
- Preferir comparación de a pares o aprobado/desaprobado antes que escalas numéricas finas.
- Controlar la longitud: los modelos tienden a preferir respuestas más largas.
- Pedir razonamiento antes del veredicto.
- Usar el modelo más capaz que puedas como juez y recién después optimizar costo.
- Calibrar contra etiquetas humanas: escalar el juez solo cuando coincide de forma consistente con las anotaciones de personas.
Un ejemplo mínimo de juez con salida estructurada:
RUBRICA = """Evaluá si la RESPUESTA responde la PREGUNTA usando solo el CONTEXTO.
Criterios: 1) no inventa datos que no están en el contexto; 2) responde lo que se preguntó.
Primero explicá tu razonamiento en 2-3 frases. Después devolvé exactamente
una línea final: VEREDICTO: APROBADO o VEREDICTO: DESAPROBADO."""
def juzgar(cliente, modelo_juez, pregunta, contexto, respuesta):
prompt = f"{RUBRICA}\n\nPREGUNTA:\n{pregunta}\n\nCONTEXTO:\n{contexto}\n\nRESPUESTA:\n{respuesta}"
salida = cliente.responses.create(model=modelo_juez, input=prompt).output_text
ultima_linea = salida.strip().splitlines()[-1].strip()
aprobado = ultima_linea == "VEREDICTO: APROBADO"
return aprobado, salida # guardamos también el razonamiento
Guardá también el razonamiento del juez: cuando un caso falla, es lo primero que vas a querer leer.
Evals para agentes y flujos de varios pasos
En un agente, evaluar solo la respuesta final esconde dónde falló. La guía de OpenAI distingue entre interacciones de un solo turno, workflows, agentes individuales y sistemas multiagente, y sugiere evaluar cada punto de decisión:
- ¿Eligió la herramienta correcta?
- ¿Pasó los argumentos correctos?
- ¿Se detuvo cuando debía, o siguió gastando pasos?
- ¿Respetó los límites (no ejecutó acciones que requerían aprobación)?
Para agentes, además de la tasa de éxito, medí el costo y la cantidad de pasos por tarea resuelta. Un agente que acierta 5% más pero usa el triple de llamadas puede no ser una mejora.
Integrar los evals al CI
El objetivo es que un cambio de prompt se trate como un cambio de código. Un esquema simple:
# Paso de CI (pseudoconfiguración)
evals:
dataset: evals/casos.jsonl # versionado junto al código
umbrales:
tasa_aprobacion_min: 0.92 # falla el pipeline si baja de acá
regresion_max_vs_main: 0.02 # o si cae más de 2 puntos contra main
reportes:
- casos_fallidos.md # para revisión humana en el PR
Algunas decisiones prácticas:
- Separá evals rápidos y baratos (se corren en cada PR) de evals completos (nocturnos o antes de un release).
- Fijá la versión del modelo en los evals, para que un cambio del proveedor no se confunda con un cambio tuyo.
- Registrá costo y latencia además de la calidad.
- Revisá a mano una muestra de los casos fallidos en cada corrida importante.
Qué hacer con esto
- Escribir el criterio de éxito de cada feature con LLM en una frase evaluable.
- Juntar 50 a 100 casos reales y etiquetarlos.
- Automatizar primero lo verificable con código (formato, esquema, campos obligatorios).
- Sumar un juez LLM solo después de calibrarlo contra etiquetas humanas.
- Correr los evals en CI con un umbral que bloquee regresiones.
- Convertir cada bug reportado en un caso nuevo del dataset.
- Antes de cambiar de modelo o de proveedor, correr el set completo y comparar calidad, costo y latencia por tarea.
¿Cuántos casos tiene hoy el dataset de evals de tu feature con IA más importante, y cuándo fue la última vez que lo corriste?
Lecturas relacionadas
- Observabilidad para apps con LLM: trazas, métricas y convenciones GenAI de OpenTelemetry: qué medir en una app con LLM (latencia, tokens, costo, errores) y cómo instrumentarla con OpenTelemetry.
- RAG o fine-tuning: guía para decidir cómo darle conocimiento y comportamiento a un LLM: cuándo conviene RAG, cuándo fine-tuning y cuándo alcanza con prompting o contexto largo.
- OWASP Top 10 para aplicaciones con LLM (2025) explicado: prompt injection y cómo mitigarla: los 10 riesgos de OWASP para apps con LLM y un plan concreto contra prompt injection y exceso de agencia.
En video (Short de menos de 1 minuto): ¿Por qué la IA inventa cosas? Alucinaciones en 50 segundos (qué es una alucinación; acá, cómo detectarlas con evals)
Fuentes
- OpenAI API docs, "Evaluation best practices": https://developers.openai.com/api/docs/guides/evaluation-best-practices
- OpenAI API docs, "Optimizing LLM accuracy": https://developers.openai.com/api/docs/guides/optimizing-llm-accuracy
- Claude Platform Docs (Anthropic), "Define success criteria and build evaluations": https://platform.claude.com/docs/en/test-and-evaluate/develop-tests
- OWASP Top 10 for LLM Applications 2025, LLM09: Misinformation: https://genai.owasp.org/llm-top-10/