Módulo 7: El lazo de datos y de retroalimentación

5. Cerrar el lazo: el feedback se vuelve el eval-set

Descripción

Al terminar esta lección vas a saber hacer lo que da nombre al módulo: cerrar el lazo —tomar el feedback que capturaste y realimentarlo a algo que mejora el sistema de forma verificable—. Es el corazón del módulo porque es donde todo lo anterior cobra sentido: el flywheel (lección 2) solo gira si el lazo se cierra, la observabilidad (lección 3) solo sirve si actúas sobre lo que ves, y el feedback capturado (lección 4) es materia prima muerta hasta que la realimentas. La tesis es concreta: los casos que un usuario reportó como malos, con su corrección, se convierten en casos nuevos del eval-set —el del módulo 3— y ese eval-set aumentado atrapa regresiones que el viejo dejaba pasar. El feedback de producción deja de ser una tabla que se acumula y se vuelve la compuerta de calidad que se hace más honesta con cada fallo real que descubre.

Esto importa porque es la diferencia entre un lazo abierto y uno cerrado, y es el error más caro del módulo. Un lazo abierto captura feedback y lo deja morir en un tablero: gastas el esfuerzo de recolectar y no obtienes ninguna mejora —la caja de sugerencias que nadie lee de la lección 1—. Un lazo cerrado convierte cada thumbs_down en una mejora concreta del sistema. Y de las tres destinaciones posibles del feedback —el eval-set, el prompt, y el retrieval—, esta lección se centra en la más fundamental: el eval-set, porque es la red de seguridad. Un caso que agregas al eval-set queda vigilado para siempre: cualquier cambio futuro que vuelva a romperlo se detecta antes del deploy. Las otras dos destinaciones (prompt y retrieval) arreglan el fallo; el eval-set garantiza que no vuelva. Por eso, pase lo que pase, todo fallo reportado va primero al eval-set.

Conexión con el módulo: esta lección es donde el lazo se cierra. La lección 2 te mostró que la rueda solo gira si cierras; la 3 te dio los ojos (observabilidad); la 4 la materia prima (el feedback capturado); aquí conviertes esa materia prima en una mejora verificable. Y es el reencuentro con el módulo 3: el eval-set que allá construimos como compuerta estática, aquí se vuelve vivo —crece con la realidad—. La lección 6 abrirá las otras palancas de mejora (prompt, RAG, fine-tune) y la lección 7 enrutará cada fallo a su palanca, pero todas comparten esta red de seguridad: el fallo también va al eval-set. Cerrar el lazo hacia el eval es el gesto que hace que ninguna de las otras mejoras pueda regresar sin que la compuerta lo note.

Analogía: la lista de "nunca más" del piloto

En aviación hay una práctica que salvó incontables vidas: cada incidente —un casi-accidente, un error de procedimiento, una lectura confusa de un instrumento— se investiga, y de esa investigación sale un cambio permanente en las listas de verificación. Si un piloto casi despega con los flaps mal configurados porque una alarma no era clara, no basta con que ese piloto tenga más cuidado: se agrega un ítem a la checklist que todos los pilotos revisan antes de cada despegue, para siempre. El incidente individual se convierte en una verificación permanente. Por eso volar es cada década más seguro: la industria tiene un lazo cerrado que convierte cada fallo en una barrera que impide que ese fallo se repita.

Esa es exactamente la idea de cerrar el lazo hacia el eval-set. Un thumbs_down —un caso donde el agente de soporte respondió mal— es el "casi-accidente". No basta con que alguien arregle esa respuesta puntual (el equivalente a "ese piloto que tenga más cuidado"): eso arregla el caso de hoy pero no impide que un cambio futuro lo rompa de nuevo. Cerrar el lazo hacia el eval es agregar el ítem a la checklist permanente: el caso reportado se vuelve un caso del eval-set que toda versión futura del componente tiene que pasar antes de desplegarse. El fallo individual se convierte en una barrera permanente. Y por eso un sistema con lazo cerrado se vuelve cada vez más robusto: su eval-set acumula todos los fallos que alguna vez le pasaron, y ninguno puede volver sin que la compuerta lo detenga.

La otra cara de la analogía es la advertencia. Una aerolínea que investiga los incidentes pero no actualiza las checklists no aprende nada: los mismos accidentes se repiten, porque nada cambió en el procedimiento. Ese es el lazo abierto —capturar el fallo y no convertirlo en una barrera—, y en aviación cuesta vidas; en un sistema de IA cuesta que la calidad se degrade en silencio mientras el equipo cree que "ya tiene feedback".

Ejemplo trabajado: el feedback se vuelve casos, y la compuerta gana ojos

No vamos a decir que cerrar el lazo mejora la compuerta: lo vamos a ejecutar. Modelamos el cierre completo: tomamos el log de feedback del agente de soporte, convertimos los thumbs_down (con su corrección) en casos nuevos del eval-set, y luego corremos dos versiones candidatas del agente contra el eval-set viejo y contra el aumentado. Vas a ver el momento clave: una versión que el eval viejo aprobaba queda bloqueada por el eval aumentado, porque ahora la compuerta prueba los casos que los usuarios reportaron.

# Leccion 05 (M7) — CERRAR el lazo: el feedback se vuelve el eval-set. SIMULADO.
# Cero red, cero API, cero claves. Determinista.
#
# El lazo se "cierra" cuando el feedback REGRESA a algo que mejora el sistema.
# Aqui lo realimentamos al EVAL-SET (la compuerta de M3): los casos que el usuario
# reporto como malos se vuelven casos nuevos, y el gate deja de ser ciego a ellos.

# --- El eval-set ORIGINAL (M3): 6 casos "faciles" con criterio must_contain. ---
EVAL_SET_V1 = [
    {"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": "quiero cancelar mi pedido",  "must_contain": "cancelar"},
    {"id": "q6", "question": "como contacto a un vendedor", "must_contain": "mensajes"},
]

# --- El log de feedback de produccion: los thumbs_down traen la CORRECCION del humano
#     (el dato correcto que debio darse). Esa correccion es el criterio del caso nuevo. ---
FEEDBACK_LOG = [
    {"input": "el producto llego roto", "thumbs": "down", "correction": "reembolso"},
    {"input": "mi cupon no funciona",   "thumbs": "down", "correction": "vigencia"},
    {"input": "no recibi mi factura",   "thumbs": "down", "correction": "correo"},
    {"input": "como cambio mi direccion", "thumbs": "down", "correction": "perfil"},
    {"input": "donde esta mi pedido",   "thumbs": "up",   "correction": None},   # up: no genera caso
]

def feedback_to_eval_cases(log, start=1):
    # La conversion: cada thumbs_down con correccion se vuelve un caso del eval-set.
    # input -> question ; correction -> must_contain (el criterio de exito).
    cases = []
    for i, r in enumerate(log, start=start):
        if r["thumbs"] == "down" and r["correction"]:
            cases.append({"id": f"fb{i}", "question": r["input"], "must_contain": r["correction"]})
    return cases

new_cases = feedback_to_eval_cases(FEEDBACK_LOG)
EVAL_SET_V2 = EVAL_SET_V1 + new_cases

print("=== Cerrar el lazo: feedback -> casos del eval-set ===")
print(f"  eval-set v1        : {len(EVAL_SET_V1)} casos")
print(f"  thumbs_down -> casos: {len(new_cases)}  {[c['id'] for c in new_cases]}")
print(f"  eval-set v2        : {len(EVAL_SET_V2)} casos  (cobertura +{len(new_cases)})")
print()

# --- Dos versiones candidatas del agente, simuladas con stubs deterministas. ---
# "known" = el conjunto de inputs que la version responde bien.
FACIL = {"donde esta mi pedido", "como devuelvo un producto", "cuanto tarda el envio",
         "puedo pagar en cuotas", "quiero cancelar mi pedido", "como contacto a un vendedor"}
REPORTADOS = {"el producto llego roto", "mi cupon no funciona",
              "no recibi mi factura", "como cambio mi direccion"}

GOLD = {
    "donde esta mi pedido": "Puedes ver el tracking en tu perfil.",
    "como devuelvo un producto": "Para una devolucion, entra a tu pedido.",
    "cuanto tarda el envio": "El envio tarda de 3 a 5 dias habiles.",
    "puedo pagar en cuotas": "Puedes pagar en cuotas sin interes.",
    "quiero cancelar mi pedido": "Puedes cancelar el pedido si no fue enviado.",
    "como contacto a un vendedor": "Escribe al vendedor desde Mensajes.",
    "el producto llego roto": "Puedes pedir un reembolso desde el pedido.",
    "mi cupon no funciona": "Revisa la vigencia del cupon; quiza expiro.",
    "no recibi mi factura": "Te reenviamos la factura al correo de tu cuenta.",
    "como cambio mi direccion": "Cambia tu direccion en la seccion Perfil.",
}
POOR = "Lo siento, no tengo informacion sobre eso."

def make_agent(known):
    def agent(question):
        return GOLD[question] if question in known else POOR
    return agent

# Version MEJORADA: aprendio los casos reportados (el equipo arreglo el prompt).
improved = make_agent(FACIL | REPORTADOS)
# Version BARATA: un modelo mas economico (cascade M2). Responde bien los casos
# comunes (roza el umbral en el eval viejo) pero NUNCA aprendio los reportados.
cheaper = make_agent(FACIL - {"como contacto a un vendedor"})

def run_eval(agent, eval_set):
    passed = sum(c["must_contain"] in agent(c["question"]).lower() for c in eval_set)
    return passed, len(eval_set), passed / len(eval_set)

THRESHOLD = 0.80
def show(name, agent):
    p1, n1, s1 = run_eval(agent, EVAL_SET_V1)
    p2, n2, s2 = run_eval(agent, EVAL_SET_V2)
    g1 = "PASS" if s1 >= THRESHOLD else "FAIL"
    g2 = "PASS" if s2 >= THRESHOLD else "FAIL"
    print(f"  {name}")
    print(f"     vs eval-set v1 (viejo)   : {p1}/{n1} = {s1:.2f}  [{g1}]")
    print(f"     vs eval-set v2 (aumentado): {p2}/{n2} = {s2:.2f}  [{g2}]")

print(f"=== El gate con el eval-set viejo vs el aumentado (umbral {THRESHOLD:.2f}) ===")
show("version MEJORADA (aprendio del feedback)", improved)
show("version BARATA (modelo economico, no aprendio los reportados)", cheaper)
print()
print("La leccion en un renglon:")
print("  la version BARATA PASA el eval-set viejo (0.83) pero FALLA el aumentado (0.50).")
print("  Sin cerrar el lazo, esa version ciega a los casos reportados se habria")
print("  desplegado. El feedback convertido en casos le dio OJOS a la compuerta.")

Qué esperar. Al correrlo, la salida es exactamente esta:

=== Cerrar el lazo: feedback -> casos del eval-set ===
  eval-set v1        : 6 casos
  thumbs_down -> casos: 4  ['fb1', 'fb2', 'fb3', 'fb4']
  eval-set v2        : 10 casos  (cobertura +4)

=== El gate con el eval-set viejo vs el aumentado (umbral 0.80) ===
  version MEJORADA (aprendio del feedback)
     vs eval-set v1 (viejo)   : 6/6 = 1.00  [PASS]
     vs eval-set v2 (aumentado): 10/10 = 1.00  [PASS]
  version BARATA (modelo economico, no aprendio los reportados)
     vs eval-set v1 (viejo)   : 5/6 = 0.83  [PASS]
     vs eval-set v2 (aumentado): 5/10 = 0.50  [FAIL]

La leccion en un renglon:
  la version BARATA PASA el eval-set viejo (0.83) pero FALLA el aumentado (0.50).
  Sin cerrar el lazo, esa version ciega a los casos reportados se habria
  desplegado. El feedback convertido en casos le dio OJOS a la compuerta.

Lee el resultado en dos partes, porque cada una es media lección.

Parte 1: la conversión mecánica de feedback a casos. El feedback log tenía cinco entradas: cuatro thumbs_down (con su corrección) y un thumbs_up. La función feedback_to_eval_cases convierte solo los thumbs_down en casos —el thumbs_up no genera caso, porque un acierto no es un fallo que vigilar—, y la conversión es directa: el input del usuario se vuelve la question, y la corrección se vuelve el must_contain (el criterio de éxito). Así, "el producto llegó roto" con corrección "reembolso" se vuelve un caso que prueba: ¿la respuesta del agente contiene "reembolso"? El eval-set pasó de 6 casos a 10. Fíjate en lo elegante del mecanismo: la corrección que el agente humano hizo en producción —el dato correcto que el modelo debió dar— es exactamente el criterio de éxito del caso nuevo. El humano, al corregir, ya te dio la clave de respuestas.

Parte 2: la compuerta gana ojos. Aquí está el golpe. Se prueban dos versiones candidatas contra los dos eval-sets. La versión mejorada —que aprendió los casos reportados— pasa las dos (1.00 y 1.00): correcto, es una buena versión y las dos compuertas lo confirman. Pero mira la versión barata —un modelo más económico que responde bien los casos comunes pero nunca aprendió los reportados—. Contra el eval-set viejo, saca 0.83: PASA (roza el umbral, pero pasa). Contra el eval-set aumentado, saca 0.50: FALLA. Es la misma versión, con dos veredictos opuestos, y el que importa es el del aumentado, porque prueba los casos que los usuarios de verdad tuvieron. Sin cerrar el lazo, esta versión barata —ciega a los cuatro fallos que los clientes reportaron— se habría desplegado con la bendición del eval viejo. El feedback convertido en casos es lo que le dio a la compuerta los ojos para verla.

Detente en la asimetría, porque es la razón de ser de la lección: el eval viejo tenía un punto ciego exactamente en los casos donde los usuarios se quejaban, y por eso daba una falsa tranquilidad. Cerrar el lazo no hace la compuerta más estricta por capricho; la hace honesta, porque le agrega justo los casos que la realidad demostró que fallan. Un eval-set que solo prueba lo que ya funciona es un examen que solo pregunta lo que ya sabes: siempre apruebas, y no significa nada.

Las tres destinaciones del feedback (y por qué el eval va primero)

El ejemplo cerró el lazo hacia el eval-set, pero el feedback tiene tres destinaciones posibles, y un buen lazo usa las tres. Vale la pena verlas, y entender por qué el eval siempre va primero.

Destinación 1: el eval-set (la red de seguridad). Todo fallo reportado se convierte en un caso del eval-set. Esto no arregla el fallo —el caso nuevo, al principio, lo va a fallar la versión actual— pero garantiza que, una vez arreglado, no pueda regresar sin que la compuerta lo note. Es la lista de "nunca más" del piloto: el caso queda vigilado para siempre. Por eso el eval va primero: es la barrera permanente, independiente de cómo arregles el fallo. Un fallo que solo arreglas en el prompt pero no metes al eval puede volver el día que alguien cambie el prompt de nuevo.

Destinación 2: el prompt (el arreglo rápido). Muchos fallos se arreglan ajustando el prompt: agregar una instrucción ("si el cliente dice que el producto llegó roto, ofrece un reembolso"), agregar un ejemplo (few-shot) del caso que fallaba, o aclarar el formato esperado. Es la palanca más barata y reversible (lección 6), y suele ser el primer intento. La corrección que capturaste en el feedback se puede convertir en un ejemplo few-shot casi directamente. Frontera: cómo se diseña un buen prompt es AI Engineering; aquí, que el feedback alimenta el prompt.

Destinación 3: el retrieval (cuando falta información). Si el fallo es que el modelo no tenía la información —no sabía la política de garantía porque ese documento no estaba en su contexto—, la destinación correcta es el retrieval (RAG): agregar el documento faltante al índice para que se recupere la próxima vez. La corrección del feedback te dice qué información faltaba. Frontera: cómo se construye el índice de RAG es AI Engineering; aquí, que el feedback señala qué agregar.

La lección 7 es justo sobre enrutar cada fallo a la destinación correcta (¿lo arreglo en el prompt, en el retrieval, o considero fine-tune?). Pero la regla que atraviesa las tres, y que se instala aquí, es: cualquiera que sea la destinación del arreglo, el caso también va al eval-set. El eval es la red de seguridad que hace verificable cualquier arreglo —después de mejorar el prompt o el retrieval, corres el eval aumentado y confirmas que el caso ahora pasa y que no rompiste ningún otro—. Sin esa red, no sabes si tu arreglo funcionó ni si causó una regresión en otro lado.

Errores comunes

No cerrar el lazo: capturar feedback y nunca usarlo (de proceso). Qué pasa: es el error más caro del módulo. El equipo captura thumbs_down —tiene la observabilidad, tiene el feedback loop— pero los datos se acumulan en una tabla que nadie convierte en mejoras. Ni un thumbs_down se volvió caso de eval, ni ajuste de prompt, ni documento de retrieval. Es la aerolínea que investiga los incidentes pero no actualiza las checklists: los mismos fallos se repiten. Por qué pasa: capturar es visible (aparece un botón); cerrar es trabajo invisible de arquitectura que compite por prioridad y siempre pierde. Cómo detectarlo: si tienes un mes de feedback y tu eval-set no creció, tu lazo está abierto. Cómo corregirlo: haz de la conversión feedback→eval una rutina (idealmente automatizada): cada thumbs_down con corrección se vuelve un caso candidato del eval-set. La lección 7 arma el flujo completo.

Arreglar el caso puntual sin agregarlo al eval-set (de omisión). Qué pasa: el equipo ve un thumbs_down, arregla la respuesta en el prompt, y da el caso por cerrado —sin agregarlo al eval-set—. El fallo se arregló hoy, pero como no quedó en la compuerta, un cambio futuro (otro ajuste de prompt, un modelo más barato) lo rompe de nuevo, y nadie se entera hasta que un cliente vuelve a quejarse del mismo problema. Es "que ese piloto tenga más cuidado" en vez de agregar el ítem a la checklist de todos. Por qué pasa: arreglar el prompt se siente como resolver el problema; agregar el caso al eval es un paso extra que parece redundante ("ya lo arreglé"). Cómo detectarlo: si tus arreglos de fallos reportados no dejan un caso nuevo en el eval-set, no tienes protección contra la regresión. Cómo corregirlo: la regla dura —todo fallo reportado va al eval-set primero, se arregle donde se arregle—; el eval es lo que impide que el fallo vuelva.

Meter el thumbs_up al eval como "caso que pasa" y inflar el score (de método). Qué pasa: en el afán de "usar todo el feedback", el equipo convierte también los thumbs_up en casos del eval-set. Como esos casos ya pasan (por eso recibieron up), inflan el score artificialmente: el eval-set se llena de casos fáciles que el componente ya resuelve, y el score sube sin que la calidad real mejore —el examen se vuelve más fácil, no el alumno más listo—. Por qué pasa: parece lógico "aprovechar todo el feedback", y un score más alto se siente como progreso. Cómo detectarlo: si tu eval-set crece pero se llena de casos que siempre pasan, tu score sube sin significar nada. Cómo corregirlo: al eval-set van los casos que fallaron (los thumbs_down con corrección), porque son los que revelan puntos ciegos; los aciertos no agregan información de calidad. (Elegir cuántos y cuáles casos para mantener el eval-set representativo es diseño de evals, AI Engineering; la regla simple de aquí es: los fallos entran, los aciertos no inflan.)

Ejercicios

Ejercicio 1 — La lista de "nunca más". Explica, con la analogía de la aviación, por qué arreglar un thumbs_down solo en el prompt (sin agregarlo al eval-set) es como decirle a un piloto "ten más cuidado" en vez de actualizar la checklist. Luego di qué garantiza el eval-set que el arreglo en el prompt por sí solo no garantiza.

Ver solución

Arreglar un thumbs_down solo en el prompt es como "que ese piloto tenga más cuidado" porque arregla el caso de hoy pero no crea una barrera permanente. En aviación, pedirle cuidado a un piloto no impide que otro (o el mismo, en un mal día) cometa el mismo error mañana; solo actualizar la checklist que todos revisan convierte el incidente en una protección duradera. Con el prompt igual: ajustaste el prompt para que hoy responda bien "el producto llegó roto", pero nada impide que un cambio futuro —otro ajuste, un modelo más barato— vuelva a romper ese caso. El arreglo es real, pero es frágil y temporal.

Lo que el eval-set garantiza y el prompt por sí solo no: que el fallo no pueda regresar sin ser detectado. Al agregar el caso al eval-set, cualquier versión futura del componente tiene que pasar ese caso antes de desplegarse; si un cambio lo rompe, la compuerta lo bloquea (como viste con la versión barata: 0.50, FAIL). El prompt arregla; el eval-set protege. Por eso la regla es: el fallo va al eval-set primero, y luego lo arreglas donde corresponda —el eval es la checklist permanente, el prompt es el arreglo del vuelo de hoy—.

Ejercicio 2 — Los dos veredictos de la versión barata. En el ejemplo, la versión barata sacó 0.83 (PASS) contra el eval viejo y 0.50 (FAIL) contra el aumentado. Explica por qué el veredicto del eval aumentado es el correcto, y qué habría pasado en producción si el equipo hubiera desplegado esta versión confiando en el eval viejo.

Ver solución

El veredicto del eval aumentado (0.50, FAIL) es el correcto porque prueba los casos que los usuarios de verdad tuvieron y reportaron como malos —"el producto llegó roto", "el cupón no funciona", "no recibí la factura", "cómo cambio mi dirección"—. La versión barata falla exactamente esos casos (nunca los aprendió), y esos casos son parte real del tráfico. El eval viejo daba 0.83 (PASS) solo porque no probaba esos casos: su score alto era una falsa tranquilidad producida por un punto ciego, no por calidad. Un examen que no incluye las preguntas que reprobarías te da una nota alta que no significa nada.

Si el equipo hubiera desplegado la versión barata confiando en el eval viejo, en producción habría pasado esto: los casos comunes (tracking, envío, cuotas) seguirían funcionando —por eso el eval viejo la aprobó—, pero cada cliente que preguntara por un producto roto, un cupón vencido, una factura o un cambio de dirección recibiría una respuesta mala ("Lo siento, no tengo información sobre eso"). El approval_rate en vivo caería, los thumbs_down se acumularían, y el equipo descubriría el problema por las quejas —semanas después—, cuando el eval aumentado lo habría bloqueado antes del deploy. Cerrar el lazo convirtió una regresión invisible-hasta-las-quejas en una regresión atrapada-antes-del-deploy. Ese es todo el valor.

Ejercicio 3 — ¿A qué destinación va cada fallo? Para cada uno de estos fallos reportados del agente de soporte, di a qué destinación del feedback lo enrutarías principalmente (prompt, retrieval, o considerar fine-tune) y por qué, y confirma qué destinación reciben todos sin excepción. (a) El agente responde correcto pero siempre en un tono demasiado seco, sin saludar. (b) El agente no sabe la política de garantía de productos reacondicionados porque ese documento no está en su contexto. (c) El agente inventa números de guía de envío que no existen.

Ver solución
  • (a) Tono seco, sin saludar → el prompt. Es un problema de instrucción/formato, sistemático y transversal a muchas respuestas. Se arregla agregando una instrucción de tono al prompt ("saluda y usa un tono cálido"). Es la palanca más barata y reversible. No necesita ni retrieval (no falta información) ni fine-tune (es un ajuste simple de instrucción).
  • (b) No sabe la política de garantía porque falta el documento → el retrieval (RAG). El problema es que falta información en el contexto del modelo, no que el modelo razone mal. La destinación correcta es agregar el documento de garantía al índice de retrieval para que se recupere cuando aplique. Meter toda la política de garantía en el prompt fijo no escala si hay muchas políticas; recuperarla cuando se necesita, sí.
  • (c) Inventa números de guía (alucinación de datos) → esto es guardrail/verificación (módulo 4/5) más que una palanca de mejora del lazo. El arreglo de fondo es no dejar que el modelo afirme un número de guía sin verificarlo contra la fuente de verdad (verificación, módulo 5) y validar la salida (guardrail, módulo 4). El feedback del lazo aquí sirve para detectar el problema, pero la solución es de contención, no de prompt/retrieval/fine-tune. (Si el patrón fuera "el modelo no distingue cuándo tiene el dato", un ajuste de prompt para que diga "déjame verificar" ayuda —así que hay un componente de prompt—.)

Y la destinación que reciben todos sin excepción: el eval-set. Cada uno de los tres fallos se convierte en un caso del eval-set (con el criterio apropiado: tono para a, presencia de la política correcta para b, ausencia de un número inventado para c), para que ninguno pueda regresar sin ser detectado. La palanca de arreglo cambia según el fallo; la red de seguridad del eval es universal.

Resumen y siguiente paso

En esta lección aprendiste a cerrar el lazo, el corazón del módulo: los casos que un usuario reportó como malos, con su corrección, se convierten en casos nuevos del eval-set —el del módulo 3—, y ese eval-set aumentado atrapa regresiones que el viejo dejaba pasar. Lo viste con la analogía de la lista de "nunca más" de la aviación —cada incidente se vuelve una verificación permanente que impide que ese fallo se repita— y lo mediste: el feedback convirtió 4 thumbs_down en 4 casos nuevos (el eval-set creció de 6 a 10), y una versión barata que el eval viejo aprobaba (0.83) el eval aumentado la bloqueó (0.50), porque ahora la compuerta prueba los casos que los usuarios reportaron. Entendiste las tres destinaciones del feedback —eval-set, prompt, retrieval— y la regla que las atraviesa: cualquiera que sea el arreglo, el caso también va al eval-set, que es la red de seguridad que hace verificable cualquier mejora.

Antes de avanzar deberías poder: explicar la conversión mecánica de feedback a casos de eval (input → question, corrección → criterio); explicar por qué el eval aumentado es más honesto (no más estricto por capricho); nombrar las tres destinaciones del feedback y por qué el eval va primero; y reconocer el error más caro (capturar y no cerrar) y sus dos variantes (arreglar sin agregar al eval; inflar el eval con aciertos).

Lo que sigue es abrir las palancas de mejora que las destinaciones 2 y 3 anticiparon. Cuando el feedback te dice que el componente falla, ¿ajustas el prompt, montas un RAG, o entrenas un fine-tune? En la lección 6 vas a ver esas tres opciones como una decisión arquitectónica: cada una tiene un perfil distinto de latencia, costo, frescura de datos y mantenimiento, y elegir mal —saltar a fine-tune cuando el prompt bastaba— es un error caro. Vas a ejecutar la comparación y un recomendador que elige por feature. Es el paso de "cerré el lazo hacia el eval" a "sé qué palanca mover para arreglar lo que el eval reveló, y qué implica cada una".

Recursos

  • Chip Huyen — AI Engineering (O'Reilly) — el tratamiento de cómo el feedback de producción se convierte en datos de evaluación y de mejora; el respaldo conceptual de convertir fallos reportados en casos de eval (la mecánica de diseñar el eval-set representativo es su frontera).
  • Chip Huyen — Designing Machine Learning Systems (O'Reilly) — el capítulo sobre feedback loops y evaluación continua trata el cierre del lazo como el mecanismo que mantiene un sistema de ML sano en producción; el marco de esta lección.
  • Anthropic — docs de Claude, evaluación de aplicaciones — la guía conceptual de construir y hacer crecer un conjunto de casos de evaluación a partir de fallos reales; sin fijar versión de modelo. En inglés.
  • architecture-decisions-and-tradeoffs-guide — Fitness functions — el eval como fitness function que gobierna la calidad; esta lección lo vuelve vivo (crece con el feedback), pero el concepto raíz de la fitness function que se mantiene con el tiempo está allá.
  • Ecosistema AI Engineering (remisión) — para el diseño del eval-set (qué casos, cuántos, cómo mantenerlo representativo a medida que el feedback lo hace crecer); este módulo cierra el lazo hacia el eval, AI Engineering diseña el conjunto.