Método Santa
Marco de verificación adversarial multiagente. Haz una lista, revísala dos veces. Si es travieso, arréglalo hasta que sea bueno.
La idea central: un solo agente que revisa su propia salida comparte los mismos sesgos, lagunas de conocimiento y errores sistemáticos que produjeron la salida. Dos revisores independientes sin contexto compartido rompen este modo de fallo.
Cuándo activarlo
Invoca esta habilidad cuando:
- La salida será publicada, desplegada o consumida por usuarios finales
- Se deben cumplir restricciones de cumplimiento normativo, regulatorio o de marca
- El código se envía a producción sin revisión humana
- La precisión del contenido es importante (documentación técnica, material educativo, texto para clientes)
- Generación por lotes a gran escala donde el muestreo puntual pasa por alto patrones sistémicos
- El riesgo de alucinación es alto (afirmaciones, estadísticas, referencias a APIs, lenguaje legal)
NO uses para borradores internos, investigación exploratoria o tareas con verificación determinista (usa pipelines de compilación/pruebas/linting para esos casos).
Arquitectura
┌─────────────┐
│ GENERADOR │ Fase 1: Haz una lista
│ (Agente A) │ Produce el entregable
└──────┬───────┘
│ salida
▼
┌──────────────────────────────┐
│ REVISIÓN DUAL INDEPENDIENTE │ Fase 2: Revísala dos veces
│ │
│ ┌───────────┐ ┌───────────┐ │ Dos agentes, misma rúbrica,
│ │ Revisor B │ │ Revisor C │ │ sin contexto compartido
│ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │
└────────┼──────────────┼────────┘
│ │
▼ ▼
┌──────────────────────────────┐
│ PUERTA DE VEREDICTO │ Fase 3: Travieso o bueno
│ │
│ B aprueba Y C aprueba → BUENO │ Ambos deben aprobar.
│ De lo contrario → TRAVIESO │ Sin excepciones.
└──────┬──────────────┬─────────┘
│ │
BUENO TRAVIESO
│ │
▼ ▼
[ ENVIAR ] ┌─────────────┐
│ CICLO DE │ Fase 4: Arréglalo hasta que sea bueno
│ CORRECCIÓN │
│ │
│ iteración++ │ Recopila todas las banderas.
│ si i > MAX: │ Corrige todos los problemas.
│ escalar │ Vuelve a ejecutar ambos revisores.
│ sino: │ Bucle hasta convergencia.
│ ir a Fase 2│
└──────────────┘
Detalles de las fases
Fase 1: Haz una lista (Generar)
Ejecuta la tarea principal. No hay cambios en tu flujo de trabajo de generación normal. El Método Santa es una capa de verificación posterior a la generación, no una estrategia de generación.
# El generador funciona normalmente
salida = generar(especificacion_tarea)
Fase 2: Revísala dos veces (Revisión dual independiente)
Genera dos agentes de revisión en paralelo. Invariantes críticos:
- Aislamiento de contexto — ningún revisor ve la evaluación del otro
- Rúbrica idéntica — ambos reciben los mismos criterios de evaluación
- Mismas entradas — ambos reciben la especificación original Y la salida generada
- Salida estructurada — cada uno devuelve un veredicto tipado, no prosa
PROMPT_REVISOR = """
Eres un revisor de calidad independiente. NO has visto ninguna otra revisión de esta salida.
## Especificación de la tarea
{especificacion_tarea}
## Salida bajo revisión
{salida}
## Rúbrica de evaluación
{rubrica}
## Instrucciones
Evalúa la salida contra CADA criterio de la rúbrica. Para cada uno:
- APROBADO: el criterio se cumple completamente, sin problemas
- RECHAZADO: se encontró un problema específico (cita el problema exacto)
Devuelve tu evaluación como JSON estructurado:
{
"veredicto": "APROBADO" | "RECHAZADO",
"verificaciones": [
{"criterio": "...", "resultado": "APROBADO|RECHAZADO", "detalle": "..."}
],
"problemas_criticos": ["..."], // bloqueantes que deben arreglarse
"sugerencias": ["..."] // mejoras no bloqueantes
}
Sé riguroso. Tu trabajo es encontrar problemas, no aprobar.
"""
# Genera revisores en paralelo (subagentes de Claude Code)
revisor_b = Agente(prompt=PROMPT_REVISOR.format(...), descripcion="Revisor Santa B")
revisor_c = Agente(prompt=PROMPT_REVISOR.format(...), descripcion="Revisor Santa C")
# Ambos se ejecutan concurrentemente — ninguno ve al otro
Diseño de la rúbrica
La rúbrica es la entrada más importante. Las rúbricas vagas producen revisiones vagas. Cada criterio debe tener una condición de aprobado/rechazado objetiva.
| Criterio | Condición de aprobado | Señal de fallo |
|---|---|---|
| Precisión factual | Todas las afirmaciones verificables contra material fuente o conocimiento común | Estadísticas inventadas, números de versión incorrectos, APIs inexistentes |
| Sin alucinaciones | Sin entidades, citas, URLs o referencias fabricadas | Enlaces a páginas que no existen, citas atribuidas sin fuente |
| Completitud | Cada requisito en la especificación está cubierto | Secciones faltantes, casos límite omitidos, cobertura incompleta |
| Cumplimiento | Pasa todas las restricciones específicas del proyecto | Términos prohibidos usados, violaciones de tono, incumplimiento regulatorio |
| Consistencia interna | Sin contradicciones dentro de la salida | La sección A dice X, la sección B dice no-X |
| Corrección técnica | El código compila/ejecuta, los algoritmos son sólidos | Errores de sintaxis, bugs lógicos, afirmaciones de complejidad incorrectas |
Extensiones de rúbrica por dominio
Contenido/Marketing:
- Adherencia a la voz de la marca
- Requisitos SEO cumplidos (densidad de palabras clave, metaetiquetas, estructura)
- Sin uso indebido de marcas registradas de competidores
- Llamada a la acción presente y correctamente enlazada
Código:
- Seguridad de tipos (sin fugas de
any, manejo correcto de nulos) - Cobertura de manejo de errores
- Seguridad (sin secretos en el código, validación de entrada, prevención de inyección)
- Cobertura de pruebas para nuevas rutas
Sensible a cumplimiento (regulado, legal, financiero):
- Sin garantías de resultados ni afirmaciones sin fundamento
- Descargos de responsabilidad requeridos presentes
- Solo terminología aprobada
- Lenguaje apropiado para la jurisdicción
Fase 3: Travieso o bueno (Puerta de veredicto)
def veredicto_santa(revision_b, revision_c):
"""Ambos revisores deben aprobar. Sin crédito parcial."""
if revision_b.veredicto == "APROBADO" and revision_c.veredicto == "APROBADO":
return "BUENO" # Enviarlo
# Combinar banderas de ambos revisores, deduplicar
todos_problemas = dedupe(revision_b.problemas_criticos + revision_c.problemas_criticos)
todas_sugerencias = dedupe(revision_b.sugerencias + revision_c.sugerencias)
return "TRAVIESO", todos_problemas, todas_sugerencias
Por qué ambos deben aprobar: si solo un revisor detecta un problema, ese problema es real. El punto ciego del otro revisor es exactamente el modo de fallo que el Método Santa existe para eliminar.
Fase 4: Arréglalo hasta que sea bueno (Bucle de convergencia)
MAX_ITERACIONES = 3
for iteracion in range(MAX_ITERACIONES):
veredicto, problemas, sugerencias = veredicto_santa(revision_b, revision_c)
if veredicto == "BUENO":
registrar_resultado_santa(salida, iteracion, "aprobado")
return enviar(salida)
# Corregir todos los problemas críticos (las sugerencias son opcionales)
salida = agente_de_correccion.ejecutar(
salida=salida,
problemas=problemas,
instruccion="Corrige SOLO los problemas marcados. No refactorices ni agregues cambios no solicitados."
)
# Volver a ejecutar AMBOS revisores sobre la salida corregida (agentes nuevos, sin memoria de la ronda anterior)
revision_b = Agente(prompt=PROMPT_REVISOR.format(salida=salida, ...))
revision_c = Agente(prompt=PROMPT_REVISOR.format(salida=salida, ...))
# Iteraciones agotadas — escalar
registrar_resultado_santa(salida, MAX_ITERACIONES, "escalado")
escalar_a_humano(salida, problemas)
Crítico: cada ronda de revisión usa agentes nuevos. Los revisores no deben tener memoria de rondas anteriores, ya que el contexto previo crea sesgo de anclaje.
Patrones de implementación
Patrón A: Subagentes de Claude Code (Recomendado)
Los subagentes proporcionan un verdadero aislamiento de contexto. Cada revisor es un proceso separado sin estado compartido.
# En una sesión de Claude Code, usa la herramienta Agent para generar revisores
# Ambos agentes se ejecutan en paralelo para mayor velocidad
# Pseudocódigo para invocación de la herramienta Agent
revisor_b = Agente(
descripcion="Revisor Santa B",
prompt=f"Revisa esta salida en busca de calidad...\n\nRÚBRICA:\n{rubrica}\n\nSALIDA:\n{salida}"
)
revisor_c = Agente(
descripcion="Revisor Santa C",
prompt=f"Revisa esta salida en busca de calidad...\n\nRÚBRICA:\n{rubrica}\n\nSALIDA:\n{salida}"
)
Patrón B: Secuencial en línea (Alternativa)
Cuando no haya subagentes disponibles, simula el aislamiento con reinicios explícitos de contexto:
- Genera la salida
- Nuevo contexto: "Eres el Revisor 1. Evalúa SOLO contra esta rúbrica. Encuentra problemas."
- Registra los hallazgos textualmente
- Borra el contexto por completo
- Nuevo contexto: "Eres el Revisor 2. Evalúa SOLO contra esta rúbrica. Encuentra problemas."
- Compara ambas revisiones, corrige, repite
El patrón de subagentes es estrictamente superior: la simulación en línea corre el riesgo de fuga de contexto entre revisores.
Patrón C: Muestreo por lotes
Para lotes grandes (más de 100 elementos), aplicar Santa completo a cada elemento es prohibitivo en coste. Utiliza muestreo estratificado:
- Ejecuta Santa en una muestra aleatoria (10-15% del lote, mínimo 5 elementos)
- Categoriza los fallos por tipo (alucinación, cumplimiento, completitud, etc.)
- Si surgen patrones sistemáticos, aplica correcciones específicas a todo el lote
- Vuelve a muestrear y verificar el lote corregido
- Continúa hasta que una muestra limpia pase
import random
def santa_lote(elementos, rubrica, tasa_muestra=0.15):
muestra = random.sample(elementos, max(5, int(len(elementos) * tasa_muestra)))
for elemento in muestra:
resultado = santa_completo(elemento, rubrica)
if resultado.veredicto == "TRAVIESO":
patron = clasificar_fallo(resultado.problemas)
elementos = corregir_lote(elementos, patron) # Corregir todos los elementos que coincidan con el patrón
return santa_lote(elementos, rubrica) # Volver a muestrear
return elementos # Muestra limpia → enviar lote
Modos de fallo y mitigaciones
| Modo de fallo | Síntoma | Mitigación |
|---|---|---|
| Bucle infinito | Los revisores siguen encontrando nuevos problemas después de las correcciones | Tope máximo de iteraciones (3). Escalar. |
| Aprobación automática | Ambos revisores aprueban todo | Prompt adversarial: "Tu trabajo es encontrar problemas, no aprobar." |
| Deriva subjetiva | Los revisores marcan preferencias de estilo, no errores | Rúbrica estricta con criterios objetivos de aprobado/rechazado solamente |
| Regresión en correcciones | Corregir el problema A introduce el problema B | Revisores nuevos en cada ronda detectan regresiones |
| Sesgo de acuerdo entre revisores | Ambos revisores pasan por alto lo mismo | Mitigado por la independencia, no eliminado. Para salidas críticas, añadir un tercer revisor o verificación humana puntual. |
| Explosión de costes | Demasiadas iteraciones en salidas grandes | Patrón de muestreo por lotes. Límites de presupuesto por ciclo de verificación. |
Integración con otras habilidades
| Habilidad | Relación |
|---|---|
| Bucle de verificación | Usar para comprobaciones deterministas (compilación, lint, pruebas). Santa para comprobaciones semánticas (precisión, alucinaciones). Ejecutar bucle de verificación primero, Santa después. |
| Arnés de evaluación | Los resultados del Método Santa alimentan métricas de evaluación. Rastrear pass@k en ejecuciones de Santa para medir la calidad del generador a lo largo del tiempo. |
| Aprendizaje continuo v2 | Los hallazgos de Santa se convierten en instintos. Fallos repetidos en el mismo criterio → comportamiento aprendido para evitar el patrón. |
| Compacto estratégico | Ejecutar Santa ANTES de compactar. No perder contexto de revisión a mitad de verificación. |
Métricas
Rastrea estas para medir la efectividad del Método Santa:
- Tasa de primer paso: % de salidas que aprueban Santa en la ronda 1 (objetivo: >70%)
- Iteraciones medias hasta convergencia: rondas promedio hasta BUENO (objetivo: <1.5)
- Taxonomía de problemas: distribución de tipos de fallo (alucinación vs. completitud vs. cumplimiento)
- Acuerdo entre revisores: % de problemas señalados por ambos revisores vs. solo uno (bajo acuerdo = la rúbrica necesita ajustes)
- Tasa de escape: problemas encontrados después del envío que Santa debería haber detectado (objetivo: 0)
Análisis de costes
El Método Santa cuesta aproximadamente 2-3 veces el coste de tokens de la generación sola por ciclo de verificación. Para la mayoría de las salidas de alto riesgo, es una ganga:
Coste de Santa = (tokens de generación) + 2×(tokens de revisión por ronda) × (rondas promedio)
Coste de NO Santa = (daño a la reputación) + (esfuerzo de corrección) + (pérdida de confianza)
Para operaciones por lotes, el patrón de muestreo reduce el coste a ~15-20% de la verificación completa mientras detecta >90% de los problemas sistemáticos.