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

现流行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=685b6ee53a038f2b261ab950

数据库梳理:https://www.processon.com/v/685ba3a83a444c5346fb296c?cid=685ba058d1eab77979de60f5

流程编排数据前后端如何交互?

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=685b7292c7884e2e72ba7529

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

posted @ 2025-06-27 10:40  舒一笑不秃头  阅读(38)  评论(0)    收藏  举报