Multi-Agente con Claude: Revisión Cruzada en Producción
TL;DR: Un agente Claude trabajando solo tiene tres problemas concretos: la ventana de contexto se degrada en tareas largas, los errores se acumulan sin corrección, y no hay nadie que valide el resultado antes de que llegue a producción. Los equipos multi-agente con revisión cruzada resuelven esto: un agente construye, otro valida de forma independiente, y un orquestador coordina sin ejecutar nada directamente. Este artículo muestra los patrones y el código para montarlo sin frameworks externos.
El límite natural del agente único
Los sistemas de agente único tienen un techo claro. Cuando una sola instancia Claude trabaja en una tarea compleja, la calidad del output cae a medida que el contexto crece, los errores iniciales se propagan sin corrección, y no existe ningún mecanismo de validación independiente.
El patrón orquestador-subagente es la respuesta directa a esto. En lugar de una sola instancia haciendo todo, tienes un agente principal que descompone la tarea y delega en agentes especializados que trabajan con su propio contexto. Según la documentación oficial de Anthropic sobre sistemas multi-agente, este enfoque mejora la calidad en tareas que requieren verificación independiente o pasos que se benefician de la especialización.
La parte que más se ignora no es la paralelización, sino la revisión cruzada: que un agente distinto al que construyó algo lo valide antes de continuar. Ese mecanismo separa un prototipo experimental de algo que puedes dejar correr en producción con cierta confianza.
¿Qué es el patrón orquestador-subagente?
El patrón orquestador-subagente es una arquitectura donde un agente principal analiza una tarea compleja, la descompone en subtareas independientes y las delega a agentes especializados que operan con su propio contexto y devuelven resultados estructurados.
No es lo mismo que un agente que llama a herramientas. En este caso, cada subagente es una llamada completa a la API con su propio system prompt, sus propias restricciones y su propio contexto aislado. El orquestador no ejecuta código directamente: planifica, delega y sintetiza.
¿Qué es la revisión cruzada entre agentes?
La revisión cruzada (cross-review) es el patrón donde el agente que valida un resultado es distinto e independiente del que lo generó. El validador recibe el output del constructor, los criterios de aceptación originales, y su único rol es detectar problemas, no generar código nuevo ni modificar archivos.
Este aislamiento es la clave. Un agente validador que también puede modificar código tiende a aprobar su propio trabajo con correcciones mínimas. Cuando el validador solo puede leer y reportar, el sistema produce feedback genuinamente crítico.
Implementación paso a paso
Paso 1: Definir roles antes de escribir código
Antes de tocar la API, define tres cosas por agente: qué puede hacer, qué no puede hacer, y qué formato devuelve. Sin esta disciplina, los agentes se solapan y el orquestador no sabe qué esperar.
Para un sistema de generación y revisión de código, los roles mínimos son:
- Orquestador: descompone la tarea, asigna contexto a cada agente, sintetiza resultados. No escribe código.
- Constructor (builder): implementa la solución según las especificaciones. Solo modifica los archivos asignados.
- Validador (reviewer): lee el output del constructor, verifica contra criterios de aceptación, reporta problemas. No modifica nada.
Paso 2: Implementar el orquestador con la API de Anthropic
import anthropic
import json
from typing import Any
# La API key se lee de la variable de entorno ANTHROPIC_API_KEY
client = anthropic.Anthropic()
def call_agent(system_prompt: str, user_message: str, model: str = "claude-sonnet-4-6") -> str:
"""Llama a un agente Claude con un rol específico y devuelve su respuesta."""
response = client.messages.create(
model=model,
max_tokens=4096,
system=system_prompt,
messages=[{"role": "user", "content": user_message}]
)
return response.content[0].text
def orchestrate(task: str) -> dict[str, Any]:
"""
Orquesta un flujo builder-validator en tres fases:
1. El orquestador planifica y descompone la tarea
2. El builder implementa la solución
3. El validator revisa el resultado de forma independiente
"""
# Fase 1: el orquestador planifica
orchestrator_system = """Eres un orquestador técnico. Tu único trabajo es analizar
una tarea de desarrollo y devolver un JSON con:
- "subtasks": lista de subtareas para el builder
- "acceptance_criteria": criterios de aceptación medibles
- "files_to_modify": lista de archivos que puede modificar el builder
No escribas código. Solo planifica. Devuelve solo JSON válido."""
plan_raw = call_agent(
system_prompt=orchestrator_system,
user_message=f"Tarea: {task}",
model="claude-opus-4-6" # Opus para planificación compleja
)
plan = json.loads(plan_raw)
# Fase 2: el builder implementa dentro de los límites definidos
builder_system = f"""Eres un agente constructor especializado.
Solo puedes modificar estos archivos: {plan['files_to_modify']}.
No toques archivos de test. Si encuentras un bloqueante, documéntalo en tu respuesta.
Implementa la solución según las subtareas asignadas."""
builder_output = call_agent(
system_prompt=builder_system,
user_message=f"Subtareas: {json.dumps(plan['subtasks'], ensure_ascii=False)}",
model="claude-sonnet-4-6"
)
# Fase 3: el validator revisa de forma completamente independiente
validator_system = """Eres un agente validador. Tu único rol es revisar.
NO puedes modificar archivos. NO puedes crear código nuevo.
Analiza el output del builder contra los criterios de aceptación y devuelve un JSON con:
- "approved": true o false
- "issues": lista de objetos con "description" y "severity" (critical/warning/info)
Devuelve solo JSON válido, sin texto adicional."""
validation_raw = call_agent(
system_prompt=validator_system,
user_message=(
f"Output del builder:\n{builder_output}\n\n"
f"Criterios de aceptación:\n{json.dumps(plan['acceptance_criteria'], ensure_ascii=False)}"
),
model="claude-sonnet-4-6"
)
validation = json.loads(validation_raw)
return {
"plan": plan,
"builder_output": builder_output,
"validation": validation
}
# Ejemplo de uso
if __name__ == "__main__":
result = orchestrate(
task="Añadir validación de email al endpoint POST /users en FastAPI"
)
print(f"Aprobado: {result['validation']['approved']}")
if not result['validation']['approved']:
for issue in result['validation']['issues']:
print(f"[{issue['severity']}] {issue['description']}")
Paso 3: Comunicación mediante archivos compartidos
Para sistemas con más de tres agentes, pasar todo a través del contexto del orquestador se convierte en un cuello de botella. El patrón que funciona en producción es el sistema de archivos compartidos: cada agente escribe su output en un archivo estructurado, y el siguiente lo lee directamente sin pasar por el orquestador.
import json
from pathlib import Path
from datetime import datetime
SHARED_DIR = Path("/tmp/agent_workspace")
SHARED_DIR.mkdir(exist_ok=True)
def write_agent_output(agent_id: str, output: dict) -> Path:
"""Persiste el output de un agente para que otros lo lean directamente."""
timestamp = datetime.now().strftime("%H%M%S")
output_path = SHARED_DIR / f"{agent_id}_{timestamp}.json"
output_path.write_text(json.dumps(output, ensure_ascii=False, indent=2))
return output_path
def validate_agent_schema(output: dict, required_keys: list[str]) -> bool:
"""Verifica que el output del agente tiene el esquema esperado antes de usarlo."""
missing = [k for k in required_keys if k not in output]
if missing:
print(f"Output inválido: faltan claves {missing}")
return False
return True
Anthropic documenta este enfoque como la forma de evitar la "degradación del teléfono" en pipelines largos: en lugar de copiar outputs completos por el historial de conversación del orquestador, los subagentes escriben en un sistema externo y pasan referencias ligeras al coordinador.
Caso práctico: revisión automática de pull requests
En equipos de producto pequeños, revisar PRs consume tiempo desproporcionado. El patrón builder-validator aplicado a code review funciona así: un agente analizador lee el diff y extrae el contexto (qué cambia, qué afecta, qué tests existen). Luego, dos agentes revisores independientes evalúan ese contexto: uno enfocado en seguridad, otro en calidad y estilo.
El resultado no es un sistema que aprueba PRs automáticamente. Es un informe estructurado listo antes de que un humano lo revise, reduciendo el tiempo necesario para llegar a una decisión informada.
| Agente | Modelo recomendado | Rol | Restricciones |
|---|---|---|---|
| Orquestador | claude-opus-4-6 | Planificación y síntesis | No modifica archivos |
| Analizador de diff | claude-sonnet-4-6 | Extrae contexto del cambio | Solo lectura |
| Revisor de seguridad | claude-sonnet-4-6 | Detecta vulnerabilidades | Solo reporta, nunca corrige |
| Revisor de calidad | claude-haiku-4-5-20251001 | Estilo, tests, cobertura | Solo reporta, nunca corrige |
Usar Haiku para el revisor de calidad no es un compromiso: las tareas de verificación de estilo y formato no requieren el mismo nivel de razonamiento que la detección de vulnerabilidades. La diferencia de coste entre Sonnet y Haiku en este rol es significativa a escala.
En Producción
Lo que cambia entre un prototipo y un sistema en producción es el control de costes y la gestión de fallos silenciosos. Con varias llamadas a la API por tarea, los costes se multiplican si no se gestionan desde el principio.
Costes aproximados por ejecución (a febrero 2026, con precios estándar de la API):
- Orquestador con Opus 4.6: entre 0,03 y 0,06 € por tarea según complejidad
- Dos subagentes con Sonnet 4.6: entre 0,01 y 0,03 € cada uno
- Total estimado por ciclo completo: 0,05 a 0,12 € por revisión
Para uso intensivo (50-100 revisiones al día), esto supone entre 2,50 y 12 € diarios. No es trivial, pero es predecible. Reserva Opus para planificación y razonamiento complejo; Sonnet para implementación y revisión crítica; Haiku para tareas mecánicas y de formato.
El problema de la autonomía sostenida es el principal dolor en producción. Los flujos multi-agente fallan cuando un subagente se bloquea silenciosamente: no devuelve error, devuelve algo parcialmente correcto que el orquestador acepta sin validar. Para esto, valida el esquema del output en cada paso antes de pasarlo al siguiente agente:
import jsonschema
VALIDATION_SCHEMA = {
"type": "object",
"required": ["approved", "issues"],
"properties": {
"approved": {"type": "boolean"},
"issues": {
"type": "array",
"items": {
"type": "object",
"required": ["description", "severity"],
"properties": {
"description": {"type": "string"},
"severity": {"enum": ["critical", "warning", "info"]}
}
}
}
}
}
def validate_agent_output(output: dict, schema: dict) -> bool:
"""Valida el output del agente contra el esquema esperado antes de usarlo."""
try:
jsonschema.validate(output, schema)
return True
except jsonschema.ValidationError as e:
print(f"Output inválido del agente: {e.message}")
return False
Escalabilidad: el patrón de archivos compartidos funciona bien hasta equipos de cinco a siete agentes. Por encima de eso, la coordinación vía archivos introduce problemas de concurrencia. A esa escala, considera SQLite con WAL mode para persistencia local o Redis si necesitas compartir estado entre sesiones.
Autonomía con techo explícito: define un límite máximo de iteraciones antes de escalar al humano. Si el builder no resuelve el problema en dos ciclos de corrección, el problema probablemente requiere intervención humana. Un sistema que puede iterar indefinidamente no es autónomo, es un bucle de costes sin control.
Errores comunes y cómo resolverlos
Error: el validador modifica código además de reportar
Causa: el system prompt no restringe explícitamente la capacidad de escritura.
Solución: añade "No puedes crear, editar ni eliminar archivos. Tu único output es un informe en JSON." La restricción debe ser explícita y aparecer al final del system prompt, no solo al principio.
Error: el orquestador genera un plan que el builder no puede ejecutar
Causa: el orquestador no tiene visibilidad del estado real del codebase cuando planifica.
Solución: incluye en el user message del orquestador un resumen del estado actual: nombres de archivo, estructura del proyecto, dependencias relevantes. No el código completo, un índice orientativo.
Error: JSON inválido devuelto por los agentes
Causa: el modelo añade texto o markdown antes o después del JSON.
Solución: usa la instrucción "Devuelve solo JSON válido, sin caracteres antes ni después, sin bloques de código markdown" y añade un parser con regex como fallback para extraer el bloque JSON si hay texto extra.
Preguntas frecuentes
¿Cuántos agentes son demasiados?
La regla práctica: si necesitas más de cinco agentes para una tarea, probablemente estás sobrediseñando. Empieza con tres roles (orquestador, builder, validator) y añade agentes especializados solo cuando identifiques cuellos de botella concretos con datos. La complejidad de coordinación crece más rápido que la capacidad del sistema.
¿Hay que usar CrewAI o LangGraph para esto?
No es necesario. Los patrones de este artículo funcionan directamente con la API de Anthropic sin dependencias externas. Los frameworks añaden abstracción útil para equipos grandes, pero también añaden opacidad en el comportamiento. Para proyectos pequeños y medianos, la API directa es más predecible y más fácil de depurar cuando algo falla.
¿Cómo evito bucles infinitos de corrección entre agentes?
Define un límite máximo de iteraciones antes de escalar al humano. Un validador que devuelve "approved: false" no debería desencadenar más de dos ciclos de corrección automática. Si el builder no resuelve el problema en dos intentos, el problema requiere intervención humana. La autonomía tiene que tener un techo explícito definido en código, no como buena intención.
Conclusión
El patrón orquestador-subagente con revisión cruzada funciona hoy con la API de Anthropic, sin frameworks externos, y resuelve el problema central de los agentes únicos: no se corrigen a sí mismos. La clave está en definir roles estrictos antes de escribir código, restringir explícitamente lo que cada agente puede hacer, y validar el esquema del output en cada transición.
Lo que cambia respecto a un agente simple no es la complejidad del código. Es la disciplina en el diseño. Un validador que puede editar archivos deja de ser un validador. Un orquestador que implementa código deja de ser un orquestador. Los límites de cada rol, bien definidos desde el principio, son lo que hace que el sistema funcione de forma predecible.
Si estás montando algo similar o tienes preguntas sobre cómo adaptar estos patrones a tu caso concreto, puedes compartirlo en los comentarios o encontrarme en Twitter en @sergiomarquezp_. El siguiente artículo explorará cómo añadir memoria persistente entre sesiones para que estos sistemas aprendan de sus propios errores.