SEXTANTEcursos técnicos de IA
métodobackward-design
árbitroel dato
Entrar
N2 · LLM-as-judge calibrado/L2

Anatomía de un LLM-as-judge

Objetivo de maestría

diseñarás un LLM-as-judge para el fallo nº1 de Aurora tomando las cuatro decisiones que lo definen: modo, referencia, escala y modelo juez. Justificarás por qué aquí es pointwise, reference-free, binario y con un juez a la altura del evaluado. Sin estas decisiones, tu juez es otra vibe con decimales.


2.1El "puntúa del 1 al 10" que no decide nada

En L1 cerraste una decisión: el fallo nº1 de Aurora —"el agente responde sobre la política sin que el chunk recuperado lo respalde"— necesita un juez. Un regex no captura "está fundamentado". Ese fallo es semántico, no mecánico.

Así que abres un notebook y escribes el primer prompt que se te ocurre:

text
1Puntúa del 1 al 10 cómo de buena es esta respuesta de soporte.

Lo corres sobre 20 trazas reales del agente. Obtienes esto:

text
1traza 01 → 7        traza 06 → 8        traza 11 → 7
2traza 02 → 8        traza 07 → 6        traza 12 → 9
3traza 03 → 6        traza 08 → 7        traza 13 → 7
4traza 04 → 7        traza 09 → 8        traza 14 → 8
5...

Ahora mírate fijamente esa columna. ¿Un 7 es aprobado? ¿Un 6 te preocupa? La traza 12 sacó un 9: ¿es mejor de verdad que la 07 con un 6, o el modelo repartió números sin un criterio estable?

No lo sabes. Y ahí está el problema. La diferencia entre un 7 y un 8 puede ser señal o puede ser ruido del modelo, y no tienes forma de distinguirlos. Acabas de construir, sin querer, otra vibe —una corazonada disfrazada de medición—, esta vez con decimales.

El juez no falló por el modelo. Falló por el diseño. Antes de escribir un solo prompt, hay cuatro decisiones que deciden si tu juez mide o adivina.


2.2Qué vas a poder hacer

Al terminar esta lección sabrás:

  • Tomar las cuatro decisiones de diseño de un LLM-as-judge: modo (pointwise/pairwise/listwise), referencia (reference-based/reference-free), escala (binario/Likert) y modelo juez.
  • Justificar por qué para el fallo nº1 de Aurora la combinación correcta es pointwise, reference-free, binario y con un juez a la altura del evaluado.
  • Detectar en un prompt de juez ajeno cuál de las cuatro decisiones está mal tomada, y corregirla.

Necesitas saber antes:

  • La decisión código-vs-juez de N2·L1: por qué el fallo nº1 cae del lado del juez.
  • Que en N1 produjiste un dataset etiquetado (casos +/−) sobre las trazas del agente.
  • Qué captura una traza explotable (de N0·L1): la respuesta del agente y el chunk recuperado.

Esta lección diseña el juez; no lo valida. Medir si juzga como un humano es el trabajo de N2·L3. Un juez bien diseñado pero sin validar sigue siendo una opinión automatizada.


2.3Recupera

Antes de seguir, responde mentalmente. No mires lo de abajo hasta tener una respuesta.

  1. En L1 decidiste que el fallo nº1 va al juez. ¿Qué propiedad de ese fallo te obligó a descartar el regex?
  2. Cuando ese juez evalúe una respuesta de Aurora, ¿qué dos cosas concretas recibe como entrada? Piensa en lo que la traza ya capturó.
  3. En L1 se dijo de pasada que "binario es más fácil de alinear". ¿Por qué crees que un pass/fail sería más estable que un 1-10?

La respuesta a la 2 es la que ancla todo: el juez recibe la respuesta del agente + el chunk recuperado de esa traza. No juzga en el vacío. Juzga un par (output, contexto) que ya tienes grabado desde N0. La pregunta del juez no es "¿es buena?", sino "¿esta respuesta está respaldada por este texto?".


2.4El concepto: cuatro decisiones, no una

Un juez no es "un prompt que puntúa". Es la suma de cuatro decisiones de diseño. Cada una tiene opciones, y para el fallo de Aurora hay una correcta. Vamos una a una, de la más concreta a la más contraintuitiva.

Esta sección define varios términos juntos. Léela despacio: cada decisión se apoya en la anterior. Al final las verás encarnadas en un prompt real.

Decisión 1 — Modo: ¿juzgas una respuesta o comparas varias?

El modo es el número de candidatas que el juez mira a la vez. La taxonomía estándar tiene tres (survey From Generation to Judgment, Li, Jiang et al., arXiv:2411.16594, EMNLP 2025):

  • Pointwise — evalúa una candidata por sí sola. Salida: un score o veredicto.
  • Pairwise — compara dos candidatas. Salida: cuál gana (ranking).
  • Listwise — ordena más de dos candidatas. Salida: una selección ordenada.

Para "¿esta respuesta está fundamentada en su chunk?", el modo natural es pointwise. Juzgas una respuesta contra su contexto. No comparas dos respuestas entre sí.

Es común confundir aquí dos usos distintos. El pairwise sirve para "¿qué versión del prompt del agente responde mejor, la A o la B?". Eso lo harás al iterar el agente, y le dedicamos N2·L4 porque ahí muerde el sesgo de posición. Pero el grader de producción que vigila el fallo nº1 mira una respuesta cada vez. Es pointwise.

Decisión 2 — Referencia: ¿comparas contra una respuesta perfecta?

La referencia es contra qué compara el juez para decidir.

  • Reference-based — comparas la respuesta contra una respuesta gold escrita de antemano, la "correcta" para ese caso.
  • Reference-free — juzgas sin respuesta gold, contra una rúbrica de criterios.

Esta distinción es metodológica, no el eje central de la taxonomía del survey (arXiv:2411.16594; confianza media en el corpus). Aun así, decide qué necesitas tener preparado.

Para la groundedness de Aurora no tienes una "respuesta perfecta" escrita por caso. Sería inviable: hay infinitas formas correctas de explicar una política. Pero sí tienes el chunk recuperado de la traza. Tu juez es reference-free —no usa respuesta gold—, pero no juzga a ciegas: usa el contexto recuperado como ancla de verdad.

Un matiz honesto, porque "reference-free" suena a "sin nada con qué comparar": aquí significa "sin respuesta de referencia". El chunk sigue siendo el patrón contra el que mides si la respuesta inventa o no.

Decisión 3 — Escala: binario sobre Likert (la contraintuitiva)

La escala es el rango de la salida del juez. Las dos opciones del hook:

  • Likert — una nota numérica, p. ej. 1 a 5 o 1 a 10.
  • Binario — un veredicto de dos valores: pass / fail.

Husain (2024) y Eugene Yan (2024) recomiendan juicios binarios sobre escalas Likert 1-5, por mejor accionabilidad y calibración (corpus C.1, hamel.dev/blog/posts/llm-judge). Shankar lo dice directo: las "binary metrics are easier to align... and easier for humans to consistently judge" que las escalas numéricas (corpus A.5, sh-reya.com/blog/ai-engineering-flywheel).

Aquí se cierra el hook. El "puntúa del 1 al 10" era el error de diseño, no un punto de partida razonable. Parece que pierdes información al pasar a binario —de diez peldaños a dos—, y esa intuición es justo la trampa. Lo que ganas:

  • Accionabilidad. Un "fail" te dice qué arreglar. Un "7" no te dice nada que puedas ejecutar.
  • Calibración. Tú y otro anotador humano coincidiréis en "¿está fundamentado: sí/no?" mucho más a menudo que en "¿es esto un 7 o un 8?". Esa coincidencia es lo que en N2·L3 mediremos como acuerdo.

La pregunta correcta para Aurora no es "¿qué nota le pones?". Es: "¿cada afirmación de la respuesta está respaldada por el chunk? sí / no".

Decisión 4 — El modelo juez: a la altura del evaluado

La cuarta decisión es qué modelo hace de juez. Los jueces efectivos suelen usar modelos mayores o más cómputo —cadena de pensamiento, prompts largos— que el sistema evaluado (corpus A.5, hamel.dev/blog/posts/llm-judge).

La regla operativa: el juez ≥ capacidad del evaluado. Si el agente Aurora corre con un modelo X, el juez no debería ser uno más débil. Un juez por debajo del evaluado no detecta fallos que él mismo cometería. Si no distingue una paráfrasis fiel de una invención, no cazará la invención del agente.

Cómo lo nombran las herramientas

Estas cuatro decisiones tienen nombre en el tooling OSS (corpus C.1). No las estudiamos a fondo aquí —eso es N3/N4—, pero te anclan el vocabulario:

  • promptfoo expone jueces model-graded: llm-rubric, g-eval (pointwise) y select-best (pairwise).
  • Langfuse registra scores en cuatro tipos: Numeric, Categorical, Boolean y Text. El Boolean es tu binario.
  • DeepEval hace pointwise vía LLMTestCase y pairwise vía ArenaGEval.

Las cuatro decisiones juntas, para el fallo nº1: pointwise, reference-free (con el chunk de ancla), binario (pass/fail) y juez ≥ evaluado. Ahora las encarnamos en un prompt.


2.5Míralo funcionar: el prompt del juez, decisión a decisión

Vamos a construir el juez binario de Aurora con la API real del SDK de Anthropic. Es el patrón de juez directo del Nivel 2: una llamada a messages.create() con output_config para forzar una salida JSON estructurada.

Lee primero el bloque entero. Después señalamos dónde vive cada una de las cuatro decisiones dentro del texto.

python
1import json
2import anthropic
3
4client = anthropic.Anthropic()
5
6# El juez de groundedness de Aurora.
7# Las {llaves} son los dos campos que la traza ya capturó (N0): respuesta + chunk.
8PROMPT_JUEZ = """Eres un evaluador del agente de soporte de Aurora (e-commerce).
9
10Tu tarea: decidir si la RESPUESTA está fundamentada en el CONTEXTO recuperado.
11
12Definición operativa de "fundamentada":
13cada afirmación de la respuesta sobre la política de Aurora (devoluciones,
14envíos, reembolsos) debe estar respaldada por el texto del CONTEXTO.
15Si la respuesta afirma algo que el CONTEXTO no dice, NO está fundamentada.
16
17CONTEXTO recuperado:
18{contexto}
19
20RESPUESTA del agente:
21{respuesta}
22
23Devuelve un veredicto binario:
24- "pass": cada afirmación está respaldada por el contexto.
25- "fail": al menos una afirmación no está respaldada.
26Indica primero la razón (qué afirmación falla, si la hay) y luego el veredicto."""
27
28
29def juez_groundedness(respuesta: str, contexto: str) -> dict:
30    response = client.messages.create(
31        model="claude-sonnet-4-6",   # juez >= modelo del agente; ajusta al de tu cuenta
32        max_tokens=256,
33        messages=[{
34            "role": "user",
35            "content": PROMPT_JUEZ.format(contexto=contexto, respuesta=respuesta),
36        }],
37        output_config={
38            "format": {
39                "type": "json_schema",
40                "schema": {
41                    "type": "object",
42                    "properties": {
43                        "razon": {"type": "string"},
44                        "veredicto": {"type": "string", "enum": ["pass", "fail"]},
45                    },
46                    "required": ["razon", "veredicto"],
47                    "additionalProperties": False,
48                },
49            }
50        },
51    )
52    return json.loads(response.content[0].text)
53
54
55# El reembolso fantasma de N0·L1, ahora medido:
56resultado = juez_groundedness(
57    respuesta="Claro, he tramitado tu reembolso de 80 €.",
58    contexto="Aurora ofrece envío estándar en 3-5 días hábiles y express en 24h.",
59)
60# {"razon": "La respuesta promete un reembolso; el contexto solo habla
61#            de plazos de envío y no menciona reembolsos.",
62#  "veredicto": "fail"}

Localiza las cuatro decisiones en el código:

  • Pointwise — la función recibe una respuesta y un contexto. No hay segunda candidata que comparar.
  • Reference-free — no hay parámetro gold ni respuesta_correcta. El ancla es contexto, el chunk recuperado.
  • Binario — el enum del schema fuerza exactamente dos valores: ["pass", "fail"]. El modelo no puede devolver un 7.
  • Juez ≥ evaluadomodel="claude-sonnet-4-6", a la altura (o por encima) del agente que evalúa.

Ahora la pregunta de auto-explicación. Antes de leer la respuesta: ¿por qué el prompt pide la razon ANTES que el veredicto? Piénsalo.

Porque obliga al modelo a razonar antes de decidir. Al escribir primero qué afirmación falla, construye la cadena de pensamiento que sostiene el veredicto, en lugar de soltar un "fail" y justificarlo después. El orden del JSON impone ese orden de razonamiento. Conectarás esto con G-Eval y el alineado en N2·L5.

Y compara con el hook. El "puntúa del 1 al 10" devolvía un 7 que no podías ejecutar. Este juez devuelve algo accionable: esta respuesta concreta falla por esta afirmación concreta ("promete un reembolso que el contexto no respalda"). Esa frase ya te dice qué arreglar. Un 7 no.


2.6Hazlo tú

Ejercicio 1 — andamiaje parcial: arregla la escala

Un compañero te pasa este prompt de juez para el mismo fallo de Aurora. Las decisiones de modo, referencia y modelo están bien. Una está mal:

python
1PROMPT_MALO = """Eres un evaluador del agente de Aurora.
2Puntúa del 1 al 5 cómo de fundamentada está la RESPUESTA en el CONTEXTO.
3CONTEXTO: {contexto}
4RESPUESTA: {respuesta}
5Devuelve un número del 1 al 5."""

Reescribe el prompt corrigiendo solo la decisión mal tomada, sin tocar las otras tres. Antes de mirar la pista, identifica cuál es.

Ver la pista

La decisión rota es la escala: es Likert 1-5, no binario. El "del 1 al 5" reintroduce el problema del hook —¿un 3 es aprobado?—. Reescríbelo a un veredicto pass/fail con criterios explícitos de qué hace que falle. Mantén la entrada (contexto + respuesta) y la definición de "fundamentada".

Ejercicio 2 — autónomo: un segundo juez desde cero

Aurora tiene un segundo modo de fallo en tu taxonomía de N1: el agente escaló de más. Abrió un ticket humano para una pregunta trivial que la KB respondía.

Diseña el juez binario para este fallo. No escribas código todavía; toma las cuatro decisiones por escrito y justifica cada una en una frase:

  • Modo: ¿juzgas una respuesta o comparas dos? ¿Por qué?
  • Referencia: ¿qué usas de ancla? ¿Tienes un "escalado gold" por caso, o juzgas contra una rúbrica?
  • Escala: ¿cuál es la pregunta binaria exacta?
  • Modelo juez: ¿qué restricción aplica respecto al agente?

Antes de seguir, una pregunta de interrogación elaborativa. Respóndela tú primero: ¿por qué este fallo también va a un juez y no a un regex? Piénsalo antes de leer la línea siguiente.

Porque "el escalado no estaba justificado" es un juicio semántico, no una propiedad mecánica. Sí puedes detectar que llamó a escalar_a_humano con un if sobre la traza. Pero decidir si debía escalar exige entender la pregunta del cliente y si la KB la cubría. Eso ningún regex lo resuelve.

Ver una respuesta razonada
  • Modo: pointwise. Juzgas una decisión de escalado contra su contexto (la pregunta del cliente). No comparas dos escalados.
  • Referencia: reference-free. No tienes un "escalado perfecto" por caso. El ancla es la pregunta del cliente + lo que la KB cubría en esa traza.
  • Escala: binario. Pregunta exacta: "¿el escalado estaba justificado? sí / no". Un "fail" = escaló algo que podía responder.
  • Modelo juez: ≥ capacidad del agente. El mismo criterio: un juez más débil no detectaría escalados injustificados que él mismo haría.

2.7Comprueba

Sin pistas. Aquí tienes un prompt de juez candidato para el fallo nº1 de Aurora. Exactamente una de las cuatro decisiones de diseño está mal tomada. Identifícala, di por qué está mal y corrígela.

python
1PROMPT_CANDIDATO = """Eres un evaluador de respuestas de soporte.
2Te doy DOS respuestas del agente de Aurora y el CONTEXTO recuperado.
3Decide cuál de las dos está mejor fundamentada en el contexto.
4
5CONTEXTO: {contexto}
6RESPUESTA A: {respuesta_a}
7RESPUESTA B: {respuesta_b}
8
9Devuelve "A" o "B"."""
Ver la respuesta razonada

La decisión mal tomada es el modo. El prompt es pairwise (compara dos respuestas, A vs B), pero el grader de producción para el fallo nº1 debe ser pointwise: en producción llega una respuesta por traza, no un par. No hay una "respuesta B" con la que comparar la del cliente real.

La escala (binario A/B), la referencia (reference-free, ancla en el contexto) y el modelo están bien. El error es el modo.

Corrección: reescribirlo a pointwise —una sola {respuesta}, veredicto pass/fail sobre "¿está fundamentada en el contexto?"—, como el juez del §2.5.


Feedback formativo:

  • Si dijiste "el modo, porque producción es de a una respuesta": dominas el criterio que más se confunde —pairwise se usa para iterar prompts, pointwise para el grader de producción—. Reutilizarás esta distinción en N2·L4, donde el pairwise trae su propio sesgo de posición.
  • Si marcaste la escala (A/B) como el error: mira otra vez. A/B no es Likert; es una salida binaria entre dos candidatas, no una nota del 1 al 10. El problema no es cuántos valores devuelve, sino que devuelve una comparación cuando debería emitir un veredicto sobre una sola respuesta. Vuelve al §2.4, Decisión 1.
  • Si no encontraste ningún error: relee qué entra al juez en producción (§2.3, pregunta 2). Llega una respuesta y su chunk. Un prompt que exige dos respuestas no puede correr sobre esa entrada. Ese desajuste es el fallo de diseño.

El gate de maestría del nivel está en N2·L6. Aquí tu objetivo es identificar y corregir la decisión rota. Si lo lograste, tienes el criterio para diseñar tu propio juez.


2.8Conecta

Vuelve al "puntúa del 1 al 10" del principio.

Ese prompt devolvía una columna de números que no decidían nada. El mismo fallo, con las cuatro decisiones bien tomadas, produce un juez pointwise, reference-free y binario. Su veredicto dice: esta respuesta falla porque promete un reembolso que el contexto no respalda. Pasaste de una vibe con decimales a un veredicto accionable.

Pero ojo con cantar victoria. Tienes un juez diseñado, no validado. Un juez diseñado sin contrastar contra etiquetas humanas sigue siendo una opinión automatizada —otra vibe, ahora más sofisticada—. Lo que decide si tu juez sirve no es lo elegante que sea su prompt: es su acuerdo con el humano cuyo criterio importa.

Eso es N2·L3: confrontarás este juez con tus etiquetas de N1 y medirás si juzga como tú. Lo harás con las herramientas de la clasificación binaria, no con la accuracy a secas. Después, N2·L4 le quitará los sesgos y N2·L5 lo alineará hasta superar tu umbral de acuerdo.

Más allá de este nivel, este mismo juez binario reaparece. Es el motor de groundedness de la RAG triad en N3, y el grader que correrás en CI en N4. No lo construyes de nuevo cada vez. Lo enchufas. Un buen diseño es necesario, pero no suficiente.

¿Dónde lo aplicarías en tu trabajo? Piensa en cualquier juez LLM que uses hoy. ¿Devuelve un número del 1 al 10, o un pass/fail accionable? ¿Compara o juzga de a una? Si no sabes responder, ya sabes qué decisión revisar primero.


2.9Reflexiona

Tómate dos minutos. Estas preguntas consolidan más que releer.

  • Nombra las cuatro decisiones de diseño de un juez sin mirar arriba. Para el fallo de Aurora, ¿qué opción elegiste en cada una y por qué?
  • De las cuatro, ¿cuál te costó más justificar? La escala binaria suele ser la más contraintuitiva —parece que pierdes información al pasar de diez peldaños a dos—. Con tus palabras: ¿qué ganas a cambio?
  • ¿Qué sigue sin estar claro? Si es "¿cómo sé que este juez juzga como yo?", es la pregunta correcta: la responde N2·L3.

Referencia rápida

  • Las cuatro decisiones de un LLM-as-judge: modo · referencia · escala · modelo juez.
  • Modo: pointwise (1 candidata, score) · pairwise (2, ranking) · listwise (>2, selección). Grader de producción = pointwise; iterar prompts = pairwise (arXiv:2411.16594, EMNLP 2025).
  • Referencia: reference-based (vs respuesta gold) · reference-free (vs rúbrica). Aurora = reference-free con el chunk recuperado como ancla (arXiv:2411.16594, confianza media).
  • Escala — binario > Likert: juicios pass/fail sobre 1-5, por accionabilidad y calibración (Husain 2024 + Eugene Yan 2024; Shankar: "binary metrics are easier to align").
  • Modelo juez: ≥ capacidad del evaluado; jueces efectivos usan modelos mayores o más cómputo (corpus A.5).
  • Para el fallo nº1 de Aurora: pointwise + reference-free + binario + juez ≥ evaluado → veredicto {"razon", "veredicto": "pass"|"fail"}.
  • Cómo lo nombran las herramientas: promptfoo (llm-rubric, g-eval, select-best) · Langfuse (score Boolean) · DeepEval (LLMTestCase pointwise, ArenaGEval pairwise).
  • Recuerda: un juez diseñado pero sin validar sigue siendo una opinión automatizada. La métrica del juez es su acuerdo con el humano (N2·L3).