Multi-Agent Loop
Sequential, parallel, and hierarchical coordination — communication protocols, shared state, and conflict resolution.
Overview
A multi-agent loop coordinates multiple AI agents working together on a complex task. While a single agent loop handles one task end-to-end, multi-agent systems decompose work across specialized agents, each running its own loop but collaborating through shared protocols. This architecture is essential for tasks that require diverse expertise, parallel processing, or hierarchical planning.
Real frameworks have validated this approach at scale. MetaGPT (45K+ GitHub stars, published at ICLR 2024) simulates an entire software company by assigning five distinct roles -- Product Manager, Architect, Project Manager, Engineer, and QA Engineer -- to collaborative LLM agents with standardized operating procedures (SOPs). CrewAI provides team-based multi-agent workflows with role-based architecture, supporting both sequential and hierarchical execution. LangGraph from LangChain offers graph-based orchestration with a built-in Supervisor pattern that routes tasks dynamically to specialized worker agents. Each of these frameworks implements the multi-agent loop pattern described in this article.
Coordination Patterns
There are three fundamental coordination patterns for multi-agent systems, and all three are implemented in production frameworks today.
Sequential Coordination
Agents process the task one after another, each building on the previous agent's output. This is the simplest pattern and works well when tasks have clear dependencies.
CrewAI implements this as its default Sequential process, where tasks pass linearly from one agent to the next:
# CrewAI sequential coordination example
from crewai import Agent, Task, Crew, Process
researcher = Agent(role="Researcher", goal="Gather technical requirements", backstory="You analyze codebases and document findings.")
writer = Agent(role="Writer", goal="Draft implementation plan", backstory="You turn research into actionable specs.")
reviewer = Agent(role="Reviewer", goal="Validate completeness", backstory="You catch gaps and inconsistencies.")
research_task = Task(description="Analyze the auth module and document dependencies", agent=researcher)
write_task = Task(description="Write implementation spec based on research output", agent=writer)
review_task = Task(description="Verify spec covers all edge cases", agent=reviewer)
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=[research_task, write_task, review_task],
process=Process.sequential, # Linear handoff between agents
)
result = crew.kickoff()
The flow looks like this:
Agent A (Research) --> Agent B (Draft) --> Agent C (Review) --> Agent D (Refine) --> Output
Parallel Coordination
Agents work simultaneously on different aspects of the task, and their results are merged. This pattern maximizes throughput for independent subtasks.
Cursor 2.0 applies this pattern with parallel agents -- up to 8 agents can work simultaneously on different files or subtasks within an IDE session. Similarly, OpenHands (github.com/All-Hands-AI/OpenHands) supports parallel execution across multiple browser instances and worker processes:
Agent A (Frontend) \
Agent B (Backend) --> Merger --> Output
Agent C (Testing) /
Hierarchical Coordination
A supervisor agent delegates subtasks to worker agents, monitors progress, and integrates results. This pattern is the most flexible and scales to complex workflows.
LangGraph implements this directly with its Supervisor pattern via the langgraph-supervisor package. The supervisor acts as a central controller whose "tools" are other agents, routing tasks dynamically based on conversation state:
# LangGraph hierarchical coordination with Supervisor pattern
from langgraph_supervisor import create_supervisor
from langgraph.prebuilt import create_react_agent
# Define specialized worker agents
planner_agent = create_react_agent(llm, tools=[...], name="planner")
executor_agent = create_react_agent(llm, tools=[...], name="executor")
validator_agent = create_react_agent(llm, tools=[...], name="validator")
# Supervisor orchestrates all workers
supervisor = create_supervisor(
model=llm,
agents=[planner_agent, executor_agent, validator_agent],
system_prompt="You manage a software development workflow. "
"Delegate to planner, executor, or validator as needed.",
)
# Invoke the multi-agent loop
result = supervisor.invoke({"messages": [("user", "Build a REST API for user management")]})
CrewAI supports the same pattern with its Hierarchical process, where a manager_agent handles delegation:
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=[research_task, write_task, review_task],
process=Process.hierarchical, # Manager agent delegates to workers
manager_agent=Agent(role="Manager", goal="Coordinate team output", backstory="You delegate and integrate."),
)
Supervisor Agent
|--- Worker A (Planning)
|--- Worker B (Execution)
|--- Worker C (Validation)
Merge --> Output
Communication Protocols
Effective multi-agent coordination requires well-defined communication protocols. Each protocol suits different coordination patterns:
| Protocol | Direction | Use Case | Framework Example |
|---|---|---|---|
| Direct Message | Point-to-point | Sequential handoff | CrewAI sequential process |
| Broadcast | One-to-all | Status updates, alerts | OpenHands event bus |
| Shared Blackboard | Read/write shared space | Parallel coordination | MetaGPT publish/subscribe |
| Request/Response | Synchronous query | Hierarchical delegation | LangGraph supervisor routing |
Shared Blackboard Pattern
The shared blackboard is a common communication mechanism where agents read from and write to a shared state space. MetaGPT uses this internally -- each role (PM, Architect, Engineer, QA) publishes structured outputs to a shared workspace that downstream agents consume:
class Blackboard:
def __init__(self):
self.state = {}
self.subscribers = defaultdict(list)
def write(self, key: str, value: Any, agent_id: str):
self.state[key] = {"value": value, "author": agent_id, "timestamp": time.time()}
for callback in self.subscribers.get(key, []):
callback(key, value)
def read(self, key: str) -> Any:
entry = self.state.get(key)
return entry["value"] if entry else None
def subscribe(self, key: str, callback):
self.subscribers[key].append(callback)
In MetaGPT's architecture, the Product Manager writes requirements to the blackboard, the Architect reads those requirements and publishes a system design, and so on through the pipeline. This loose coupling means agents can be swapped or upgraded independently.
Message Passing in AutoGen
AutoGen (github.com/microsoft/autogen) uses direct message passing between agents via a conversational pattern. Agents send messages to each other through a group chat or pairwise channels:
import autogen
assistant = autogen.AssistantAgent("coder", llm_config={"config_list": config_list})
reviewer = autogen.UserProxyAgent("reviewer", human_input_mode="NEVER")
# Direct message passing between agents
groupchat = autogen.GroupChat(agents=[assistant, reviewer], messages=[], max_round=10)
manager = autogen.GroupChatManager(groupchat=groupchat)
Shared State and Conflict Resolution
When multiple agents access shared state, conflicts are inevitable. Documented failure scenarios in production agent systems include write-write conflicts (two agents update the same field), read-write conflicts (stale reads during writes), and semantic conflicts (logically incompatible outputs). These are among the "four major failure scenarios" identified in production agent deployments: exception handling gaps, blind retries, context overflow, and infinite loops.
Conflict Resolution Strategies
class ConflictResolver:
def resolve(self, key: str, writes: list[Write]) -> Any:
# Strategy 1: Last-Writer-Wins (simplest)
if self.strategy == "last-writer-wins":
return max(writes, key=lambda w: w.timestamp).value
# Strategy 2: Priority-based (supervisor agent takes precedence)
if self.strategy == "priority":
return max(writes, key=lambda w: w.agent.priority).value
# Strategy 3: Merge (for list/map values)
if self.strategy == "merge":
merged = {}
for write in sorted(writes, key=lambda w: w.timestamp):
merged.update(write.value)
return merged
# Strategy 4: Escalate to supervisor
if self.strategy == "escalate":
return self.supervisor.arbitrate(key, writes)
In LangGraph, state conflicts are managed through the framework's built-in state management. The graph state is versioned and each node transition produces a new state snapshot, eliminating read-write conflicts by design. CrewAI takes a different approach -- memory systems maintain shared context across agents, and the hierarchical process gives the manager agent final authority on conflicting outputs.
Complete Multi-Agent Example
This example demonstrates a multi-agent loop with all three coordination patterns, built with patterns inspired by LangGraph and MetaGPT:
class MultiAgentLoop:
def __init__(self, agents: dict, blackboard: Blackboard, resolver: ConflictResolver):
self.agents = agents
self.blackboard = blackboard
self.resolver = resolver
def run_sequential(self, task):
"""Sequential: each agent builds on the previous output (like MetaGPT's SOP pipeline)."""
result = task.initial_data
for agent_name in task.pipeline:
agent = self.agents[agent_name]
result = agent.execute(result)
self.blackboard.write(agent_name + "_output", result, agent_name)
return result
def run_parallel(self, task):
"""Parallel: independent agents work simultaneously (like Cursor 2.0 parallel agents)."""
results = {}
with ThreadPoolExecutor(max_workers=len(task.workers)) as executor:
futures = {
executor.submit(self.agents[name].execute, subtask): name
for name, subtask in task.workers.items()
}
for future in as_completed(futures):
name = futures[future]
results[name] = future.result()
self.blackboard.write(name + "_output", results[name], name)
return self._merge_results(results)
def run_hierarchical(self, task, supervisor="supervisor"):
"""Hierarchical: supervisor delegates and integrates (like LangGraph Supervisor pattern)."""
plan = self.agents[supervisor].plan(task)
worker_results = {}
for step in plan.steps:
agent = self.agents[step.agent]
worker_results[step.id] = agent.execute(step.subtask)
return self.agents[supervisor].integrate(plan, worker_results)
Real-World Multi-Agent Systems
MetaGPT: Software Company Simulation
MetaGPT (github.com/geekan/MetaGPT, 45K+ stars) is the most direct real-world implementation of the multi-agent loop. It simulates a software company with five agent roles -- Product Manager, Architect, Project Manager, Engineer, and QA Engineer -- each following SOPs. You can run it from the CLI:
# Install MetaGPT
pip install metagpt
# Initialize configuration
metagpt --init-config
# Run a full multi-agent software development loop
metagpt "Create a command-line Snake game in Python"
The output includes PRD docs, system architecture designs, project task lists, and actual source code -- all produced by specialized agents collaborating through a shared blackboard.
Cursor 2.0: Parallel Agents in the IDE
Cursor (cursor.com) implements parallel multi-agent coordination directly in the IDE. In Agent mode, up to 8 agents can work on different files or subtasks simultaneously, then merge their changes. This is the parallel coordination pattern applied to practical software development, reducing latency on multi-file refactoring tasks.
OpenHands: Autonomous Coding Platform
OpenHands (github.com/All-Hands-AI/OpenHands) is a full autonomous coding agent platform that orchestrates multiple specialized agents for planning, coding, browsing, and debugging. Each agent operates in its own sandbox environment and communicates through a shared event system, implementing the hierarchical coordination pattern at platform scale.
When to Use Multi-Agent Architecture
Multi-agent systems add significant complexity. Use them when:
- The task naturally decomposes into independent subtasks (e.g., frontend + backend + tests)
- Different subtasks require different expertise or tools (MetaGPT's role-based approach)
- Subtasks can benefit from parallel execution (Cursor 2.0's parallel agents)
- The system needs to scale horizontally across subtask types
Avoid multi-agent overhead when:
- A single agent can handle the task effectively (most single-file edits in Aider or Claude Code)
- Subtasks are tightly coupled and cannot be parallelized
- The coordination overhead exceeds the benefit of specialization