8
n8n 中文网amn8n.com

🎓 使用并行处理优化速度关键工作流(扇出-扇入)

高级

这是一个Engineering, Multimodal AI领域的自动化工作流,包含 34 个节点。主要使用 If, Set, Code, Wait, Switch 等节点。 🎓 使用并行处理(扇出/扇入)优化速度关键工作流

前置要求
  • 可能需要目标 API 的认证凭证
  • Google Gemini API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "creator": "Lucas Peyrin",
    "instanceId": "e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0",
    "fingerprint": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVhdG9yIjoiIiwiaXNzIjoibjhuIiwiaWF0IjoxNzUzMTQ0MDU0fQ.wnimKzcmWe7ihoVF2LKDp24GNwgHh-nFEGhNJd1iP_s",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "a514f04d-0f18-4016-bb0f-20f598210dff",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Start Project",
      "type": "n8n-nodes-base.manualTrigger",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -784,
        -1184
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3fac5b1b-d94c-4b0a-a3d2-3edf5fd2934b",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "The Dispatcher",
      "type": "n8n-nodes-base.switch",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        16,
        -384
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "write_description",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9ba4d141-2f64-4b74-8e72-a3da836e3f8f",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.process }}",
                    "rightValue": "write_description"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "write_ad_copy",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "88b909d3-9bc2-4ae8-841d-58b88df591ef",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.process }}",
                    "rightValue": "write_ad_copy"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "write_email",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "664df8e3-81f2-43e6-b852-c02693fa6ef2",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.process }}",
                    "rightValue": "write_email"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "58e0764e-1d4a-4ff3-9274-1943ad2b6645",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Split Out Tasks",
      "type": "n8n-nodes-base.splitOut",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -224,
        -1184
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "tasks"
      },
      "typeVersion": 1
    },
    {
      "id": "da60465a-b7b4-4746-a9a5-c4bca8e66a78",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "The Project Brief",
      "type": "n8n-nodes-base.set",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -448,
        -1184
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "550d27f1-bb91-4290-ab17-f055d08920be",
              "name": "tasks",
              "type": "array",
              "value": "=[{\"process\":\"write_description\",\"data\":{\"product\":\"Super Widget\"}},{\"process\":\"write_ad_copy\",\"data\":{\"product\":\"Super Widget\",\"tone\":\"Excited\"}},{\"process\":\"write_email\",\"data\":{\"product\":\"Super Widget\",\"audience\":\"Tech CEOs\"}}]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "4145b00b-b9f5-4573-a44b-529709d9de61",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Wait for All Teams to Finish",
      "type": "n8n-nodes-base.wait",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        592,
        -1184
      ],
      "webhookId": "834824f3-7ace-4224-bb60-53ff8f12e89d",
      "parameters": {
        "resume": "webhook",
        "options": {},
        "httpMethod": "POST"
      },
      "executeOnce": true,
      "typeVersion": 1.1
    },
    {
      "id": "6edc8c72-8372-4a4f-9698-f5279c90663e",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Assign Tasks to Teams",
      "type": "n8n-nodes-base.executeWorkflow",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        128,
        -1184
      ],
      "parameters": {
        "options": {
          "waitForSubWorkflow": false
        },
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {
            "data": "={{ $json.data }}",
            "status": "initialise",
            "process": "={{ $json.process }}",
            "resume_url": "={{ $execution.resumeUrl }}",
            "main_execution_id": "={{ $execution.id }}"
          },
          "schema": [
            {
              "id": "main_execution_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "main_execution_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "process",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "data",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "data",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "resume_url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "resume_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2,
      "alwaysOutputData": true
    },
    {
      "id": "5493e3ed-ae58-48df-8315-cf4599525b7a",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Receive Work Order",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -432,
        -176
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "main_execution_id"
            },
            {
              "name": "process"
            },
            {
              "name": "data",
              "type": "object"
            },
            {
              "name": "status"
            },
            {
              "name": "resume_url"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "11b9ba94-349b-4af2-921e-b1933cc2b9b6",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "The AI Specialist",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        416,
        0
      ],
      "parameters": {
        "options": {
          "temperature": 0
        }
      },
      "credentials": {
        "googlePalmApi": {
          "id": "AXawYbABK5aZbGBE",
          "name": "IA2S"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0d9fb81e-a2ca-40e6-841a-bf0341b4b902",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Description Team",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        320,
        -560
      ],
      "parameters": {
        "text": "=Write a product description for: {{$json.data.product}}",
        "options": {
          "systemMessage": "No preamble. Just what you're asked for."
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b6ebf60e-dcff-4f6c-aefc-8bd1bc65c848",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Ad Copy Team",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        320,
        -368
      ],
      "parameters": {
        "text": "=Write ad copy for: {{$json.data.product}}. The tone should be: {{$json.data.tone}}",
        "options": {
          "systemMessage": "No preamble. Just what you're asked for."
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "f2029b42-6a36-4220-bc4f-8c8b12dcb977",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Email Team",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        320,
        -176
      ],
      "parameters": {
        "text": "=Write a cold email about {{$json.data.product}} for the following audience: {{$json.data.audience}}",
        "options": {
          "systemMessage": "No preamble. Just what you're asked for."
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "41ddaf46-6e78-4463-9454-0bc6aa9c6075",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Report Back to Manager",
      "type": "n8n-nodes-base.executeWorkflow",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        784,
        -368
      ],
      "parameters": {
        "mode": "each",
        "options": {
          "waitForSubWorkflow": false
        },
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {
            "data": "={{ $json }}",
            "status": "completed",
            "process": "={{ $('Receive Work Order').last().json.process }}",
            "main_execution_id": "={{ $('Receive Work Order').last().json.main_execution_id }}"
          },
          "schema": [
            {
              "id": "main_execution_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "main_execution_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "process",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "data",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "data",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "resume_url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "resume_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b54e5478-9723-48ef-94aa-563726294d3b",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -544,
        -1520
      ],
      "parameters": {
        "color": 7,
        "width": 1904,
        "height": 544,
        "content": "## The Main Workflow (The Project Manager)\n\nThis top flow is the **Project Manager**. Its only job is to start the project, assign the tasks, and wait for all the teams to report back that their work is complete."
      },
      "typeVersion": 1
    },
    {
      "id": "07aa4fd8-fa34-481a-8735-c21b0a5458dd",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -544,
        -944
      ],
      "parameters": {
        "color": 7,
        "width": 1600,
        "height": 1680,
        "content": "## The Sub-Workflow (The Specialist Teams)\n\nThis bottom flow represents the **Specialist Teams**. It receives a single work order, does the job, and reports its status back to the Project Dashboard."
      },
      "typeVersion": 1
    },
    {
      "id": "b454585f-b383-4b60-8766-6f114aee7baf",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "The Project Dashboard (Code)",
      "type": "n8n-nodes-base.code",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        16,
        352
      ],
      "parameters": {
        "jsCode": "// This node is the brain of the whole operation.\n// It uses Static Data, which is like a shared whiteboard for the workflow.\n\n// Get the shared whiteboard data.\nconst staticData = $getWorkflowStaticData('global');\nif (!staticData.projects) {\n  staticData.projects = {};\n}\n\n// Get the status from the incoming item.\nconst status = $json.status;\n\n// --- CASE 1: A new project is starting --- //\nif (status === 'initialise') {\n  const mainId = $json.main_execution_id;\n  const resumeUrl = $json.resume_url;\n  const tasksToRun = $input.all();\n\n  // Create a new section on our dashboard for this project.\n  staticData.projects[mainId] = {\n    resumeUrl: resumeUrl,\n    tasks: {}\n  };\n\n  // Add each task to the dashboard with a 'pending' status and start time.\n  for (const task of tasksToRun) {\n    const processName = task.json.process;\n    staticData.projects[mainId].tasks[processName] = {\n      status: 'pending',\n      startTime: new Date().toISOString()\n    };\n  }\n  console.log(`Project ${mainId} initialized with ${tasksToRun.length} tasks.`);\n\n  // Send the tasks out to the specialist teams.\n  return tasksToRun;\n}\n\n// --- CASE 2: A specialist team has finished a task --- //\nif (status === 'completed') {\n  const mainId = $json.main_execution_id;\n  const completedProcess = $json.process;\n  const resultData = $json.data;\n  const projectDashboard = staticData.projects[mainId];\n\n  if (!projectDashboard) {\n    console.log(`No dashboard found for mainId: ${mainId}.`);\n    return []; // Stop if the project doesn't exist.\n  }\n\n  // Update the task on the dashboard.\n  const task = projectDashboard.tasks[completedProcess];\n  task.status = 'completed';\n  task.endTime = new Date().toISOString();\n  task.result = resultData;\n  // Calculate duration in seconds\n  const durationMs = new Date(task.endTime) - new Date(task.startTime);\n  task.duration_seconds = parseFloat((durationMs / 1000).toFixed(2));\n\n  console.log(`Task ${completedProcess} for project ${mainId} marked as completed in ${task.duration_seconds}s.`);\n\n  // Check if ALL tasks on the dashboard are now 'completed'.\n  const allDone = Object.values(projectDashboard.tasks).every(t => t.status === 'completed');\n\n  if (allDone) {\n    console.log(`All tasks for project ${mainId} are done. Resuming main workflow.`);\n    const resumeUrl = projectDashboard.resumeUrl;\n    const finalResponse = projectDashboard.tasks;\n\n    // Clean up the dashboard for this project.\n    delete staticData.projects[mainId];\n\n    // Return a special item that will trigger the 'Resume Parent Workflow' node.\n    return [{\n      json: {\n        end_process: true,\n        resume_url: resumeUrl,\n        response: finalResponse\n      }\n    }];\n  }\n\n  // If not all tasks are done, we do nothing and wait for the next team to report back.\n  return [];\n}\n\n// By default, if the status is not 'initialise' or 'completed', do nothing.\nreturn [];"
      },
      "typeVersion": 2
    },
    {
      "id": "7f8dde47-d0d1-4a6d-8835-747acfead126",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Start Process",
      "type": "n8n-nodes-base.executeWorkflow",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        816,
        528
      ],
      "parameters": {
        "mode": "each",
        "options": {
          "waitForSubWorkflow": false
        },
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {
            "data": "={{ $json.data }}",
            "status": "pending",
            "process": "={{ $json.process }}",
            "main_execution_id": "={{ $json.main_execution_id }}"
          },
          "schema": [
            {
              "id": "main_execution_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "main_execution_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "process",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "data",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "data",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5d738915-c7aa-476c-ac3f-2db43c55848a",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Check Work Order Status",
      "type": "n8n-nodes-base.if",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -208,
        -176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bed89853-0399-4038-8650-5d578d34e5fb",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "pending"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c44019a3-fd3a-4c75-9dcb-18f46da0f84a",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Is Project Complete?",
      "type": "n8n-nodes-base.if",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        416,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "aab184da-7adb-4008-9ccd-99152b55e837",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.end_process }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a05d0e03-c51a-4bfd-ac45-d285f17d7696",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Resume Parent Workflow",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        816,
        144
      ],
      "parameters": {
        "url": "={{ $json.resume_url }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json.response }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "8dab80dc-6ea8-47b1-bfde-546cd6a853a5",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Project Complete!",
      "type": "n8n-nodes-base.set",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        1056,
        -1184
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c8f45ef6-748c-42e0-937b-48766f039259",
              "name": "email",
              "type": "string",
              "value": "={{ $json.body.write_email.result.output }}"
            },
            {
              "id": "c3db0b0f-86c6-4de3-980d-f3d8570b132b",
              "name": "ad_copy",
              "type": "string",
              "value": "={{ $json.body.write_ad_copy.result.output }}"
            },
            {
              "id": "d6894be9-9835-41dd-8cec-e40044b84d2e",
              "name": "description",
              "type": "string",
              "value": "={{ $json.body.write_description.result.output }}"
            },
            {
              "id": "e7f8a9b0-c1d2-e3f4-a5b6-c7d8e9f0a1b2",
              "name": "seconds_saved",
              "type": "number",
              "value": "={{ $json.body.values().map(item => item.duration_seconds).sum() - $json.body.values().map(item => item.duration_seconds).max() }}"
            },
            {
              "id": "5477e4af-b915-4129-b573-5c35ea15aa08",
              "name": "task_duration_seconds",
              "type": "number",
              "value": "={{ $json.body.values().map(item => item.duration_seconds).max() }}"
            },
            {
              "id": "bb5305a7-1d69-4d68-8610-500e19a947e4",
              "name": "task_duration_without_parallelisation",
              "type": "number",
              "value": "={{ $json.body.values().map(item => item.duration_seconds).sum() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8ca34e6a-bfe6-4fbd-8744-c8b7d00e9c56",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -512,
        -1408
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 400,
        "content": "### The Project Brief\n\nThis node defines all the independent tasks we need to accomplish for this project. Each task has a `process` name and the `data` it needs."
      },
      "typeVersion": 1
    },
    {
      "id": "c76dcf95-13a2-45e5-961f-1342e33aec62",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -48,
        -1408
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 400,
        "content": "### Assign Tasks (Fan-Out)\n\nThis is the **Fan-Out** moment. This node calls our sub-workflow for each task.\n\n**Crucial Setting:** `Wait for Sub-Workflow` is **OFF**. This means the main workflow doesn't wait. It fires off all the tasks and immediately moves to the `Wait` node."
      },
      "typeVersion": 1
    },
    {
      "id": "da5e23d0-9167-4ac9-9c76-c81f6e492bd3",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        416,
        -1408
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 400,
        "content": "### Wait for Completion (Pause)\n\nThis node **pauses** the main workflow indefinitely. It's the Project Manager waiting in their office.\n\nIt will only resume when another node (in our case, the `Resume Parent Workflow` node) makes a `POST` request to its unique `resume_url`."
      },
      "typeVersion": 1
    },
    {
      "id": "73387584-46dc-4bfb-816b-20d88a2f88a4",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        880,
        -1408
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 400,
        "content": "### Project Complete! (Fan-In)\n\nThis is the **Fan-In** moment. This node only runs *after* the `Wait` node has been resumed.\n\nIt receives the final, aggregated data from all the parallel tasks and can now continue with the rest of the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "27335a12-cede-465c-8b71-309d5dd5d37b",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -512,
        -336
      ],
      "parameters": {
        "color": 7,
        "height": 336,
        "content": "### Receive Work Order\n\nThis is the entry point for the Specialist Teams. It receives a single task from the main workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "0f42ccf2-bdab-4882-b1c7-90d91d2f74b2",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -80,
        -528
      ],
      "parameters": {
        "color": 4,
        "width": 288,
        "height": 336,
        "content": "### The Dispatcher\n\nThis Switch node acts as a dispatcher, sending the work order to the correct Specialist Team based on the `process` name."
      },
      "typeVersion": 1
    },
    {
      "id": "6d1b4c86-c663-4420-a2da-60e4fc87ddab",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        256,
        -720
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 848,
        "content": "### The Specialist Teams\n\nThese three Agent nodes represent the different teams doing the actual work. In a real-world scenario, these could be complex sub-workflows themselves."
      },
      "typeVersion": 1
    },
    {
      "id": "c82f2081-50a5-488c-bbde-d59c5adcb2bc",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        688,
        -576
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "### Report Back to Manager\n\nThis node doesn't talk to the main workflow directly. Instead, it calls the sub-workflow *again*, but this time with a `status` of `completed`. This is the signal for the Project Dashboard to update."
      },
      "typeVersion": 1
    },
    {
      "id": "a7841998-7c67-448c-8c98-c94e851402c7",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -256,
        32
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 512,
        "content": "### The Project Dashboard (Code)\n\nThis is the most important node. It acts as the central brain and state manager for the entire operation, using **Static Data** as a shared whiteboard.\n\nIt handles two cases:\n1.  **`status: 'initialise'`:** When a new project starts, it creates a new entry on the dashboard and lists all tasks as 'pending'.\n2.  **`status: 'completed'`:** When a team reports back, it updates that task's status on the dashboard. It then checks if *all* tasks are complete. If they are, it triggers the `Resume Parent Workflow` node."
      },
      "typeVersion": 1
    },
    {
      "id": "a0e3bb3c-71ca-485d-8daf-67f8df6ba97d",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        704,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 368,
        "content": "### Resume Parent Workflow\n\nThis node is only triggered when the Project Dashboard confirms all tasks are complete. It makes a `POST` request to the `Wait` node's unique URL, sending the final results and waking up the main workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "410c8b95-c5fc-4ad0-85a3-e2f647a23cd3",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -256,
        -816
      ],
      "parameters": {
        "color": 4,
        "width": 496,
        "height": 816,
        "content": "### Alternative Architecture\n\nFor even more complex projects, you could replace this Switch node with a more modular design:\n\n- Each \"Team\" (Description, Ad Copy, etc.) could be its own separate, dedicated workflow.\n- The main workflow would call the correct workflow based on the `process` name (that could be a workflow id).\n- A single, separate \"Status Handler\" workflow would manage the Project Dashboard logic, called by each team when they finish."
      },
      "typeVersion": 1
    },
    {
      "id": "1d9b9fc4-d181-4555-a9c4-febf7c1fa459",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        -1152,
        -1600
      ],
      "parameters": {
        "width": 576,
        "height": 616,
        "content": "## Tutorial: Parallel Processing (Fan-Out/Fan-In)\n\nWelcome! This template demonstrates an advanced but incredibly powerful n8n pattern for running multiple tasks **in parallel**.\n\n**When to use this?**\nWhen **speed is your top priority**. If you have multiple independent tasks (like calling an AI 3 times), running them at the same time is much faster than running them one after another.\n\n**The Analogy: A Construction Project**\n- **Main Workflow:** The **Project Manager** who starts the project and waits for it to be done.\n- **Sub-Workflow:** The **Specialist Teams** (electricians, painters) who do the actual work.\n- **Static Data:** The **Project Dashboard** where the manager tracks each team's progress."
      },
      "typeVersion": 1
    },
    {
      "id": "7ad3b188-ad65-42e1-870b-ace7e61a5d9b",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        704,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 384,
        "content": "### Start Specialit Teams\n\nThis node doesn't talk to the main workflow directly. Instead, it calls the sub-workflow *again*, but this time with a `status` of `pending`. This is the signal for the Teams to start. This could be replaced with calling specific sub workflows for each task."
      },
      "typeVersion": 1
    },
    {
      "id": "751c86aa-9223-4431-a252-560b16c4d4c3",
      "cid": "Ikx1Y2FzIFBleXJpbiI",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "notes": "© 2025 Lucas Peyrin",
      "creator": "Lucas Peyrin",
      "position": [
        1088,
        -544
      ],
      "parameters": {
        "color": 3,
        "width": 540,
        "height": 1280,
        "content": "## Was this helpful? Let me know!\n[![clic](https://supastudio.ia2s.app/storage/v1/object/public/assets/n8n/clic_down_lucas.gif)](https://n8n.ac)\n\nI really hope this tutorial helped you grasp parallel processing in n8n. Your feedback is incredibly valuable and helps me create better resources for the n8n community.\n\n### **Share Your Thoughts & Ideas**\n\nWhether you have a suggestion, found a typo, or just want to say thanks, I'd love to hear from you!\nHere's a simple n8n form built for this purpose:\n\n#### ➡️ **[Click here to give feedback](https://api.ia2s.app/form/templates/feedback?template=Parallel%20Processing%20Tutorial)**\n\n### **Ready to Build Something Great?**\n\nIf you're looking to take your n8n skills or business automation to the next level, I can help.\n\n**🎓 n8n Coaching:** Want to become an n8n pro? I offer one-on-one coaching sessions to help you master workflows, tackle specific problems, and build with confidence.\n#### ➡️ **[Book a Coaching Session](https://api.ia2s.app/form/templates/coaching?template=Parallel%20Processing%20Tutorial)**\n\n**💼 n8n Consulting:** Have a complex project, an integration challenge, or need a custom workflow built for your business? Let's work together to create a powerful automation solution.\n#### ➡️ **[Inquire About Consulting Services](https://api.ia2s.app/form/templates/consulting?template=Parallel%20Processing%20Tutorial)**\n\n---\n\nHappy Automating!\nLucas Peyrin | [n8n Academy](https://n8n.ac)"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "f2029b42-6a36-4220-bc4f-8c8b12dcb977": {
      "main": [
        [
          {
            "node": "41ddaf46-6e78-4463-9454-0bc6aa9c6075",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b6ebf60e-dcff-4f6c-aefc-8bd1bc65c848": {
      "main": [
        [
          {
            "node": "41ddaf46-6e78-4463-9454-0bc6aa9c6075",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a514f04d-0f18-4016-bb0f-20f598210dff": {
      "main": [
        [
          {
            "node": "da60465a-b7b4-4746-a9a5-c4bca8e66a78",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3fac5b1b-d94c-4b0a-a3d2-3edf5fd2934b": {
      "main": [
        [
          {
            "node": "0d9fb81e-a2ca-40e6-841a-bf0341b4b902",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b6ebf60e-dcff-4f6c-aefc-8bd1bc65c848",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "f2029b42-6a36-4220-bc4f-8c8b12dcb977",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "58e0764e-1d4a-4ff3-9274-1943ad2b6645": {
      "main": [
        [
          {
            "node": "6edc8c72-8372-4a4f-9698-f5279c90663e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0d9fb81e-a2ca-40e6-841a-bf0341b4b902": {
      "main": [
        [
          {
            "node": "41ddaf46-6e78-4463-9454-0bc6aa9c6075",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "11b9ba94-349b-4af2-921e-b1933cc2b9b6": {
      "ai_languageModel": [
        [
          {
            "node": "0d9fb81e-a2ca-40e6-841a-bf0341b4b902",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "b6ebf60e-dcff-4f6c-aefc-8bd1bc65c848",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "f2029b42-6a36-4220-bc4f-8c8b12dcb977",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "da60465a-b7b4-4746-a9a5-c4bca8e66a78": {
      "main": [
        [
          {
            "node": "58e0764e-1d4a-4ff3-9274-1943ad2b6645",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5493e3ed-ae58-48df-8315-cf4599525b7a": {
      "main": [
        [
          {
            "node": "5d738915-c7aa-476c-ac3f-2db43c55848a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c44019a3-fd3a-4c75-9dcb-18f46da0f84a": {
      "main": [
        [
          {
            "node": "a05d0e03-c51a-4bfd-ac45-d285f17d7696",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "7f8dde47-d0d1-4a6d-8835-747acfead126",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6edc8c72-8372-4a4f-9698-f5279c90663e": {
      "main": [
        [
          {
            "node": "4145b00b-b9f5-4573-a44b-529709d9de61",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5d738915-c7aa-476c-ac3f-2db43c55848a": {
      "main": [
        [
          {
            "node": "3fac5b1b-d94c-4b0a-a3d2-3edf5fd2934b",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b454585f-b383-4b60-8766-6f114aee7baf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b454585f-b383-4b60-8766-6f114aee7baf": {
      "main": [
        [
          {
            "node": "c44019a3-fd3a-4c75-9dcb-18f46da0f84a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4145b00b-b9f5-4573-a44b-529709d9de61": {
      "main": [
        [
          {
            "node": "8dab80dc-6ea8-47b1-bfde-546cd6a853a5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 工程, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量34
分类2
节点类型13
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Lucas Peyrin

Lucas Peyrin

@lucaspeyrin

Innovative builder with a passion for crafting automation solutions that solve real-world challenges. From streamlining workflows to driving efficiency, my work empowers teams and individuals to achieve more with less effort. Experienced in developing scalable tools and strategies that deliver results with n8n, supabase and cline.

外部链接
在 n8n.io 查看

分享此工作流

分类

分类: 34