Todos os artigos
26 min de leitura

Arquitetura de Multi-Agents: Orquestrando LLMs em Pipelines de Produção

Um único LLM resolve problemas bem definidos. Sistemas multi-agent resolvem problemas complexos — dividindo raciocínio, especializando responsabilidades e orquestrando execução paralela. Este artigo detalha como projetar, implementar e operar essas arquiteturas em produção.

A evolução de sistemas de IA não seguiu o caminho que muitos esperavam. Em vez de modelos cada vez maiores resolvendo tudo sozinhos, o que emergiu como padrão de produção em 2025-2026 é a arquitetura multi-agent: múltiplos LLMs especializados, cada um com um escopo restrito, colaborando através de interfaces bem definidas.

É a mesma intuição que guia a arquitetura de microsserviços — e pelos mesmos motivos. Um agente que faz tudo é tão perigoso quanto um monólito que faz tudo: difícil de testar, difícil de depurar, impossível de otimizar localmente sem efeitos colaterais globais.

O Modelo Mental: Agentes como Atores

O modelo mais útil para pensar sobre sistemas multi-agent é o modelo de atores: cada agente é uma unidade de computação independente com estado local, que se comunica com outros agentes exclusivamente através de mensagens. Sem memória compartilhada. Sem acoplamento direto.

Isso tem implicações profundas. Agentes podem ser escalados independentemente, substituídos por versões melhores sem afetar o sistema, testados em isolamento, e monitorados individualmente. A complexidade do sistema emerge das interações, não da complexidade interna de cada agente.

Os Três Padrões de Orquestração

1. Orchestrator-Worker (Hub and Spoke)

O padrão mais simples e mais robusto. Um agente orquestrador recebe a tarefa, a decompõe em subtarefas, delega para agentes especializados e sintetiza os resultados.

from langchain_core.prompts import ChatPromptTemplate
from langchain_google_vertexai import ChatVertexAI

orchestrator_prompt = ChatPromptTemplate.from_messages([ ("system", """You are an orchestrator that decomposes complex tasks. Available agents: research_agent, code_agent, review_agent Output format: JSON with keys: plan, agents, synthesis_strategy"""), ("human", "{input}"), ])

llm = ChatVertexAI(model_name="gemini-1.5-pro", temperature=0.1) orchestrator = orchestrator_prompt | llm

A chave é que o orquestrador não executa nada — apenas planeja. Isso mantém o grafo de dependências explícito e auditável.

2. Pipeline Sequencial com Handoff

Agentes em cadeia onde a saída de cada um é a entrada do próximo. Ideal para fluxos com transformações progressivas de dados.

from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator

class PipelineState(TypedDict): input: str research_output: str analysis_output: str errors: Annotated[list[str], operator.add]

def research_node(state: PipelineState) -> PipelineState: result = research_agent.invoke({"query": state["input"]}) return {"research_output": result["output"]}

graph = StateGraph(PipelineState) graph.add_node("research", research_node) graph.set_entry_point("research") graph.add_edge("research", END) pipeline = graph.compile()

O StateGraph do LangGraph é o mecanismo mais robusto para pipelines stateful: o estado é explícito, as transições são tipadas, e o grafo pode ser visualizado e inspecionado.

3. Grafo com Roteamento Condicional

O padrão mais poderoso — e o mais perigoso se mal projetado.

def should_escalate(state: PipelineState) -> str:
    confidence = extract_confidence(state["analysis_output"])
    if confidence < 0.7:
        return "human_review"
    if "error" in state["errors"]:
        return "error_handler"
    return "report"

graph.add_conditional_edges( "analysis", should_escalate, {"human_review": "human_review_node", "report": "report"}, )

A regra mais importante: roteamento deve ser determinístico ou baseado em métricas concretas, nunca em "o LLM decide para onde ir". LLMs tomando decisões de roteamento criam loops infinitos e comportamentos emergentes impossíveis de debugar.

Memória em Sistemas Multi-Agent

Memória é o problema mais subestimado em arquiteturas multi-agent. Existem quatro tipos:

Memória de trabalho (in-context): o estado atual da conversa. Limitado pela janela de contexto. Descartado ao fim da sessão.

Memória episódica (external store): histórico de interações passadas, recuperado por similaridade semântica. Redis com embeddings ou pgvector são as implementações de referência.

Memória semântica (knowledge base): fatos e conhecimento estável do domínio — o que RAG provê.

Memória procedural (few-shot examples): exemplos de execuções bem-sucedidas anteriores, usados como few-shot no próximo contexto.

class AgentMemory:
    def __init__(self, redis_client, vector_store):
        self.redis   = redis_client
        self.vectors = vector_store

def store_episode(self, session_id: str, outcome: dict) -> None: key = f"episode:{session_id}" self.redis.setex(key, 86400 * 30, json.dumps(outcome)) self.vectors.add(embed(json.dumps(outcome)), metadata=outcome)

def retrieve_similar(self, query: str, k: int = 3) -> list[dict]: return self.vectors.search(embed(query), k=k)

Guardrails em Sistemas Multi-Agent

A superfície de ataque aumenta com cada agente adicional. Os três controles obrigatórios:

Input validation em cada nó: nunca confiar na saída de um agente como entrada segura para outro.

Output constraints: cada agente deve produzir output em formato estruturado — JSON com schema definido.

Execution budget: limite máximo de tokens e chamadas de API por pipeline.

class BudgetedExecutor:
    def __init__(self, max_tokens: int = 50_000, max_steps: int = 20):
        self.max_tokens   = max_tokens
        self.max_steps    = max_steps
        self._tokens_used = 0
        self._steps       = 0

def execute(self, agent, input_data: dict) -> dict: if self._steps >= self.max_steps: raise BudgetExceededError("max steps reached") if self._tokens_used >= self.max_tokens: raise BudgetExceededError("token budget exceeded") self._steps += 1 result = agent.invoke(input_data) self._tokens_used += result.get("token_usage", 0) return result

A arquitetura multi-agent não é mais complexa que a single-agent por capricho — é porque os problemas que resolve são intrinsecamente mais complexos. A complexidade está no domínio, não na solução.