Patrones de Orquestador/Trabajador con el Claude Agent SDK
Un orquestador es un agente de nivel superior cuya tarea consiste en decidir qué trabajo distribuir, esperar o recopilar resultados de los subagentes trabajadores y fusionar esos resultados en una salida coherente.
Resumen
El patrón orquestador/trabajador separa dos preocupaciones: la distribución y la síntesis.
El orquestador no realiza el trabajo subyacente por sí mismo. Decide qué trabajador maneja qué parte, envía a cada trabajador una tarea con ámbito definido y recopila lo que regresa.
Los trabajadores pueden ejecutarse uno tras otro o uno al lado del otro; lo que distingue a este patrón no es la concurrencia, sino que el orquestador posee el paso final de fusión.
Ese paso de fusión es la parte difícil. Dos trabajadores rara vez devuelven resultados con la misma forma, por lo que el orquestador tiene que leer ambos, reconciliarlos y producir una salida sobre la que un humano o un sistema descendente pueda actuar.
Esta página cubre la distribución a trabajadores con el Claude Agent SDK y la escritura de un prompt de orquestador que realmente sintetice los resultados de los trabajadores en lugar de simplemente concatenarlos.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
from claude_agent_sdk import query, AgentOptions, SubagentConfig
options = AgentOptions(
allowed_tools=["file_edit"],
subagents=[
SubagentConfig(
name="changelog-worker",
description="Resume los cambios de código en un diff como una lista de viñetas.",
allowed_tools=["bash", "file_edit"],
),
SubagentConfig(
name="risk-worker",
description="Marca cambios arriesgados o incompatibles en un diff, con razonamiento.",
allowed_tools=["bash"],
),
],
)
async for message in query(
prompt=(
"Distribuye el changelog-worker y el risk-worker sobre este diff, luego "
"fusiona sus resultados en una única descripción de PR con un Resumen y una "
"sección de Riesgos."
),
options=options,
):
if message.get("type") == "text":
print(message["text"], end="", flush=True)Cuándo recurrir a esto:
- Una tarea se descompone en dos o más subtareas cuyos resultados deben reconciliarse en una salida final, no solo imprimirse una al lado de la otra.
- Las subtareas son heterogéneas: trabajadores diferentes, ámbitos de herramientas diferentes, formas de salida diferentes.
- El orden importa para la fusión, pero no necesariamente para la distribución (los trabajadores pueden ejecutarse secuencialmente o concurrentemente; el trabajo del orquestador comienza una vez que se tienen los resultados).
- Quieres un lugar en tu prompt o código que posea "cómo se ve la respuesta final", separado de los trabajadores que producen la materia prima para ella.
Ejemplo de Trabajo
import asyncio
from claude_agent_sdk import query, AgentOptions, SubagentConfig
async def draft_pr_description(repo_path: str, base_branch: str) -> str:
"""Orquesta dos trabajadores sobre el mismo diff y fusiona sus
resultados de forma diferente en una única descripción de PR."""
options = AgentOptions(
cwd=repo_path,
allowed_tools=[],
subagents=[
SubagentConfig(
name="changelog-worker",
description=(
"Lee un diff de git contra la rama base y devuelve una "
"lista estructurada de lo que cambió, agrupado por área "
"(api, ui, tests, config)."
),
allowed_tools=["bash"],
tool_config={"bash": {"allowed_commands": ["git diff", "git log"]}},
),
SubagentConfig(
name="risk-worker",
description=(
"Lee un diff de git contra la rama base y devuelve una "
"evaluación breve y libre de cambios incompatibles, pasos de "
"migración o riesgo de despliegue. No se requiere estructura."
),
allowed_tools=["bash"],
tool_config={"bash": {"allowed_commands": ["git diff", "git log"]}},
),
],
)
prompt = (
f"Compara la rama actual contra '{base_branch}'. Distribuye el "
"changelog-worker para una lista estructurada de cambios y el "
"risk-worker para una evaluación de riesgos libre. Espera a ambos, luego "
"fusiona en una descripción de PR con exactamente dos secciones: "
"'## Resumen' (de las viñetas del changelog worker, ligeramente editadas "
"para fluidez de prosa) y '## Riesgos' (de la evaluación del risk worker, "
"condensada a un máximo de 3 frases). No te limites a concatenar los dos "
"resultados brutos; escríbelos como un documento cohesivo."
)
final_text = ""
async for message in query(prompt=prompt, options=options):
if message.get("type") == "text":
final_text += message["text"]
elif message.get("type") == "subagent_result":
print(f"[{message['subagent_name']} devolvió]")
return final_text
pr_description = asyncio.run(draft_pr_description("/repo", "main"))
print(pr_description)Lo que esto demuestra:
- Dos trabajadores con diferentes ámbitos de herramientas, diferentes trabajos y formas de salida deliberadamente diferentes: uno estructurado (viñetas agrupadas), uno libre (evaluación de riesgos en prosa).
- El orquestador en sí no necesita herramientas (
allowed_tools=[]); su trabajo completo es la distribución y la escritura del resultado fusionado. - La instrucción de fusión es explícita en el prompt: secciones de destino exactas y una instrucción explícita de "no concatenar", porque un modelo dejado a su suerte a menudo simplemente pegará ambos resultados uno detrás del otro.
- Recopilar el texto fusionado final de los mensajes
"text"del propio orquestador, mientras se utilizan los mensajes"subagent_result"solo como señales de progreso, no como lo que se devuelve.
Profundización
Cómo Funciona
- El orquestador es el agente de nivel superior pasado a
query(); los trabajadores son sussubagents, invocados de la misma manera que se invoca cualquier herramienta, desde el propio bucle decidir-actuar-observar del orquestador. - Cada trabajador ejecuta su propio bucle interno hasta completarse y devuelve un resultado final al orquestador; el orquestador nunca ve las llamadas intermedias a herramientas de un trabajador, solo su respuesta.
- El orden de distribución es decisión del orquestador, impulsado por el prompt y el propio razonamiento del modelo: los trabajadores independientes pueden invocarse uno tras otro para concurrencia, o uno después del otro cuando la tarea de un trabajador posterior depende del resultado de uno anterior.
- La fusión ocurre dentro del propio turno de razonamiento final del orquestador, después de que tiene los resultados de ambos trabajadores en contexto. No hay un "paso de fusión" separado en el SDK; es generación de texto ordinaria, por lo que la calidad de la fusión es enteramente una función de cuán claramente tu prompt especifica cómo debería verse la salida fusionada.
- Los mensajes
"text"transmitidos después de que todos los mensajes"subagent_result"hayan llegado son el orquestador sintetizando; esa es la salida que tu aplicación debe tratar como la respuesta.
Distribución Secuencial vs. Paralela
| Estilo de distribución | Cuándo | Compromiso |
|---|---|---|
| Secuencial (el trabajador B necesita la salida del trabajador A) | La tarea del trabajador B depende del resultado del trabajador A | Más fácil de razonar, tiempo de reloj más lento |
| Paralelo (trabajadores independientes) | Los trabajadores operan sobre la misma entrada pero no necesitan la salida del otro | Tiempo de reloj más rápido, pero el orquestador aún fusiona solo después de que todos han regresado |
| Abanico, fusión única (enfoque de esta página) | Varios trabajadores, una salida final sintetizada | La instrucción de fusión importa más que el orden de distribución |
Notas de Python
# Dale al orquestador ninguna herramienta propia cuando su trabajo sea puramente
# distribución y fusión; eso mantiene su rol inequívoco en el prompt
# y evita que haga el trabajo de los trabajadores por sí mismo.
options = AgentOptions(
allowed_tools=[],
subagents=[changelog_worker, risk_worker],
)
# Distingue el progreso del trabajador de la respuesta fusionada durante la transmisión.
async for message in query(prompt=prompt, options=options):
msg_type = message.get("type")
if msg_type == "subagent_result":
continue # salida bruta del trabajador, no la respuesta fusionada final
if msg_type == "text":
merged_output_chunk = message["text"]Parámetros y Valores de Retorno
| Parámetro | Tipo | Descripción |
|---|---|---|
subagents | list[SubagentConfig] | Los trabajadores a los que el orquestador puede distribuir |
allowed_tools | list[str] | Ámbito de herramientas para el propio orquestador, separado de cualquier ámbito de trabajador |
SubagentConfig.name | str | Identificador que el orquestador usa para invocar a un trabajador dado |
SubagentConfig.description | str | Indica al modelo del orquestador cuándo se aplica este trabajador |
SubagentConfig.allowed_tools | list[str] | Ámbito de herramientas solo para ese trabajador |
Trampas Comunes
- Dejar que el modelo concatene en lugar de fusionar. Sin una instrucción explícita, un orquestador a menudo pegará el resultado bruto de cada trabajador uno detrás del otro bajo encabezados separados en lugar de sintetizarlos. Solución: declara la estructura de salida de destino e instruye explícitamente que los resultados deben combinarse, no concatenarse.
- Dar al orquestador la unión de todas las herramientas de los trabajadores. Esto difumina quién es responsable de qué y permite al orquestador omitir la distribución y hacer el trabajo él mismo. Solución: limita el orquestador de forma estrecha, a menudo a ninguna herramienta en absoluto cuando su único trabajo es fusionar texto.
- Tratar los mensajes
subagent_resultcomo la respuesta final. Estos son resultados por trabajador; la lógica de tu aplicación debe seguir leyendo hasta los mensajes"text"del orquestador, que contienen la salida sintetizada. Solución: acumula los mensajes"text"después de la distribución como la respuesta, y usa"subagent_result"solo para registrar el progreso. - Forzar la distribución paralela cuando un trabajador depende de la salida de otro. Distribuir ambos trabajadores a la vez cuando el trabajador B en realidad necesita el resultado del trabajador A produce un trabajador B que está adivinando. Solución: secuencia los trabajadores dependientes en el prompt, y solo invoca a los trabajadores independientes concurrentemente.
- Sin límite en cuántos trabajadores puede distribuir el orquestador. Un prompt abierto ("usa los trabajadores que necesites") puede generar muchas más distribuciones, y mucho más gasto de tokens, de lo que la tarea justifica. Solución: nombra los trabajadores específicos a usar en el prompt, o limita el número y la profundidad de los subagentes en la lógica de tu aplicación.
- Instrucciones de fusión vagas que dejan la forma de la salida al azar. "Combina los resultados" sin especificar secciones o formato produce una salida inconsistente entre ejecuciones. Solución: especifica la estructura de destino exacta (encabezados de sección, orden, límites de longitud) de la misma manera que especificarías el tipo de retorno de una función.
Alternativas
| Alternativa | Usar Cuándo | No Usar Cuándo |
|---|---|---|
| Un solo agente haciendo todo por sí mismo | La tarea no se descompone realmente en piezas independientes | Dos o más subtareas genuinamente separables necesitan ámbitos de herramientas diferentes o de lo contrario abarrotarían un contexto |
| Delegación simple de subagentes sin paso de fusión | Solo necesitas el resultado bruto de cada trabajador, reportado por separado | Necesitas una salida final coherente sintetizada a partir de múltiples resultados |
| Encadenamiento de prompts (la salida de cada paso alimenta al siguiente) | Los pasos son estrictamente secuenciales y cada uno solo necesita la salida del paso anterior | Múltiples trabajadores independientes necesitan ser reconciliados juntos, no solo pasados uno a la vez |
| Fusión manual en el código de la aplicación (no el modelo) | La fusión es determinista y basada en reglas, por ejemplo, concatenar dos blobs JSON | La fusión requiere juicio, como síntesis de prosa o resolución de hallazgos conflictivos de trabajadores |
Preguntas Frecuentes
¿Qué significa "orquestador" en este patrón, exactamente?
El agente de nivel superior en una llamada query() que tiene uno o más subagents configurados. Decide qué distribuir, cuándo, y es responsable de producir la salida final después de que los trabajadores regresan.
¿Tienen que ejecutarse los trabajadores en paralelo para que esto sea un patrón de orquestador/trabajador?
No. Lo que define el patrón es que el orquestador distribuye a los trabajadores y posee el paso de fusión, no la concurrencia. La distribución secuencial, donde el resultado de un trabajador se utiliza para informar o alimentar al siguiente, es igualmente válida.
¿En qué se diferencia esto de simplemente delegar a subagentes?
La delegación es el mecanismo; orquestador/trabajador es una división de roles construida sobre ella, donde el propio trabajo del orquestador se enmarca explícitamente como distribución más fusión en lugar de hacer el trabajo de la tarea en sí.
¿Debería el orquestador tener sus propias herramientas?
Solo si necesita hacer algo más allá de la distribución y la fusión, como escribir el resultado final en un archivo. Cuando su trabajo es puramente síntesis, una lista allowed_tools vacía mantiene su rol inequívoco.
¿Cómo obtengo la salida fusionada del stream de mensajes?
Acumula los mensajes "text" del orquestador. Los mensajes "subagent_result" transportan el resultado bruto de cada trabajador y son útiles para registrar el progreso, pero la respuesta sintetizada proviene de la propia generación de texto del orquestador después de que tiene ambos resultados.
¿Qué pasa si el modelo simplemente concatena los resultados de los trabajadores en lugar de fusionarlos?
Este es el modo de fallo más común. Especifica la estructura de destino exacta en el prompt (nombres de sección, orden, límites de longitud) e instruye explícitamente en contra de la concatenación; las instrucciones vagas como "combina estos" por defecto pegan los resultados uno detrás del otro.
¿Puede la salida de un trabajador alimentar la entrada de otro trabajador?
Sí, eso es distribución secuencial. Instruye al orquestador para que distribuya el primer trabajador, use su resultado para construir el prompt para el segundo, y solo entonces fusione. El SDK no requiere que los trabajadores sean independientes, solo que secuencies los dependientes correctamente.
¿Cuántos trabajadores puede distribuir un orquestador?
Tantos como defina subagents, pero más trabajadores significan más decisiones de distribución, más gasto de tokens y una fusión más difícil. Nombra los trabajadores específicos necesarios en el prompt en lugar de dejar el recuento de distribución abierto.
¿Ve el orquestador el razonamiento intermedio de cada trabajador?
No. Cada trabajador ejecuta su propio bucle interno y devuelve solo un resultado final; el contexto del orquestador se mantiene limpio de los pasos exploratorios de los trabajadores.
¿Qué salvaguardias son específicas para las configuraciones de orquestador/trabajador?
Las mismas tres que para cualquier configuración multiagente: limita la profundidad de los subagentes (evita que los trabajadores generen sus propios trabajadores a menos que sea realmente necesario), limita el acceso a herramientas de cada trabajador al mínimo privilegio para su trabajo, y limita el gasto total de tokens entre la distribución y la fusión, ya que un paso de síntesis lee el resultado completo de cada trabajador en contexto.
¿Es el paso de fusión en sí mismo una llamada a herramienta?
No. La distribución a un trabajador es una llamada a herramienta; la fusión es generación de texto ordinaria por parte del orquestador una vez que tiene todos los resultados que necesita en contexto. No hay una primitiva de SDK separada para la fusión.
¿Cuándo es mejor un solo agente que un orquestador con trabajadores?
Cuando la tarea no se descompone realmente en piezas independientes o con ámbitos diferentes. Un solo bucle de llamada a herramientas es suficiente para la mayoría de las tareas; recurre a orquestador/trabajador solo cuando las subtareas son genuinamente separables o necesitan acceso a herramientas diferentes.
Relacionado
- Bucles de Agente Único vs. Sistemas Multiagente - cuándo este patrón vale la pena la complejidad añadida
- Conceptos Básicos de Orquestación Agentica - conceptos fundamentales de orquestación sobre los que se basa este patrón
- Creación de Subagentes para Investigación y Delegación Paralela - la contraparte de abanico paralelo al enfoque de fusión de esta página
- Salvaguardias para Sistemas Multiagente - limitando la profundidad de subagentes, el acceso a herramientas y el gasto de tokens
- Delegación de Trabajo a Subagentes en el Claude Agent SDK - el mecanismo subyacente de subagentes sobre el que se construye este patrón
- El Modelo Mental del Claude Agent SDK - cómo el bucle de uso de herramientas sustenta tanto al orquestador como al trabajador
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 Claude Agent SDK (última versión). Los nombres de los modelos, las versiones del SDK y los precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.