博客 / 詳情

返回

工作流引擎技術方案<第一版>

現流行AI工作流引擎技術方案與實現方式調研

n8n

前端技術棧

  1. 核心流程圖庫:Vue Flow
  2. 圖形佈局引擎:Dagre
  3. 拖拽功能:Vuedraggable

    n8n 的流程圖繪製技術棧是:

    Vue Flow(核心) + Dagre(佈局) + Vuedraggable(拖拽) + Vue 3 Composition API(架構)

後端技術棧

後端代碼模塊化梳理:https://www.processon.com/v/685b72107dbaf842a9ee9b54?cid=685b...

數據庫梳理:https://www.processon.com/v/685ba3a83a444c5346fb296c?cid=685b...

流程編排數據前後端如何交互?

n8n核心規則文件位置:
Schema 定義文件:

packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflow.yml - 流程主結構定義

packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/node.yml - 節點結構定義

packages/cli/src/public-api/v1/handlers/workflows/spec/schemas/workflowSettings.yml - 流程設置定義

驗證規則實現:

packages/workflow/src/node-helpers.ts - 節點參數驗證核心邏輯

packages/workflow/src/type-validation.ts - 字段類型驗證
packages/core/src/execution-engine/workflow-execute.ts - 執行順序規則

JSON數據格式

connections 和 nodes 的關聯機制

關聯方式:通過節點名稱。connections 中的 key 是節點的 name 屬性,不是 id 或數組索引。

{
    "data": {
        "createdAt": "2025-06-24T06:43:23.739Z",
        "updatedAt": "2025-06-24T06:53:51.000Z",
        "id": "yWlJODJAPrxpVgwZ",
        "name": "官方示例流程搭建",
        "active": false,
        "isArchived": false,
        "nodes": [
            {
                "parameters": {
                    "rule": {
                        "interval": [
                            {
                                "field": "weeks",
                                "triggerAtHour": 9
                            }
                        ]
                    }
                },
                "type": "n8n-nodes-base.scheduleTrigger",
                "typeVersion": 1.2,
                "position": [
                    -1680,
                    -60
                ],
                "id": "b3636ac3-e645-4ea3-9462-fd9943d7afcb",
                "name": "Schedule Trigger"
            },
            {
                "parameters": {
                    "resource": "donkiSolarFlare",
                    "additionalFields": {
                        "startDate": "={{ $today.minus(7, 'days') }}"
                    }
                },
                "type": "n8n-nodes-base.nasa",
                "typeVersion": 1,
                "position": [
                    -1460,
                    -60
                ],
                "id": "ed81a5a0-3809-4030-ae43-fb9c35c4b796",
                "name": "Get a DONKI solar flare",
                "credentials": {
                    "nasaApi": {
                        "id": "jpAq9avliTj8I2Mc",
                        "name": "NASA account"
                    }
                }
            },
            {
                "parameters": {
                    "conditions": {
                        "options": {
                            "caseSensitive": true,
                            "leftValue": "",
                            "typeValidation": "strict",
                            "version": 2
                        },
                        "conditions": [
                            {
                                "id": "5a346300-620a-4805-ab25-2f74083fecd3",
                                "leftValue": "={{ $json.classType }}",
                                "rightValue": "C",
                                "operator": {
                                    "type": "string",
                                    "operation": "contains"
                                }
                            }
                        ],
                        "combinator": "and"
                    },
                    "options": {}
                },
                "type": "n8n-nodes-base.if",
                "typeVersion": 2.2,
                "position": [
                    -1240,
                    -60
                ],
                "id": "8268a6c4-a2ae-4e5c-a618-5122437c0211",
                "name": "If"
            },
            {
                "parameters": {
                    "resource": "request",
                    "operation": "send",
                    "binId": "1750747132830-0653709420002",
                    "binContent": "=There was a solar flare of class {{$json[\"classType\"]}}",
                    "requestOptions": {}
                },
                "type": "n8n-nodes-base.postBin",
                "typeVersion": 1,
                "position": [
                    -1020,
                    -160
                ],
                "id": "ba6013d4-0bb2-45d8-8999-4ca80bba59d2",
                "name": "Send a request"
            },
            {
                "parameters": {
                    "resource": "request",
                    "operation": "send",
                    "binId": "1750747132830-0653709420002",
                    "binContent": "=There was a solar flare of class {{$json[\"classType\"]}}",
                    "requestOptions": {}
                },
                "type": "n8n-nodes-base.postBin",
                "typeVersion": 1,
                "position": [
                    -1020,
                    80
                ],
                "id": "a69d4bed-a83c-4a17-abeb-b6ec0f151d18",
                "name": "Send a request1"
            }
        ],
        "connections": {
            "Schedule Trigger": {
                "main": [
                    [
                        {
                            "node": "Get a DONKI solar flare",
                            "type": "main",
                            "index": 0
                        }
                    ]
                ]
            },
            "Get a DONKI solar flare": {
                "main": [
                    [
                        {
                            "node": "If",
                            "type": "main",
                            "index": 0
                        }
                    ]
                ]
            },
            "If": {
                "main": [
                    [
                        {
                            "node": "Send a request",
                            "type": "main",
                            "index": 0
                        }
                    ],
                    [
                        {
                            "node": "Send a request1",
                            "type": "main",
                            "index": 0
                        }
                    ]
                ]
            }
        },
        "settings": {
            "executionOrder": "v1"
        },
        "staticData": null,
        "meta": {
            "templateCredsSetupCompleted": true
        },
        "pinData": {},
        "versionId": "6628dbf5-4035-4295-9ac0-a07aac39d82c",
        "triggerCount": 0,
        "shared": [
            {
                "createdAt": "2025-06-24T06:43:23.744Z",
                "updatedAt": "2025-06-24T06:43:23.744Z",
                "role": "workflow:owner",
                "workflowId": "yWlJODJAPrxpVgwZ",
                "projectId": "uhlnaXhqHMZSgKsg",
                "project": {
                    "createdAt": "2025-06-24T03:16:05.640Z",
                    "updatedAt": "2025-06-24T03:17:41.564Z",
                    "id": "uhlnaXhqHMZSgKsg",
                    "name": "jia meng <mengjia@mengjia.net>",
                    "type": "personal",
                    "icon": null,
                    "description": null,
                    "projectRelations": [
                        {
                            "createdAt": "2025-06-24T03:16:05.640Z",
                            "updatedAt": "2025-06-24T03:16:05.640Z",
                            "role": "project:personalOwner",
                            "userId": "a420601c-a721-4516-997a-c9bc27a0604b",
                            "projectId": "uhlnaXhqHMZSgKsg",
                            "user": {
                                "createdAt": "2025-06-24T03:16:05.253Z",
                                "updatedAt": "2025-06-24T06:46:46.400Z",
                                "id": "a420601c-a721-4516-997a-c9bc27a0604b",
                                "email": "mengjia@mengjia.net",
                                "firstName": "jia",
                                "lastName": "meng",
                                "personalizationAnswers": {
                                    "version": "v4",
                                    "personalization_survey_submitted_at": "2025-06-24T03:17:59.199Z",
                                    "personalization_survey_n8n_version": "1.99.1",
                                    "companySize": "<20",
                                    "companyType": "saas",
                                    "role": "business-owner",
                                    "reportedSource": "google"
                                },
                                "settings": {
                                    "userActivated": false,
                                    "easyAIWorkflowOnboarded": true
                                },
                                "role": "global:owner",
                                "disabled": false,
                                "mfaEnabled": false,
                                "isPending": false
                            }
                        }
                    ]
                }
            }
        ],
        "tags": [],
        "parentFolder": null,
        "scopes": [
            "workflow:create",
            "workflow:delete",
            "workflow:execute",
            "workflow:list",
            "workflow:move",
            "workflow:read",
            "workflow:share",
            "workflow:update"
        ]
    }
}

技術特點:

  • 基於 TypeORM 的 ORM 框架
  • Repository 模式數據訪問
  • 事件驅動的架構設計
  • 依賴注入的模塊化設計
  • 事務管理確保數據一致性

n8n與BPMN引擎對比

Dify

前端技術棧

後端技術棧

後端代碼模塊梳理:https://www.processon.com/v/685b966e74aa236c0c49b6b1?cid=685b...

Dify 工作流的數據結構特徵

大體JSON組成
{
  "id": "工作流唯一ID",
  "graph": {
    "nodes": [],     // 節點數組
    "edges": [],     // 邊數組  
    "viewport": {}   // 視圖配置
  },
  "features": {},    // 功能配置
  "hash": "版本哈希",
  "version": "版本號",
  "created_by": {},  // 創建者信息
  "updated_by": {},  // 更新者信息
  "environment_variables": [],
  "conversation_variables": []
}
節點數組的數據組成示例與解釋(數據來自官方真實數據)
  • id: 節點唯一標識符
  • type: 節點類型(如"start", "llm", "if-else"等)

    支持的節點類型:

    • start - 開始節點
    • end - 結束節點
    • answer - 答案節點

    處理節點

    • llm - LLM大模型節點
    • code - 代碼執行節點
    • tool - 工具調用節點
    • http-request - HTTP請求節點
    • template-transform - 模板轉換節點

    邏輯控制節點

    • if-else - 條件分支節點
    • question-classifier - 問題分類節點
    • parameter-extractor - 參數提取節點

    循環節點

    • loop - 循環節點
    • loop-start - 循環開始節點
    • loop-end - 循環結束節點
    • iteration - 迭代節點
    • iteration-start - 迭代開始節點

    數據處理節點

    • knowledge-retrieval - 知識檢索節點
    • variable-aggregator - 變量聚合器
    • variable-assigner - 變量賦值器
    • document-extractor - 文檔提取器
    • list-operator - 列表操作器

    高級節點

    • agent - 智能體節點
  • data: 節點具體配置數據
  • position: 在畫布上的位置座標
  • targetPosition/sourcePosition: 連接點位置
{
                "id": "1748242293709",
                "type": "custom",
                "data": {
                    "type": "start",
                    "title": "\u5f00\u59cb",
                    "desc": "",
                    "variables": [

                    ],
                    "selected": false
                },
                "position": {
                    "x": 26,
                    "y": 244
                },
                "targetPosition": "left",
                "sourcePosition": "right",
                "positionAbsolute": {
                    "x": 26,
                    "y": 244
                },
                "width": 244,
                "height": 54,
                "selected": false
            }
邊數組的數據組成與解釋
  • source: 源節點ID
  • target: 目標節點ID
  • sourceHandle: 源節點連接點
  • targetHandle: 目標節點連接點
  • data: 邊的附加數據
{
                "id": "1748242293709-source-1748242320059-target",
                "type": "custom",
                "source": "1748242293709",
                "sourceHandle": "source",
                "target": "1748242320059",
                "targetHandle": "target",
                "data": Object{...},
                "zIndex": 0
            }
節點執行順序邏輯圖

Java復刻n8n流程邏輯demo地址

https://github.com/shuyixiao-better/Java-n8nV1

user avatar li1076629390 頭像 achuanya 頭像 deltaf 頭像 shadowck 頭像 lianhuatongzina 頭像 tangtaixian_5fc4b5d1c3eff 頭像 wslongchen 頭像 javaguide 頭像
8 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.