Guía10 min

LLM-as-judge para agentes: rúbrica, schema y calibración (el juez no es la verdad)

Resumen

Un juez LLM puntúa al agente; no lo reemplaza. Contrato práctico: rúbrica con ejemplos de oro y fallo, veredicto en JSON schema, temperatura 0 y kappa contra humanos antes de automatizar. El juez es una métrica más —no la verdad— y no sustituye tests de tools ni evals deterministas.

OpenAIAnthropicLangfuse
Un evaluador LLM separado del agente, con rúbrica y veredicto estructurado, no como verdad absoluta

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

Un juez LLM puntúa al agente. No lo absuelve. Si tu rúbrica dice “fue útil” sin ejemplos de oro y de fallo, el modelo del juez improvisa tanto como el agente que estás midiendo. El contrato es estrecho: rúbrica con ejemplos, veredicto en schema, calibración contra humanos. El juez es una métrica más —no la verdad— y entra después de los tests de tools sin LLM.

No es cómo armar la suite de evals: esa guía decide dataset, umbrales y cuándo el agente está listo. Aquí el objeto es el evaluador: cómo pedirle un veredicto que no se desvíe cada martes. No es structured outputs del agente hacia el usuario; el schema de esta guía es el del juez. Y no es un prompt de “sé crítico” suelto: sin rúbrica anclada, eso es otra demo.

Contrato: si un humano no puede aplicar la rúbrica en 30 segundos, el juez tampoco. Si el veredicto no cabe en un schema, no es un score: es un ensayo.

Cuándo el juez sí (y cuándo es un lujo caro)

Anthropic ordena los graders de más barato a más caro: código primero, LLM después, humano al final. OpenAI, en graders, reserva string_check y text_similarity para igualdad y cercanía; el score_model entra cuando el criterio no cabe en un eq. Langfuse resume el patrón: rúbrica + input + output (+ referencia opcional) → score con razonamiento.

CriterioGrader correctoPor qué
Tool name / status HTTP / JSON parseableCódigo o string_checkCero tokens; kappa = 1.0 por construcción
Argumentos idénticos al goldCódigo; semántica dudosa → similarity1 vs 1.0 tumba un eq
“¿La respuesta cita la fuente?”Código (regex / URL presente)El juez alucina citas igual que el agente
Tono, empatía, “¿resolvió la intención?”LLM-as-judgeNo hay gold único
Política / seguridad / PII en salidaFiltro + juez binario, no LikertUn 3/5 no es un allow

Si puedes escribir expect(tool.name).toBe("refund"), no pagues un juez. El juez cubre lo que el test no ve: intención, omisión, alucinación útil.

Rúbrica que un humano firmaría

Una rúbrica vaga (“sé justo, 1–5”) produce deriva. Anthropic pide rúbricas empíricas: correct/incorrect o 1–5 con anclas. Langfuse recomienda 1 = factualmente incorrecto, 5 = preciso y con fuente. Tú anclas con ejemplos, no con adjetivos.

Mínimo por criterio:

  1. Nombre (tool_correct, no_pii, answered_intent).
  2. Pass en una frase observable.
  3. Fail en una frase observable.
  4. Un ejemplo de oro y un ejemplo de fallo (el borde, no el caricaturesco).
  5. Desempate: si hay duda, fail o partial — nunca “el juez decide”.

Ejemplo para un agente de soporte que puede llamar refund:

  • Pass: llamó refund con order_id del turno y no prometió plazos que la tool no devolvió.
  • Fail: describió el reembolso en prosa sin llamar la tool, o inventó un order_id.
  • Gold: user “pedido 4412 no llegó” → refund({"order_id":"4412"}) → “el reembolso quedó registrado”.
  • Fallo borde: user igual → texto empático y “ya lo procesé”, cero tool call.

Varios criterios, un juez por criterio cuando puedas. Un mega-prompt de “calidad global” esconde el fallo (tono 5, tool 0 → promedio 2.5 que nadie puede actuar).

Veredicto en schema, no en prosa

OpenAI, en score_model, no pide un párrafo: pide result numérico y steps de razonamiento, y recorta a un range. Si el modelo no emite número, el grader cae a 0. Esa es la disciplina correcta: el score es un campo, el ensayo es desechable.

Schema mínimo del juez:

{
  "type": "object",
  "additionalProperties": false,
  "required": ["verdict", "score", "criteria", "rationale"],
  "properties": {
    "verdict": { "enum": ["pass", "fail", "partial"] },
    "score": { "type": "number", "minimum": 0, "maximum": 1 },
    "criteria": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "pass"],
        "properties": {
          "id": { "type": "string" },
          "pass": { "type": "boolean" },
          "note": { "type": "string" }
        }
      }
    },
    "rationale": { "type": "string" }
  }
}

Reglas de muestreo del juez:

  • Temperatura 0 (o el equivalente seed + top_p=1 del grader). Un juez con temperatura 0.7 es un dado.
  • Razonar primero, score después (Anthropic lo pide explícito; OpenAI lo mete en steps). Conserva el rationale para auditoría; el umbral de CI mira verdict/score.
  • No reuses el modelo del agente como juez sin medir sesgo. Misma familia = mismos puntos ciegos.
  • No pases PII de producción al juez. Redacta antes; ver detectar y redactar PII. Un eval no es licencia para filtrar tickets reales a otro proveedor.

Diagrama de rúbrica a schema: el juez emite un veredicto tipado, no un párrafo libre

Calibrar contra humanos (kappa, no vibes)

OpenAI lo pone como anti-patrón: ignorar el feedback humano al calibrar scores automáticos. Langfuse escala el juez después de tener criterio. El número que te dice si el juez sirve no es su score medio: es el acuerdo con un gold humano.

Protocolo corto, el que evita autoengaño:

  1. Toma 40–80 trazas reales (no sintéticas bonitas). Incluye fails de producción.
  2. Dos humanos aplican la misma rúbrica, a ciegas. Si ellos no se ponen de acuerdo (kappa humano-humano bajo), arregla la rúbrica, no el juez.
  3. Corre el juez sobre el mismo set. Calcula kappa (o acuerdo porcentual + matriz de confusión) juez vs consenso humano.
  4. Mira falsos pass: el juez dice pass y el humano fail. Esos son los que llegan a usuarios. Un falso fail molesta al CI; un falso pass silencia incidentes.
  5. No despliegues el juez en CI/producción si el kappa juez-humano queda por debajo del umbral que tú fijaste (un piso habitual de trabajo es ~0.6; “casi perfecto” pide ≥0.8). Si no llega, acota la rúbrica o vuelve a código.

Sesgos clásicos del juez, medibles en esa matriz:

  • Sesgo de posición en A/B: el primer candidato gana más de la cuenta. Alterna el orden.
  • Sesgo de verbosidad: respuestas largas puntúan más. Ancla “conciso y correcto” en el fail de relleno.
  • Deriva semanal: el juez también cambia de versión. Pinea el modelo del juez y re-calibra cuando lo muevas, igual que un schema de tool.

El juez nunca es la fuente de verdad en un postmortem. Es un detector. La verdad sigue siendo el humano, el log de la tool y el dinero movido.

Dónde vive en el pipeline (y dónde no)

Offline: el juez corre sobre el dataset de la suite de evals. Cada cambio de prompt o modelo del agente dispara el dataset; el juez es constante.

Online: Langfuse recomienda evaluar observaciones (la generación final, el retrieval), no el trace entero, para no pagar un ensayo por cada tool call interno. Muestrea. Un juez al 100% del tráfico es una factura, no un SLO.

CI: el job falla por verdict=fail en casos gold, no por el rationale. Si el schema no parsea, es fail — mismo espíritu que el grader de OpenAI cayendo a 0.

No uses el juez para:

  • Autorizar un refund o un deploy. Eso es human-in-the-loop o un test.
  • Sustituir defensas de prompt injection: el juez también es un LLM.
  • “Mejorar el agente” reentrenando contra el juez sin gold. Optimizas al juez, no al usuario.

Calibración del juez: acuerdo con humanos primero, automatización después

Checklist antes de dejar el juez en CI

  1. Cada criterio tiene pass/fail observable y un ejemplo de borde.
  2. El veredicto sale por schema (additionalProperties: false); prosa fuera del score.
  3. Temperatura 0; modelo del juez pineado y distinto al del agente cuando el sesgo importa.
  4. Kappa (o matriz) contra humanos en un set sucio de producción; umbral escrito, no “se siente bien”.
  5. Falsos pass inspeccionados a mano; rúbrica ajustada antes de subir el umbral.
  6. PII redactada; el juez no ve secretos ni tickets crudos.
  7. Código y tests de tools en verde antes de invocar al juez.
  8. Recalibración cuando cambias el modelo del juez, no “ya quedó”.

FAQ

¿Mismo modelo como agente y juez? Puedes, pero mides menos: misma familia, mismos puntos ciegos. Si el presupuesto obliga, calibra igual y reporta el sesgo.

¿Likert 1–5 o pass/fail? Empieza binario o pass/fail/partial. El 1–5 sin anclas es ruido; con anclas sirve para tono, no para “¿llamó la tool?”.

OpenAI depreca la plataforma de Evals. Verificado el 2026-09-06: solo lectura el 31 oct 2026, apaga el 30 nov 2026. El método (rúbrica + grader + humanos) no se depreca. Migra el harness; no tires la rúbrica.

Más operación en el hub de seguridad, coste y operación. Si todavía no tienes el loop del agente en local, empieza por el curso de instalar un agente.