Debuggear evals: cuando el número miente, y cómo confirmarlo
El eval dio verde y producción está peor. O el judge puntúa alto y tus revisores no coinciden. O un upgrade de model que no podías ver hundió la calidad. Un eval engañoso es peor que no tener eval — es un tilde verde en el que confiaste. El playbook por síntoma para tres formas en que un eval miente: pasa offline pero producción está peor (distribution shift, un set viejo, leakage que infla el puntaje), el LLM-judge no coincide con humanos (un rubric vago, un judge sin calibrar, un sesgo de posición/verbosidad/auto-preferencia), y un upgrade de model-o-prompt regresionó la calidad en silencio sin gate que lo cace. Cada una con el síntoma, qué está realmente mal, cómo confirmarlo, y el arreglo. El hilo: cada una es más barata de debuggear cuando ya tenías el eval set y los traces — debuggear un eval es sobre todo 'tenías la medición antes de necesitarla.'
Un eval se supone que es eso en lo que confiás en vez de una sensación — un número que podés puntuar, comparar y defender (qué es evaluation). Así que un eval engañoso es una clase especial de caro: es peor que no tener eval, porque no tener eval te vuelve cauto y un tilde verde te vuelve confiado, y confiado-y-equivocado es como se lanza una regresión. Cuando el eval y la realidad no coinciden, el instinto es discutirle a la realidad — producción son "solo edge cases", los revisores son "demasiado quisquillosos", el upgrade "debería estar bien". Ese instinto es el bug. El eval es una medición, y una medición que no coincide con el mundo es una medición para arreglar, no un mundo para descartar.
Esta página es por síntoma, la misma forma que debuggear prompts: encontrá la falla que coincide con lo que estás viendo, confirmá qué está realmente mal antes de tocar nada, y arreglá el eval para que la mentira no pueda repetirse. Asume que tenés los dos activos sobre los que está construida toda la subcategoría — un eval set y un trace de lo que producción de verdad hizo — porque el paso de confirmación en cada flujo de abajo es "andá a mirar datos reales", y sin el set y los traces no tenés nada que mirar. Esa dependencia es el hilo, así que vale decirlo de entrada: debuggear un eval es sobre todo una prueba de si tenías la medición en su lugar antes de necesitarla. Nada de esto depende del toolkit — un agente de Agentforce puntuado en Testing Center, una llamada a Claude puntuada contra un eval de Anthropic, o un grafo off-platform evaluado en LangSmith mienten todos en las mismas tres formas.
"Pasa offline pero producción está peor"
Cómo reconocerlo. El eval offline está verde — el set pasa, el puntaje está donde lo querés — y el sistema vivo está visiblemente peor: más quejas, más escalaciones, más respuestas que no habrías lanzado. El laboratorio dice bien y el campo dice roto, y la brecha entre los dos es todo el problema.
Qué está realmente mal. Offline no es online, y la brecha tiene tres causas habituales. Primero, distribution shift: tu eval set ya no coincide con el tráfico. LangSmith traza esta línea exacto — la evaluación offline corre contra "datasets with reference outputs", la evaluación online corre sobre "real production traces without reference outputs" — y si la distribución de producción derivó lejos del set, el set está puntuando un mundo que ya no existe. Segundo, un set viejo o no representativo: se construyó con casos limpios de camino feliz y nunca se surtió con los edge cases que producción de verdad manda — los casos de "irrelevant or nonexistent input", "overly long input" y "ambiguous" que la guía de diseño de evals de Anthropic dice tener en cuenta y que los demos nunca ven. Tercero, leakage que infla el puntaje: el eval set se solapa con los propios examples del prompt, o con un caso sobre el que el model fue efectivamente tuneado, así que el set testea recall de algo ya visto en vez de performance sobre algo nuevo — y el puntaje está alto por la razón equivocada.
Cómo confirmarlo. Dejá de razonar sobre esto y andá a mirar producción. Muestreá traces reales — un puñado estratificado a través del tráfico que de verdad servís, no los tres que dispararon la queja — y puntualos a mano con el mismo rubric que usa el eval offline. Dos resultados, y apuntan a lados opuestos. Si los traces de producción muestreados puntúan peor que el set offline, la brecha es real y es distribución o vejez — tu set no está testeando lo que producción manda. Si los traces muestreados puntúan más o menos igual que el set offline pero los usuarios siguen descontentos, la brecha está en tus criterios, no en tu set — estás midiendo lo equivocado, y eso es un problema de qué es evaluation (tus success criteria no capturan qué significa "bueno" para un usuario), no de debuggear el set.
El arreglo. Devolvé las fallas reales al set. Los traces de producción que puntuaron mal son los casos más valiosos que vas a agregar nunca, porque codifican las formas en que tu sistema de verdad se rompe en la cancha — etiquetalos con su resultado conocido-bueno y se vuelven casos de regresión permanentes (eval datasets and metrics). Este es el loop que cierra la brecha offline-online: producción saca a la luz una falla, la falla se vuelve un caso offline, y el próximo cambio que la reintroduciría ahora dispara un caso rojo en el laboratorio en vez de una queja en el campo. Hacelo continuamente, no una vez — la distribución sigue derivando, así que un set que espeja la realidad este trimestre está viejo para el próximo a menos que los traces sigan volviendo. Y si el paso de confirmación apuntó a leakage, el arreglo es un split held-out limpio: casos que el prompt nunca vio, separados de cualquier cosa sobre la que el sistema fue tuneado, para que el puntaje mida generalización en vez de memoria.
"El LLM-judge no coincide con humanos"
Cómo reconocerlo. Tu LLM-as-judge puntúa alto la salida, y los humanos que leen la misma salida no coinciden — los revisores marcan respuestas que el judge pasó, o pasan respuestas que el judge falló. El grader y la gente a la que se supone que reemplaza divergieron, lo que significa que los diez mil puntajes del judge están midiendo otra cosa que calidad.
Qué está realmente mal. Un judge que no coincide con humanos está sin calibrar, y hay tres razones habituales. Primero, un rubric vago: "puntuá la calidad" no le da al judge nada concreto que chequear, así que deriva, y un rubric que deriva produce un puntaje que deriva — la vara de Anthropic es un rubric específico al punto de ser mecánico ("la respuesta debe mencionar 'Acme Inc.' en la primera oración; si no, puntuala incorrecta"). Segundo, un judge sin calibrar en sentido literal: nadie lo chequeó nunca contra labels humanos, así que "el judge dice 4 de 5" jamás se confirmó que signifique lo que un humano quiere decir con 4 de 5 — es un número que decidiste creer. Tercero, un sesgo del judge que no tiene nada que ver con el rubric: sesgo de posición (favorecer la salida que vino primero en una comparación), sesgo de verbosidad (leer más largo como mejor), o sesgo de auto-preferencia (favorecer salida en el estilo de su propio model) — los modos de falla cubiertos en LLM-as-judge, cada uno de los cuales hace que el puntaje parezca plausible mientras está mal.
Cómo confirmarlo. Re-puntuá una muestra etiquetada por humanos y medí el acuerdo directamente. Tomá un set de casos que los humanos puntuaron, corré el judge sobre esos mismos casos, y compará veredicto-a-veredicto — ¿dónde divergen, y la divergencia tiene patrón? El patrón nombra la causa: si el judge premia consistentemente la respuesta más larga, es sesgo de verbosidad; si se da vuelta cuando intercambiás el orden de dos salidas comparadas, es sesgo de posición; si favorece la respuesta escrita en la prosa de su propia familia, es auto-preferencia; si el desacuerdo está disperso sin patrón, el rubric es demasiado vago para puntuar consistente y el judge está adivinando. La muestra etiquetada por humanos es el instrumento acá — sin ella solo podés sospechar que el judge está mal, nunca confirmar dónde.
El arreglo. Arreglá el rubric, no los humanos. El reflejo cuando un judge no coincide con la gente es "recalibrar" empujando el rubric hacia el puntaje que querías — eso es ajustar el grader a una idea preconcebida, y corrompe el eval. La disciplina corre al revés: los humanos son la fuente de verdad, así que cambiás el judge hasta que los siga. Ajustá el rubric hasta que sea lo bastante mecánico como para que un humano cuidadoso y el judge lleguen al mismo veredicto; fijá la escala para que "4" y "5" tengan una diferencia declarada y chequeable en vez de una sensación; puntuá con un model distinto del que produjo la salida (la nota permanente de Anthropic — "best practice to use a different model to evaluate than the model used to generate the evaluated output" — que saca la auto-preferencia de raíz); y para el sesgo de posición, intercambiá el orden y solo confiá en veredictos que sobreviven el intercambio. Después re-chequeá contra la muestra humana. Un judge es confiable solo después de que coincide con humanos sobre casos que de verdad verificaste — y "confiable" no es un sello de una sola vez, así que recalibrá cuando el rubric cambia o la tarea juzgada deriva.
"Un upgrade de model (o prompt) hundió la calidad"
Cómo reconocerlo. Algo cambió — saltó una versión de model, se editó un prompt, se cambió un retriever — y la calidad cayó, pero nada obvio lo marcó. El cambio parecía seguro, se lanzó en silencio, y la degradación apareció río abajo como peor salida que nadie conectó de vuelta al upgrade. Esta es la regresión silenciosa, y lo que la hace peligrosa es justamente que nada se puso rojo cuando pasó.
Qué está realmente mal. No había gate de regresión. Un cambio llegó a producción sin ser puntuado contra un eval set congelado primero, así que una caída de calidad que una sola corrida de eval habría cazado se lanzó a fe y salió a la luz como una queja. LangSmith nombra esta categoría directo — "regression testing" y "backtesting" son trabajos de evaluación offline, la comparación de una versión nueva contra un baseline conocido sobre un set fijo — y todo el punto de un eval offline es que corre antes de que el cambio esté vivo. Una regresión que llega a producción es, por definición, una regresión que se salteó el gate.
Cómo confirmarlo. Corré el eval set congelado contra ambas versiones y leé el diff. Mantené el set fijo y puntuá el antes y el después — LangSmith captura cada corrida como un "experiment" y "supports comparing multiple experiments side-by-side", que es exactamente la lectura antes-versus-después que necesitás — y los casos que cayeron te dicen dónde vive la regresión. Después bisectá la causa: si una versión de model y un edit de prompt se lanzaron juntos, no podés decir cuál lastimó hasta separarlos, así que corré el model viejo contra el prompt nuevo y el model nuevo contra el prompt viejo. La combinación que recupere el puntaje aísla al culpable — el cambio de prompt está ajustado al model viejo y no se transfirió, o el upgrade de model lee el prompt existente distinto. El set congelado es lo que hace significativo al diff: cambiá el set y el cambio al mismo tiempo y no podés atribuir la caída a ninguno, por lo que el set tiene que estar versionado y mantenido constante a través de la comparación (eval datasets and metrics).
El arreglo. Hacé del eval set un gate pre-merge para que esto no pueda volver a llegar a producción. El arreglo de una sola vez es re-tunear contra el set sobre la versión nueva hasta que el puntaje se recupere; el arreglo permanente es estructural — el eval set corre automáticamente en cada salto de model, edit de prompt y cambio de retriever antes de que mergee, y una caída por debajo del baseline bloquea el cambio. Eso convierte "el upgrade lo empeoró en silencio, y un usuario se enteró por nosotros" en "un caso rojo bloqueó el merge, y nos enteramos antes de que nadie lanzara". Esta es la red de regresión a la que apunta toda la subcategoría: los agentes que construís, el retrieval que tuneás, los prompts que endurecés se mantienen correctos solo porque un cambio que los rompería dispara un gate primero. Un eval set que no gatea nada es documentación; un eval set cableado al merge es lo que evita que la regresión silenciosa sea silenciosa alguna vez.
El hilo
Tres formas en que un eval miente — pasa-offline-pero-producción-peor, el-judge-no-coincide-con-humanos, el-upgrade-hundió-la-calidad — y un hecho debajo de las tres: cada una es más barata de debuggear cuando la medición ya estaba en su lugar. La brecha offline-online cierra solo si tenés traces de producción para muestrear y un set al que devolverlos. El desacuerdo del judge se resuelve solo si tenés una muestra etiquetada por humanos contra la cual calibrar. La regresión silenciosa se caza solo si un eval set congelado ya estaba gateando el merge. Debuggear un eval es, casi por completo, una prueba de si construiste la medición antes de necesitarla — el equipo que lo hizo está muestreando traces y leyendo un diff para el mediodía; el equipo que no, está reconstruyendo qué pasó desde la memoria y una queja. Por eso esta subcategoría pone adelante el eval set y los traces: no como burocracia, sino porque son los instrumentos con los que debuggeás, y no podés instalarlos después de la falla para la que los necesitabas. Evaluá antes de lanzar, trazá todo, y un eval engañoso se vuelve algo que confirmás y arreglás en una tarde en vez de un misterio sobre el que discutís una semana.
Si un eval engañó a tu equipo en una forma que no está acá, escribí a hello@wearecleon.com — la agregamos, con crédito.
Related
- Qué es evaluation — el loop y el split offline/online que estas fallas rompen
- Eval datasets and metrics — el set al que devolvés fallas, versionás, y congelás para el gate
- LLM-as-judge — el rubric, la calibración, y los sesgos detrás del flujo del judge-no-coincide
- Evaluation gotchas — los modos de falla que esta página operacionaliza, cada uno con la pregunta a hacer primero
- Testing y observabilidad de Agentforce — donde corrés casos y leés producción para un agente on-platform
- Tracing y monitoring — los traces de producción de los que depende el paso de confirmación en cada flujo
- Debuggear prompts — el mismo método por síntoma una capa abajo, para el prompt mismo
- Debuggear grounding — cuando la respuesta mala es un miss de retrieval, no de eval
- Principios de AI Engineering — evaluá antes de lanzar (4), trazá todo (11), un demo no es un producto (1)
Reference: