Estudio de Arquitectura y Orquestación Agéntica: el Dominio más Grande del Examen CCA
Arquitectura y Orquestación Agéntica vale el 27% del examen CCA Foundations, más que cualquier otro dominio.
Busca en todas las páginas de la documentación
Arquitectura y Orquestación Agéntica vale el 27% del examen CCA Foundations, más que cualquier otro dominio.
Cubre cómo diseñas sistemas donde Claude no solo responde una pregunta, sino que planifica, llama a herramientas, delega trabajo a otros agentes y decide cuándo ha terminado.
Este artículo recorre los patrones de orquestación que aparecen con más frecuencia en los escenarios del examen, con ilustraciones prácticas en Python construidas sobre el SDK de anthropic.
Los sistemas multiagente intercambian simplicidad por capacidad, y el examen evalúa si sabes cuándo vale la pena hacer ese intercambio.
Un único agente bien definido con buenas herramientas supera casi siempre a un sistema multiagente mal descompuesto.
Los patrones centrales que vale la pena conocer son los pipelines secuenciales, las topologías supervisor-trabajador y el fan-out paralelo con un paso de fusión.
Cada patrón necesita una condición de terminación explícita, o corre el riesgo de entrar en un bucle más allá de su utilidad.
Las preguntas de orquestación en el examen suelen centrarse en elegir la arquitectura más pequeña que resuelve el problema, no la más sofisticada.
Tarjeta de receta de referencia rápida: la forma mínima de un bucle supervisor-trabajador.
from anthropic import Anthropic
client = Anthropic()
def run_worker(task: str, model: str = "claude-sonnet-5") -> str:
"""Un agente trabajador con un propósito único que hace un trabajo y retorna."""
response = client.messages.create(
model=model,
max_tokens=1024,
system="Eres un agente trabajador enfocado. Haz exactamente la tarea dada. Devuelve solo el resultado.",
messages=[{"role": "user", "content": task}],
)
return response.content[0].text
def run_supervisor(goal: str, max_steps: int = 5) -> str:
"""Un supervisor que descompone un objetivo en tareas de trabajador y se detiene al completarse."""
completed_work = []
for step in range(max_steps):
plan_prompt = f"Objetivo: {goal}\nCompletado hasta ahora: {completed_work}\nSiguiente subtarea única, o DONE si está terminado:"
plan = run_worker(plan_prompt, model="claude-sonnet-5")
if plan.strip().upper().startswith("DONE"):
break
result = run_worker(plan)
completed_work.append({"task": plan, "result": result})
return "\n".join(w["result"] for w in completed_work)Cuándo usar esto:
from anthropic import Anthropic
from dataclasses import dataclass
client = Anthropic()
@dataclass
class AgentResult:
agent_name: str
output: str
def draft_agent(topic: str) -> AgentResult:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=512,
system="Redacta un breve esquema técnico. Devuelve solo el esquema, sin preámbulos.",
messages=[{"role": "user", "content": f"Esquema: {topic}"}],
)
return AgentResult("draft", response.content[0].text)
def critic_agent(draft: str) -> AgentResult:
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=512,
system="Critica un esquema técnico buscando lagunas y riesgos fácticos. Sé conciso. Devuelve solo la crítica.",
messages=[{"role": "user", "content": draft}],
)
return AgentResult("critic", response.content[0].text)
def reviser_agent(draft: str, critique: str) -> AgentResult:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=768,
system="Revisa un borrador de esquema dada una crítica. Devuelve solo el esquema revisado.",
messages=[{"role": "user", "content": f"Borrador:\n{draft}\n\nCrítica:\n{critique}"}],
)
return AgentResult("reviser", response.content[0].text)
def orchestrate_draft_critique_revise(topic: str) -> str:
"""Un pipeline secuencial de tres agentes: borrador -> crítico -> revisor.
Cada agente tiene un solo trabajo y un prompt de sistema específico, que es el
patrón que el examen llama 'diseño de agente de única responsabilidad'.
"""
draft = draft_agent(topic)
critique = critic_agent(draft.output)
final = reviser_agent(draft.output, critique.output)
return final.output
if __name__ == "__main__":
result = orchestrate_draft_critique_revise("Estrategia de migración de bases de datos sin tiempo de inactividad")
print(result)Lo que esto demuestra:
| Patrón | Forma | Mejor para | Terminación |
|---|---|---|---|
| Pipeline secuencial | A -> B -> C | Número conocido y fijo de pasos de transformación | Longitud fija, no se necesita bucle |
| Supervisor-trabajador | El supervisor planifica y despacha a los trabajadores | Número desconocido de subtareas, objetivos descomponibles | El supervisor emite DONE o alcanza el presupuesto de pasos |
| Fan-out paralelo | Un despachador, N trabajadores concurrentes, una fusión | Subtareas independientes, sensible a la latencia | Todos los trabajadores retornan, o expira un tiempo de espera |
| Agente único + herramientas | Un agente, múltiples llamadas a herramientas en un solo bucle | La mayoría de las tareas de producción; más simple de razonar y depurar | El agente deja de solicitar herramientas |
MAX_STEPS = 8
def safe_supervisor_loop(goal: str) -> str:
step = 0
history = []
while step < MAX_STEPS:
step += 1
next_action = run_worker(f"Objetivo: {goal}\nHistorial: {history}\nSiguiente paso o DONE:")
if "DONE" in next_action.upper():
break
history.append(next_action)
else:
# El bucle agotó MAX_STEPS sin una señal DONE - tratar como un fallo, no un éxito.
raise RuntimeError(f"El supervisor no terminó dentro de {MAX_STEPS} pasos para el objetivo: {goal}")
return "\n".join(history)Un presupuesto de pasos fijo combinado con una ruta de fallo explícita (en lugar de devolver silenciosamente un resultado parcial) es el patrón que el examen recompensa: un agente que no puede decirte que falló es peor que uno que lanza una excepción.
# Prefiere dataclasses tipados o TypedDicts para las cargas útiles entre agentes en lugar de diccionarios crudos,
# para que un desajuste de esquema entre agentes falle rápidamente en lugar de aparecer como un
# confuso error de formato de prompt descendente.
from typing import TypedDict
class SubtaskResult(TypedDict):
agent: str
task: str
output: str| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| Agente único con un bucle de herramientas | La tarea es acotada y un agente con herramientas puede razonarla de principio a fin | La tarea requiere genuinamente roles distintos o trabajo paralelo independiente |
| Pipeline secuencial | Los pasos y su orden se conocen de antemano | El número u orden de los pasos depende de resultados intermedios |
| Supervisor-trabajador | El número de subtareas es desconocido hasta el tiempo de ejecución y el objetivo se descompone limpiamente | El objetivo es lo suficientemente simple como para que la descomposición añada sobrecarga sin beneficio |
| Fan-out paralelo | Las subtareas son independientes y la latencia importa más que el costo de coordinación | Las subtareas dependen de la salida de las otras, lo que te obliga a volver a lo secuencial |
Porque las decisiones de orquestación (agente único vs. multiagente, qué topología, cómo se maneja la terminación) tienden a ser las decisiones que hacen o deshacen la fiabilidad de un sistema de producción, más que cualquier prompt o definición de herramienta individual.
No. Un agente único bien definido con buenas herramientas suele ser más fiable y económico que un sistema multiagente mal descompuesto; el examen evalúa específicamente el juicio sobre cuándo el multiagente aporta valor real frente a la simple sobrecarga de coordinación.
Cualquier bucle donde la condición de salida dependa de la propia salida del modelo (como emitir "DONE") necesita un límite de pasos fijo como respaldo, ya que un modelo puede no emitir esa señal.
No necesariamente. Asignar un modelo más potente a pasos que requieren mucho juicio (como crítica o síntesis) y un modelo más rápido a pasos mecánicos (como redacción o formato) es una compensación de costo y calidad que el examen espera que razones.
Se refiere a decidir exactamente qué información pasa de un agente al siguiente, en lugar de pasar por defecto todo el historial de conversación, lo que infla el costo de tokens con cada agente adicional en la cadena.
No, típicamente no es más barato. El fan-out reduce la latencia de reloj de pared al ejecutar llamadas independientes concurrentemente, pero cada llamada sigue costando lo mismo en tokens; no confundas "más rápido" con "más barato".
Optar por la arquitectura más compleja (multiagente, multi-paso) cuando un solo agente con un mejor diseño de herramientas resuelve el escenario de manera más fiable y económica.
Se superponen mucho: si un agente necesita un agente auxiliar o solo una mejor herramienta es en sí misma una decisión de orquestación, y una herramienta mal definida a menudo se disfraza de "problema de orquestación" en el examen.
La estrategia de fusión debe decidirse antes del despacho, ya sea que un supervisor arbitre entre las salidas, un voto mayoritario o una simple concatenación, en lugar de improvisarla después.
El dominio evalúa los patrones subyacentes (secuencial, supervisor-trabajador, fan-out paralelo, agente-único-más-herramientas) y el juicio detrás de la elección entre ellos, no la memorización de la API de ningún marco de terceros en particular.
Las cargas útiles tipadas hacen que los desajustes de esquema entre agentes fallen rápidamente y de forma visible, en lugar de aparecer más tarde como un confuso error de formato dentro de un prompt posterior.
Versiones de Stack: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado), y Claude Haiku 4.5 - y el SDK oficial de Python
anthropic(última versión 0.x). Los nombres de los modelos, precios, formato del examen y versiones del SDK cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs y la guía oficial del examen CCA antes de confiar en ellos.
Revisado por Chris St. John·Última actualización: 13 jul 2026