A multi-agent system has independent AI agents with specialized roles that communicate and delegate work. This guide covers the architecture, communication patterns, and n8n implementation.

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           User/External Request              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   Dispatcher   β”‚  (routes requests)
         β”‚   (n8n core)   β”‚
         β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜
             β”‚        β”‚
      β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”  β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
      β”‚ Agent A  β”‚  β”‚ Agent B β”‚  Specialist agents
      β”‚Research β”‚  β”‚ Builder β”‚  (each has role)
      β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
            β”‚            β”‚
      β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”
      β”‚  Message Queue      β”‚  (n8n webhooks)
      β”‚  (async comms)      β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Agent Roles (Example)

Define clear responsibilities for each agent:

Agent Role Tools Input Output
Researcher Finds info, evaluates sources Web API, documents Topic Summary, sources
Builder Implements solutions Code, n8n Spec Working code/workflow
Reviewer QA, tests output Test frameworks Artifact Pass/fail, issues
Dispatcher Routes tasks Scheduling, webhooks Request Task assignment

Communication Pattern 1: Synchronous (Webhook Chain)

Sequential execution: Agent A finishes β†’ calls Agent B β†’ waits for result.

Pros: Simple, results immediately available Cons: Slow, failure in Agent B blocks whole chain

Request
   ↓ (API call)
Agent A (research)
   ↓ (webhook POST with results)
Agent B (build)
   ↓ (response)
Response

Implementation in n8n

Agent A Workflow: "Research Topic"

Trigger: HTTP POST webhook
β”œβ”€β”€ Input: { "topic": "Docker for AI" }
β”œβ”€β”€ Search Web API for topic
β”œβ”€β”€ Summarize with Ollama
└── Call Agent B webhook with results

Agent B Workflow: "Build Tutorial"

Trigger: HTTP webhook (from Agent A)
β”œβ”€β”€ Input: { "research_summary": "..." }
β”œβ”€β”€ Create tutorial structure
β”œβ”€β”€ Write content with Ollama
└── Return tutorial to caller

In n8n:

  1. Agent A: Add HTTP Request node

    URL: http://your-server:5678/webhook/build-tutorial
    Method: POST
    Body:
    {
      "research": {{ $json.research_summary }},
      "topic": {{ $json.topic }}
    }
    
  2. Agent B: Webhook trigger accepts request, processes, returns response

Test:

curl -X POST http://your-server:5678/webhook/research \
  -H "Content-Type: application/json" \
  -d '{"topic": "Docker for AI"}'

# Response comes from Agent B (full chain executed)

Communication Pattern 2: Asynchronous (Message Queue)

Fire-and-forget: Agent A submits task β†’ Agent B processes when ready.

Pros: Scalable, agents independent, fault-tolerant Cons: Complex, need status polling

Request
   ↓
Agent A (queue task)
   ↓ (immediate return: "task_id")
Client polls status
   ↓
Agent B (background)
   β”œβ”€β”€ Processes task
   └── Updates status

Client checks: /api/task/task_id β†’ status, result

Implementation with n8n + Database

Dispatcher (Main Workflow)

Trigger: HTTP POST
β”œβ”€β”€ Input: { "action": "analyze_feedback" }
β”œβ”€β”€ Set node: Generate task_id = UUID
β”œβ”€β”€ Write to tasks table:
β”‚   {
β”‚     "task_id": {{ $json.task_id }},
β”‚     "action": "analyze_feedback",
β”‚     "status": "pending",
β”‚     "created_at": now()
β”‚   }
└── Respond: { "task_id": "...", "status": "pending" }

Agent Worker (Background Workflow)

Trigger: Schedule (every 1 minute)
β”œβ”€β”€ Query: SELECT * FROM tasks WHERE status = 'pending'
β”œβ”€β”€ For each pending task:
β”‚   β”œβ”€β”€ Run specialized agent (n8n sub-workflow)
β”‚   β”œβ”€β”€ Update task row:
β”‚   β”‚   {
β”‚   β”‚     "status": "completed",
β”‚   β”‚     "result": {{ $json.agent_output }},
β”‚   β”‚     "completed_at": now()
β”‚   β”‚   }
β”‚   └── Notify requestor (email/webhook)

Status Endpoint

Trigger: HTTP GET /task/{task_id}
β”œβ”€β”€ Query: SELECT * FROM tasks WHERE task_id = {task_id}
└── Return: { "status": "completed", "result": {...} }

Communication Pattern 3: Hierarchical (Manager β†’ Workers)

A manager agent coordinates multiple worker agents.

Manager (Orchestrator)
β”œβ”€β”€ Task 1 β†’ Worker A
β”œβ”€β”€ Task 2 β†’ Worker B (parallel)
└── Task 3 β†’ Worker C (parallel)
   ↓ (wait for all)
Combine results
   ↓
Return to user

Example: Content Pipeline Manager

  1. Manager: "Create blog post"
  2. Split into subtasks:
    • Task A: Research topic (Worker A)
    • Task B: Create outline (Worker B)
    • Task C: Generate images (Worker C)
  3. Parallel execution (all run at same time)
  4. Merge results β†’ Final blog post

In n8n:

Trigger
  ↓
Set: Generate subtask IDs
  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Parallel branches (3 workers)   β”‚
β”œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚          β”‚                β”‚
Task A Task B    Task C           β”‚
β”‚     β”‚          β”‚                β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  ↓
Merge node (wait for all)
  ↓
Combine results
  ↓
Save to file/database

Agent Communication via Shared Database

Agents write to shared tables, read others' output.

# Agent A writes findings to database
INSERT INTO findings (agent_id, topic, data, created_at)
VALUES ('researcher', 'Docker', {...}, now())

# Agent B reads from findings table
SELECT * FROM findings WHERE agent_id = 'researcher'

# Agent B writes its own findings
INSERT INTO findings (agent_id, topic, data, created_at)
VALUES ('builder', 'Docker', {...}, now())

In n8n:

Agent A Workflow:
  β”œβ”€β”€ Research topic
  β”œβ”€β”€ Write to database:
  β”‚   Table: findings
  β”‚   Rows: [agent='researcher', topic='Docker', ...]
  └── Emit event: 'research_complete'

Agent B Workflow:
  β”œβ”€β”€ Webhook: listen for 'research_complete'
  β”œβ”€β”€ Read findings table (WHERE agent='researcher')
  β”œβ”€β”€ Build tutorial
  β”œβ”€β”€ Write results to database:
  β”‚   Table: deliverables
  β”‚   Rows: [type='tutorial', status='complete', ...]
  └── Emit event: 'build_complete'

State & Memory

Agents need to remember past interactions.

Short-term (Session): In-memory

# Shared state during single workflow execution
session_state = {
    "topic": "Docker",
    "research_findings": [...],
    "outline": [...],
    "current_step": 3
}

In n8n: Use Set node to build object across steps.

Long-term (Persistent): Database

CREATE TABLE agent_memory (
    id PRIMARY KEY,
    agent_id TEXT,
    context_key TEXT,  -- "docker_tutorial_v1"
    memory_data JSON,   -- {"research": {...}, "outline": {...}}
    created_at TIMESTAMP,
    expires_at TIMESTAMP
);

Example: Memory for multi-turn conversation

Message 1: "Explain Docker"
  └─ Agent stores: { "topic": "Docker", "messages": [...] }

Message 2: "What about images?"
  └─ Agent reads memory, context-aware response
  └─ Updates: { "topic": "Docker", "messages": [..., message2] }

Message 3: "Compare with VMs"
  └─ Agent has full conversation history

Error Handling & Retries

When Agent A fails calling Agent B:

Agent A calls Agent B (HTTP request)
β”œβ”€β”€ Success (200): Continue
β”œβ”€β”€ Timeout (504): Retry 3 times with exponential backoff
β”œβ”€β”€ Rate limit (429): Queue for later
└── Server error (500): Log and alert human

In n8n:

HTTP Request node
β”œβ”€β”€ Retry logic:
β”‚   - Max retries: 3
β”‚   - Delay: 2s, 4s, 8s (exponential)
β”œβ”€β”€ Error handling:
β”‚   - If still fails: Email admin
β”‚   - Log error to database

Example: Complete Multi-Agent System

Workflow: "Content from Brief"

User submits: { "brief": "Write API guide" }
   ↓
Dispatcher
   β”œβ”€β”€ Task 1 (parallel): Research β†’ n8n workflow
   β”œβ”€β”€ Task 2 (parallel): Outline β†’ n8n workflow
   └── Task 3 (parallel): Code examples β†’ n8n workflow
   ↓ (all complete)
Merge results
   ↓
Writer agent (sequential)
   β”œβ”€β”€ Combine research + outline + code
   β”œβ”€β”€ Write tutorial with Ollama
   └── Format as markdown
   ↓
Reviewer agent
   β”œβ”€β”€ Check quality
   β”œβ”€β”€ Test code examples
   └── Return pass/fail
   ↓
If failed: Notify writer agent for revision
If passed: Save to wiki, email user

Monitoring Multi-Agent Systems

Track agent health and task flow:

Metrics to monitor:
  - Task success rate (per agent)
  - Average task time (per agent)
  - Queue depth (pending tasks)
  - Agent uptime (workflow executions)
  - Error types (failures grouped by type)

In Grafana dashboard:

# Success rate per agent
(agent_tasks_success / agent_tasks_total) * 100

# Queue depth
count(tasks WHERE status='pending')

# Average task duration
avg(task_duration_ms) group by agent_id

Scalability Considerations

  • Number of agents: Start with 3-5, add as needed
  • Message queue: n8n webhooks scale to ~100 tasks/sec
  • Database: PostgreSQL holds unlimited task history
  • Rate limiting: Prevent one agent from overwhelming others
n8n workflow rate limiting:
  - Add "Wait" node: 1-2 seconds between Ollama calls
  - Distribute load: Stagger agent start times
  - Queue max size: Reject new tasks if queue > 1000

Checklist

  • Define agent roles and responsibilities
  • Choose communication pattern (sync/async/hierarchy)
  • Design message format (JSON schema)
  • Create dispatcher workflow
  • Create 2-3 worker workflows
  • Implement error handling (retries, fallbacks)
  • Set up shared state (database tables)
  • Add logging (what each agent does)
  • Monitor success rates and latencies
  • Document agent responsibilities
  • Test agent-to-agent communication
  • Set up backup/recovery (if agent fails)
  • Scale test (simulate 100+ concurrent tasks)