Skip to content

执行子流程

执行子流程节点允许你从另一个工作流中调用一个可复用的工作流(即子流程)。这实现了模块化的工作流设计——将共享逻辑作为子流程构建一次,然后从多个父工作流中调用它。

前置条件:目标子流程必须已发布(active 状态)且以 Subflow 触发器 作为入口。每个工作流最多只能有一个 Subflow 触发器。

使用场景

典型应用

  • 可复用验证 — 将输入验证逻辑集中到子流程中,供多个工作流调用
  • 数据补充 — 调用子流程从外部 API 获取并格式化数据
  • 多阶段流水线 — 将复杂流程拆分为多个阶段,每个阶段实现为一个子流程
  • 错误处理模块 — 复用标准化的错误日志和通知逻辑
  • 循环迭代 — 在 循环与迭代 节点内调用子流程处理每个元素

节点配置

基础设置(参数面板)

1. 选择子流程

从下拉列表中选择要调用的子流程。仅显示已发布(active)且包含 Subflow 触发器 的工作流。

选择前:所有其他设置均隐藏。 选择后:根据子流程定义的输入 Schema 自动填充输入字段。

节点始终调用所选子流程的最新 active 版本。如果子流程的触发器被更改(例如替换为 Webhook 触发器),节点将在运行时报错,因为该子流程不再可被调用。

2. 输入参数

选择子流程后,其预期的输入参数会被自动读取并显示。每个输入是一个键值对:

字段说明
Variable(变量名)子流程中定义的输入名称
Value(值)要传递的值 — 支持 表达式 引用上游节点输出
Type(类型)预期的数据类型(从子流程 Schema 自动读取)

支持的输入类型

  • text — 字符串
  • number — 数值
  • array — 列表/数组
  • object — JSON 对象
  • booleantrue / false
  • datetime — 日期时间

向子流程传递数据

javascript
// 引用上游节点输出
$('Webhook 触发器').body.userId

// 引用多个上游节点
$('代码').processedData

// 传递字面值
"active"

// 传递数值
42

必填输入:如果子流程定义了必填输入,你必须为其提供值。子流程本身不在边界处验证输入类型——如果传递了错误类型的值,子流程将在下游节点尝试使用该值时报错。

无必填输入:如果子流程没有必填输入,可以留空所有输入字段并正常执行节点。

3. 等待子流程完成

控制父工作流是等待子流程完成后继续,还是立即继续执行。

开启(默认) — 父工作流暂停,等待子流程完成后接收其输出。

执行子流程 (wait = on)
  → 子流程执行至完成
  → 输出返回给父工作流
  → 父工作流继续执行下一个节点

关闭 — 子流程被异步触发。父工作流立即继续执行,不等待结果。

执行子流程 (wait = off)
  → 子流程在后台运行
  → 父工作流立即继续(无输出)

警告:当等待子流程完成关闭时,节点输出 null。如果后续节点引用了子流程的输出,将因无结果而报错。

高级设置(设置面板)

节点描述

为节点添加自定义描述,说明子流程调用的目的:

yaml
nodeDescription: "调用订单验证子流程。
返回 { isValid: boolean, message: string }。"

输出数据

等待开启时

子流程完成后,其输出数据可通过父工作流中该节点的名称访问。输出结构由被调用子流程中的 Subflow Output 节点定义。

javascript
// 在父工作流中访问子流程输出
$('执行子流程').isValid
$('执行子流程').message
$('执行子流程').processedAt

等待关闭时

节点输出 null。下游节点无法获取子流程的输出。

工作原理

执行流程

父工作流:
  触发器节点
    → 处理节点
    → 执行子流程节点 ← 收集输入,调用子流程

子流程(被调用):
  Subflow 触发器 ← 接收输入
    → 处理节点
    → Subflow Output ← 打包结果

父工作流(继续):
    → 后续节点 ← 访问 $('执行子流程').outputField

版本选择

节点始终调用所选子流程的最新 active(已发布)版本。如果子流程被取消发布或触发器类型被更改为非 Subflow 触发器,节点将在运行时报错。

嵌套子流程

子流程本身也可以包含执行子流程节点,实现多层编排。避免循环调用(工作流 A → 工作流 B → 工作流 A),这会导致运行时错误。

工作流示例

示例 1:简单验证子流程

父工作流:
  Webhook 触发器(POST,订单数据)
    → 执行子流程
        子流程:"订单验证器"
        输入:
          orderTotal: $('Webhook 触发器').body.total
          customerId: $('Webhook 触发器').body.customerId
        等待:开启
    → 条件分支
        条件:$('执行子流程').isValid === true
        → [有效] → 处理订单
        → [无效] → 返回错误响应

示例 2:同步数据补充

父工作流:
  聊天触发器
    → 执行子流程
        子流程:"客户信息查询"
        输入:
          customerId: $('聊天触发器').customerId
        等待:开启
    → LLM 节点
        System:"使用以下客户数据来个性化你的回复"
        Context: $('执行子流程')
    → Answer 节点

示例 3:发后即忘(异步触发)

父工作流:
  Webhook 触发器(POST,日志数据)
    → 执行子流程
        子流程:"日志处理器"
        输入:
          logEntry: $('Webhook 触发器').body
        等待:关闭                    ← 不等待,立即继续
    → Webhook 响应(No Data)        ← 立即确认

示例 4:循环中调用子流程

父工作流:
  Webhook 触发器(POST,批量数据)
    → 代码节点(解析数组)
    → 循环与迭代
        遍历:$('代码').items
        → 执行子流程
            子流程:"数据处理"
            输入:
              item: $('循环与迭代').currentItem   ← 当前迭代项
            等待:开启
    → 聚合结果

约束条件

输入类型不验证

执行子流程节点不验证输入值是否匹配子流程的预期类型。如果传递了错误类型的值(例如预期数字却传递了字符串),子流程将在下游节点尝试使用该值时在运行时报错。请确保以预期格式传递值。

必填输入校验

必填输入的校验在前端配置层面执行——你必须在保存节点前填写必填值。但后端不会在运行时重新验证必填字段。如果有必填字段在运行时意外为空,子流程在使用缺失数据时很可能失败。

每个工作流只能有一个 Subflow 触发器

每个工作流最多只能有一个 Subflow 触发器。如果需要子流程有多个入口点,请考虑创建单独的子流程或在子流程内部使用条件分支。

异步调用不支持结果获取

等待子流程完成关闭时,子流程异步运行。如果父工作流多次调用同一子流程且等待关闭,会生成多个并发执行。确保子流程设计支持并发执行。

最佳实践

1. 重命名节点

双击节点标题设置描述性名称:

[执行子流程]          ← 默认名称
[验证订单]            ← 更好的命名
[查询客户档案]         ← 最佳命名

2. 记录输出约定

使用节点描述字段记录调用方可预期的输出结构:

yaml
nodeDescription: "返回 { isValid: boolean, errors: string[] }。
使用下游数据前请先检查 `isValid`。"

3. 仅在需要输出时开启等待

如果不需要子流程的输出,关闭等待子流程完成。这让父工作流保持快速:

yaml
# 需要输出 — 保持等待开启
Wait: On → $('执行子流程').result

# 发后即忘 — 关闭等待
Wait: Off → 父工作流立即继续

4. 处理子流程错误

执行子流程节点有错误输出端口。将其连接到错误处理节点:

执行子流程
  → [成功端口 0] → 继续处理
  → [错误端口] → 记录错误 → 发送告警

5. 先独立测试子流程

在从父工作流调用子流程之前,使用子流程自己的触发器先独立测试,确保其正常工作。这有助于隔离问题并加快调试速度。

常见问题

Q1: 能否调用没有 Subflow 触发器的工作流?

A: 不能。目标工作流必须有 Subflow 触发器。如果工作流的触发器被更改为非 Subflow 类型,节点将报错 "Subflow not found"。

Q2: 子流程执行失败会怎样?

A: 当等待开启时,节点通过错误端口输出错误。你可以将错误端口连接到日志、通知或备选处理节点。当等待关闭时,失败异步发生,不影响父工作流。

Q3: 子流程的版本如何管理?

A: 节点始终调用所选子流程的最新 active(已发布)版本。如果你发布了子流程的新版本,节点将在下次执行时自动使用。不支持固定到特定版本。

Q4: 能否传递复杂对象作为输入?

A: 可以。使用表达式引用对象、数组或任何上游数据:

javascript
// 传递对象
$('代码').customerProfile

// 传递数组
$('代码').itemList

// 传递嵌套字段
$('HTTP 请求').body.data.attributes

Q5: 如果需要传递大量输入怎么办?

A: 考虑使用 代码节点 将数据聚合为单个对象后传递给子流程。这样可以使执行子流程节点的输入列表保持可管理。

Q6: 能在同一个父工作流中多次调用同一个子流程吗?

A: 可以。你可以在同一个父工作流中放置多个执行子流程节点,每个使用不同的输入。当等待开启时,它们顺序执行。当等待关闭时,它们并发运行。

下一步

相关资源