---
myst:
  html_meta:
    "moi:status": "paper-verified"
---

# 工作流

数据接入并在 Catalog 登记后，仍是原始形态——PDF、Word、音视频无法被直接检索。将它们解析、分块、向量化为 AI 可检索的数据，这一加工过程由工作流承担。

工作流（Workflow）是 MOI 中定义数据加工过程的基本单位：由算子和连线组成，描述数据在算子之间的流转顺序。解析、分块、向量化等每个加工步骤由一个算子执行；MOI 按工作流定义调度算子，并在算子之间传递数据。

先分开三个容易混用的词：**工作流**指一份定义——描述加工步骤与顺序的文件，保存在 Catalog，不运行时不产生动作；**运行**指这份定义被启动后的一次执行，每次启动产生一条新的工作流作业；**画布**只是编辑这份定义的方式之一。这个区分决定了排查问题时第一个该问的是：定义错了，还是执行坏了。

一条工作流的完整周期是：被定义，被发布，被启动；运行中，数据沿定义在算子间流转；成功或失败，都留下一条工作流作业。本页按这个周期展开，示例采用平台内置的文档入库工作流 `catalog-parse-index-lineage`——从源文件到向量索引的完整加工链：

| 算子名称 | 算子 ID | 作用 |
|---|---|---|
| read_source | `moi:catalog.source.read.v2` | 按源引用读取文件清单 |
| parse_documents | `moi:parse` | 将文件解析为结构化文本 |
| split_documents | `moi:parser.split.documents.length` | 将文本按长度分块 |
| build_knowledge_index | `moi:knowledge.index.build` | 将分块向量化，写入向量表 |
| write_parsed_documents | `moi:files.write_documents` | 将解析产物写为文件 |
| save_result | `moi:catalog.sink.write` | 将结果写入目标表 |
| register_lineage | `moi:data.lineage.register` | 登记产物与源文件的血缘 |

各算子的输入输出约定，以及完整的系统算子清单，见[工作流算子](workflow-nodes.md)。

## 创建与发布

您通过四种方式创建工作流，产出的都是同一种工作流定义文件：

| 方式 | 说明 |
|---|---|
| 模板 | 从系统模板实例化，按向导填写配置即可运行；创建最快的方式 |
| 画布 | 以可视化方式编排算子与连线 |
| 代码 | 直接编写工作流定义文件（YAML） |
| 自然语言 | 在画布中描述需求，由内置 AI 生成定义，再继续调整 |

您编辑的始终是草稿；发布后，平台按发布版本调度执行。

## 启动

工作流发布后，平台随即自动发起一次运行。此后可通过以下方式再次启动：

| 方式 | 说明 | 适用 |
|---|---|---|
| 手动运行 | 您直接发起一次执行 | 调试定义、一次性加工 |
| 定时运行 | 按 cron 表达式周期执行 | 周期性批量加工 |
| 文件卷触发 | 工作流绑定到文件卷后，上传文件即自动启动 | 无人值守的持续摄取 |

每次启动，平台按输入文件扇出为作业：一个文件对应一条工作流作业，包含各算子的执行状态、输入输出与日志。运行、作业与失败定位，见[运行与调试](run-debug.md)。

## 运行中的数据传递

您在启动时传入变量：示例工作流的变量是源引用、目标表与嵌入模型。运行开始后，引擎逐算子推进——按定义将输入派发给算子，收取输出，再派发下一个算子。

工作流运行时维护三类数据：

| 类别 | 读写 | 说明 |
|---|---|---|
| 变量（vars） | 全程只读 | 启动时注入的参数，如源引用、目标表名 |
| 状态（state） | 跨算子读写 | 各算子以 `save` 写入的中间结果；单个值上限 1 MB，超限自动转存为文件并保留引用 |
| 算子输出（data） | 每算子执行后整体替换 | 上一算子的直接输出，仅相邻算子可用 |

算子输入以模板引用这三类数据，如 `{{ .vars.名称 }}`、`{{ .state.名称 }}`、`{{ .data.字段 }}`。跨越多个算子的传递使用状态；算子输出不跨算子保留。

工作流数据中不传递文件内容，只传递文件引用——需要文件内容的算子凭引用自行读取。大体量内容直接进入数据通道会压垮传输层，平台已据此禁用将文件正文读入工作流数据的算子。

## 失败排查

MOI 的调度引擎按工作流定义执行，不校验任务语义：定义中的错误会被原样执行。因此一份能保存、能启动的工作流，不代表它能产出正确结果。排查失败时先区分两类问题：

- **定义问题**：算子选择、执行顺序或参数绑定错误——修改工作流定义。
- **执行问题**：定义正确，某算子对合法输入处理失败——查看该算子的工作流作业。

具体的定位方法与常见失败成因，见[运行与调试](run-debug.md)。

## 使用限制

- 子工作流仅支持在同一工作流定义内展开，不支持跨工作流引用或合并；工作流之间不共享状态，也不存在数据通道。
- SQL 算子的输入仅包含 SQL 语句本身，不支持自然语言转 SQL；详见 [SQL 编辑器](sql-editor.md)。
- 可用算子及其输入输出约定，以工作区实时接口 `GET /workspaces/:id/workitems` 的实时返回为准，静态清单可能滞后。

## 下一步

| 您想做的事 | 前往 |
|---|---|
| 查询算子的输入与输出 | [工作流算子](workflow-nodes.md) |
| 定位一次运行的失败 | [运行与调试](run-debug.md) |
| 将加工产物交给 AI 使用 | [知识库](../knowledge-bases/index.md) |

> 面向 AI 代理的说明：本页示例为平台内置示例 `catalog-parse-index-lineage` 的原文节选；「运行中的数据传递」与「使用限制」为权威约定；可用算子以实时接口为准，不要依据静态列表选择算子。
