Workflow、Node、Connection、Execution:四个词讲清 n8n 的世界

画布上是五个方块、四条线。把这东西导出成 JSON,只剩两个键:nodes 和 connections。执行记录在另一个地方,一条一条排着,每条带个编号。

三处说的是同一件事,用四个词:workflow、node、connection、execution。这四个词理清了,后面读任何节点教程都省力;理不清,你会一直在「我明明点了执行」和「它为什么没跑」之间来回撞。

不用会写代码。装好的 n8n 能打开、跑过一次工作流就够(没装看这篇,界面还不熟的先翻界面导览)。我这台是 2.43.7,你那边小版本不同,按钮位置可能差一点。

四个词,四样东西

先摆一张对照表,后面几节都是把它拆开讲。

词 它是什么 存在哪 数量关系
Workflow 一组节点连起来干一件事 数据库里的工作流表,一份 JSON 1 个工作流有 N 个节点
Node 一个执行单元,干一步活 工作流 JSON 的 nodes 数组里 1 个节点属于 1 个工作流
Connection 把上一个节点的输出接到下一个的输入 同一个 JSON 的 connections 对象里 1 个工作流有 N 条线
Execution 这个工作流被跑了一次 执行表,独立于工作流 1 个工作流有 N 条执行

最容易混的是最后一行。工作流是图纸,执行是施工。图纸改十遍,之前施的工不会跟着变。

n8n 画布上的五个节点与四条连线,IF 节点右侧标着 true 和 false
五个方块、四条线,就是这四样东西里的前三个。判断大单右边那两个小圆点,一个标 true 一个标 false,是两个不同的出口

Workflow:一个容器,外加两个状态

官方给的定义很短:一组连起来自动完成某件事的节点;触发器响了、你手点了、别的流程调它了,它就开始跑,按节点一个个执行,可以分叉、合并、循环。

定义没什么可挑的。真正要留神的是 2.x 之后多出来的那个状态:草稿和已发布是两回事。

你在画布上改东西,n8n 自己存,一秒到五秒之内落库,没有保存按钮。但这只是存进草稿。想让改动上线,得点右上角那个「发布」,把某一个版本钉到生产上。之后定时器、Webhook、应用事件跑的都是那个钉住的版本,不是你现在屏幕上这版。

这条规矩解决了一个老问题(改到一半被定时任务撞上),也造了一个新坑:参数改完忘了发布,线上跑的还是昨天那套逻辑,而画布上看着一切正常。我第一次遇到时盯着两版参数比了十分钟,才想起上面那按钮还是亮的。

只有手动触发器的工作流,发布按钮是灰的,提示没有需要发布的触发节点
只看右上角。按钮灰着,鼠标停上去给的理由很直白:此工作流没有需要发布的触发节点。手动触发器不上线,所以没东西可发

这也顺便解释了为什么有些人的第一个工作流死活「激活」不了。只有一个手动触发器,它天生没有生产形态,发布按钮永远灰着。要定时,加 Schedule Trigger;要接外部请求,加 Webhook。有了这类触发器,按钮才会亮。

从接口看更清楚:我这台实例上,新建的工作流 active 是 false,activeVersionId 是 null,只有一个 versionId 在跟着每次改动变。没发布过,就没有线上版本。

Node:名字才是主键

节点是一个执行单元。有的负责开局(触发器),有的取数据、发数据、算数据,有的只做流程控制,一行 IF 也能是一个节点。

落到 JSON 里,一个节点就七样东西:

{
  "parameters": { "jsCode": "return [{ json: { amount: 620 } }];" },
  "id": "n2",
  "name": "造两条订单",
  "type": "n8n-nodes-base.code",
  "typeVersion": 2,
  "position": [-400, 0]
}
  • type:它是哪种节点。n8n-nodes-base.code 就是 Code 节点,-base. 后面那截是节点名的小写。
  • typeVersion:节点定义的版本。同一个节点的不同版本,参数结构会变。我这份里 IF 是 2.2、Edit Fields 是 3.5、Code 是 2、Manual Trigger 是 1。这数字不是你填的,是它创建时按当时的定义写进去的。
  • parameters:你在右边面板里填的一切都在这里。换节点类型,这块整个换掉。
  • position:画布坐标,纯显示用,跟执行顺序无关。
  • id:工作流内部用的短标识,复制节点会生成新的。

name 看着最不起眼,实际是这四个词里最容易吃亏的一处:它是主键。连接记的是名字,不是 id。

我在画布上把「小单归档」改成「小单归档(改)」,四条连线一条没断,保存后接口里的 connections 也跟着变成了新名字——这是界面替你补的。换个方式,直接改 JSON 里的 name、连接不动,服务端会当场拒绝,报错还一次报两条:

Workflow structure is invalid. nodes[4].name (duplicate_node_name):
Duplicate node name "大单跟进"; connections.判断大单.main[1][0].node
(unknown_connection_target): Connection target "小单归档" does not
reference an existing node

第一句说重名,第二句说有条线指着一个不存在的节点。两句其实是一件事的两面:你把一个节点改成了别人的名字,而被顶掉的那个名字,连接还在指着它。

所以节点名我建议当变量名来起:别用「Set」「Code 1」这种,也别隔两天改一次。名字里带空格、括号、中文都行,n8n 认,但你自己在表达式里写 $('小单归档(改)') 的时候容易漏个括号。

Connection:两层数组,第一层是出口序号

连接是把一个节点的输出接到另一个节点的输入。JSON 里长这样:

"connections": {
  "造两条订单": { "main": [[{ "node": "判断大单", "type": "main", "index": 0 }]] },
  "判断大单": { "main": [
    [{ "node": "大单跟进", "type": "main", "index": 0 }],
    [{ "node": "小单归档", "type": "main", "index": 0 }]
  ]}
}

拆开读:最外层键是源节点名;main 是连接类型(普通数据流;AI 那套是 ai_tool、ai_languageModel 这些);里面那层数组的下标就是第几个出口;再里面是目标列表,一个出口可以连好几个下游。

判断大单有两组,所以它是 [,]。第一组对应节点上那个标 true 的圆点,第二组对应 false。粗看会以为数组套多了,其实就是「第几个出口 → 连到谁」。

判断大单节点内部:条件大于 500,输出分 True 分支与 False 分支各 1 个项目
节点里面就一个条件:金额大于 500。右边输出分成 True 分支、False 分支,跑完各 1 项。这跟 JSON 里那两组数组是一一对应的

这里有个概念上的误会值得掰开。很多人以为 IF 是「二选一」:条件成立走这边,不成立走那边,只走一条。

不是。IF 是按条分流。我让它收两条订单,620 和 180,结果是 true 分支 1 项、false 分支 1 项,两条线都亮了。你要是拿 100 条数据进去,它按每条自己的金额分到两边,可能左边 30 条右边 70 条,也可能一边 0 条。

所以「IF 后面的节点没执行」这句话,先确认是不是那一侧压根没数据。这不是故障。

Execution:一次运行,带一份快照

执行是这个工作流被跑了一次。手动点一次算一次,定时器响一次算一次,Webhook 来一个请求算一次。它不属于工作流 JSON,存在另一张表里,靠 workflowId 挂回去。

一条执行记录里我关心的字段:

字段 这条记录里的值 有什么用
id 35 全实例一条自增序列,不是每个工作流从 1 开始
workflowId 9biNEw9D0DqWOVV1 它属于哪个工作流
mode manual 手动跑的还是生产跑的
status success 成功、失败、取消、崩溃、等待中
startedAt / stoppedAt 01:17:42.352 / 01:17:42.513 差 161 毫秒,就是界面上那个「在 161毫秒 内」
workflowVersionId 一个 uuid 这次跑的是哪个版本

最后一行容易忽略但很有用:执行认的是版本。你改完参数没发布,生产跑的还是旧版本,执行记录里挂的就是旧版本的 id。

执行记录列表与跑完的画布,每条连线上标着流过的项目数
左边两条执行,右边是选中那条跑完的样子。每条连线上标着流过的项目数:造两条订单出 2 项,分流后两边各 1 项。这个数字比任何日志都直观

还有一个我这次才注意到的细节:每条执行里存了一份当时的工作流的快照(workflowData)。我把「小单归档」改成「小单归档(改)」之后,回去翻 09:17:42 那条执行,画布上显示的仍然是「小单归档」——因为渲染用的是那条执行自带的快照,不是你现在的画布。

这解释了两件事。好的一面:改参数、删节点,旧记录不会被篡改,回头查问题看到的就是当时的现场。坏的一面:你拿旧记录去对照现在的画布,节点名可能对不上,别以为是自己记错了。

所有执行列表:工作流、状态、开始时间、运行时间、执行 ID 五列
「所有执行」这一页把整个实例的执行摊在一起,第一列是工作流名。同一个工作流三条,ID 34、35、36,连着涨;最下面那条 5 号是 13 天前另一个工作流的

存多久是个现实问题。默认开自动清理:超过 336 小时(14 天)的删掉,总量超过 10000 条也从旧的开始删。成功和失败都存,手动跑的也存。两条规矩谁先撞上算谁:每 5 分钟跑一次的工作流,一天 288 次,14 天攒到 4032 条,先撞年龄;一天 2000 次的,第五天就满一万,先撞条数。所以「执行列表里没有那次」,不一定是没跑,可能已经被清掉了。

串起来看:一次排错的顺序

四个词分开都懂,用起来还得有个顺序。我的习惯是从外往里收:

  1. 先看执行记录的状态。没有记录,说明压根没触发——问题在触发器或发布状态,不在节点里。
  2. 状态是失败,点进去看哪个节点红着。节点详情里看输入,多数时候输入就已经不对了。
  3. 状态成功但结果不对,看连线上的项目数。某条线是 0,后面的节点当然什么都不干。
  4. 数字对但字段不对,才轮到怀疑节点参数,或者上游把类型改了。

这个顺序的好处是每一步都能否掉一大片可能。反过来,一上来就盯着 Code 节点看代码,往往看半小时才发现是上游只发了 0 条。

怎么算真看懂了

不用背定义,做三件事就够了,每件都有可观察的结果。

一、数一数。画布上有几个方块,导出的 JSON 里 nodes 数组就该有几个。我这份是 5 个,数组长度 5。连线条数也一样,4 条线对应 connections 里 4 个源键(判断大单一个键里装了两组,但仍是 4 条线)。

二、改条线。把 false 那一路的节点删掉,再导出,判断大单 的第二组数组应该变成空数组,而不是整组消失。这一步能让你记住「出口是位置决定的,不是有没有下游决定的」。

三、跑两次。跑完去「所有执行」,应该多一条,ID 比上一条大 1,时间是你点下去的那一刻。再改一个参数、不发布,跑一次,然后去线上(定时或 Webhook)看它用的还是旧参数——如果这是你的真实业务,这一步建议在测试工作流上做。

五个真会撞上的错

1. 两个节点同名。复制节点后忘了改名,或者手工改 JSON。保存时服务端拒绝,报 Duplicate node name,并且同时甩一条 unknown_connection_target。看到两条别慌,改回唯一的名字就好。

2. 改了节点名,表达式没跟着改。连接会被界面自动补,表达式不会。上一个节点叫 A,你在下游用 $('A').item.json.amount 取数,改名成 B 之后这句就找不到东西了,报错指向表达式那一行,而不是改名这件事。

3. 发布按钮是灰的。工作流里只有手动触发器,没有能上线的东西。鼠标停上去会写「此工作流没有需要发布的触发节点」。加个 Schedule Trigger 或 Webhook 才有得发。

4. 改完参数,定时任务跑的还是旧逻辑。改的是草稿,没点发布。这类问题最难查,因为画布、参数、测试执行全都正常,只有线上的行为不对。

5. 执行记录找不到。三种可能:超过保留期被清理、工作流被删导致记录跟着没了、或者把「成功也存」的开关关了(EXECUTIONS_DATA_SAVE_ON_SUCCESS=none)。前两种最常见。

导出、分享、留痕的风险

工作流 JSON 是可以整份导出、发给别人的。这里有三处会漏东西。

参数里的明文。凭据本体不在 JSON 里(只留一个名字引用),但 parameters 里什么都可能有:URL 上带的 token、HTTP 请求头里手写的 key、Webhook 的 path。grep 一遍 key、token、Bearer 再发出去,两分钟的事。

执行记录里是原始数据。节点跑过什么,记录里就存什么原文,订单号、客户名、地址都在。自托管能自己控保留期,把 EXECUTIONS_DATA_MAX_AGE 调小是最省事的做法;多人共用的实例,最好一开始就设。

别人发来的 JSON 直接粘。粘进来就是在你实例上跑他写的代码,Code 节点里的 JS 不会问你要不要执行。来源不明的工作流丢进空的测试实例,看完再说。

小结

工作流是图纸,节点是图纸上的方块,连接是方块之间的箭头,执行是照着图纸施工的那一次。四个词对应四样东西,位置不一样,改动的后果也不一样:改节点参数影响以后每一次执行,改执行记录什么都改不了(它本来就是记录),改名会让连接跟着走但表达式不一定。

真要我挑一个最该先记住的,是「执行带快照」这件事。它同时解释了为什么旧记录不会骗你、为什么新改动不一定生效、为什么清理期一过就什么都查不到。

判断自己懂没懂,有个笨办法:随便打开一个别人做的工作流,不看画布,只看导出的 JSON,能不能说出它跑起来会有几个节点、几条路、哪条是空跑。说得出来,这四个词就过关了。

接着往下

还没跑通过第一个工作流的,先看《第一个工作流:手动触发 → 编辑字段 → 代码》,那篇讲怎么把三个节点连起来跑通。启动报错、端口占用这类进不去门的问题,在这里。整门课的目录在这一页,节点相关的都在这个分类下。

参考资料

  • Key concept glossary:workflow、node、execution、publish 这几个词的官方定义,本文对齐的就是这里
  • Understand workflows:工作流是什么,以及创建工作流、组件、执行这四块的分卷
  • Connect nodes together:连接的建立与删除,一个节点的输出接到另一个节点的输入
  • Save and publish workflows:自动保存的时间范围、发布把版本钉到线上、生产执行用已发布版本
  • Understand executions:手动与生产执行的区别,哪些执行计入配额
  • If:条件的数据类型与比较方式,两个输出
  • Executions 环境变量:保留 336 小时、上限 10000 条、成功与失败都存这些默认值

最后更新:2026 年 11 月 4 日,用的是 n8n 2.43.7。

参与讨论