volver al blog

Evaluar un LLM en serio: por qué 'a mí me funciona' no basta

iallmevaluación

La demo que engaña

Cambias una frase del prompt, lanzas tres preguntas, las respuestas se ven mejor y declaras la victoria. Subes el cambio. Una semana después alguien reporta que el asistente ha empezado a fallar en un caso que antes funcionaba.

Eso no es un accidente. Es lo que pasa cuando evalúas un LLM mirándolo de reojo. “A mí me funciona” es una anécdota, no una medida. Y con sistemas no deterministas, donde la misma entrada puede dar salidas distintas, las anécdotas mienten con una confianza notable.

Evaluar en serio no es un lujo de equipos grandes. Es lo que separa un cambio que sabes que mejora las cosas de uno que solo esperas que las mejore.

Qué significa evaluar de verdad

Evaluar un LLM es comparar sus salidas contra un criterio fijo, sobre un conjunto estable de casos, de forma repetible. Las tres palabras importan.

Criterio fijo: sabes qué cuenta como respuesta buena antes de mirar la salida, no después. Conjunto estable: las mismas preguntas, ejecución tras ejecución, para poder comparar manzanas con manzanas. Repetible: cualquiera del equipo lanza la evaluación y obtiene el mismo veredicto.

Si te falta cualquiera de las tres, no estás evaluando. Estás formando una opinión.

El conjunto de evaluación es el activo

Todo empieza por un golden set: una colección de casos representativos con su resultado esperado. No hace falta que sea enorme. Treinta o cuarenta casos bien elegidos rinden más que mil generados al azar.

La regla para construirlo: que cada caso exista por una razón. Mete los flujos felices, sí, pero sobre todo mete lo que duele. La pregunta ambigua. El cliente enfadado. El dato que no está en el contexto y el modelo no debería inventar. El caso que rompió en producción el mes pasado, convertido ahora en prueba de regresión permanente.

Ese conjunto es el activo que de verdad importa. Los prompts cambian, el modelo de moda cambia, el proveedor cambia. El conjunto de casos que define qué es “funcionar bien” para tu producto se queda, y crece cada vez que algo falla.

Elige la métrica según la tarea

No hay una métrica universal. La que sirve depende de cuánto margen tiene la respuesta correcta.

Tipo de tareaEjemploCómo medir
Salida cerradaClasificar, extraer un campo, responder sí/noComparación exacta o por reglas; accuracy directa
Salida estructuradaGenerar un JSON con un esquemaValidar el esquema y comparar campos clave
Salida abiertaResumir, redactar, responder con maticesRúbrica con criterios; revisión humana o LLM como juez
Recuperación (RAG)¿Trajo el fragmento correcto?Recall sobre los documentos relevantes

El error frecuente es usar una métrica abierta para una tarea cerrada, o al revés. Si tu modelo clasifica tickets en cinco categorías, no necesitas un juez con rúbrica: necesitas comparar la etiqueta predicha con la real y contar aciertos. Empezar por las tareas medibles con reglas te da señal barata y fiable antes de meterte en lo subjetivo.

El LLM como juez: útil con cuidado

Para las salidas abiertas, pedirle a otro LLM que puntúe la respuesta según una rúbrica escala mucho mejor que la revisión humana. Funciona, pero tiene trampas que conviene conocer.

Un juez LLM tiende a premiar lo largo sobre lo correcto, se deja llevar por el orden en que le presentas las opciones y es generoso consigo mismo si juzga su propia familia de modelos. Se mitiga con una rúbrica explícita, ejemplos de qué es un 1 y qué es un 5, y validando al juez contra un puñado de casos puntuados a mano. Si el juez coincide con tu criterio humano en esos casos, puedes confiar en él para el resto. Si no, arréglalo antes de usarlo.

Cómo se ve en código

Un arnés de evaluación no necesita un framework. Empieza con un bucle que recorra tus casos, ejecute el sistema y compruebe el resultado.

def evaluar(casos, sistema, comprobar):
    resultados = []
    for caso in casos:
        salida = sistema(caso["entrada"])
        ok = comprobar(salida, caso["esperado"])
        resultados.append({
            "id": caso["id"],
            "entrada": caso["entrada"],
            "salida": salida,
            "ok": ok,
        })

    aciertos = sum(r["ok"] for r in resultados)
    print(f"Aciertos: {aciertos}/{len(casos)} ({aciertos/len(casos):.0%})")
    # Lo más valioso no es el porcentaje: son los fallos concretos
    for r in resultados:
        if not r["ok"]:
            print(f"  FALLO [{r['id']}]: {r['entrada']}")
    return resultados

El número agregado te dice si vas mejor o peor. La lista de fallos te dice por qué. Mira siempre los dos. Un 85 % puede esconder que justo se rompió el caso del que depende tu cliente más importante.

Conviértelo en una red de seguridad

Una evaluación que lanzas una vez y olvidas no sirve de nada. El valor aparece cuando la conviertes en un guardarraíl que se dispara con cada cambio.

Cada vez que toques el prompt, cambies de modelo o ajustes la temperatura, pasa el conjunto entero y compara contra la ejecución anterior. La pregunta deja de ser “¿se ve mejor?” y pasa a ser “¿cuántos casos he ganado y cuántos he perdido?”. Esa segunda pregunta es la que evita las regresiones silenciosas, esas mejoras que arreglan un caso y rompen otros tres sin que nadie se entere.

Cuando el conjunto madura, engánchalo a tu CI. Un cambio de prompt que baja la puntuación por debajo de un umbral no se mergea, igual que no mergearías código con los tests en rojo. A partir de ahí, mejorar el sistema deja de ser una sensación y pasa a ser un número que sube.

Por dónde empezar mañana

No montes una plataforma de evaluación. Abre un archivo, escribe diez casos con su respuesta esperada incluyendo los dos o tres que más te han dolido, y escribe el bucle de veinte líneas que los comprueba. Lánzalo contra tu prompt actual para tener una línea base.

A partir de ahí, cada vez que algo falle en producción, no lo arregles solo: añádelo al conjunto. En unas semanas tendrás algo que ningún “a mí me funciona” puede darte: la capacidad de cambiar tu sistema sabiendo, y no esperando, que va a mejorar.