---
title: "Grafos de agentes: por que orquestração séria virou um problema de grafo"
description: "Contexto maior não substitui arquitetura. Por que decompor trabalho em nós e arestas — com fan-out, barreiras e verificação adversarial — costuma vencer um agente único com um milhão de tokens de contexto."
date: 2026-08-11
canonical: https://arvor.co/noticias/grafos-de-agentes-orquestracao-2026
---

Toda vez que sai um modelo com janela de contexto maior, alguém me manda mensagem dizendo que orquestração de agentes virou problema resolvido. Joga o repositório inteiro no contexto, pede o resultado, pronto. Já vi esse filme em três gerações de tecnologia, e ele termina sempre igual.

Passei duas décadas construindo busca enterprise antes da Arvor — Solr, Lucene, índices com bilhões de documentos. A lição é chata e universal: capacidade bruta nunca consertou modelagem ruim. Índice maior não conserta esquema errado. Contexto maior não conserta trabalho mal decomposto.

Orquestração séria de agentes, em 2026, é um problema de grafo. E o time que enxerga isso primeiro para de brigar com o modelo e começa a brigar com o problema certo.

## Um agente único é um grafo de um nó só

Quando você entrega tudo para um agente com contexto gigante, você não eliminou o grafo — você colapsou ele num nó só, e perdeu tudo que a estrutura te dava.

<div style="overflow-x:auto;max-width:640px;margin:26px auto 10px">
<svg viewBox="0 0 640 272" role="img" aria-labelledby="ag1-t" style="width:100%;height:auto;min-width:560px;display:block;margin:0 auto" font-family="ui-monospace, SFMono-Regular, Menlo, monospace">
  <title id="ag1-t">À esquerda, um agente único com todas as tarefas empilhadas no mesmo contexto. À direita, um grafo com entrada, três nós em paralelo, nó de verificação e saída.</title>
  <defs>
    <marker id="ag1-c" viewBox="0 0 8 8" refX="7.5" refY="4" markerWidth="8" markerHeight="8" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 Z" fill="#27e3ff"/></marker>
    <marker id="ag1-g" viewBox="0 0 8 8" refX="7.5" refY="4" markerWidth="8" markerHeight="8" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 Z" fill="#d4af37"/></marker>
  </defs>
  <rect x="4" y="30" width="252" height="228" rx="14" fill="#070e1a" stroke="#112030"/>
  <rect x="284" y="30" width="352" height="228" rx="14" fill="#070e1a" stroke="#112030"/>
  <text x="130" y="20" text-anchor="middle" font-size="13" letter-spacing="1.4" fill="#7a9ab8">AGENTE ÚNICO</text>
  <text x="460" y="20" text-anchor="middle" font-size="13" letter-spacing="1.4" fill="#27e3ff">GRAFO</text>
  <rect x="32" y="70" width="196" height="116" rx="16" fill="#0a1828" stroke="#4a6785" stroke-width="1.5"/>
  <rect x="48" y="82" width="164" height="20" rx="5" fill="#112030"/>
  <text x="58" y="96" font-size="13" fill="#f0ede6">nó A</text>
  <rect x="48" y="106" width="164" height="20" rx="5" fill="#112030"/>
  <text x="58" y="120" font-size="13" fill="#f0ede6">nó B</text>
  <rect x="48" y="130" width="164" height="20" rx="5" fill="#112030"/>
  <text x="58" y="144" font-size="13" fill="#f0ede6">nó C</text>
  <rect x="48" y="154" width="164" height="20" rx="5" fill="#112030"/>
  <text x="58" y="168" font-size="13" fill="#d4af37">verificar</text>
  <text x="130" y="244" text-anchor="middle" font-size="13" fill="#7a9ab8"><tspan fill="#5b6b7f">&#10007;</tspan> tudo no mesmo contexto</text>
  <rect x="408" y="46" width="104" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="460" y="63.5" text-anchor="middle" font-size="13" fill="#f0ede6">entrada</text>
  <path d="M460 72 V85 H350 V98" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <path d="M460 72 V98" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <path d="M460 72 V85 H570 V98" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <rect x="306" y="98" width="88" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="350" y="115.5" text-anchor="middle" font-size="13" fill="#f0ede6">nó A</text>
  <rect x="416" y="98" width="88" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="460" y="115.5" text-anchor="middle" font-size="13" fill="#f0ede6">nó B</text>
  <rect x="526" y="98" width="88" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="570" y="115.5" text-anchor="middle" font-size="13" fill="#f0ede6">nó C</text>
  <path d="M350 124 V137 H460 V150" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <path d="M460 124 V150" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <path d="M570 124 V137 H460 V150" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag1-c)"/>
  <rect x="376" y="150" width="168" height="28" rx="7" fill="#0a1828" stroke="#d4af37"/>
  <text x="460" y="168.5" text-anchor="middle" font-size="13" fill="#d4af37">verificação</text>
  <path d="M460 178 V198" fill="none" stroke="#d4af37" stroke-width="1.5" marker-end="url(#ag1-g)"/>
  <rect x="408" y="198" width="104" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="460" y="215.5" text-anchor="middle" font-size="13" fill="#f0ede6">saída</text>
  <text x="460" y="244" text-anchor="middle" font-size="13" fill="#7a9ab8"><tspan fill="#27e3ff">&#10003;</tspan> isolamento + paralelismo</text>
</svg>
</div>

*Um agente único não elimina o grafo — colapsa ele num nó só. O grafo devolve isolamento, paralelismo e um ponto de verificação explícito.*

Perdeu isolamento: um passo que dá errado contamina todos os seguintes, porque o raciocínio ruim continua no contexto. Perdeu paralelismo: dez verificações independentes viram dez etapas em série. Perdeu retentativa granular: quando falha, você refaz tudo, não o pedaço que quebrou. E perdeu observabilidade: "o agente errou em algum lugar dessas 400 mil tokens" não é diagnóstico, é lamento.

Há um custo mais sutil ainda: dentro de uma janela grande, tudo compete por atenção, e essa disputa não se ganha no texto do prompt — se ganha decidindo o que entra em cada nó.

## Nós, arestas e a parte chata que ninguém quer fazer

Um nó é uma unidade de trabalho com entrada declarada e saída verificável. Se você não consegue escrever o critério de aceite do nó em uma frase, não é um nó — é um desejo.

Uma aresta é uma dependência real: B só pode rodar depois de A porque B precisa da saída de A. E aqui está a parte chata, a que quase ninguém faz: a maioria das arestas que os times desenham não é dependência, é só a ordem em que a pessoa pensou nas tarefas. Sequência acidental virando arquitetura.

Separar dependência real de hábito de escrita é o que transforma uma lista de tarefas num grafo. É onde o ganho aparece: tudo que não depende de nada pode rodar junto.

## Fan-out, fan-in, pipeline e barreira

Quatro padrões cobrem quase tudo:

**Fan-out** é o mesmo insumo indo para vários nós com objetivos diferentes, em paralelo. Cada um com contexto pequeno e missão estreita.

**Fan-in** é a agregação. É o padrão que os times mais fazem errado, porque tratam agregação como resumo. Um nó de fan-in precisa de regra de conflito: o que acontece quando dois verificadores discordam? Sem essa regra explícita, o agregador escolhe o texto mais bem escrito, não o mais correto.

**Pipeline** é a cadeia em série. Latência soma, e — pior — erro propaga. Faça a conta honesta: doze passos com 95% de acerto cada dão pouco mais de 54% de chance de sair inteiro do outro lado. Times constroem pipelines de doze passos porque é mais fácil de escrever, e depois culpam o modelo pelo cara-ou-coroa.

**Barreira** é o oposto: nada avança até que tudo chegue. Custa latência e compra consistência. É o que impede um merge de migração antes de build, testes, type check e lint terem todos voltado verdes.

<div style="overflow-x:auto;max-width:640px;margin:26px auto 10px">
<svg viewBox="0 0 640 292" role="img" aria-labelledby="ag2-t" style="width:100%;height:auto;min-width:560px;display:block;margin:0 auto" font-family="ui-monospace, SFMono-Regular, Menlo, monospace">
  <title id="ag2-t">Em cima, três verificações em pipeline: cada uma segue adiante assim que termina. Embaixo, as mesmas três esperam numa barreira até que todas cheguem, e só então o merge acontece.</title>
  <defs>
    <marker id="ag2-c" viewBox="0 0 8 8" refX="7.5" refY="4" markerWidth="8" markerHeight="8" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 Z" fill="#27e3ff"/></marker>
    <marker id="ag2-g" viewBox="0 0 8 8" refX="7.5" refY="4" markerWidth="8" markerHeight="8" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 L8 4 L0 8 Z" fill="#d4af37"/></marker>
  </defs>
  <text x="16" y="20" font-size="13" letter-spacing="1.2" fill="#27e3ff">PIPELINE<tspan fill="#7a9ab8" letter-spacing="0"> &#183; cada um segue sozinho</tspan></text>
  <text x="16" y="50.5" font-size="13" fill="#7a9ab8">build</text>
  <line x1="76" y1="46" x2="228" y2="46" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="240" cy="46" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="240" y="50.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <path d="M254 46 H280" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag2-c)"/>
  <rect x="280" y="33" width="70" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="315" y="50.5" text-anchor="middle" font-size="13" fill="#f0ede6">segue</text>
  <text x="16" y="82.5" font-size="13" fill="#7a9ab8">testes</text>
  <line x1="76" y1="78" x2="338" y2="78" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="350" cy="78" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="350" y="82.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <path d="M364 78 H390" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag2-c)"/>
  <rect x="390" y="65" width="70" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="425" y="82.5" text-anchor="middle" font-size="13" fill="#f0ede6">segue</text>
  <text x="16" y="114.5" font-size="13" fill="#7a9ab8">lint</text>
  <line x1="76" y1="110" x2="168" y2="110" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="180" cy="110" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="180" y="114.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <path d="M194 110 H220" fill="none" stroke="#27e3ff" stroke-width="1.5" marker-end="url(#ag2-c)"/>
  <rect x="220" y="97" width="70" height="26" rx="7" fill="#0a1828" stroke="#4a6785"/>
  <text x="255" y="114.5" text-anchor="middle" font-size="13" fill="#f0ede6">segue</text>
  <line x1="16" y1="140" x2="624" y2="140" stroke="#112030"/>
  <text x="16" y="170" font-size="13" letter-spacing="1.2" fill="#d4af37">BARREIRA<tspan fill="#7a9ab8" letter-spacing="0"> &#183; todos ou nenhum</tspan></text>
  <text x="16" y="204.5" font-size="13" fill="#7a9ab8">build</text>
  <line x1="76" y1="200" x2="228" y2="200" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="240" cy="200" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="240" y="204.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <line x1="254" y1="200" x2="466" y2="200" stroke="#5b6b7f" stroke-width="1.5" stroke-dasharray="3 4"/>
  <text x="16" y="236.5" font-size="13" fill="#7a9ab8">testes</text>
  <line x1="76" y1="232" x2="338" y2="232" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="350" cy="232" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="350" y="236.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <line x1="364" y1="232" x2="466" y2="232" stroke="#5b6b7f" stroke-width="1.5" stroke-dasharray="3 4"/>
  <text x="16" y="268.5" font-size="13" fill="#7a9ab8">lint</text>
  <line x1="76" y1="264" x2="168" y2="264" stroke="#27e3ff" stroke-width="6" stroke-linecap="round" opacity="0.7"/>
  <circle cx="180" cy="264" r="10" fill="#0a1828" stroke="#3ddc97"/>
  <text x="180" y="268.5" text-anchor="middle" font-size="12" fill="#3ddc97">&#10003;</text>
  <line x1="194" y1="264" x2="466" y2="264" stroke="#5b6b7f" stroke-width="1.5" stroke-dasharray="3 4"/>
  <rect x="470" y="186" width="5" height="92" rx="2" fill="#d4af37"/>
  <path d="M479 232 H520" fill="none" stroke="#d4af37" stroke-width="1.5" marker-end="url(#ag2-g)"/>
  <rect x="520" y="219" width="96" height="26" rx="7" fill="#0a1828" stroke="#d4af37"/>
  <text x="568" y="236.5" text-anchor="middle" font-size="13" fill="#d4af37">merge</text>
</svg>
</div>

*No pipeline cada verificação segue assim que termina; na barreira, nada avança até que todas cheguem.*

## Verificação adversarial é um nó, não um adjetivo

"Revise seu trabalho antes de responder" no fim do prompt não é verificação. É o mesmo modelo, com o mesmo contexto e o mesmo viés, sendo perguntado se gostou de si mesmo. A resposta é sempre sim.

Verificação de verdade é um nó separado no grafo: contexto próprio, objetivo invertido (achar o erro, não confirmar o acerto), e acesso apenas ao artefato — nunca ao raciocínio de quem gerou. Se o verificador lê o raciocínio do gerador, ele é capturado por ele. Só sobe no grafo o que sobrevive à tentativa de derrubar.

E o melhor verificador quase nunca é um LLM. Compilador, teste, type checker, linter, validação de schema: são baratos, determinísticos e não têm opinião. Use o modelo para verificar o que máquina não verifica — intenção, regra de negócio, contrato implícito — e deixe o resto para ferramentas que não alucinam.

## Três grafos que pagam o trabalho de desenhar

**Revisão de código com verificadores em paralelo.** Fan-out do diff para nós especializados: segurança, regressão, contrato de API, cobertura de teste. Cada um com contexto pequeno e um único critério. Fan-in num nó que deduplica e ordena por severidade, com regra de precedência definida. Um agente único lendo o diff inteiro acha o óbvio e cansa antes do resto.

**Migração com worktrees isoladas.** Cada módulo numa worktree git própria. O isolamento deixa de ser promessa e vira propriedade do sistema: dois nós não conseguem escrever no mesmo arquivo porque nem enxergam o mesmo diretório de trabalho. Barreira antes do merge, e rollback vira descartar uma worktree. É o padrão que rodamos com o [Relentless](/relentless).

**Pesquisa multi-modal.** Fan-out por fonte — documentação interna, código, web, planilha — com a ferramenta certa em cada nó, e fan-in com precedência explícita para quando as fontes discordarem. Sem essa regra, o agregador escolhe a fonte mais eloquente. É o que aprendemos construindo governança no [BRAIN MAKER](/brain-maker): proveniência não é enfeite, é critério de desempate.

## Quando o grafo determinístico ganha — e quando perde

O grafo ganha quando o trabalho é decomponível, o critério de aceite é verificável por máquina, você precisa auditar o resultado, precisa repetir amanhã com a mesma saída, ou custo importa — porque nó pequeno roda com modelo menor.

O grafo perde quando o problema é exploratório e você ainda não sabe quais são as etapas. Desenhar grafo para um problema que você não entendeu é chute com diagrama. Aí um agente único, com boas ferramentas e liberdade, é o instrumento certo.

Minha regra prática: agente único para descobrir o grafo, grafo para rodar em produção. Confundir os dois é caro nas duas direções — grafo prematuro engessa a exploração, agente único em produção não escala nem audita.

## Ferramentas, sem review de fachada

O ecossistema já convergiu para esse vocabulário. O [LangGraph](https://docs.langchain.com/oss/python/langgraph/overview), da LangChain, é o exemplo mais explícito: nós, arestas estáticas e condicionais, estado central compartilhado, fan-out e fan-in como primitivas. Se você quer uma biblioteca que já pensa em grafo, é um lugar honesto para começar.

Não vou fingir que usamos a mesma biblioteca para tudo: boa parte do que rodamos é grafo em código próprio, com git como estado. O ponto não é a ferramenta. É que o grafo existe de qualquer jeito — se você não desenhar, ele fica implícito dentro de um prompt de duas mil palavras, sem dono e sem verificação.

Grafo é o mapa. O motor que percorre esse mapa é outro assunto — e é sobre isso que escrevi em [loops de agentes](/noticias/loops-de-agentes-depois-do-ralph-loop). Se você quer parar de apostar em prompt e começar a desenhar arquitetura, [fale com a gente](/contato) ou conheça nossa [consultoria agêntica](/consultoria).

Árvore não cresce em linha reta. Cresce em galho — e cada galho sabe de onde veio.
