Contents

Multi-Agent Systems in Practice: How Multiple AI Agents Collaborate

When Multi-Agent Is Needed

Not every scenario needs multiple Agents.

Single Agent handles:
  - task boundaries clear
  - needs centralized decision
  - tool call chain not long

Consider Multi-Agent:
  - task needs different expertise
  - needs parallel processing of independent subtasks
  - decisions need multi-party verification
  - system scale needs responsibility separation

Common Architectures

1. Supervisor + Workers

Supervisor Agent
    ├── Worker Agent A (handles domain)
    ├── Worker Agent B (handles another domain)
    └── Worker Agent C (handles third domain)
# Supervisor handles task decomposition and coordination
class Supervisor:
    def handle(self, task):
        subtasks = self.decompose(task)
        
        results = []
        for subtask in subtasks:
            worker = self.select_worker(subtask)
            result = worker.execute(subtask)
            results.append(result)
        
        return self.synthesize(results)

Good for: tasks decomposable, subtasks relatively independent.

2. Sequential Pipeline

Agent A → Agent B → Agent C → Agent D
# Pipeline style, each step depends on previous output
pipeline = [
    ("research", ResearchAgent()),
    ("analyze", AnalyzeAgent()),
    ("write", WriteAgent()),
    ("review", ReviewAgent()),
]

def run_pipeline(initial_input):
    output = initial_input
    for name, agent in pipeline:
        output = agent.process(output)
    return output

Good for: ordered steps, each with clear input/output.

3. Parallel + Merge

        → Agent A (parallel)
Task → → Agent B (parallel) → Merge Agent → Result
        → Agent C (parallel)
# Same task, multiple perspectives, merge results
async def parallel_analyze(task):
    agents = [ResearchAgent(), AnalyzeAgent(), CritiqueAgent()]
    
    results = await asyncio.gather(*[
        agent.process(task) for agent in agents
    ])
    
    return merge_agent.synthesize(results)

Good for: multi-perspective analysis, synthesizing different viewpoints.

Communication Protocols

Multi-Agent needs communication. Two approaches:

1. Shared Message Queue

# Communicate via shared queue
class Agent:
    def __init__(self, name, inbox, outbox):
        self.name = name
        self.inbox = inbox
        self.outbox = outbox
    
    async def run(self):
        while True:
            msg = await self.inbox.get()
            result = await self.process(msg)
            await self.outbox.put(Message(
                from_agent=self.name,
                to="merge",
                content=result
            ))

2. Explicit Message Passing

# Agents send messages directly
class Agent:
    async def send_to(self, target, message):
        await self.messenger.send(
            to=target,
            message=message
        )
    
    async def receive(self):
        return await self.messenger.receive()

Pitfalls Encountered

Pit 1: Information Loss Between Agents

# Problem: Agent A's output, Agent B can't understand

# Solution: standardize output format
class ResearchAgent:
    def output_format(self):
        return {
            "findings": [...],
            "sources": [...],
            "confidence": 0.8,
            "raw_data": {...}
        }

Pit 2: Circular Dependencies

Agent A → Agent B → Agent C
  ↑                     ↓
  └─────────────────────┘

# Agent C depends on A
# Agent A also indirectly depends on C
# Solution: organize with DAG
# Or introduce arbitration mechanism
class Orchestrator:
    def resolve_conflict(self, result_a, result_c):
        if result_a.confidence > result_c.confidence:
            return result_a
        return result_c

Pit 3: Debugging Difficulty

# Problem: when Multi-Agent breaks, hard to locate which Agent

# Solution: each Agent has complete logs, message queue replayable
class Agent:
    def process(self, msg):
        logger.info(f"{self.name} received: {msg}")
        result = self._process_impl(msg)
        logger.info(f"{self.name} output: {result}")
        return result

Framework Selection

Framework Use Case Characteristics
LangGraph complex flow orchestration strong state management
AutoGen multi-Agent dialogue rich collaboration modes
CrewAI clear role separation easy to start
Custom highly customized flexible but high effort

Conclusion

Multi-Agent’s value: let specialists do specialized work.

Multiple Agents each have strengths, combined they handle more complex tasks than single Agent.

But Multi-Agent adds complexity: communication, debugging, consistency all cost extra.

Recommendation: start with single Agent, split when confirmed insufficient. Don’t overdesign.