工作流引擎技术方案<第一版>
现流行AI工作流引擎技术方案与实现方式调研
n8n
前端技术栈
-
核心流程图库:Vue Flow
-
图形布局引擎:Dagre
-
拖拽功能: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
}