Phase 16 - Lesson 01
Por que Multiagentes?
Um único agente encontra um limite. A jogada inteligente não é um agente maior - são mais agentes.
Type: Learn Languages: TypeScript Prerequisites: Phase 14 (Agent Engineering) Time: ~60 minutos
Objetivos de Aprendizado
- Identificar o teto do agente único (estouro de contexto, especialidades mistas, gargalo sequencial) e explicar quando a divisão em múltiplos agentes é a escolha certa
- Comparar padrões de orquestração (pipeline, fan-out paralelo, supervisor, hierárquico) e selecionar o correto para uma determinada estrutura de tarefa
- Projetar um sistema multiagente com limites claros de papéis, estado compartilhado e um contrato de comunicação
- Analisar os prós e contras da complexidade multiagente (latência, custo, dificuldade de depuração) versus a simplicidade de um agente único
O Problema
Você construiu um único agente na Phase 14. Ele funciona. Ele pode ler arquivos, executar comandos, chamar APIs e raciocinar sobre os resultados. Então você o direciona para uma base de código real: 200 arquivos, três linguagens, testes que dependem de infraestrutura e a necessidade de pesquisar APIs externas antes de escrever o código.
O agente engasga. Não porque o LLM seja burro, mas porque a tarefa excede o que um loop de agente único pode suportar. A janela de contexto fica cheia com o conteúdo dos arquivos. O agente esquece o que leu 40 chamadas de ferramenta atrás. Ele tenta ser um pesquisador, um codificador e um revisor, tudo de uma vez, e faz as três coisas mal.
Esse é o teto do agente único. Você o atinge toda vez que uma tarefa exige:
- Mais contexto do que cabe em uma janela - ler 50 arquivos ultrapassa os 200k tokens
- Diferentes especialidades em diferentes etapas - a pesquisa exige um direcionamento (prompting) diferente da geração de código
- Trabalho que pode ocorrer em paralelo - por que ler três arquivos sequencialmente quando você pode lê-los simultaneamente?
O Conceito
O Teto do Agente Único
Um único agente é um loop, uma janela de contexto, um system prompt. Imagine:
┌─────────────────────────────────────────┐
│ SINGLE AGENT │
│ │
│ ┌───────────────────────────────────┐ │
│ │ Context Window │ │
│ │ │ │
│ │ research notes │ │
│ │ + code files │ │
│ │ + test output │ │
│ │ + review feedback │ │
│ │ + API docs │ │
│ │ + ... │ │
│ │ │ │
│ │ ██████████████████████ FULL ███ │ │
│ └───────────────────────────────────┘ │
│ │
│ One system prompt tries to cover │
│ research + coding + review + testing │
│ │
│ Result: mediocre at everything │
└─────────────────────────────────────────┘
Três coisas falham:
Saturação de contexto - os resultados das ferramentas se acumulam. Na iteração 30, o agente já consumiu 150k tokens de conteúdo de arquivos, saídas de comandos e raciocínios anteriores. Detalhes críticos da iteração 5 se perdem.
Confusão de papéis - um system prompt que diz "você é um pesquisador, codificador, revisor e testador" gera um agente que pesquisa pela metade, codifica pela metade e nunca termina a revisão.
Gargalo sequencial - o agente lê o arquivo A, depois o arquivo B, depois o arquivo C. Três chamadas sequenciais de LLM. Três execuções de ferramentas em série. Sem paralelismo.
A Solução Multiagente
Divida o trabalho. Dê a cada agente uma tarefa, uma janela de contexto e um system prompt ajustado para essa tarefa:
┌──────────────────────────────────────────────────────────┐
│ ORCHESTRATOR │
│ │
│ "Build a REST API for user management" │
│ │
│ ┌──────────┬──────────┬──────────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │RESEARCHER│ │ CODER │ │ REVIEWER │ │ TESTER │ │
│ │ │ │ │ │ │ │ │ │
│ │ Reads │ │ Writes │ │ Checks │ │ Runs │ │
│ │ docs, │ │ code │ │ code │ │ tests, │ │
│ │ finds │ │ based on │ │ quality, │ │ reports │ │
│ │ patterns │ │ research │ │ finds │ │ results │ │
│ │ │ │ + spec │ │ bugs │ │ │ │
│ └─────┬────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ └───────────┴────────────┴─────────────┘ │
│ │ │
│ Merge results │
└──────────────────────────────────────────────────────────┘
Cada agente tem:
- Um system prompt focado ("Você é um revisor de código. Seu único trabalho é encontrar bugs.")
- Sua própria janela de contexto (não poluída pelo trabalho de outros agentes)
- Um contrato claro de entrada/saída (recebe notas de pesquisa, gera código)
Sistemas Reais que Fazem Isso
Subagentes do Claude Code - quando o Claude Code gera um subagente com Task, ele cria um agente filho com uma tarefa com escopo delimitado. O pai mantém seu contexto limpo. O filho faz o trabalho focado e retorna um resumo.
Devin - executa um agente planejador, um agente codificador e um agente de navegador. O planejador divide o trabalho em etapas. O codificador escreve o código. O navegador pesquisa a documentação. Cada um tem um contexto separado.
Equipes de desenvolvimento multiagente (SWE-bench) - os sistemas com melhor desempenho no SWE-bench usam um pesquisador que lê a base de código, um planejador que projeta a correção e um codificador que a implementa. Sistemas de agente único obtêm pontuações mais baixas.
ChatGPT Deep Research - gera múltiplos agentes de busca em paralelo, cada um explorando um ângulo diferente, e depois sintetiza os resultados.
O Espectro
Multiagentes não é algo binário. É um espectro:
SIMPLE ──────────────────────────────────────────── COMPLEX
Single Sub- Pipeline Team Swarm
Agent agents
┌───┐ ┌───┐ ┌───┐───┐ ┌───┐───┐ ┌─┐┌─┐┌─┐
│ A │ │ A │ │ A │ B │ │ A │ B │ │ ││ ││ │
└───┘ └─┬─┘ └───┘─┬─┘ └─┬─┘─┬─┘ └┬┘└┬┘└┬┘
│ │ │ │ ┌┴──┴──┴┐
┌─┴─┐ ┌───┘───┐ │ │ │shared │
│ a │ │ C │ D │ ┌─┴───┴─┐ │ state │
└───┘ └───┘───┘ │ msg │ └───────┘
│ bus │
1 loop Parent + Stage by │ │ N peers,
1 context child tasks stage └───────┘ emergent
Explicit behavior
roles
Agente único (Single agent) - um loop, um prompt. Bom para tarefas simples.
Subagentes (Subagents) - um pai cria filhos para subtarefas focadas. O pai mantém o plano. Os filhos reportam de volta. É isso que o Claude Code faz.
Pipeline - os agentes rodam em sequência. A saída do Agente A torna-se a entrada do Agente B. Bom para fluxos de trabalho em etapas: pesquisa -> código -> revisão -> teste.
Equipe (Team) - os agentes rodam em paralelo com um barramento de mensagens compartilhado. Cada um tem um papel. Um orquestrador coordena. Bom quando diferentes habilidades são necessárias simultaneamente.
Enxame (Swarm) - muitos agentes idênticos ou quase idênticos com estado compartilhado. Sem orquestrador fixo. Os agentes pegam o trabalho de uma fila. Bom para tarefas paralelas de alto rendimento.
Os Quatro Padrões Multiagentes
Padrão 1: Pipeline
Input ──▶ Agent A ──▶ Agent B ──▶ Agent C ──▶ Output
(research) (code) (review)
Cada agente transforma os dados e os passa adiante. Simples de raciocinar sobre. A falha em uma etapa bloqueia o restante.
Padrão 2: Fan-out / Fan-in
┌──▶ Agent A ──┐
│ │
Input ──▶ Split ├──▶ Agent B ──├──▶ Merge ──▶ Output
│ │
└──▶ Agent C ──┘
Divide o trabalho entre agentes paralelos e depois mescla os resultados. Bom para tarefas que se decompõem em subtarefas independentes.
Padrão 3: Orquestrador-Trabalhador (Orchestrator-Worker)
┌──────────┐
│ Orch. │
└──┬───┬───┘
task │ │ task
┌─────┘ └─────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ Worker A │ │ Worker B │
└──────────┘ └──────────┘
Um orquestrador inteligente decide o que fazer, delega para os trabalhadores e sintetiza os resultados. O orquestrador é, ele próprio, um agente com ferramentas para criar trabalhadores.
Padrão 4: Enxame de Pares (Peer Swarm)
┌───┐ ◄──── msg ────▶ ┌───┐
│ A │ │ B │
└─┬─┘ └─┬─┘
│ │
msg │ ┌───────────┐ │ msg
└───▶│ Shared │◄────┘
│ State │
┌───▶│ / Queue │◄────┐
│ └───────────┘ │
msg │ │ msg
┌─┴─┐ ┌─┴─┐
│ C │ ◄──── msg ────▶ │ D │
└───┘ └───┘
Sem orquestrador central. Os agentes se comunicam de igual para igual (peer-to-peer). As decisões surgem da interação. Mais difícil de depurar, mas escala para muitos agentes.
Quando NÃO Usar Multiagentes
Múltiplos agentes adicionam complexidade. Cada mensagem entre agentes é um ponto potencial de falha. A depuração passa de "ler uma única conversa" para "rastrear mensagens em cinco agentes".
Permaneça com agente único quando:
- A tarefa couber em uma janela de contexto (menos de ~100k tokens de dados de trabalho)
- Você não precisar de system prompts diferentes para etapas diferentes
- A execução sequencial for rápida o suficiente
- A tarefa for simples o suficiente para que a divisão adicione mais sobrecarga do que valor
O custo da complexidade:
- Cada limite de agente é uma etapa de compressão com perdas: o contexto completo do agente A é resumido em uma mensagem para o agente B
- A lógica de coordenação (quem faz o quê, quando e em que ordem) é sua própria fonte de bugs
- A latência aumenta: N agentes significam no mínimo N chamadas sequenciais de LLM, e mais se eles precisarem conversar de um lado para o outro
- O custo se multiplica: cada agente consome tokens de forma independente
Regra geral: se uma tarefa leva menos de 20 chamadas de ferramenta e cabe em 100k tokens, mantenha-a como agente único.
Construa
Passo 1: O Agente Único Sobrecarregado
Aqui está um agente único tentando fazer tudo. Ele tem um system prompt massivo e uma única janela de contexto que contém pesquisa, código e revisões:
type AgentResult = {
content: string;
tokensUsed: number;
toolCalls: number;
};
async function singleAgentApproach(task: string): Promise<AgentResult> {
const systemPrompt = `You are a full-stack developer. You must:
1. Research the requirements
2. Write the code
3. Review the code for bugs
4. Write tests
Do ALL of these in a single conversation.`;
const contextWindow: string[] = [];
let totalTokens = 0;
let totalToolCalls = 0;
const research = await fakeLLMCall(systemPrompt, `Research: ${task}`);
contextWindow.push(research.output);
totalTokens += research.tokens;
totalToolCalls += research.calls;
const code = await fakeLLMCall(
systemPrompt,
`Given this research:\n${contextWindow.join("\n")}\n\nNow write code for: ${task}`
);
contextWindow.push(code.output);
totalTokens += code.tokens;
totalToolCalls += code.calls;
const review = await fakeLLMCall(
systemPrompt,
`Given all previous context:\n${contextWindow.join("\n")}\n\nReview the code.`
);
contextWindow.push(review.output);
totalTokens += review.tokens;
totalToolCalls += review.calls;
return {
content: contextWindow.join("\n---\n"),
tokensUsed: totalTokens,
toolCalls: totalToolCalls,
};
}
Problemas com essa abordagem:
- A janela de contexto cresce a cada etapa. Na etapa de revisão, ela contém notas de pesquisa E código E raciocínio anterior.
- O system prompt é genérico. Ele não pode ser ajustado para cada etapa.
- Nada roda em paralelo.
Passo 2: Agentes Especialistas
Agora divida. Cada agente recebe uma tarefa:
type SpecialistAgent = {
name: string;
systemPrompt: string;
run: (input: string) => Promise<AgentResult>;
};
function createSpecialist(name: string, systemPrompt: string): SpecialistAgent {
return {
name,
systemPrompt,
run: async (input: string) => {
const result = await fakeLLMCall(systemPrompt, input);
return {
content: result.output,
tokensUsed: result.tokens,
toolCalls: result.calls,
};
},
};
}
const researcher = createSpecialist(
"researcher",
"You are a technical researcher. Read documentation, find patterns, and summarize findings. Output only the facts needed for implementation."
);
const coder = createSpecialist(
"coder",
"You are a senior TypeScript developer. Given requirements and research notes, write clean, tested code. Nothing else."
);
const reviewer = createSpecialist(
"reviewer",
"You are a code reviewer. Find bugs, security issues, and logic errors. Be specific. Cite line numbers."
);
Cada especialista tem um prompt focado. Cada um recebe uma janela de contexto limpa contendo apenas a entrada de que precisa.
Passo 3: Coordenação por Mensagens
Interligue os especialistas com passagem explícita de mensagens:
type AgentMessage = {
from: string;
to: string;
content: string;
timestamp: number;
};
async function multiAgentApproach(task: string): Promise<AgentResult> {
const messages: AgentMessage[] = [];
let totalTokens = 0;
let totalToolCalls = 0;
const researchResult = await researcher.run(task);
messages.push({
from: "researcher",
to: "coder",
content: researchResult.content,
timestamp: Date.now(),
});
totalTokens += researchResult.tokensUsed;
totalToolCalls += researchResult.toolCalls;
const coderInput = messages
.filter((m) => m.to === "coder")
.map((m) => `[From ${m.from}]: ${m.content}`)
.join("\n");
const codeResult = await coder.run(coderInput);
messages.push({
from: "coder",
to: "reviewer",
content: codeResult.content,
timestamp: Date.now(),
});
totalTokens += codeResult.tokensUsed;
totalToolCalls += codeResult.toolCalls;
const reviewerInput = messages
.filter((m) => m.to === "reviewer")
.map((m) => `[From ${m.from}]: ${m.content}`)
.join("\n");
const reviewResult = await reviewer.run(reviewerInput);
messages.push({
from: "reviewer",
to: "orchestrator",
content: reviewResult.content,
timestamp: Date.now(),
});
totalTokens += reviewResult.tokensUsed;
totalToolCalls += reviewResult.toolCalls;
return {
content: messages.map((m) => `[${m.from} -> ${m.to}]: ${m.content}`).join("\n\n"),
tokensUsed: totalTokens,
toolCalls: totalToolCalls,
};
}
Cada agente recebe apenas as mensagens endereçadas a ele. Sem poluição de contexto. A leitura de 50k tokens de documentação do pesquisador nunca entra no contexto do revisor.
Passo 4: Comparação
async function compare() {
const task = "Build a rate limiter middleware for an Express.js API";
console.log("=== Single Agent ===");
const single = await singleAgentApproach(task);
console.log(`Tokens: ${single.tokensUsed}`);
console.log(`Tool calls: ${single.toolCalls}`);
console.log("\n=== Multi-Agent ===");
const multi = await multiAgentApproach(task);
console.log(`Tokens: ${multi.tokensUsed}`);
console.log(`Tool calls: ${multi.toolCalls}`);
}
A versão multiagente usa mais tokens no total (três agentes, três chamadas de LLM separadas), mas o contexto de cada agente permanece limpo. A qualidade de cada etapa melhora porque o system prompt é especializado.
Use
Esta lição produz um prompt reutilizável para decidir quando adotar múltiplos agentes. Consulte outputs/prompt-multi-agent-decision.md.
Exercícios
- Adicione um quarto especialista: um agente "testador" que recebe o código do codificador e o feedback de revisão do revisor, e então escreve os testes
- Modifique o pipeline para que o revisor possa enviar feedback de volta ao codificador para um loop de revisão (máximo de 2 rodadas)
- Converta o pipeline sequencial em um fan-out: execute o pesquisador e um agente "analisador de requisitos" em paralelo e, em seguida, mescle suas saídas antes de passá-las para o codificador
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| Swarm | "Uma mente de colmeia de agentes de IA" | Um conjunto de agentes pares com estado compartilhado e sem líder fixo. O comportamento surge de interações locais. |
| Orchestrator | "O agente chefe" | Um agente cujas ferramentas incluem gerar e gerenciar outros agentes. Ele planeja e delega, mas pode não fazer o trabalho real. |
| Coordinator | "O guarda de trânsito" | Um componente não agente (geralmente apenas código, não um LLM) que roteia mensagens entre agentes com base em regras. |
| Consensus | "Os agentes concordam" | Um protocolo em que vários agentes devem chegar a um acordo antes de prosseguir. Usado quando saídas conflitantes precisam de resolução. |
| Emergent behavior | "Os agentes descobriram sozinhos" | Padrões em nível de sistema que surgem das interações dos agentes, mas não foram explicitamente programados. Podem ser úteis ou prejudiciais. |
| Fan-out / fan-in | "Map-reduce para agentes" | Divisão de uma tarefa entre agentes paralelos (fan-out) e posterior combinação de seus resultados (fan-in). |
| Message passing | "Agentes conversando entre si" | O mecanismo de comunicação entre agentes: dados estruturados enviados de um agente para outro, substituindo as janelas de contexto compartilhadas. |
Leituras Adicionais
- The Landscape of Emerging AI Agent Architectures - pesquisa sobre padrões multiagentes
- AutoGen: Enabling Next-Gen LLM Applications - framework de conversa multiagente da Microsoft
- Claude Code subagents documentation - como o Claude Code delega tarefas com o Task
- CrewAI documentation - framework multiagente baseado em papéis