Módulo 3: El eval como fitness function

1. Presentación del módulo: el eval como fitness function

Descripción

Al terminar esta lección vas a entender la idea que sostiene todo el módulo, y que es la más contraintuitiva de la guía entera: un componente probabilístico no se prueba con un assert exacto, sino con un eval-set que produce un score, y ese score contra un umbral es una compuerta que gobierna su deploy. En el módulo 1 aprendiste que un LLM no da la misma salida dos veces, y en el módulo 2 le pusiste presupuestos de latencia y de costo. Cerramos ese módulo con una promesa: toda feature de IA pasa tres compuertas —latencia, costo y calidad—. El módulo 2 te dio las dos primeras. Esta es la tercera, y es especial porque las otras dos las mide un cronómetro y un contador, mientras que esta mide algo que un test clásico no puede tocar: si la respuesta del componente es lo bastante buena.

Esto importa porque, sin esta compuerta, la calidad de la IA es una opinión. "Se ve bien" no es una prueba: no es reproducible, no escala, y no sobrevive a un cambio de prompt hecho un viernes por la tarde. La pregunta "¿la respuesta es buena?" parece imposible de automatizar —¿cómo verificas algo que se escribe distinto cada vez?—, y esa aparente imposibilidad es exactamente donde muchos equipos se rinden y dejan la calidad a la vista y al olfato. La respuesta del módulo es un cambio de forma de la prueba: en vez de comparar una salida contra un valor exacto, defines un eval-set —un conjunto de casos, cada uno con su criterio de éxito— y lo corres contra el componente. El resultado no es un "pasó / no pasó" por caso, sino un score: la fracción de casos que cumplen el criterio. Y ese score, comparado contra un umbral explícito, se vuelve una compuerta binaria y verificable —el mismo salto que en el módulo 2 convirtió "rápido" y "barato" en compuertas de presupuesto—.

Conexión con el módulo: esta lección es el mapa, no el territorio. Aquí no construyes nada todavía; entiendes por qué las seis lecciones que siguen van en el orden que van. Primero el problema: la lección 2 muestra por qué el assert exacto se rompe contra un componente probabilístico y qué lo reemplaza. Luego la herramienta: la lección 3 define la anatomía del eval-set —casos, criterio, score— y lo corre. Con el score en la mano, la lección 4 —el corazón del módulo— lo convierte en una compuerta comparándolo contra un umbral, y conecta esa compuerta con la fitness function de architecture-decisions. Luego las dos aplicaciones que hacen del eval algo vivo: la lección 5 lo usa para atrapar regresiones al cambiar el prompt o el modelo, y la lección 6 lo mete en CI para que bloquee el deploy cuando el score cae. La lección 7 abre los tipos de criterio (exact-match, contains, LLM-as-judge, umbral estadístico) y advierte que el juez es otro componente de IA. La lección 8 —el proyecto— te pone a montar la compuerta de calidad de una feature de Mercado de punta a punta.

Dos analogías: el examen estandarizado y el control de calidad

Antes de bajar al código, dos imágenes cotidianas que vas a reconocer en cada lección del módulo. Cada una captura una de las dos ideas centrales.

El examen estandarizado con clave de respuestas. Piensa en un examen de admisión que toman miles de estudiantes. Cada uno escribe distinto —distinta letra, distinta redacción, distinto orden—, y sin embargo el examen se puede calificar de forma objetiva y automática, porque no se evalúa "qué tan bonito escribió cada quien" sino cuántas respuestas coinciden con la clave. La clave de respuestas es el criterio de éxito; el examen completo —muchas preguntas, cada una con su clave— es el eval-set; y la calificación final —"85 de 100"— es el score. Fíjate en lo que hace esta idea: convierte un montón de respuestas irrepetibles y distintas entre sí en un solo número comparable. Eso es exactamente lo que necesitas para un componente probabilístico: no puedes exigir que dé la misma redacción siempre, pero puedes medir qué fracción de sus respuestas cumple el criterio. El score es la calificación del componente contra su clave de respuestas. Guárdala: el eval-set es el examen, el criterio es la clave, el score es la nota.

El control de calidad de la fábrica. Ahora imagina una línea de producción que fabrica focos. Al final de la línea hay una estación de control de calidad que toma una muestra de cada lote y cuenta cuántos focos están defectuosos. Hay una regla escrita: si la tasa de defectos supera el 2%, el lote entero se rechaza —no sale a la venta—. No importa que la mayoría de los focos funcionen; el umbral es el umbral, y un lote que lo cruza no pasa. Esa estación es la compuerta de calidad: toma una medición agregada (la tasa de defectos, el equivalente del score) y la compara contra un umbral para dar un veredicto binario —el lote pasa o se rechaza—. En IA, esa estación es el eval gate: toma el score del componente y lo compara contra el umbral de calidad; arriba del umbral, el componente sale a producción (deploy permitido); abajo, se bloquea. Y la parte más poderosa: esa estación puede estar en la línea todo el tiempo, revisando cada lote automáticamente. Ahí es donde el eval se vuelve una compuerta de CI —lección 6—: cada cambio del componente pasa por la estación antes de llegar al cliente.

Guarda las dos. El examen estandarizado es cómo mides un componente que responde distinto cada vez —lo calificas contra una clave y obtienes un score—. El control de calidad es cómo ese score se vuelve una decisión de deploy —lo comparas contra un umbral y pasa o se bloquea—. El módulo entero es aprender a montar esas dos cosas sobre una feature real.

El caso: el agente de soporte de Mercado

Bajemos a Mercado, el marketplace del ecosistema. De sus features de IA, la protagonista de este módulo es el agente de soporte al cliente: un asistente conversacional que responde dudas frecuentes —"¿dónde está mi pedido?", "¿cómo devuelvo un producto?", "¿cuánto tarda el envío?"—. Es un candidato perfecto para el eval por una razón concreta: sus respuestas son verificables. Para "¿cuánto tarda el envío?" hay una respuesta correcta —"de 3 a 5 días hábiles"— que el agente debe comunicar, aunque la redacte distinto cada vez. Eso nos da un criterio de éxito claro: la respuesta debe contener la información correcta.

El eval-set del agente es un conjunto de esas preguntas frecuentes, cada una con la frase clave que la respuesta correcta debe contener. Correrlo contra el agente nos dice qué fracción de las preguntas responde bien —el score—. Y cuando alguien cambie el prompt del agente, o proponga bajarlo a un modelo más barato para ahorrar (el cascade del módulo 2), correremos el eval de nuevo: si el score bajó, el cambio regresó la calidad y no debe entrar. La búsqueda semántica —la otra feature protagonista del módulo 2— aparece en los ejercicios, porque su eval-set se construye igual (queries con los productos que deberían salir) aunque su criterio sea distinto.

No vamos a construir el agente ni a decidir qué preguntas frecuentes debería cubrir su eval-set —eso es diseño de evals, y es de AI Engineering—. Vamos a tomar el eval-set como dado y a usarlo como compuerta de calidad: correrlo, medir el score, compararlo contra el umbral, y dejar que la compuerta decida si un cambio se despliega.

Y para arrancar, veamos el módulo entero condensado en un bloque ejecutado. Fíjate bien, porque aquí está la tesis en acción.

# Leccion 01 (intro) — el modulo en miniatura: el eval como compuerta de deploy
# Todo SIMULADO. Cero red, cero API, cero claves. Salida determinista.

# El eval-set del agente de soporte: cada caso es una pregunta + la frase
# que la respuesta correcta debe contener (el criterio de exito).
# NOTA DE FRONTERA: como se ELIGEN estos casos y este criterio es AI Engineering.
# Aqui el eval-set YA existe; lo usamos COMO COMPUERTA.
EVAL_SET = [
    {"id": "q1",  "question": "donde esta mi pedido",       "must_contain": "tracking"},
    {"id": "q2",  "question": "como devuelvo un producto",  "must_contain": "devolucion"},
    {"id": "q3",  "question": "cuanto tarda el envio",      "must_contain": "3 a 5 dias"},
    {"id": "q4",  "question": "puedo pagar en cuotas",      "must_contain": "cuotas"},
    {"id": "q5",  "question": "el producto llego roto",     "must_contain": "reembolso"},
    {"id": "q6",  "question": "como cambio mi direccion",   "must_contain": "perfil"},
    {"id": "q7",  "question": "no recibi mi factura",       "must_contain": "correo"},
    {"id": "q8",  "question": "quiero cancelar mi pedido",  "must_contain": "cancelar"},
    {"id": "q9",  "question": "el cupon no funciona",       "must_contain": "vigencia"},
    {"id": "q10", "question": "como contacto a un vendedor", "must_contain": "mensajes"},
]

# La respuesta correcta ("gold") por caso. Cada una contiene la frase del criterio.
GOLD = {
    "q1":  "Puedes ver el tracking de tu pedido en tu perfil.",
    "q2":  "Para una devolucion, entra a tu pedido y pulsa Devolver.",
    "q3":  "El envio estandar tarda de 3 a 5 dias habiles.",
    "q4":  "Si, puedes pagar en cuotas sin interes con tarjeta.",
    "q5":  "Lamentamos eso; puedes pedir un reembolso desde el pedido.",
    "q6":  "Cambia tu direccion en la seccion Perfil, Direcciones.",
    "q7":  "Te reenviamos la factura al correo de tu cuenta.",
    "q8":  "Puedes cancelar el pedido si aun no fue enviado.",
    "q9":  "Revisa la vigencia del cupon; quiza ya expiro.",
    "q10": "Escribe al vendedor desde la seccion Mensajes.",
}
POOR_ANSWER = "Lo siento, no tengo informacion sobre eso."

def make_agent(competent_ids):
    # STUB del LLM: simula una version del agente. Responde bien los casos en
    # competent_ids; para el resto da una respuesta pobre que falla el criterio.
    def agent(question, case_id):
        return GOLD[case_id] if case_id in competent_ids else POOR_ANSWER
    return agent

def run_eval(agent):
    passed = sum(
        case["must_contain"] in agent(case["question"], case["id"]).lower()
        for case in EVAL_SET
    )
    return passed / len(EVAL_SET)          # el score: fraccion de casos que pasan

def gate(score, threshold):
    return ("PASS", "deploy PERMITIDO") if score >= threshold else ("FAIL", "deploy BLOQUEADO")

THRESHOLD = 0.80
ALL = {c["id"] for c in EVAL_SET}
version_a = make_agent(ALL - {"q9"})                          # buena: 9/10
version_b = make_agent({"q1","q2","q3","q4","q6","q8"})       # regresada: 6/10

print(f"eval gate del agente de soporte — umbral (threshold) = {THRESHOLD:.2f}\n")
print(f"{'version':<22}{'score':>7}   {'gate':<6}  resultado")
for name, agent in (("A (candidata)", version_a), ("B (cambio de prompt)", version_b)):
    s = run_eval(agent)
    verdict, action = gate(s, THRESHOLD)
    print(f"{name:<22}{s:>7.2f}   [{verdict}]  {action}")

Qué esperar. Al correrlo:

eval gate del agente de soporte — umbral (threshold) = 0.80

version                 score   gate    resultado
A (candidata)            0.90   [PASS]  deploy PERMITIDO
B (cambio de prompt)     0.60   [FAIL]  deploy BLOQUEADO

Detente en esos dos renglones, porque son el módulo entero en miniatura. Las dos son la misma feature —el agente de soporte de Mercado— en dos versiones. La versión A responde bien 9 de las 10 preguntas del eval-set: su score es 0.90, arriba del umbral de calidad de 0.80, así que el gate la deja pasar —deploy permitido—. La versión B —quizá alguien "mejoró" el prompt, o lo bajó a un modelo más barato— responde bien solo 6 de 10: su score cae a 0.60, por debajo del umbral, y el gate la bloquea —deploy denegado, en rojo—. Nadie tuvo que leer las respuestas una por una y opinar si estaban bien. La compuerta lo decidió con un número contra un umbral, igual que la estación de control de calidad rechaza el lote que cruza el 2% de defectos.

No entiendas todavía cómo funciona cada pieza —para eso son las lecciones—. Quédate con la forma del resultado: dos versiones del mismo componente probabilístico, una que pasa la compuerta de calidad y otra que la falla, decidido por un score contra un umbral, sin que un humano tenga que juzgar a ojo. Eso es exactamente lo que significa "el eval como fitness function": una prueba automatizada que gobierna si un cambio en la calidad del componente puede entrar a producción.

El mapa de las seis lecciones

Las seis lecciones que siguen van en este orden porque cada una arma la pieza que la siguiente necesita.

LecciónQué te daPor qué va aquí
2El problema: por qué el assert exacto se rompe y qué lo reemplaza (score, no binario por caso)No puedes construir la compuerta sin entender por qué la prueba clásica no sirve
3La anatomía: eval-set (casos + criterio), correrlo, el scoreLa herramienta base; todo lo demás opera sobre el score que produce esta lección
4La compuerta: score contra umbral = fitness function del componenteEl corazón del módulo: donde el score se vuelve una decisión de deploy
5La regresión: el eval detecta cuando un cambio de prompt/modelo baja la calidadLa compuerta cobra vida: protege contra el cambio, que es cuando la calidad se rompe
6El eval en CI: un score bajo el umbral bloquea el deploy, como un test rojoConvierte la compuerta en algo que el pipeline hace cumplir solo, en cada cambio
7Los tipos de criterio: exact-match, contains, LLM-as-judge, umbral estadísticoAbre la caja del "criterio de éxito" y advierte que el juez es otro componente de IA

El arco es: primero entiendes por qué la prueba clásica no aplica (2), luego construyes la herramienta que la reemplaza —el eval-set y su score (3)—, luego la conviertes en compuerta con un umbral (4), y con la compuerta lista la pones a trabajar: atrapa regresiones (5) y vive en CI bloqueando deploys (6). La lección 7 abre los tipos de criterio para que sepas qué gobierna cada uno. La lección 8 —el proyecto— junta todo sobre una feature de Mercado que arquitectas de cero, para que confirmes que aprendiste el método y no memorizaste una tabla.

Lo que este módulo NO toca

Conviene marcar la frontera desde ahora, porque hay temas vecinos que parecen de aquí y son de otra parte del ecosistema. Esta frontera es dura: crúzala solo para remitir.

Cómo diseñar buenos evals es de AI Engineering, no de aquí. Esta es la frontera más importante del módulo, así que léela con cuidado. Construir un buen eval-set es un oficio profundo: elegir casos representativos que cubran lo que importa (y no solo lo fácil), evitar el sesgo de probar solo lo que ya sabes que funciona, medir la relevancia de una búsqueda semántica con métricas serias, decidir cuántos casos bastan, calibrar un juez para que sus notas correlacionen con el juicio humano, versionar el dataset a medida que la feature evoluciona. Todo eso es diseño de evals, es un cuerpo de conocimiento entero, y es del ecosistema AI Engineering. Este módulo no lo enseña: en estas lecciones el eval-set ya existe —te lo damos hecho— y tu trabajo es usarlo como compuerta arquitectónica: correrlo, medir el score, compararlo contra el umbral, y gobernar el deploy con el resultado. La regla mental: si la pregunta es "¿qué casos y qué criterio pongo en el eval-set?", es AI Engineering; si la pregunta es "¿cómo uso el score del eval-set para decidir si esto se despliega?", es de aquí.

La fitness function como concepto general es de architecture-decisions. Todo este módulo dice que el eval es una fitness function —una prueba automatizada que verifica que una propiedad del sistema (aquí, la calidad de un componente probabilístico) se mantiene, y frena el cambio si se degrada—. Pero la idea general de fitness function, aplicada a cualquier propiedad arquitectónica (latencia, acoplamiento entre capas, tamaño de un módulo, dependencias prohibidas), se enseña en architecture-decisions-and-tradeoffs-guide (M6). Aquí tomamos ese concepto como conocido y lo especializamos a la calidad de la IA. Si quieres el marco completo de fitness functions como técnica de gobernanza arquitectónica, esa es la guía; aquí ves su versión para componentes probabilísticos.

La mecánica de CI/CD a fondo es de otra guía. En la lección 6 el eval vive en un pipeline y produce un exit code que bloquea el deploy. Pero cómo se arma un pipeline de CI/CD serio —los runners, las etapas, los ambientes, el rollback, los secretos— es de las guías de entrega e infraestructura. Aquí el pipeline es el mínimo necesario para mostrar el eval como el paso que gobierna el deploy: un gate que pasa o falla. No construimos el pipeline; mostramos dónde encaja la compuerta.

Errores comunes

Probar el componente de IA con un assert exacto (de modelo mental). Qué pasa: el equipo escribe tests como con cualquier código —assert agent(pregunta) == "respuesta esperada"— y el test se rompe en la primera corrida porque el LLM redactó distinto. La conclusión errónea que sacan es "la IA no se puede probar", y abandonan las pruebas por completo. Por qué pasa: la prueba de igualdad exacta es el reflejo de todo programador, y funciona con código determinista, así que se aplica por costumbre. Cómo detectarlo: si tu suite de pruebas de un componente de IA usa == contra una salida literal, está condenada a romperse o a ser inútilmente frágil. Cómo corregirlo: es el módulo entero —cambiar la forma de la prueba de un binario por caso a un score sobre un eval-set (lecciones 2 y 3)—.

No tener eval-set y "probar a ojo" (de omisión). Qué pasa: la calidad del componente se verifica mirando algunas respuestas a mano antes de cada release y diciendo "se ve bien". No es reproducible (cada quien mira casos distintos), no escala (nadie revisa cientos de casos a mano), y no atrapa regresiones (el cambio que rompió el caso que nadie miró pasa sin ruido). Por qué pasa: montar un eval-set cuesta trabajo al inicio, y "a ojo" da la ilusión de estar verificando. Cómo detectarlo: si no puedes decir en un número qué tan bueno es tu componente hoy, no lo estás midiendo —lo estás sintiendo—. Cómo corregirlo: un eval-set con criterio y un score (lección 3), que es reproducible y corre solo.

Cambiar el prompt o el modelo sin correr el eval (de proceso). Qué pasa: alguien ajusta el prompt del agente para arreglar un caso, o lo baja a un modelo más barato para ahorrar, y lo despliega sin correr el eval. El cambio arregló lo que buscaba pero rompió tres cosas que nadie volvió a revisar —una regresión silenciosa—, y se descubre semanas después por quejas de clientes. Por qué pasa: un cambio de prompt se siente inofensivo ("es solo texto"), y sin una compuerta que lo verifique, nada frena el deploy. Cómo detectarlo: si tus cambios de prompt o de modelo llegan a producción sin un score que los respalde, estás volando a ciegas. Cómo corregirlo: el eval como gate ante cada cambio (lección 5) y en CI para que sea obligatorio (lección 6).

Ejercicios

Ejercicio 1 — Traduce las analogías al diseño. Para cada analogía del módulo, di qué pieza del eval representa y da un ejemplo concreto en el agente de soporte de Mercado. (a) El examen estandarizado con su clave de respuestas. (b) La calificación final del examen ("85 de 100"). (c) El control de calidad que rechaza el lote si la tasa de defectos cruza el 2%.

Ver solución
  • (a) El examen con su clave → el eval-set con su criterio de éxito. El examen es el conjunto de casos (las preguntas frecuentes del agente), y la clave de respuestas es el criterio (la frase que cada respuesta debe contener). Ejemplo en Mercado: la pregunta "¿cuánto tarda el envío?" es un caso, y su clave es que la respuesta contenga "3 a 5 días". El eval-set completo son las diez preguntas con sus diez claves.
  • (b) La calificación final → el score. Es el agregado: qué fracción de los casos cumplió su criterio, condensado en un número comparable. Ejemplo en Mercado: si el agente responde bien 9 de las 10 preguntas, su score es 0.90 —la nota del componente contra su clave, sin importar que redactó cada respuesta distinto—.
  • (c) El control de calidad con su umbral → el eval gate. Toma la medición agregada (el score) y la compara contra un umbral para dar un veredicto binario de deploy. Ejemplo en Mercado: con un umbral de 0.80, la versión de 0.90 pasa (deploy permitido) y una de 0.60 se rechaza (deploy bloqueado), igual que el lote que cruza el 2% de defectos.

Lo importante: el examen es cómo mides algo que responde distinto cada vez (score contra clave), y el control de calidad es cómo ese score se vuelve una decisión de deploy (score contra umbral).

Ejercicio 2 — La frase peligrosa. Un compañero propone probar el agente de soporte así: "Fácil: escribo un test que le manda '¿cuánto tarda el envío?' y verifico que responda exactamente 'El envío estándar tarda de 3 a 5 días hábiles.'. Si coincide, pasa." Identifica el error de fondo y explica qué prueba debería escribir en su lugar.

Ver solución

El error de fondo es probar un componente probabilístico con igualdad exacta. El agente es un LLM: la próxima vez que le mande la misma pregunta puede responder "Normalmente tu pedido llega en 3 a 5 días hábiles" —igual de correcta, redactada distinto—. El assert output == "..." se rompería, no porque la respuesta esté mal, sino porque no es idéntica letra por letra. El test sería frágil (se rompe con cualquier reformulación válida) o, peor, empujaría a forzar al modelo a repetir una frase fija, perdiendo la naturalidad que justifica usar un LLM.

Lo que debería escribir en su lugar: un test de propiedad, no de igualdad. El criterio de éxito es que la respuesta contenga la información correcta —la frase clave "3 a 5 días"—, sin importar cómo la redacte. Así, tanto "El envío estándar tarda de 3 a 5 días hábiles" como "Normalmente llega en 3 a 5 días" pasan, porque ambas comunican el dato correcto. Y mejor aún: ese caso no vive solo, vive dentro de un eval-set de muchas preguntas, y lo que importa no es el veredicto de un caso sino el score del conjunto contra el umbral. Es exactamente el cambio de forma de la lección 2.

Ejercicio 3 — ¿Diseño de eval o eval como gate? Para cada actividad, di si cae dentro de este módulo (el eval como compuerta arquitectónica) o en la frontera de AI Engineering (diseñar el eval), y por qué. (a) Correr el eval-set y bloquear el deploy si el score cae bajo 0.80. (b) Decidir qué 200 preguntas de clientes deben estar en el eval-set para que sea representativo. (c) Integrar el eval como un paso de CI que corre en cada PR. (d) Calibrar un modelo juez para que sus notas correlacionen con las de un evaluador humano.

Ver solución
  • (a) Bloquear el deploy si el score cae → este módulo. Es usar el score como compuerta de deploy: la esencia del eval como fitness function. Lecciones 4 y 6.
  • (b) Elegir las 200 preguntas representativas → frontera (AI Engineering). Es diseño del eval-set: qué casos lo componen, cómo asegurar cobertura y representatividad. Es un oficio profundo y no es de aquí. Este módulo toma el eval-set como dado.
  • (c) Integrar el eval en CI → este módulo. Es poner la compuerta en el pipeline para que gobierne el deploy automáticamente. Lección 6.
  • (d) Calibrar el modelo juez → frontera (AI Engineering). Hacer que las notas de un LLM-as-judge correlacionen con el juicio humano es diseño y calibración del criterio, no uso del gate. Este módulo usa el juez como componente (lección 7), pero calibrarlo es de AI Engineering.

La regla que separa: si la actividad construye o afina el eval-set o su criterio (b, d), es AI Engineering; si usa el score del eval-set para gobernar el deploy (a, c), es de aquí.

Resumen y siguiente paso

En esta lección conociste la tesis del módulo: un componente probabilístico no se prueba con un assert exacto, sino con un eval-set que produce un score, y ese score contra un umbral es la compuerta de calidad que gobierna su deploy —el equivalente probabilístico de la fitness function—. Viste por qué esta es la tercera compuerta que toda feature de IA necesita, junto a las de latencia y costo del módulo 2. Las dos analogías te dieron el marco: el examen estandarizado con clave de respuestas (cómo mides algo que responde distinto cada vez: lo calificas contra un criterio y obtienes un score) y el control de calidad de fábrica (cómo ese score se vuelve una decisión: lo comparas contra un umbral y el lote pasa o se rechaza). Y en el bloque ejecutado viste la tesis en acción: la misma feature en dos versiones, una que pasa la compuerta de calidad (score 0.90 → deploy permitido) y otra que regresó y la falla (score 0.60 → deploy bloqueado), decidido por un número contra un umbral, sin que un humano juzgue a ojo.

Antes de avanzar deberías poder: explicar por qué la calidad de un componente de IA no se puede dejar "a ojo"; nombrar las tres piezas del eval (eval-set, criterio, score) y la cuarta que las convierte en compuerta (el umbral); y separar el eval como gate (este módulo) del diseño del eval (AI Engineering), que está fuera de la frontera.

Lo que sigue es entender a fondo por qué la prueba clásica no sirve, porque hasta que no veas el assert exacto romperse no vas a apreciar por qué necesitas un score. En la lección 2 vas a ejecutar el intento fallido —un assert output == expected que funciona con una función normal y se rompe contra un componente que da redacciones distintas— y vas a ver el cambio de forma que lo reemplaza: de una prueba binaria por caso a un score agregado sobre un eval-set con criterio de propiedad. Es el paso de "sé que la IA no se prueba con ==" a "sé exactamente con qué se prueba, y por qué".

Recursos