Padrões de Orquestrador/Worker com o Claude Agent SDK
Um orquestrador é um agente de nível superior cuja função é decidir qual trabalho distribuir, aguardar ou coletar resultados de subagentes workers e mesclar esses resultados em uma saída coerente.
Resumo
O padrão orquestrador/worker separa duas preocupações: distribuição e síntese.
O orquestrador não realiza o trabalho subjacente. Ele decide qual worker lida com qual parte, envia uma tarefa com escopo para cada worker e coleta o que retorna.
Os workers podem ser executados um após o outro ou lado a lado; o que distingue esse padrão não é a concorrência, mas sim que o orquestrador detém a etapa final de mesclagem.
Essa etapa de mesclagem é a parte difícil. Dois workers raramente retornam resultados com a mesma forma, então o orquestrador precisa ler ambos, reconciliá-los e produzir uma saída sobre a qual um humano ou sistema downstream possa agir.
Esta página cobre a distribuição para workers com o Claude Agent SDK e a escrita de um prompt de orquestrador que realmente sintetiza os resultados dos workers em vez de apenas concatená-los.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
from claude_agent_sdk import query, AgentOptions, SubagentConfig
options = AgentOptions(
allowed_tools=["file_edit"],
subagents=[
SubagentConfig(
name="changelog-worker",
description="Summarizes code changes in a diff as a bullet list.",
allowed_tools=["bash", "file_edit"],
),
SubagentConfig(
name="risk-worker",
description="Flags risky or breaking changes in a diff, with reasoning.",
allowed_tools=["bash"],
),
],
)
async for message in query(
prompt=(
"Dispatch the changelog-worker and risk-worker on this diff, then "
"merge their results into one PR description with a Summary and a "
"Risks section."
),
options=options,
):
if message.get("type") == "text":
print(message["text"], end="", flush=True)Quando usar isso:
- Uma tarefa se decompõe em duas ou mais subtarefas cujos resultados precisam ser reconciliados em uma saída final, não apenas impressos lado a lado.
- As subtarefas são heterogêneas: workers diferentes, escopos de ferramentas diferentes, formas de saída diferentes.
- A ordem importa para a mesclagem, mas não necessariamente para a distribuição (os workers podem ser executados sequencialmente ou concorrentemente; o trabalho do orquestrador começa quando os resultados estão em mãos).
- Você deseja um local em seu prompt ou código que possua "como a resposta final deve ser", separado dos workers que produzem o material bruto para ela.
Exemplo de Trabalho
import asyncio
from claude_agent_sdk import query, AgentOptions, SubagentConfig
async def draft_pr_description(repo_path: str, base_branch: str) -> str:
"""Orchestrate two workers over the same diff and merge their
differently-shaped results into a single PR description."""
options = AgentOptions(
cwd=repo_path,
allowed_tools=[],
subagents=[
SubagentConfig(
name="changelog-worker",
description=(
"Reads a git diff against the base branch and returns a "
"structured bullet list of what changed, grouped by area "
"(api, ui, tests, config)."
),
allowed_tools=["bash"],
tool_config={"bash": {"allowed_commands": ["git diff", "git log"]}},
),
SubagentConfig(
name="risk-worker",
description=(
"Reads a git diff against the base branch and returns a "
"short freeform assessment of breaking changes, migration "
"steps, or rollout risk. No structure required."
),
allowed_tools=["bash"],
tool_config={"bash": {"allowed_commands": ["git diff", "git log"]}},
),
],
)
prompt = (
f"Compare the current branch against '{base_branch}'. Dispatch the "
"changelog-worker for a structured list of changes and the "
"risk-worker for a freeform risk assessment. Wait for both, then "
"merge them into one PR description with exactly two sections: "
"'## Summary' (from the changelog worker's bullets, lightly edited "
"for prose flow) and '## Risks' (from the risk worker's assessment, "
"condensed to at most 3 sentences). Do not just concatenate the two "
"raw results; write them as one cohesive document."
)
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']} returned]")
return final_text
pr_description = asyncio.run(draft_pr_description("/repo", "main"))
print(pr_description)O que isso demonstra:
- Dois workers com escopos de ferramentas diferentes, trabalhos diferentes e formas de saída deliberadamente diferentes: um estruturado (marcadores em texto livre), um em texto livre (avaliação de risco em prosa).
- O próprio orquestrador não precisa de ferramentas (
allowed_tools=[]); seu trabalho é inteiramente distribuir e escrever o resultado mesclado. - A instrução de mesclagem é explícita no prompt: seções de destino exatas e uma instrução explícita de "não apenas concatenar", porque um modelo deixado por conta própria muitas vezes apenas colará ambos os resultados um após o outro.
- Coletar o texto mesclado final das mensagens
"text"do próprio orquestrador, enquanto usa as mensagens"subagent_result"apenas como sinais de progresso, não como o que você retorna.
Mergulho Profundo
Como Funciona
- O orquestrador é o agente de nível superior passado para
query(); os workers são seussubagents, invocados da mesma forma que qualquer ferramenta é invocada, a partir do próprio loop de decisão-ação-observação do orquestrador. - Cada worker executa seu próprio loop interno até a conclusão e retorna um resultado final para o orquestrador; o orquestrador nunca vê as chamadas de ferramenta intermediárias de um worker, apenas sua resposta.
- A ordem de distribuição é uma decisão do orquestrador, impulsionada pelo prompt e pelo próprio raciocínio do modelo: workers independentes podem ser invocados um após o outro para concorrência, ou um após o outro quando a tarefa de um worker posterior depende do resultado de um anterior.
- A mesclagem ocorre dentro do próprio turno de raciocínio final do orquestrador, depois que ele tem os resultados de ambos os workers em contexto. Não há uma "etapa de mesclagem" separada no SDK; é geração de texto comum, então a qualidade da mesclagem é inteiramente uma função de quão claramente seu prompt especifica como o resultado mesclado deve parecer.
- Mensagens
"text"transmitidas em fluxo após a chegada de ambas as mensagens"subagent_result"são o orquestrador sintetizando; essa é a saída que sua aplicação deve tratar como a resposta.
Distribuição Sequencial vs. Paralela
| Estilo de distribuição | Quando | Compromisso |
|---|---|---|
| Sequencial (worker B precisa da saída do worker A) | A tarefa do worker B depende do resultado do worker A | Mais simples de raciocinar, tempo de parede mais lento |
| Paralelo (workers independentes) | Os workers operam na mesma entrada, mas não precisam da saída um do outro | Tempo de parede mais rápido, mas o orquestrador ainda mescla apenas depois que todos retornaram |
| Fan-out, mesclagem única (foco desta página) | Vários workers, uma saída final sintetizada | A instrução de mesclagem importa mais do que a ordem de distribuição |
Notas Python
# Give the orchestrator no tools of its own when its job is purely
# dispatch-and-merge - that keeps its role unambiguous in the prompt
# and prevents it from doing the workers' jobs itself.
options = AgentOptions(
allowed_tools=[],
subagents=[changelog_worker, risk_worker],
)
# Distinguish worker progress from the merged answer while streaming.
async for message in query(prompt=prompt, options=options):
msg_type = message.get("type")
if msg_type == "subagent_result":
continue # raw worker output, not the final merged answer
if msg_type == "text":
merged_output_chunk = message["text"]Parâmetros e Valores de Retorno
| Parâmetro | Tipo | Descrição |
|---|---|---|
subagents | list[SubagentConfig] | Os workers para os quais o orquestrador pode distribuir |
allowed_tools | list[str] | Escopo de ferramentas para o próprio orquestrador, separado do escopo de qualquer worker |
SubagentConfig.name | str | Identificador que o orquestrador usa para invocar um determinado worker |
SubagentConfig.description | str | Informa ao modelo do orquestrador quando este worker se aplica |
SubagentConfig.allowed_tools | list[str] | Escopo de ferramentas apenas para esse worker |
Armadilhas
- Permitir que o modelo concatene em vez de mesclar. Sem uma instrução explícita, um orquestrador muitas vezes colará o resultado bruto de cada worker um após o outro sob cabeçalhos separados em vez de sintetizá-los. Correção: declare a estrutura de saída de destino e diga explicitamente que os resultados devem ser combinados, não concatenados.
- Dar ao orquestrador a união de todas as ferramentas dos workers. Isso confunde quem é responsável pelo quê e permite que o orquestrador pule a distribuição e faça o trabalho sozinho. Correção: escopo o orquestrador de forma restrita, muitas vezes sem ferramentas quando seu único trabalho é mesclar texto.
- Tratar mensagens
subagent_resultcomo a resposta final. Estes são resultados por worker; a lógica da sua aplicação precisa continuar lendo até as mensagens"text"do próprio orquestrador, que contêm a saída sintetizada. Correção: acumule mensagens"text"após a distribuição como a resposta, e use"subagent_result"apenas para registro de progresso. - Forçar a distribuição paralela quando um worker depende da saída de outro. Distribuir ambos os workers ao mesmo tempo quando o worker B realmente precisa do resultado do worker A produz um worker B que está adivinhando. Correção: sequencie workers dependentes no prompt e invoque workers independentes apenas concorrentemente.
- Sem limite de quantos workers o orquestrador pode distribuir. Um prompt em aberto ("use quaisquer workers que precisar") pode levar a muito mais distribuições e gastos de tokens do que a tarefa justifica. Correção: nomeie os workers específicos a serem usados no prompt, ou limite a contagem e a profundidade dos subagentes na lógica da sua aplicação.
- Instruções de mesclagem vagas que deixam a forma da saída ao acaso. "Combine os resultados" sem especificar seções ou formato produz resultados inconsistentes entre as execuções. Correção: especifique a estrutura de destino exata (nomes de seção, ordenação, limites de comprimento) da mesma forma que você especificaria o tipo de retorno de uma função.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Um único agente fazendo tudo sozinho | A tarefa não se decompõe realmente em peças independentes | Duas ou mais peças genuinamente separáveis precisam de escopos de ferramentas diferentes ou, de outra forma, lotariam um contexto |
| Delegação simples de subagentes sem etapa de mesclagem | Você só precisa do resultado bruto de cada worker, reportado separadamente | Você precisa de uma saída final coerente sintetizada a partir de múltiplos resultados |
| Encadeamento de prompts (a saída de cada etapa alimenta a próxima) | As etapas são estritamente sequenciais e cada uma só precisa da saída da etapa anterior | Múltiplos workers independentes precisam ser reconciliados juntos, não apenas passados adiante um de cada vez |
| Mesclagem manual no código da aplicação (não no modelo) | A mesclagem é determinística e baseada em regras, por exemplo, concatenando dois blobs JSON | A mesclagem requer julgamento, como síntese de prosa ou resolução de descobertas conflitantes de workers |
FAQs
O que exatamente significa "orquestrador" neste padrão?
O agente de nível superior em uma chamada query() que tem um ou mais subagents configurados. Ele decide o que distribuir, quando, e é responsável por produzir a saída final após o retorno dos workers.
Os workers precisam rodar em paralelo para que isso seja um padrão orquestrador/worker?
Não. O que define o padrão é que o orquestrador distribui para os workers e detém a etapa de mesclagem, não a concorrência. A distribuição sequencial, onde o resultado de um worker é usado para informar ou alimentar o próximo, é igualmente válida.
Como isso é diferente de apenas delegar para subagentes?
A delegação é o mecanismo; orquestrador/worker é uma divisão de papéis construída sobre ela, onde o próprio trabalho do orquestrador é explicitamente enquadrado como distribuição mais mesclagem em vez de realizar o trabalho da tarefa em si.
O orquestrador deve ter suas próprias ferramentas?
Somente se ele precisar fazer algo além de distribuir e mesclar, como gravar o resultado final em um arquivo. Quando seu trabalho é puramente síntese, uma lista allowed_tools vazia mantém seu papel inequívoco.
Como obtenho a saída mesclada do fluxo de mensagens?
Acumule as mensagens "text" do orquestrador. As mensagens "subagent_result" carregam o resultado bruto de cada worker e são úteis para registrar o progresso, mas a resposta sintetizada vem da própria geração de texto do orquestrador depois que ele tem ambos os resultados.
E se o modelo apenas concatenar os resultados dos workers em vez de mesclá-los?
Este é o modo de falha mais comum. Declare a estrutura de destino exata no prompt (nomes de seção, ordenação, limites de comprimento) e instrua explicitamente contra a concatenação; instruções vagas como "combine estes" resultam em colar os resultados um após o outro.
A saída de um worker pode alimentar a entrada de outro worker?
Sim, essa é a distribuição sequencial. Instrua o orquestrador a distribuir o primeiro worker, usar seu resultado para construir o prompt para o segundo e, somente então, mesclar. O SDK não exige que os workers sejam independentes, apenas que você os sequencie corretamente quando dependentes.
Quantos workers um orquestrador pode distribuir?
Quantos subagents definirem, mas mais workers significam mais decisões de distribuição, mais gastos de tokens e uma mesclagem mais difícil. Nomeie os workers específicos necessários no prompt em vez de deixar a contagem de distribuição em aberto.
O orquestrador vê o raciocínio intermediário de cada worker?
Não. Cada worker executa seu próprio loop interno e retorna apenas um resultado final; o contexto do orquestrador permanece limpo das etapas exploratórias dos workers.
Quais salvaguardas são importantes especificamente para configurações de orquestrador/worker?
As mesmas três de qualquer configuração multiagente: limite a profundidade dos subagentes (evite que workers criem seus próprios workers, a menos que realmente necessário), escopo o acesso a ferramentas de cada worker para o privilégio mínimo para seu trabalho e limite o gasto total de tokens entre distribuição e mesclagem, pois uma etapa de síntese lê o resultado completo de cada worker no contexto.
A etapa de mesclagem é uma chamada de ferramenta?
Não. A distribuição para um worker é uma chamada de ferramenta; a mesclagem é geração de texto comum pelo orquestrador assim que ele tem todos os resultados necessários em contexto. Não há um primitivo SDK separado para mesclagem.
Quando um único agente é melhor do que um orquestrador com workers?
Quando a tarefa não se decompõe realmente em peças independentes ou com escopos diferentes. Um único loop de chamada de ferramenta é suficiente para a maioria das tarefas; use orquestrador/worker apenas quando as subtarefas forem genuinamente separáveis ou precisarem de acesso a ferramentas diferentes.
Relacionado
- Loops de Agente Único vs. Sistemas Multiagente - quando este padrão vale a pena pela complexidade adicionada
- Noções Básicas de Orquestração de Agentes - conceitos fundamentais de orquestração nos quais este padrão se baseia
- Construindo Subagentes para Pesquisa e Delegação Paralelas - a contraparte de fan-out paralelo ao foco de mesclagem desta página
- Salvaguardas para Sistemas Multiagente - limitando a profundidade dos subagentes, o acesso a ferramentas e o gasto de tokens
- Delegando Trabalho para Subagentes no Claude Agent SDK - o mecanismo subjacente de subagentes no qual este padrão é construído
- O Modelo Mental do Claude Agent SDK - como o loop de uso de ferramentas sustenta tanto o orquestrador quanto o worker
Versões da Stack: Escrito contra a linha de modelos Claude atual em ~junho de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (o padrão), e Claude Haiku 4.5 - e o Claude Agent SDK (última versão). Nomes de modelos, versões de SDK e preços mudam rapidamente - verifique os detalhes atuais em platform.claude.com/docs antes de confiar neles.