05-03-02 — Comunicação entre agentes: shared state vs message passing

⏱ 12 minFontes validadas em: 2026-04-29

TL;DR

Em sistemas multi-agent, agentes precisam trocar informações. Dois modelos: Shared State (todos acessam um contexto comum — simples, mas com race conditions) e Message Passing (agentes enviam mensagens estruturadas — mais robusto, mais complexo). A escolha impacta escalabilidade, consistência e custo de debug.

Shared State (estado compartilhado)

Todos os agentes acessam e modificam um objeto de estado centralizado. É como um quadro branco que todos podem ver e escrever.

graph TD S[(Estado Compartilhado\nJSON/Dict)] A1[Agent 1: Pesquisador] -->|lê/escreve| S A2[Agent 2: Analista] -->|lê/escreve| S A3[Agent 3: Escritor] -->|lê/escreve| S style S fill:#1e40af,color:#fff
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
import operator

# Define o estado compartilhado (typed)
class ResearchState(TypedDict):
    query: str
    search_results: list[str]
    analysis: str
    final_report: str
    messages: Annotated[list, operator.add]  # append-only

# Cada nó (agente) lê e escreve no estado
def researcher(state: ResearchState) -> ResearchState:
    results = search_web(state["query"])
    return {"search_results": results}  # Atualiza apenas seu campo

def analyst(state: ResearchState) -> ResearchState:
    # Lê os resultados do pesquisador
    analysis = analyze(state["search_results"])
    return {"analysis": analysis}

def writer(state: ResearchState) -> ResearchState:
    report = write_report(state["analysis"])
    return {"final_report": report}

# Grafo com estado compartilhado (LangGraph)
graph = StateGraph(ResearchState)
graph.add_node("researcher", researcher)
graph.add_node("analyst", analyst)
graph.add_node("writer", writer)
graph.add_edge("researcher", "analyst")
graph.add_edge("analyst", "writer")
graph.add_edge("writer", END)

app = graph.compile()
result = app.invoke({"query": "Market share ERP Brasil 2024"})
LangGraph usa shared state: É o modelo nativo do LangGraph. O estado é um dict tipado que flui pelo grafo, cada nó recebe o estado atual e retorna as mudanças. Simples de debugar porque você vê o estado a qualquer ponto.

Message Passing (passagem de mensagens)

Agentes se comunicam enviando mensagens estruturadas. Não há estado global — cada agente tem seu próprio contexto e recebe apenas o que é enviado a ele.

graph LR A1[Agent 1] -->|Message: {task, data}| Q[(Queue)] Q -->|deliver| A2[Agent 2] A2 -->|Message: {result}| Q2[(Queue)] Q2 -->|deliver| A3[Agent 3] style Q fill:#4c1d95,color:#fff style Q2 fill:#4c1d95,color:#fff
import asyncio
from dataclasses import dataclass
from typing import Any

@dataclass
class AgentMessage:
    sender: str
    recipient: str
    task: str
    data: Any
    correlation_id: str

# Message bus simples
class MessageBus:
    def __init__(self):
        self.queues: dict[str, asyncio.Queue] = {}
    
    def register(self, agent_name: str):
        self.queues[agent_name] = asyncio.Queue()
    
    async def send(self, message: AgentMessage):
        await self.queues[message.recipient].put(message)
    
    async def receive(self, agent_name: str) -> AgentMessage:
        return await self.queues[agent_name].get()

# Agente que usa message passing
class ResearcherAgent:
    def __init__(self, bus: MessageBus):
        self.bus = bus
        bus.register("researcher")
    
    async def run(self):
        while True:
            msg = await self.bus.receive("researcher")
            results = await search_web(msg.data["query"])
            
            # Envia resultado para o próximo agente
            await self.bus.send(AgentMessage(
                sender="researcher",
                recipient="analyst",
                task="analyze",
                data={"results": results},
                correlation_id=msg.correlation_id
            ))

Trade-offs: quando usar cada um

CritérioShared StateMessage Passing
Simplicidade✅ Mais simples❌ Mais complexo
Debugabilidade✅ Estado visível💛 Requer tracing
Race conditions⚠️ Risco com paralelo✅ Isolado por design
Escalabilidade💛 Limitada ao processo✅ Distribuível (queues)
Agentes distribuídos❌ Difícil✅ Nativo (Kafka, Service Bus)
Consistência⚠️ Requer locks✅ Eventual consistency
Modelo híbrido (comum em produção): Shared state dentro de um grafo de execução (LangGraph) + message passing para comunicação entre serviços diferentes (Azure Service Bus, Kafka). O estado local é shared; a comunicação entre microsserviços é via mensagens.
Azure Service Bus para multi-agent: Para sistemas multi-agent em escala, Azure Service Bus ou Azure Event Grid fornecem a infraestrutura de message passing. Cada agente é um serviço separado consumindo de uma fila. Isso permite deploy independente e scaling por agente.
Shared state + paralelismo = risco: Se dois agentes modificam o mesmo campo do estado ao mesmo tempo, você pode ter condições de corrida. LangGraph resolve isso com reducer functions (ex: operator.add para listas). Sem reducers, use message passing para operações paralelas.

Como isso se conecta

  • 05-03-01 — Os padrões de multi-agent (orchestrator, swarm) implementam comunicação via um desses modelos.
  • 05-04-01 — Memória compartilhada é uma forma de shared state persistente entre sessões.
  • 05-04-03 — Anthropic discute communication patterns em "Building Effective Agents".

Fontes

  1. LangGraph — Low Level Concepts (State Management) — documentação do modelo de shared state do LangGraph.
  2. Microsoft — Azure Service Bus overview — message passing em escala no Azure.
  3. Microsoft AutoGen — AgentChat — message passing entre agentes com AutoGen.
  4. Chen et al. — AgentVerse: Facilitating Multi-Agent Collaboration (2024) — análise de padrões de comunicação em sistemas multi-agent.