Skip to content
This page has been auto-translated and may contain errors.View in English

Evaluaciones ​

docs.scrimba.com

Cambias un prompt, lo pruebas una vez, la respuesta se ve mejor, y lo lanzas; una semana después los usuarios encuentran los casos que quedaron peor sin que te dieras cuenta. Una evaluación (o "eval", del inglés evaluation) es la solución: una prueba repetible de si tu funcionalidad de IA funciona, un conjunto de entradas junto con lo que debería ser una buena salida, calificado de la misma forma cada vez para que puedas saber si un cambio realmente ayudó. Un modelo es una caja negra probabilística que responde la misma pregunta de forma distinta en cada corrida, así que medir es la única manera de saberlo con certeza, y esa disciplina es gran parte de lo que separa una demo de un producto real.

Por qué revisar a simple vista no basta ​

Revisar las respuestas de tu IA a mano se siente bien al principio. Corres un prompt, lees la respuesta, se ve bien, y sigues adelante. El problema es que hay tres cosas que juegan en tu contra sin que lo notes, y ya te has topado con las tres.

Aquí están:

  • La salida varía. El mismo prompt puede dar respuestas distintas en cada corrida, así que un buen resultado no garantiza que el siguiente también lo sea.
  • Los cambios provocan regresiones. Un ajuste al prompt que arregla un caso a menudo rompe otro que no estabas mirando.
  • No escala. Puedes leer cinco respuestas. No puedes leer quinientas cada vez que cambias una línea.

Nada de esto significa que hayas hecho algo mal. Significa que revisar a simple vista es la herramienta equivocada para un trabajo de este tamaño, y hay una forma más tranquila de hacerlo.

JunoPor qué revisar a simple vista no basta Leer respuestas a mano falla por tres razones, todas relacionadas con cómo funciona el modelo: la salida varía de una corrida a otra, las modificaciones rompen casos que no estabas vigilando, y no puedes seguirle el ritmo a mano cuando hay cientos de respuestas. No es un problema de disciplina, es la herramienta equivocada para el tamaño del trabajo. La buena noticia es que la solución es accesible, y viene a continuación.

Revisar una sola respuesta a simple vista casi no te dice nada, y la razón está en cómo funciona el modelo. Como la salida es no determinística (el mismo prompt puede dar respuestas distintas en cada corrida), una sola respuesta es una muestra de tamaño uno. No puede decirte la tasa de aciertos (pass rate), es decir, la proporción de casos que salen bien, porque necesitas muchas corridas sobre los mismos casos para estimar qué tan bien funciona en realidad.

Las regresiones se esconden por una razón parecida. Si arreglas un caso a mano no tienes registro de los demás, así que el siguiente ajuste puede romper algo que dejaste de vigilar. La única forma de detectarlo es un conjunto fijo de casos calificado de la misma manera cada vez, para que una caída aparezca como un número y no como una sorpresa en producción.

Encima de eso hay un problema humano. La revisión manual varía según la persona y según el estado de ánimo: la misma respuesta se lee como buena un lunes y como débil un viernes. Por eso la jugada es convertir "se ve bien" en una tasa de aciertos medida sobre un conjunto fijo de casos. Convierte una sensación en un número sobre los mismos casos.

JunoPor qué revisar a simple vista no basta Una sola respuesta es una muestra de tamaño uno, así que solo te dice que el modelo funcionó una vez, no qué tan seguido funciona. Para ver una tasa de aciertos real corres muchos casos; para detectar regresiones fijas ese conjunto de casos y lo calificas de la misma forma siempre. La revisión manual también varía según quien revisa, así que la tarea es reemplazar "se ve bien" con un número medido.

Revisar al azar no falla porque seas descuidado. Falla porque tiene un sesgo de selección incorporado: miras los casos que esperas que funcionen, así que el comportamiento que nunca revisas es justo el que empeora frente a los usuarios. La métrica que no rastreas es exactamente la que se mueve.

Sin una línea base, cada cambio de calidad es una historia que te cuentas a ti mismo. No puedes atribuir un cambio a un ajuste específico, ni puedes hacer bisección sobre un conjunto de cambios para encontrar cuál bajó la tasa de aciertos (pass rate, la proporción de tus casos que salen correctos), porque nunca mediste el "antes". "Se siente mejor" sobrevive porque nada lo contradice.

La iteración basada en sensaciones también sobreajusta. Sigues reescribiendo los mismos pocos ejemplos, ajustas hasta que se ven bien, y sin darte cuenta entrenas tu prompt para ese pequeño conjunto privado mientras el tráfico real se desvía hacia otro lado. La revisión manual no puede ver ese cambio de distribución, porque las entradas nuevas son precisamente las que no estás escribiendo. Un conjunto de evaluación versionado con una puntuación registrada es la única forma de decir que un cambio ayudó en lugar de simplemente sentirse mejor, y es la diferencia entre iterar y adivinar.

JunoPor qué revisar a simple vista no basta He lanzado cosas basándome en sensaciones y luego he visto cómo el único camino que nunca revisé encendía los registros de errores; eso es el sesgo de selección haciendo su trabajo. Sin línea base no hay atribución ni bisección posible: no puedes probar qué cambio movió el número si nunca tuviste un número. Mantén un conjunto versionado y una puntuación registrada, o estarás sobreajustando a los cinco ejemplos que sigues reescribiendo mientras el tráfico real se va a algún lugar que no puedes ver.

Armar un conjunto de evaluación ​

Un conjunto de evaluación es una lista de casos de prueba. Cada caso tiene una entrada y lo que debería ser una buena salida para ella. Empieza en pequeño. De diez a veinte casos que cubran tus situaciones comunes más algunos casos límite complicados son mucho más útiles que ninguno, y puedes ir ampliando el conjunto a medida que descubres nuevas fallas en el mundo real.

python
eval_set = [
    {"input": "La comida llegó fría y tarde.", "expected": "NEGATIVE"},
    {"input": "¡La mejor comida de mi vida!", "expected": "POSITIVE"},
    {"input": "Estuvo bien, nada especial.", "expected": "NEUTRAL"},
    # ...agrega casos reales y casos límite a medida que los descubras
]

Cuando un usuario reporta una mala respuesta, agrégala al conjunto junto con la respuesta que debería haber dado. Tu conjunto de evaluación se convierte entonces en una memoria creciente de cada error que nunca quieres volver a cometer, de la misma forma que un bug que arreglas se convierte en una prueba que conservas.

JunoArmar un conjunto de evaluación Un conjunto de evaluación es una lista de casos de prueba: una entrada, y lo que debería ser una buena respuesta. Empieza con diez o veinte que cubran tus situaciones cotidianas y algunas complicadas. Cada vez que un usuario se topa con una mala respuesta, agrégala junto con la respuesta que debió haber dado, y tu conjunto va recordando en silencio cada error que nunca quieres repetir.

Un conjunto de evaluación (eval set) es tu colección de casos de prueba, cada uno una entrada junto con la salida que aceptarías como buena. El número que importa no es el tamaño, es la cobertura. Un conjunto de veinte casos bien elegidos vence a cincuenta casos descartables cualquier día.

Apunta a cubrir tres cosas: el camino común que realmente enfrentan tus usuarios, los límites de decisión donde dos etiquetas quedan muy cerca (los casos ambiguos justo en la frontera), y los modos de falla conocidos que ya has visto fallar. Elegir a dedo entradas favorables hace que tus puntuaciones se vean bien y no te dice nada, así que mantén el conjunto representativo del tráfico real.

Cada bug que reporta un usuario se convierte en un caso permanente del conjunto. Eso lo transforma en una suite de regresión: un bug arreglado se mantiene arreglado porque el caso que lo expuso corre cada vez. Cuando tus salidas esperadas están estructuradas en lugar de ser texto libre, como una etiqueta o un campo JSON, puedes calificar con comparación de coincidencia exacta, que es limpia y sin ambigüedad; ve salida estructurada.

Mantén una porción separada que dejas fuera y nunca usas para ajustar. Si ajustas el prompt hasta pasar exactamente los casos que estás observando, te estás calificando a ti mismo sobre las respuestas que ya estudiaste, y la puntuación deja de significar algo.

JunoArmar un conjunto de evaluación La cobertura vence al tamaño puro: cubre el camino común, los límites ambiguos entre etiquetas, y las fallas que ya has visto. Convierte cada bug reportado en un caso permanente para que el conjunto funcione como una suite de regresión. Mantén una porción reservada que nunca usas para ajustar, o estarás calificándote a ti mismo sobre las respuestas que ya estudiaste.

Trata el conjunto de evaluación (eval set) como un activo que versionas junto al prompt, porque ambos avanzan juntos y un cambio de prompt puede alterar sin avisar qué cuenta como buena respuesta. La calidad de las etiquetas del conjunto es el tope de tu métrica: un solo valor "esperado" equivocado limita tu puntuación y sin darte cuenta te enseña la lección equivocada, así que curar las etiquetas con cuidado importa tanto como recolectar los casos.

Cuídate de la filtración de datos de prueba. Si ajustas hasta pasar exactamente el conjunto que reportas, el número es teatro. Reserva una porción que no miras mientras iteras, y rótala con el tiempo para que igual no se filtre poco a poco hacia tu ciclo de ajuste.

Vigila el balance entre clases. Un conjunto que es noventa por ciento casos positivos claros va a reportar un número halagador mientras esconde cada falla en el diez por ciento que realmente importa, así que muestrea de forma que los casos difíciles y raros pesen de verdad. Extrae casos de los registros de producción en lugar de imaginarlos, ya que el tráfico real revela formas de expresarse que nunca inventarías desde tu escritorio.

Acepta que el conjunto se degrada con el tiempo. A medida que el producto cambia, los casos viejos dejan de reflejar lo que envían los usuarios y aparecen nuevos modos de falla que el conjunto nunca ha visto. Curarlo es trabajo continuo, no una construcción de una sola vez.

JunoArmar un conjunto de evaluación El conjunto es un activo que versionas junto al prompt, y la calidad de sus etiquetas es el tope duro de tu métrica: un solo valor esperado equivocado limita toda la puntuación. Reserva una porción y rótala, o el número que reportas es teatro. Vigila el balance entre clases, muestrea casos reales de los registros, y asume que el conjunto se degrada a medida que el producto avanza, así que curarlo nunca termina de verdad.

Cómo calificar ​

Distintas tareas necesitan distintas formas de calificar, así que el primer paso es hacer coincidir la verificación con el tipo de respuesta que esperas.

  • Coincidencia exacta funciona cuando hay una sola respuesta correcta: una etiqueta de clasificación, un campo extraído, un sí o un no. Comparas la salida con el valor esperado directamente.
  • Basada en criterios funciona cuando no hay una única respuesta correcta, como un resumen o una respuesta abierta. Revisas si la salida cumple ciertas condiciones: ¿El resumen menciona el dato clave? ¿Tiene menos de 50 palabras? ¿El tono es cordial?
  • Modelo como juez (LLM-as-judge) usa una segunda llamada al modelo para calificar la salida contra tus criterios. Escala bien para preguntas de calidad difusas que una verificación simple no puede capturar, pero el juez es en sí mismo un modelo, así que puede equivocarse, y conviene verificarlo de vez en cuando contra el juicio humano.
python
# calificación por coincidencia exacta sobre el conjunto de evaluación
def run_evals(eval_set, classify):
    passed = 0
    for test in eval_set:
        output = classify(test["input"])
        if output == test["expected"]:
            passed += 1
        else:
            print(f'FAIL: "{test["input"]}" -> got {output}, wanted {test["expected"]}')
    print(f"{passed}/{len(eval_set)} passed")

La coincidencia exacta es el punto de partida más amigable, y encaja perfecto con el trabajo de clasificación y extracción de capítulos anteriores. La idea del modelo como juez funciona porque detectar si una respuesta cumple un estándar suele ser una predicción más fácil que producir la respuesta en sí, de la misma forma que revisar un ensayo es más fácil que escribirlo. Pero el juez es otro modelo con las mismas debilidades, así que trata sus puntuaciones como una estimación útil, dale una rúbrica clara, y compara sus calificaciones con las tuyas en una muestra de vez en cuando.

JunoCómo calificar Elige la verificación que encaje con la respuesta: coincidencia exacta cuando hay una sola respuesta correcta, criterios cuando hay varias buenas, y un segundo modelo como juez para calidad difusa. La coincidencia exacta es el comienzo más suave, y coincide perfecto con la clasificación y extracción que ya practicaste. Pero el juez también es un modelo, así que revisa sus calificaciones tú mismo de vez en cuando.

Haz coincidir el calificador con la tarea, y luego elige el más económico que aún capture lo que te importa. Un calificador (grader) es el código o la llamada al modelo que decide si una salida pasó, y elegir mal hace que se te escapen fallas reales o que marques como incorrectas respuestas que en realidad estaban bien.

La coincidencia exacta es para etiquetas y campos extraídos: comparas la salida con el valor esperado y el resultado es determinístico, así que puedes confiar en él. Combina naturalmente con la salida estructurada, ya que un modelo que devuelve un esquema fijo te da algo limpio contra qué comparar en lugar de prosa libre.

Los criterios programáticos cubren el terreno intermedio a bajo costo: revisa la longitud, confirma que una cadena requerida esté presente, valida que el JSON se pueda parsear, corre una expresión regular. Estos corren en milisegundos sin ninguna llamada al modelo, así que úsalos para cualquier cosa semiestructurada antes de gastar dinero en un juez.

El modelo como juez es para calidad abierta, donde un resumen o una respuesta tiene muchas formas buenas y ningún objetivo exacto. Necesita una rúbrica por escrito para que el juez aplique un estándar consistente, más una verificación de calibración donde comparas sus calificaciones con tus propias etiquetas en una muestra. Recuerda que un calificador también es código en el que tienes que confiar: un calificador poco fiable te entrega una puntuación equivocada con toda seguridad.

JunoCómo calificar Usa el calificador más económico que aún capture lo que importa: coincidencia exacta para etiquetas y campos, verificaciones programáticas para longitud o JSON válido o una cadena requerida, y un modelo como juez solo para calidad abierta. La coincidencia exacta combina bien con la salida estructurada porque un esquema fijo te da algo limpio con qué comparar. Sea lo que elijas, el calificador también es código en el que confías, así que uno poco fiable te entrega una puntuación equivocada con toda confianza.

El modelo como juez (LLM-as-judge) es el calificador que falla de las formas más interesantes, así que planea para sus sesgos antes de apoyarte en él. Un juez favorece las respuestas más largas, elige la primera opción al comparar un par, y premia el texto que se lee como su propio estilo, y sus puntuaciones absolutas están mal calibradas, así que un 8 en una corrida no es un 8 en la siguiente.

Trata al juez como un modelo que estás evaluando por sí mismo. Fija y versiona el modelo juez, porque cambia cuando se actualiza y tus puntuaciones se mueven con él. Dale una rúbrica estricta con algunos ejemplos de referencia, y luego mide el acuerdo entre el juez y una persona sobre una muestra etiquetada para saber cuánto confiar en él.

Donde puedas, pide una comparación de a pares ("¿es mejor A o B?") en lugar de una puntuación absoluta del 1 al 10; los juicios relativos suelen ser más confiables que pedirle a un modelo que dé con un número calibrado. Fija al juez, dale una rúbrica estricta, verifícalo contra personas.

Ten en cuenta la circularidad y el costo. La misma familia de modelos calificando su propia salida comparte sus puntos ciegos, así que una falla que cometió el generador es probablemente una falla que el juez pasará por alto, y juzgar cada caso a gran escala es una segunda factura de modelo sobre la primera.

JunoCómo calificar El juez tiene opiniones que no pediste: le gustan las respuestas largas, la primera opción, y la prosa que suena como él mismo, y sus puntuaciones absolutas varían entre corridas. Fíjalo y versiónalo, dale una rúbrica estricta con ejemplos de referencia, y rastrea cuán seguido coincide con una persona, porque ahora estás calificando al calificador. Apóyate en comparaciones de a pares en vez de un solitario 1 al 10, y ten presente que un modelo juzgando a su propia familia comparte sus puntos ciegos y duplica la factura.

Córrelas en cada cambio ​

Un conjunto de evaluación solo sirve si realmente lo corres. Trata tus prompts como código: antes de lanzar un cambio a un prompt, a un modelo, o a tu recuperación de información, corre las evaluaciones y compara la puntuación con la de antes. Si el número bajó, causaste una regresión, aunque tu única prueba manual haya salido bien.

Esto es lo que convierte la ingeniería de prompts de una adivinanza en algo sobre lo que puedes iterar con confianza. Cambia algo, mídelo, conserva lo que puntúa más alto, y descarta lo que puntúa más bajo. Es el mismo ciclo que hace confiable al software común, ahora aplicado a las partes difusas de una funcionalidad de IA.

Si la puntuación bajó, causaste una regresión. Una prueba manual con suerte no anula al conjunto, así que deja que el número sea el que decida siempre.

JunoCórrelas en cada cambio Un conjunto de evaluación solo ayuda si lo corres, así que vuélvelo un hábito: antes de que cualquier cambio se lance, corre las evaluaciones y compara la puntuación con la anterior. Si bajó, eso es una regresión que hay que arreglar, no una casualidad que se ignora. Cambia, mide, conserva lo que puntúa más alto, y estarás iterando en lugar de adivinar.

Integra la corrida de evaluaciones a tu ciclo de desarrollo para que filtre los cambios igual que una suite de pruebas filtra un merge. Un cambio en un prompt, en un modelo, o en tu recuperación de información (el paso que trae documentos de soporte) no se lanza hasta que hayas corrido el conjunto y comparado la puntuación con la corrida anterior. El número, no tu instinto tras una sola prueba manual, decide si el cambio es una mejora.

Cambia una sola variable a la vez. Si editas el prompt y cambias el modelo en el mismo paso, un movimiento en la puntuación tiene dos causas posibles y no puedes atribuirlo a ninguna con certeza. Aísla el cambio, corre el conjunto, lee el resultado, y luego pasa al siguiente.

Lee la diferencia caso por caso, no solo la puntuación agregada (aggregate score, el número único promediado sobre todos los casos). Un total estable puede esconder un caso que se arregló y otro que se rompió al mismo tiempo, lo cual da neto cero mientras tu comportamiento cambiaba en silencio. Ver qué casos cambiaron de resultado te dice qué hizo realmente tu cambio.

Registra la puntuación a lo largo del tiempo para que las mejoras sean visibles y las regresiones resalten. Un historial registrado convierte "esto se siente mejor" en una línea que puedes señalar, y hace que una caída repentina sea fácil de rastrear hasta el cambio que la causó.

JunoCórrelas en cada cambio Filtra los cambios con la puntuación igual que filtras un merge con pruebas: sin corrida, no hay lanzamiento. Cambia una sola variable por paso para que un movimiento en la puntuación tenga una sola causa, y lee la diferencia caso por caso, ya que un total plano puede esconder un caso arreglado y otro roto. Registra la puntuación a lo largo del tiempo para que las victorias sean visibles y las regresiones resalten.

Conviértelo en un filtro real, no en un ritual. Pon un umbral de puntuación en el CI para que un cambio que caiga por debajo de la marca haga fallar la construcción en lugar de depender de que alguien se acuerde de revisar. Y vuelve a correr el conjunto en cada actualización de versión del modelo, porque el mismo prompt cae distinto en pesos nuevos; fija la versión del modelo contra la que probaste y vuelve a evaluar antes de adoptar una nueva.

Ten presentes dos trampas. Primero, el conjunto de evaluación (eval set, tu colección fija de casos de prueba con resultados esperados) es un indicador aproximado, no la verdad absoluta, así que ajustar demasiado en función de él sobreajusta: subes la puntuación mientras el comportamiento real se estanca. Sigue ampliando y rotando el conjunto para estar midiendo la tarea, no memorizando la prueba.

Segundo, las evaluaciones fuera de línea no muestran todo el panorama. Combínalas con señales en línea: tráfico de producción muestreado, retroalimentación de usuarios, tasas de quejas, y alimenta las fallas reales de vuelta al conjunto como nuevos casos.

Porque la salida es no determinística, la misma entrada puede puntuar distinto entre corridas. Corre suficientes muestras por caso y juzga contra un margen de tolerancia en lugar de perseguir el ruido de una sola corrida; un vaivén de un punto entre corridas es la medición respirando, no una regresión. Fija la marca a un nivel que sobreviva esa variación, o vas a pasarte la semana investigando fantasmas. Ya me pasó, más de una vez.

JunoCórrelas en cada cambio Pon un umbral en el CI para que un mal cambio haga fallar la construcción, y vuelve a evaluar en cada actualización de versión del modelo porque pesos nuevos leen el mismo prompt de forma distinta. El conjunto es un indicador aproximado, así que sigue rotándolo y combínalo con señales en línea, o vas a sobreajustar a tu propia prueba. Y como la salida es no determinística, juzga contra un margen de tolerancia en lugar de investigar fantasmas, que sí, ya me pasó.

En la práctica ​

La función run_evals de la sección anterior es un arnés de evaluación completo, aunque pequeño. Lo apuntas a tu clasificador y a tu conjunto de evaluación, y te dice cuántos casos pasan y te muestra exactamente cuáles fallan:

python
run_evals(eval_set, classify_review)
# FAIL: "Estuvo bien, nada especial." -> got POSITIVE, wanted NEUTRAL
# 2/3 passed

Esa única línea que falla vale más que una docena de pruebas manuales exitosas, porque señala una debilidad real que ahora puedes arreglar y volver a medir. El capítulo final, Seguridad y límites, cubre los riesgos contra los que hay que diseñar antes de poner cualquiera de esto frente a usuarios reales.

JunoEn la práctica Un pequeño arnés como run_evals ya se justifica por sí solo: te da una puntuación y los casos exactos que fallaron. Arregla uno, corre de nuevo, mira cómo se mueve el número. Lo siguiente, Seguridad y límites, cubre qué cuidar antes de que lleguen los usuarios reales.

Un pequeño arnés de evaluación (eval harness), el fragmento de código que corre cada caso de tu conjunto de evaluación y califica la salida contra lo que esperabas, es el ciclo que convierte "parece que está bien" en un número que puedes mover. Corres el conjunto, obtienes una puntuación más una lista de fallas, arreglas la falla real más económica, y vuelves a correrlo.

Cada caso que falla es una unidad de trabajo con una definición clara de "terminado": el caso pasa. Eso es un objetivo más preciso que "mejorar el prompt", porque puedes ver exactamente cuándo lo logras y exactamente cuándo retrocedes.

Antes de que cualquiera de esto llegue a usuarios reales, el siguiente capítulo, Seguridad y límites, cubre los riesgos que hay que considerar desde el principio.

JunoEn la práctica El arnés convierte las sensaciones en un número que puedes mover: corres el conjunto, lees la puntuación y las fallas, arreglas la real más económica, y vuelves a correr. Cada falla es una tarea con una definición clara de "terminado", que es un objetivo más preciso que "mejorarlo". Luego viene Seguridad y límites antes de que los usuarios reales lo vean.

En producción, ese pequeño arnés deja de ser un script que corres a mano y se vuelve parte del sistema. Se convierte en un filtro de CI, una verificación que bloquea un lanzamiento cuando la puntuación cae por debajo de una línea que fijaste, más un panel que vigilas a través de los lanzamientos para detectar la deriva lenta que una sola corrida nunca muestra.

Las evaluaciones fuera de línea, el conjunto fijo que calificas antes de lanzar, y el monitoreo en línea, las señales que recolectas del tráfico real después, se alimentan mutuamente: las fallas de producción se convierten en nuevos casos fuera de línea, y el conjunto fuera de línea te dice si tu arreglo funcionó. Los equipos que ganan en esto no son los que tienen el prompt más ingenioso. Son los que midieron mientras todos los demás revisaban a simple vista.

Esa es la disciplina. El siguiente capítulo, Seguridad y límites, cubre los riesgos contra los que hay que diseñar antes de que cualquiera de esto llegue a usuarios reales.

JunoEn la práctica Si esto madura, el script se convierte en un filtro de CI más un panel, con evaluaciones fuera de línea y monitoreo en línea alimentándose entre sí. He lanzado cosas confiando en "a mí me parece que está bien" y lo he pagado después, así que hazme caso: los equipos que ganan midieron mientras el resto revisaba a simple vista. Lee Seguridad y límites antes de que lleguen los usuarios reales.