Agent Mentor Learn
De loops a grafos: engenharia de orquestração para sistemas de agentes · Lição 2 de 6

Lição 2: Encadeie, roteie: encadeamento e roteamento

Objetivos de aprendizado:

  • Quebrar um prompt que faz quatro tarefas em uma cadeia e enunciar o que você está trocando e o que está ganhando
  • Instalar gates programáticos entre os estágios da cadeia para que resultados intermediários fora do padrão parem onde deveriam
  • Decidir quando uma tarefa precisa de encadeamento, de roteamento, dos dois ou de nenhum, e escrever a chamada de roteamento como uma chamada barata com a saída apertada

Pré-requisitos: Ler a Lição 1, saber escrever à mão um loop de harness dirigido por stop_reason (curso 7 desta série), entender verificadores determinísticos (curso 10 desta série) | Anterior: << Lição 1 | Próxima: Lição 3 >>

Um prompt fazendo quatro coisas — uma vai cair

Você precisa escrever a documentação de ajuda de um recurso novo: ler os requisitos do produto → rascunhar um esboço → escrever o texto completo com base no esboço → conferir o documento em busca de terminologia descontinuada.

Sua primeira versão provavelmente enfia as quatro etapas em um prompt só e entrega isso a um loop de harness. A primeira execução parece boa. O problema aparece na segunda, e na terceira: desta vez o esboço está bom, mas falta uma seção no texto; da próxima o texto está completo, mas vem misturado com “grupos de usuários”, que foi descontinuado na versão passada; depois ele reescreve o esboço no meio do caminho e entrega um esboço que não bate com o texto.

Essas falhas parecem diferentes na superfície, mas têm a mesma raiz: em uma chamada só, o modelo tem que fazer malabarismo simultâneo com entender requisitos, projetar estrutura, gerar texto e fazer conferências de consistência. Você não controla qual delas vai ser espremida para fora, e não consegue ver isso acontecendo. Pior, você não tem onde intervir — quando a saída chega às suas mãos, as quatro coisas já foram feitas, e “o esboço não atendeu à especificação” está enterrado dentro da versão final.

A Lição 1 discutiu o eixo de “quem detém o plano”. Este prompt de uma tacada só entrega o plano inteiro ao modelo. A primeira coisa que esta lição faz é retomá-lo.

Encadeamento: trocar latência por acurácia

A definição oficial deste padrão tem só duas frases, e cada palavra carrega peso.

O encadeamento de prompts decompõe uma tarefa em uma sequência de etapas, em que cada chamada de LLM processa a saída da anterior. Você pode acrescentar verificações programáticas (veja “gate” no diagrama abaixo) em quaisquer etapas intermediárias para garantir que o processo continua nos trilhos1. Quando usar este fluxo de trabalho: ele é ideal para situações em que a tarefa pode ser decomposta de forma fácil e limpa em subtarefas fixas. O objetivo principal é trocar latência por mais acurácia, tornando cada chamada de LLM uma tarefa mais fácil1.

“Tornar cada chamada de LLM uma tarefa mais fácil” — essa meia-frase dá o diagnóstico e a cura. Uma chamada fazendo quatro coisas é uma tarefa difícil; uma chamada que só rascunha um esboço e não escreve nada é uma tarefa fácil. O encadeamento não reduz o trabalho — ele torna mais simples o trabalho que o modelo precisa concluir em cada chamada.

O custo está impresso bem na etiqueta de preço: latência. Cada estágio a mais acrescenta uma ida e volta completa. A Anthropic apresentou essa contabilidade logo no começo do mesmo artigo — sistemas agênticos com frequência trocam latência e custo por melhor desempenho na tarefa, e você deveria considerar quando essa troca faz sentido1. “Lento e caro” não é um efeito colateral acidental do encadeamento.

text
Requisitos ──▶ Rascunhar esboço ──▶ Escrever o texto ──▶ Conferir termos ──▶ Entregar

A entrada de cada trecho é a saída do trecho anterior. Se um elo sai torto, tudo o que vem depois vai atrás.

Cada estágio é um loop de harness completo

Um estágio da cadeia não é “uma chamada de API” — é um loop de harness completo. O mesmo while que você escreveu à mão no curso 7 desta série: manda messages, confere o stop_reason, se for tool_use executa a ferramenta e devolve o resultado, senão retorna o texto.

Esse uso tem fonte. Quando a Anthropic descreveu como avaliar agentes, a montagem recomendada tinha exatamente esta forma: chamadas diretas à API do LLM, loops agênticos simples (loops while envolvendo chamadas alternadas de API do LLM e de ferramentas), um loop por tarefa de avaliação, cada agente de avaliação recebendo um único prompt de tarefa e as suas ferramentas2. Aquele artigo era sobre avaliação, mas o bloco de construção em si é de uso geral: uma tarefa, um loop, dirigido por código. Encadear é enfileirar esses blocos com o código decidindo a ordem.

O resto das lições usa a mesma notação:

A cadeia inteira é código sequencial que você lê de bate-pronto:

Repare no que não está nestas linhas: não há espaço para “o modelo decide o que fazer em seguida”. A sequência está fixada no código, e os resultados intermediários outline e doc são variáveis comuns do script. O modelo continua autônomo dentro de cada estágio (pode chamar ferramentas quantas vezes quiser), mas o controle entre estágios está nas mãos do código. Um benefício lateral: o prompt de cada estágio pode ser rigoroso a respeito de uma coisa só. O prompt do esboço exige apenas títulos e proíbe qualquer corpo de texto; o prompt de escrita foca em estilo e termos proibidos — essas duas listas de exigências brigariam se fossem empacotadas em um prompt só.

Essa forma aparece também em produtos. A documentação oficial do Claude Code recomenda, para fluxos de trabalho de várias etapas: peça ao Claude que use subagentes em sequência, cada um concluindo sua tarefa e devolvendo resultados ao Claude, que então passa o contexto relevante ao subagente seguinte3. A diferença aterrissa no eixo da Lição 1 — na forma de produto, o Claude decide “o que passar”; quando você escreve o script, isso é o seu código.

Gates: mover os verificadores do curso 10 para entre os estágios

A última meia-frase da definição é o que o encadeamento realmente acrescenta para além de “um prompt grande”: você pode acrescentar verificações programáticas em quaisquer etapas intermediárias para garantir que o processo continua nos trilhos1. O texto original chama essas verificações de “gate”, e com aspas: (see "gate" in the diagram below) — uma aspa reta, outra curva, exatamente como na fonte; não é erro de digitação aqui.

“Programáticas” é a palavra-chave: é código, não outra chamada de modelo, só uns if.

O curso 10 desta série ensinou verificadores determinísticos: quando algo pode ser julgado certo ou errado por código, não gaste dinheiro perguntando ao modelo. Aquele curso instalava verificadores no estado terminal — depois que tudo roda, confira se a saída é aceitável. O encadeamento oferece um novo local para a mesma verificação: entre os estágios.

Sete linhas, nenhuma chamada de modelo, e a mesma entrada sempre produz o mesmo julgamento. Isso barra exatamente aquela falha de “texto misturado com termos descontinuados”; um gate que conta quantos títulos de capítulo há no esboço é igualmente simples.

O que fazer quando um gate reprova é uma decisão de projeto: parar e reportar o erro (melhor quando você ainda está ajustando esta cadeia, mas a mensagem de falha precisa dizer qual estágio falhou, senão você só sabe “não funcionou”, e não qual prompt de estágio consertar), devolver o motivo da falha ao prompt do mesmo estágio e tentar de novo (com um teto de tentativas), ou registrar e continuar com um valor de fallback (só quando esse estágio não é estrutural). O exercício do Nível 2 usa a primeira abordagem.

Isso também acerta as contas do curso 6 desta série: o trabalho que você delega precisa ter prompts autocontidos — objetivo, formato de saída, ferramentas disponíveis, fronteiras, os quatro escritos. A tarefa de cada estágio é um prompt de delegação exatamente com essa forma. Esses quatro elementos têm uma fonte primária precisa, que a Lição 4 vai desdobrar item a item ao cobrir como orquestradores delegam.

Roteamento: classificar primeiro, despachar depois

O encadeamento cuida de “uma tarefa quebrada em etapas”. Outra classe de tarefas tem forma completamente diferente: o que entra não é uma coisa, são vários tipos de coisa, cada um com seu próprio tratamento.

A definição oficial: o roteamento classifica uma entrada e a direciona a uma tarefa de continuação especializada. Este fluxo de trabalho permite separação de responsabilidades e a construção de prompts mais especializados. Sem ele, otimizar para um tipo de entrada pode prejudicar o desempenho em outras entradas1.

A última frase é o motivo de o roteamento existir. Suponha que os e-mails de clientes caiam em três categorias: reembolso, incidente, cobrança. Você usa um prompt para tratar de tudo. Para tratar bem os reembolsos, você acrescenta uma linha “primeiro confirme o número do pedido e o meio de pagamento”; essa regra é puro ruído para e-mails de incidente, e o modelo vai usá-la para pedir o meio de pagamento a quem está relatando uma página em branco. Você acrescenta outra linha, “se for incidente, não peça número do pedido”, e o prompt começa a criar remendo sobre remendo.

Quando usar este fluxo de trabalho: o roteamento funciona bem para tarefas complexas em que existem categorias distintas que são mais bem tratadas em separado, e em que a classificação pode ser feita com acurácia, seja por um LLM, seja por um modelo ou algoritmo de classificação mais tradicional1. Essa última precondição não é enfeite de bolo: se a classificação erra, ela erra de um jeito furtivo — um e-mail de reembolso roteado para o fluxo de incidentes recebe uma resposta conscienciosa de diagnóstico de problema.

Em código, o roteamento é mais simples que o encadeamento:

Três coisas que valem atenção.

Aperte a saída da chamada de classificação até uma palavra — o curso 10 desta série usou o mesmo truque ao discutir juízes LLM: liste os valores permitidos, diga que não quer explicação; apertar a saída torna determinística a etapa de parsing. Se não bater com a tabela, vá para o fallback — aquela linha LABELS.includes(label) ? label : 'other' não é pedantismo defensivo. O modelo às vezes devolve “acho que pode ser incidente, ou talvez outra coisa”, e aí HANDLERS[essa string toda] é undefined e a linha seguinte quebra. Deixe um ramo de fallback e a incerteza da classificação fica contida nesta única linha.

O classificador não precisa ser um modelo — a definição diz explicitamente que modelos ou algoritmos de classificação tradicionais também valem1. Se o e-mail carrega um formato fixo de número de pedido ou vem de um ponto de entrada de formulário dedicado, uma regex basta e é muito mais rápida.

Depois do despacho, cada handler pode ser qualquer coisa: um loop de harness, uma cadeia, até um trecho de código completamente sem modelo.

Duas variantes de roteamento no vocabulário atual da API

A definição de roteamento acima vem do artigo de padrões do fim de 2024, que carrega um aviso dizendo que suas descrições do ecossistema de ferramentas estão desatualizadas. Então vale conferir: este padrão continua vivo no vocabulário atual de primeira mão? Sim, e é nomeado explicitamente. A documentação de orquestração multiagente da plataforma Claude tem duas entradas que são roteamento:

  • Specialization: rotear para agentes com prompts de sistema e ferramentas focados em domínio, como um agente de segurança ou um agente de documentação, em vez de carregar um único agente com todas as capacidades4. Esta é a formulação oficial para a tabela HANDLERS.
  • Escalation: consultar um agente ou modelo mais capaz para um subconjunto de subtarefas complexas4.

A segunda merece menção à parte: ela despacha por dificuldade, não por assunto. O classificador não julga “isto é reembolso ou incidente?”, e sim “este e-mail pode ser tratado pelo meu nível barato?”. Isso é mais difícil de julgar com acurácia do que classificação por assunto, então o caminho de escalonamento tem uma escrita mais estável: rode primeiro o nível barato, e se a saída não passar no gate, escale — trocando um problema de classificação difícil de julgar por um problema de verificação conferível.

Saber quando não dividir

Cada elo da cadeia acrescenta latência. Isso não é implementação mal otimizada, é o preço que a definição oficial estabelece: trocar latência por mais acurácia1. O usuário espera a soma de todos os trechos. Se o usuário está esperando o resultado de forma síncrona em uma interface, antes de acrescentar mais um elo à cadeia, considere se a pessoa ainda está lá.

Quando há uma categoria só, roteamento é puro custo extra. O benefício do roteamento vem da separação de responsabilidades1. Se a entrada realmente só tem um tipo, você pagou o custo e a latência de uma chamada de classificação e não recebeu nada em troca, mais uma chance a mais de classificar errado.

Quando a tarefa não se divide de forma limpa, não force. A condição “decomposta de forma fácil e limpa em subtarefas fixas” tem dentes1. Um rascunho que precisa olhar o quadro inteiro, indo e voltando, para ser bem revisado, se você o dividir em “primeiro revise a estrutura, depois revise o texto”, o segundo estágio não tem acesso às razões que o primeiro estágio não escreveu, e vai revisar apenas com base no texto literal. Neste caso, um loop, um contexto é de fato melhor — este é exatamente o uso das condições inversas da Lição 1.

Na dúvida, meça primeiro. A Anthropic disse isso duas vezes: considere acrescentar complexidade só quando ela comprovadamente melhora os resultados1. A trilha de avaliação do curso 10 desta série foi feita para isto: rode a versão de prompt único e obtenha uma nota, rode a versão dividida e obtenha outra, veja a diferença e se ela vale aqueles segundos a mais de latência — essa é a evidência que você leva para uma discussão com um colega.

Por fim, marque a fronteira. Encadeamento e roteamento são ambos orquestração de forma fixa: quantos estágios a cadeia tem, quais categorias o roteador tem, tudo é decidido quando você escreve o código. Rodar vários estágios ao mesmo tempo e depois agregar é a paralelização da Lição 3; nem saber quantas subtarefas existem antes de ver a entrada é o orquestrador-workers da Lição 4.

💻 Exercícios

Recapitulação

  • O encadeamento decompõe uma tarefa em uma sequência de etapas em que cada chamada processa a saída anterior, tornando cada chamada uma tarefa mais fácil1; ele é precificado explicitamente: o objetivo principal é trocar latência por mais acurácia1.
  • Um estágio da cadeia é um loop de harness completo, não uma chamada de API — a montagem que a Anthropic recomendou para avaliação é exatamente este bloco de construção: uma tarefa, um loop while, código chamando a API diretamente2.
  • As posições acrescentadas depois da divisão são a chave: você pode acrescentar verificações programáticas em quaisquer etapas intermediárias para garantir que o processo continua nos trilhos1. Este é o verificador determinístico do curso 10 mudado de local de instalação — do estado terminal para entre os estágios; na forma de produto, parece subagentes executando em sequência, cada um concluindo e a camada acima passando o contexto relevante ao seguinte3.
  • O roteamento classifica a entrada e despacha para tarefas de continuação especializadas, ganhando separação de responsabilidades e prompts mais especializados; sem ele, otimizar para um tipo de entrada pode prejudicar o desempenho em outras entradas1. Precondição: categorias claras e classificação que em si pode ser feita com acurácia, seja por LLM, seja por algoritmos de classificação tradicionais1.
  • Aperte a saída da chamada de classificação até um rótulo, e deixe um ramo de fallback para pegar respostas que não batem com a tabela.
  • Este padrão está vivo no vocabulário atual de primeira mão: despachar por domínio para agentes com prompts e ferramentas dedicados chama-se specialization, e consultar um agente ou modelo mais capaz para um subconjunto de subtarefas complexas chama-se escalation4 — o segundo é roteamento despachando por dificuldade.
  • Não force: quando há uma categoria só, roteamento é puro custo extra; quando a tarefa não se divide de forma limpa, forçar vai perder informação entre os estágios1. Na dúvida, meça primeiro — a complexidade tem que passar pelo limiar de “comprovadamente melhora os resultados”1.

>> Lição 3: Paralelização: seccionamento e votação

Footnotes

  1. Building Effective AI Agents — Anthropic Engineering — https://www.anthropic.com/engineering/building-effective-agents 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

  2. Writing effective tools for agents — with agents — Anthropic Engineering — https://www.anthropic.com/engineering/writing-tools-for-agents 2

  3. Create custom subagents — Claude Code official documentation — https://code.claude.com/docs/en/sub-agents 2

  4. Multiagent orchestration — Claude API documentation (Managed Agents) — https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration 2 3

Exercícios

01

Para cada uma das quatro tarefas abaixo, decida se usar encadeamento, roteamento, os dois ou nenhum. Além da conclusão, escreva com clareza: se você julgou encadeamento, o que o gate programático entre os estágios confere? Se julgou roteamento, onde fica o classificador, quantas categorias, é modelo ou código?

Nível 1: Decida encadeamento, roteamento ou nenhum dos dois (sem código)
  1. A caixa de entrada de atendimento recebe centenas de e-mails por dia; reembolso/incidente/cobrança são três categorias com tratamentos completamente diferentes, hoje compartilhando um prompt, e mudar a redação para uma categoria afeta outra.
  2. Um contrato em inglês precisa primeiro ser revisado para um parecer de risco estruturado (cada item contendo a localização da cláusula, o nível de risco e a explicação), e depois esse parecer precisa ser traduzido para versões em chinês e japonês, para times diferentes.
  3. Uma fila mista de tíquetes: tanto “redefinir senha”, que se responde em uma etapa, quanto “falha na migração de dados”, que exige conferir logs, diagnosticar, propor uma solução e escrever uma resposta — tarefas de várias etapas.
  4. O usuário digita uma frase em uma caixa de entrada, e você precisa corrigir os erros de digitação e devolver a frase corrigida.
Critérios de conclusão · marcado localmente
02

Escreva um chain.mjs que implemente a tarefa de escrita de documento da abertura como uma cadeia de três estágios: rascunhar esboço → escrever o texto com base no esboço → conferir consistência terminológica, com dois gates no meio. Requisitos:

Nível 2: Escreva a cadeia de três estágios e faça rodar (com código)
  1. Use um cliente stub (a abordagem usada nos cursos 8 a 11 desta série): uma fila fixa de respostas, sem rede, sem custo, a mesma entrada sempre produzindo o mesmo resultado.
  2. runAgent(client, task, tools) é um loop de harness de verdade — julgando pelo stop_reason, se for tool_use executa a ferramenta e devolve o resultado. O estágio três deve efetivamente passar por uma chamada de ferramenta (ler o glossário).
  3. Gate 1: o esboço precisa conter exatamente 3 títulos de capítulo começando com ## . Gate 2: o texto não pode conter termos descontinuados proibidos (defina a sua própria tabela de duas ou três palavras). Os dois são código puro, sem mais chamadas de modelo.
  4. Quando um gate reprova, imprima em qual etapa ele reprovou e por quê, e saia com código diferente de zero; se as três etapas passarem, saia com 0.
  5. Prepare dois conjuntos de respostas fixas e rode duas vezes: uma passando por tudo, outra barrada pelo segundo gate. Cole a saída real e os códigos de saída das duas execuções.
Critérios de conclusão · marcado localmente