Módulo 7: Observability Latency And Evals In Production
5. Qué es un eval en producción, y por qué no es un test unitario
Descripción
Esta lección responde una pregunta puramente conceptual, sin una sola línea de código, antes de que la lección 6 construya el arnés de smoke test que la necesita: ¿qué es exactamente un eval —el término que la industria usa para "evaluar la calidad de un sistema de IA"— y en qué se diferencia, con precisión, de un test unitario como los que pytest ya corrió dieciséis veces en el Módulo 4, lección 6? La respuesta traza, otra vez, la misma frontera que el Módulo 1, lección 4 ya fijó con una cita textual de STRATEGY.md — esta vez aplicada, específicamente, a la evaluación de calidad, el último rincón donde esa frontera podría cruzarse sin que nadie se diera cuenta.
Conexión con el módulo
La lección 4 cerró el único SLI 100% literal de este módulo. Esta lección abre el terreno donde esa honestidad se vuelve más difícil de sostener: medir si extract-shipment-manifest-fields extrae bien los campos de un manifiesto es, genuinamente, la pregunta más interesante sobre esta carga de IA — y también, precisamente por eso, la que esta guía tiene más motivo de nombrar con precisión y no intentar responder. La lección 6 construye el arnés que correría esa evaluación; esta lección explica, con cuidado, qué parte de ese arnés pertenece a esta guía y qué parte no.
Analogía: revisar que una traducción "suena bien" frente a revisar que el código compila
Un test unitario es como un corrector ortográfico: verifica que un texto cumpla reglas mecánicas, objetivas, sin ambigüedad — ¿está la palabra bien escrita? ¿el paréntesis que abrió se cerró? ¿la función que se llamó existe? La respuesta es siempre binaria, siempre la misma para el mismo texto, y cualquier hablante del idioma —o cualquier compilador— llegaría a la misma conclusión sin discutir. Un eval de calidad, en cambio, es como pedirle a un traductor humano bilingüe que lea una traducción y diga si "suena bien" — no si cada palabra individual está bien escrita (eso ya lo revisó el corrector), sino si el texto completo transmite el matiz, el tono, la intención del original. Dos traductores expertos, leyendo la misma traducción, podrían discrepar razonablemente sobre si "suena bien" — no porque uno esté equivocado, sino porque la pregunta misma admite juicio, no solo verificación mecánica. post_invoke_checks.py (Módulo 4, lección 6) es el corrector ortográfico de extract-shipment-manifest-fields: verifica que la respuesta tenga la forma correcta, con una respuesta binaria e indiscutible. Un eval de calidad semántica es la pregunta del traductor bilingüe: ¿esta extracción capturó, de verdad, lo que el manifiesto en texto libre decía? — y esa pregunta, esta guía no la contesta.
Qué es un eval, con precisión
La industria usa "eval" (de evaluation) como término corto para un tipo específico de verificación: correr un sistema de IA contra un conjunto de casos de prueba, y medir qué tan bien las respuestas del sistema coinciden con lo que un humano —o un criterio explícito diseñado para imitar el juicio humano— consideraría correcto. Vale la pena ser preciso sobre el mecanismo, porque sre-and-incident-response-guide, sin usar la palabra "eval", ya describió exactamente este patrón, en un contexto distinto:
"[Correctness SLIs can be measured by] inject[ing] data with known outputs into the system, and count[ing] the proportion of times that the output matches our expectations."
Léelo con cuidado: "inyectar datos con salidas conocidas, y contar la proporción de veces que la salida coincide con lo esperado" — es, literalmente, la mecánica de un eval, descrita por Google SRE en el contexto de sistemas de procesamiento de datos, años antes de que "eval" se volviera el término de moda para IA generativa. La mecánica —dataset fijo, comparación contra una respuesta esperada, un porcentaje de coincidencia— no es nueva ni exclusiva de la IA. Lo que cambia, y cambia todo, es qué significa "coincide con lo esperado" cuando la salida viene de un modelo de lenguaje en vez de un sistema determinista.
Dos formas de "coincidir", y por qué son preguntas distintas
COINCIDENCIA DE FORMA COINCIDENCIA DE SIGNIFICADO
(esta guía, Modulo 4 y 7) (AI Engineering)
"¿Tiene la respuesta las cinco "¿Esta respuesta especifica es
claves de ShipmentFields, con correcta PARA ESTE manifiesto
valores no vacios, weightKg especifico? ¿capturo el matiz
numerico?" correcto de un texto ambiguo?"
Verificable con codigo Python Requiere juicio -- humano, o un
puro, determinista, sin ningun modelo actuando como "juez",
modelo de por medio el o cual introduce su PROPIA
incertidumbre semantica
Un mismo candidato SIEMPRE produce Dos evaluadores razonables
el mismo resultado PASS/FAIL podrian discrepar sobre la
MISMA respuesta
Un ejemplo concreto hace la distinción imposible de confundir. Imagina dos respuestas representativas, ambas para el mismo manifiesto de texto libre del Módulo 1, lección 3 (envío 4471, "120kg de textiles, Lima a Santiago, AndesExpress"):
Respuesta A: {"shipmentId": "4471", "originCountry": "Peru",
"destinationCountry": "Chile", "carrier": "AndesExpress",
"weightKg": "120"}
Respuesta B: {"shipmentId": "4471", "originCountry": "Chile",
"destinationCountry": "Peru", "carrier": "AndesExpress",
"weightKg": "120"}
Las dos pasan post_invoke_checks.py sin ningún problema — ambas tienen las cinco claves, todos los valores son cadenas no vacías, weightKg es numérico. validate_shipment_fields() marcaría a ambas como is_valid: True, exactamente el mismo resultado. Pero la Respuesta B invirtió origen y destino — un error de extracción real, del tipo que solo una comparación semántica contra el texto original (o contra el resultado esperado, expectedFields, si existiera un dataset con esa columna) podría detectar. Esta es, con la máxima precisión posible, la brecha exacta que separa "esta guía" de "AI Engineering": la Respuesta B es una falla de calidad, invisible para cualquier chequeo de forma, sin importar cuán cuidadosamente esté escrito.
Por qué esta guía no cruza esa línea, otra vez
El Módulo 1, lección 4 de esta guía ya citó, textual, la posición de STRATEGY.md en el grafo del ecosistema NIEVA: "Continuidad desde AI Engineering: el alumno llega sabiendo construir sistemas de IA. No repite fundamentos: aprende a operarlos." Evaluar si una extracción semántica es correcta —¿el modelo entendió que "Lima" es origen y "Santiago" es destino en este texto específico, con esta redacción específica?— es, precisamente, una habilidad de construir sistemas de IA con criterio, no de operarlos. Es territorio que AI Engineering ya cubre a fondo: cómo diseñar un conjunto de evals con salidas esperadas verificadas por humanos, cómo usar un modelo como "juez" de otro modelo, cómo medir tasas de alucinación con rigor estadístico. Repetir ese contenido aquí, aunque fuera técnicamente posible dentro del alcance $0 de esta guía, produciría exactamente el resultado que el Módulo 1, lección 4 ya advirtió: una versión más débil de algo que otro ecosistema ya enseña a fondo.
Lo que esta guía sí construye —y es un trabajo real, no una excusa para evitar el tema— es el arnés: la infraestructura de prueba que, el día que alguien conecte una invocación real de Bedrock, correría automáticamente contra un conjunto fijo de manifiestos y produciría un reporte. Un arnés vacío, sin ninguna infraestructura detrás, no sirve de nada el día que sí exista una cuenta real con Bedrock habilitado. Construir ese arnés ahora —con la estructura de comparación funcionando de verdad, aunque la respuesta que compara sea representativa— es trabajo de infraestructura genuino, exactamente del mismo tipo que el resto de esta guía ya construyó para IAM, guardrails y costo.
La tabla, retomada del Módulo 1, con una fila nueva resaltada
| Esta guía SÍ construye | Esta guía NO construye — es AI Engineering |
|---|---|
| … (siete filas ya establecidas en el Módulo 1, lección 4) | … |
| El arnés de smoke test — estructura de comparación, no la métrica de calidad — M7.6 | La métrica de calidad semántica que ese arnés compararía en producción real |
Esta es, literalmente, la última fila de la tabla que el Módulo 1, lección 4 ya construyó completa — el Módulo 7 no agrega una tabla nueva, cierra la que ya existía con la única pieza que faltaba nombrar en detalle.
Errores comunes
Pensar que "construir el arnés" es una forma indirecta de sí hacer evaluación de calidad, solo que sin decirlo (de subestimar la precisión de la frontera). Qué pasa: alguien argumenta que, como el arnés de la lección 6 va a comparar una respuesta contra expectedFields, en el fondo sí está haciendo evaluación semántica, solo que con un nombre distinto. Cómo detectarlo: si tu descripción del arnés de la lección 6 usa la frase "verifica que la extracción sea correcta" sin la palabra "forma" o "esquema" en algún lugar cercano. Cómo corregirlo: revisa el ejemplo de las Respuestas A y B de esta lección — el arnés de la lección 6, tal como está diseñado, aprobaría ambas, porque las dos tienen la forma correcta. Un arnés que sí hiciera evaluación semántica rechazaría la Respuesta B por invertir origen y destino; el que esta guía construye, deliberadamente, no lo hace. Esa es, exactamente, la línea.
Concluir que un eval "no es más que" un test unitario con datos distintos, sin ninguna diferencia real de fondo (de subestimar por qué la industria usa un término nuevo). Qué pasa: alguien argumenta que "eval" es solo una palabra de moda para lo que pytest ya hace desde hace años. Cómo detectarlo: si tu explicación de "eval" no menciona, en ningún punto, que la respuesta bajo prueba viene de un sistema no determinista. Cómo corregirlo: la mecánica de comparación —dataset fijo, contar coincidencias— sí es la misma, la cita de Google SRE de esta lección lo confirma. La diferencia real es que un test unitario prueba código determinista, donde "correcto" tiene una única respuesta objetiva verificable con lógica; un eval prueba la salida de un modelo, donde "correcto" a menudo admite más de una respuesta razonable, y la comparación necesita, con frecuencia, juicio humano o un modelo actuando como juez — un tipo de verificación estructuralmente distinto, no solo una diferencia de vocabulario de marketing.
Buscar en esta lección una definición de "qué tan bueno es suficientemente bueno" para una extracción de Andes Cargo (de esperar un umbral de calidad que esta guía no puede dar). Qué pasa: alguien, terminando esta lección, pregunta "entonces, ¿qué porcentaje de aciertos necesitaría extract-shipment-manifest-fields para ser aceptable en producción?". Cómo detectarlo: si tu pregunta después de esta lección busca un número de calidad mínima aceptable. Cómo corregirlo: esa pregunta —fijar un umbral de calidad semántica aceptable, y medir contra él— es, con precisión exacta, territorio de AI Engineering; esta guía no tiene ninguna base para responderla, porque nunca invoca el modelo real que produciría los datos necesarios para calcular esa tasa. Lo que sí puede decir con honestidad: la infraestructura para correr esa medición, el día que exista, está construida en la lección 6.
Ejercicios
Ejercicio 1 — Usando el ejemplo de las Respuestas A y B de esta lección, diseña una TERCERA respuesta representativa que falle post_invoke_checks.py (Módulo 4, lección 6) pero que, si hubiera sido correcta en su forma, también habría tenido un error semántico distinto al de la Respuesta B. ¿Qué demuestra esto sobre la independencia de los dos tipos de chequeo?
Ver solución
Por ejemplo: {"shipmentId": "4471", "originCountry": "Peru", "destinationCountry": "Chile", "carrier": "AndesExpress"} — sin weightKg, así que post_invoke_checks.py la rechaza (missing required field(s): weightKg). Pero imagina que, además, esa misma respuesta hubiera escrito "carrier": "RutaSur" en vez de "AndesExpress" (un error semántico, el manifiesto original sí menciona AndesExpress). El punto de este ejercicio: los dos tipos de fallo —forma y significado— son completamente independientes. Una respuesta puede fallar solo en forma (como esta), solo en significado (como la Respuesta B), en ambos a la vez, o en ninguno. post_invoke_checks.py solo puede detectar el primer tipo, sin importar qué tan grave sea el segundo — la demostración más clara de por qué un chequeo de forma nunca sustituye a una evaluación de calidad, y viceversa.
Ejercicio 2 — Explica, con tus propias palabras y sin repetir la analogía de esta lección, por qué dos evaluadores humanos razonables podrían discrepar sobre si la Respuesta B (origen/destino invertidos) es "una falla grave" o "un error menor". ¿Qué tipo de decisión de negocio determinaría cuál de las dos posturas es correcta para Andes Cargo?
Ver solución
Podrían discrepar porque la gravedad de invertir origen y destino depende de qué hace el sistema después de esa extracción — una pregunta de negocio, no de lingüística. Si Shipments alimenta, por ejemplo, un sistema de facturación de aduana que cobra distinto según el país de origen declarado, invertir Perú y Chile podría generar una declaración incorrecta con consecuencias legales reales — una falla grave. Si, en cambio, el campo se usa solo para un reporte interno de volumen que un humano revisa antes de actuar, el mismo error podría corregirse con una simple revisión manual — un error menor, aunque siga siendo un error. Esta es, precisamente, la clase de decisión que un eval real necesitaría como criterio explícito antes de poder calificar cualquier respuesta como "aceptable" o no — y es, con la misma precisión, la clase de decisión de producto que esta guía, deliberadamente, no toma, porque pertenece al dominio de quien diseña el sistema de IA, no de quien lo opera.
Ejercicio 3 — Un compañero de trabajo, después de leer esta lección, propone: "démosle este arnés al modelo mismo, y que el modelo evalúe si sus propias respuestas son correctas — así cerramos el círculo sin necesitar AI Engineering". ¿Qué problema tiene esa propuesta, incluso si fuera técnicamente posible dentro de esta guía?
Ver solución
El problema de fondo no es de factibilidad técnica —usar un modelo como "juez" de las respuestas de otro modelo (o del mismo modelo) es, de hecho, una técnica real y documentada, mencionada de pasada en la definición de "eval" de esta lección—. El problema es que "usar un LLM como juez, con un prompt diseñado para evaluar calidad semántica con criterio" es, precisamente, la clase de técnica de prompt engineering avanzada que el Módulo 1, lección 4 de esta guía ya nombró explícitamente como territorio de AI Engineering, no de esta guía. Construir esa pieza aquí no "cerraría el círculo sin necesitar AI Engineering" — sería, con precisión exacta, empezar a construir AI Engineering dentro de una guía que existe, deliberadamente, para no hacerlo. La respuesta correcta a la propuesta de tu compañero: "esa es una idea real, y el lugar correcto para aprenderla a fondo es el ecosistema AI Engineering, no aquí."
Resumen y siguiente paso
Esta lección definió, con precisión y sin código, qué es un eval —"inyectar datos con salidas conocidas, contar la proporción de coincidencias", citado de la misma fuente de Google SRE que ya sostuvo el resto de esta guía— y por qué esa mecánica, aplicada a un modelo de lenguaje, se divide en dos preguntas completamente independientes: ¿tiene la respuesta la forma correcta? (esta guía) y ¿tiene la respuesta el significado correcto? (AI Engineering). Viste, con un ejemplo concreto —origen y destino invertidos—, una respuesta que pasa cualquier chequeo de forma sin problema, mientras falla de manera grave en significado, la demostración más clara posible de por qué un chequeo nunca sustituye al otro.
Antes de avanzar deberías poder: citar, de memoria o cerca, la definición de "eval" de Google SRE y explicar por qué aplica aquí; construir, sin ayuda, un ejemplo de una respuesta que pasa forma pero falla significado; y explicar por qué esta guía nunca construye la mitad de "significado", incluso cuando sería técnicamente posible dentro de su alcance $0.
La lección 6 construye el arnés real: evals/manifest_extraction_smoke_test.py, sobre evals/fixtures/sample_manifests.json — la estructura de comparación corre de verdad, contra candidatos representativos etiquetados con precisión, exactamente en el lado de la línea que esta lección acaba de trazar.
Recursos
- Google — SRE Workbook, Implementing SLOs — la fuente exacta de la definición de evaluación por inyección de datos con salidas conocidas, citada en esta lección.
- Este mismo curso, Módulo 1, lección 4 (
04-the-boundary-with-ai-engineering-said-out-loud.md) — la tabla completa de la frontera con AI Engineering, que esta lección cierra con su última fila. - Este mismo curso, Módulo 4, lección 6 (
06-hands-on-the-output-schema-validator.md) — el origen depost_invoke_checks.py, la pieza de "coincidencia de forma" que esta lección contrasta con la evaluación semántica. src/paths/aws-cloud-ecosystem/STRATEGY.md— la fuente completa de la posición de esta guía en el grafo del ecosistema NIEVA, citada primero en el Módulo 1, lección 4, retomada aquí.