AutomationFlowsAI & RAG › Agent Swarm - Main Orchestrator

Agent Swarm - Main Orchestrator

Agent Swarm - Main Orchestrator. Uses httpRequest. Webhook trigger; 13 nodes.

Webhook trigger★★★★☆ complexity13 nodesHTTP Request
AI & RAG Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Agent Swarm - Main Orchestrator",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "agent-swarm",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-node",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Extract and structure input from webhook\nconst body = $input.item.json.body || $input.item.json;\n\nreturn {\n  json: {\n    task: body.task || '',\n    context: body.context || {},\n    preferences: body.preferences || {},\n    user_id: body.context?.user_id || 'anonymous',\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "id": "set-input",
      "name": "Set Input",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "url": "=https://api.openai.com/v1/chat/completions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": []
        },
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"gpt-4o\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Du bist der ORCHESTRATOR im Agent-Swarm-System f\u00fcr KI-Automatisierung.\\n\\nROLLE:\\nDu steuerst die Arbeit der anderen Agenten (Builder, Reviewer, Documenter).\\nDu zerlegst komplexe Aufgaben in klare Teilaufgaben und weist sie den richtigen Agenten zu.\\n\\nAUFGABEN:\\n1. Verstehe das Ziel oder Problem des Nutzers\\n2. Zerlege komplexe Aufgaben in klare Teilaufgaben\\n3. Entscheide, welcher Agent welche Teilaufgabe \u00fcbernimmt:\\n   - BUILDER: Technische Umsetzung (Code, Skripte, Workflows)\\n   - REVIEWER: Qualit\u00e4tskontrolle (Pr\u00fcfung, Fehlererkennung)\\n   - DOCUMENTER: Dokumentation (Zusammenfassung, Strukturierung)\\n4. Priorisiere die Aufgaben\\n5. Erstelle eine klare Zusammenfassung\\n\\nOUTPUT-FORMAT (JSON, zwingend einhalten):\\n{\\n  \\\"task_breakdown\\\": [\\n    {\\n      \\\"subtask_id\\\": 1,\\n      \\\"subtask\\\": \\\"Kurze Beschreibung\\\",\\n      \\\"agent\\\": \\\"builder|reviewer|documenter\\\",\\n      \\\"priority\\\": 1,\\n      \\\"description\\\": \\\"Detaillierte Beschreibung\\\"\\n    }\\n  ],\\n  \\\"summary\\\": \\\"Zusammenfassung\\\",\\n  \\\"estimated_time\\\": \\\"X Minuten\\\",\\n  \\\"requires_parallel\\\": true\\n}\\n\\nAntworte NUR mit validem JSON, keine zus\u00e4tzlichen Erkl\u00e4rungen.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"=Task: {{ $json.task }}\\nContext: {{ JSON.stringify($json.context) }}\"\n    }\n  ],\n  \"temperature\": 0.3,\n  \"response_format\": { \"type\": \"json_object\" }\n}",
        "options": {}
      },
      "id": "orchestrator-llm",
      "name": "Orchestrator LLM",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        650,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse LLM Response and extract task breakdown\nconst response = $input.item.json;\nlet content;\n\ntry {\n  // Handle OpenAI API response format\n  if (response.choices && response.choices[0]) {\n    content = JSON.parse(response.choices[0].message.content);\n  } else if (response.content) {\n    content = typeof response.content === 'string' ? JSON.parse(response.content) : response.content;\n  } else {\n    content = response;\n  }\n} catch (e) {\n  throw new Error(`Failed to parse LLM response: ${e.message}`);\n}\n\n// Validate structure\nif (!content.task_breakdown || !Array.isArray(content.task_breakdown)) {\n  throw new Error('Invalid response format: missing task_breakdown array');\n}\n\nreturn {\n  json: {\n    task_breakdown: content.task_breakdown,\n    summary: content.summary || '',\n    estimated_time: content.estimated_time || 'unknown',\n    requires_parallel: content.requires_parallel || false,\n    original_task: $('Set Input').item.json.task,\n    context: $('Set Input').item.json.context\n  }\n};"
      },
      "id": "parse-orchestrator",
      "name": "Parse Orchestrator",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        850,
        300
      ]
    },
    {
      "parameters": {
        "mode": "splitInBatches",
        "batchSize": 1,
        "options": {}
      },
      "id": "split-tasks",
      "name": "Split Tasks",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1050,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "current-subtask",
              "name": "current_subtask",
              "value": "={{ $json.task_breakdown[$json.item] }}",
              "type": "object"
            },
            {
              "id": "agent-type",
              "name": "agent_type",
              "value": "={{ $json.task_breakdown[$json.item].agent }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "set-current-task",
      "name": "Set Current Task",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1250,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "builder-case",
              "leftValue": "={{ $json.agent_type }}",
              "rightValue": "builder",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "reviewer-case",
              "leftValue": "={{ $json.agent_type }}",
              "rightValue": "reviewer",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "documenter-case",
              "leftValue": "={{ $json.agent_type }}",
              "rightValue": "documenter",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "id": "route-agent",
      "name": "Route to Agent",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        1450,
        300
      ]
    },
    {
      "parameters": {
        "workflowId": "agent-builder",
        "source": "database",
        "options": {}
      },
      "id": "call-builder",
      "name": "Call Builder Agent",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.1,
      "position": [
        1650,
        200
      ],
      "notes": "Sub-Workflow: agent-builder"
    },
    {
      "parameters": {
        "workflowId": "agent-reviewer",
        "source": "database",
        "options": {}
      },
      "id": "call-reviewer",
      "name": "Call Reviewer Agent",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.1,
      "position": [
        1650,
        300
      ],
      "notes": "Sub-Workflow: agent-reviewer"
    },
    {
      "parameters": {
        "workflowId": "agent-documenter",
        "source": "database",
        "options": {}
      },
      "id": "call-documenter",
      "name": "Call Documenter Agent",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.1,
      "position": [
        1650,
        400
      ],
      "notes": "Sub-Workflow: agent-documenter"
    },
    {
      "parameters": {
        "mode": "combine",
        "combinationMode": "mergeByPosition",
        "options": {}
      },
      "id": "merge-results",
      "name": "Merge Results",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        1850,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Aggregate all agent results\nconst items = $input.all();\nconst taskBreakdown = $('Parse Orchestrator').item.json.task_breakdown;\n\nconst results = {\n  status: 'success',\n  task_id: `task_${Date.now()}`,\n  original_task: $('Parse Orchestrator').item.json.original_task,\n  summary: $('Parse Orchestrator').item.json.summary,\n  estimated_time: $('Parse Orchestrator').item.json.estimated_time,\n  agents: {},\n  execution_time: new Date().toISOString()\n};\n\n// Organize results by agent type\nitems.forEach((item, index) => {\n  const agentType = taskBreakdown[index]?.agent || 'unknown';\n  results.agents[agentType] = {\n    output: item.json.output || item.json,\n    status: item.json.status || 'completed',\n    subtask: taskBreakdown[index]?.subtask || ''\n  };\n});\n\nreturn { json: results };"
      },
      "id": "aggregate-results",
      "name": "Aggregate Results",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2050,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": {}
      },
      "id": "respond-webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        2250,
        300
      ]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Set Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Input": {
      "main": [
        [
          {
            "node": "Orchestrator LLM",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Orchestrator LLM": {
      "main": [
        [
          {
            "node": "Parse Orchestrator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Orchestrator": {
      "main": [
        [
          {
            "node": "Split Tasks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Tasks": {
      "main": [
        [
          {
            "node": "Set Current Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Current Task": {
      "main": [
        [
          {
            "node": "Route to Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route to Agent": {
      "main": [
        [
          {
            "node": "Call Builder Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Call Reviewer Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Call Documenter Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call Builder Agent": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call Reviewer Agent": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call Documenter Agent": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Results": {
      "main": [
        [
          {
            "node": "Aggregate Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Results": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [],
  "triggerCount": 0,
  "updatedAt": "2025-12-19T12:00:00.000Z",
  "versionId": "1"
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Agent Swarm - Main Orchestrator. Uses httpRequest. Webhook trigger; 13 nodes.

Source: https://github.com/timo-goetz-ai/apki-infra-hetzner/blob/133589ea8bc73203bd0b1e7a93f1df5c0a71941c/workflows/agent_swarm_01_main-orchestrator.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Jigsaw API key for image processing, I use this as a gatekeeper/second pair of eyes. LINK to their website https://jigsawstack.com/ SECOND A postgress DATABASE (I use Supabase) LlamaCloud for the pars

HTTP Request, Postgres, Stop And Error +2
AI & RAG

Onsite Photos to Jobs (SMS Agent). Uses dataTable, twilio, httpRequest, airtable. Webhook trigger; 62 nodes.

Data Table, Twilio, HTTP Request +1
AI & RAG

AML Alert Triage. Uses httpRequest. Webhook trigger; 57 nodes.

HTTP Request
AI & RAG

W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 50 nodes.

Postgres, Redis, HTTP Request
AI & RAG

W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 48 nodes.

Postgres, Redis, HTTP Request