Skip to content

plugin-workflow — DAG 工作流编排

包名: @aalis/plugin-workflow
契约: @aalis/api-workflow
源码: packages/plugin-workflow/src/index.ts(引擎 engine.ts

概述

声明式 DAG 工作流:一个工作流 = 触发器 + 节点图(nodes + deps 边)。引擎按 deps 拓扑分层执行,同层并行;任一节点失败整个 run 标记 failed。节点可声明 out 把字符串结果 存入 outputs 命名空间,供下游节点用 {{outputs.<out>}} 插值。

定义存 workspace:/workflows/*.yaml(用户/AI 资产),运行实例存 data:/workflow-runs.json(同一文件里还记 once 触发器的 firedAt,形状 { runs, onceFired };旧版的顶层数组仍能读入)。

插件声明

typescript
meta.name = '@aalis/plugin-workflow'
meta.displayName = '工作流'
meta.provides = ['workflow']
meta.subsystem = 'workflow'
meta.inject = { required: ['cron-engine'], optional: ['tools', 'storage', 'webui'] }

配置

字段类型默认值说明
defsDirstring'workspace:/workflows'工作流定义目录:加载存储下的 *.yaml 定义(storage URI,也兼容旧【workspace/workflows】);AI 通过 workflow_define 创建的定义也写入此处。
runsFilestring'data:/workflow-runs.json'运行历史文件:保存最近 N 条运行实例(storage URI,也兼容旧【data/workflow-runs.json】)。
maxRunsnumber200保留最近运行条数:超过则按时间裁剪最旧的;最小 10。
enableToolsbooleantrue注册 AI 工具:开启后向 LLM 暴露 workflow_define / workflow_run 等工具。

触发器

类型字段说明
cronexpr按 cron 表达式周期触发,经 cron-engine 服务订阅
intervalseconds每隔 seconds 秒触发(向下取整,最小 1),经 cron-engine@every <N>s 订阅
oncerunAt在指定时间触发一次,一生只触发一次:触发即把 firedAt 记入运行历史文件(runsFile),此后重启进程、重新注册、重复 workflow_define 都不再触发;定义不存在时记账随之清除——workflow_remove 清账,手动删掉 defsDir 里的 yaml 也会在下次启动扫描定义后补清,同 id 重建都算新工作流。runAt 须能被 Date.parse 解析;时间已过且从未触发过,则注册时立即补触发一次
eventevent, filter?订阅指定事件;filter 的每个键须与事件第一个参数的同名顶层字段严格相等;事件参数数组以运行变量 args 注入
manual不注册触发器,仅手动运行

event 触发器不接受 inbound:messageoutbound:messageinbound:command:这些事件承载会话内容,若被 send-message 节点转发到其它会话会造成跨会话泄露。订阅这些事件的触发器不会注册,仅记录警告。

节点类型

类型关键字段说明
tooltool, args调用一个已注册工具;args 支持插值
send-messagesessionId, content, platform?向会话投递 inbound:message(fire-and-forget,不等回复);platform 默认 internal
waitseconds等待固定秒数
agentinstruction, sessionId?, platform?, timeoutSeconds?把指令派发给 agent 并等待本轮回复;回复文本作节点结果;platform 默认 workflow

args(递归处理其中的字符串)、contentinstructionsessionIdplatform 支持 {{vars.X}}(运行变量)与 {{outputs.Y}}(上游节点输出)插值;tool(工具名)、idoutdeps 不插值。

agent 节点:确定性的多智能体编排

agent 节点是 send-message 的「等回复」版:派发前注册 agent:turn:after 监听,按目标 sessionId 捕获本轮回复(与 delegate_to_session 相同的 join 方式),把回复经 out 存入 outputs。配合 deps + 插值,单个 DAG 即可表达「分解 → 依赖 → 串/并行 → 管道 → 聚合」的确定性编排流程。

  • 省略 sessionId 时为该节点生成一次性隔离子会话 workflow:agent:<runId>:<nodeId>, 并行 agent 节点互不串扰,适合子任务场景。
  • timeoutSeconds(默认 120)内未收到回复 → 节点失败;outcome=error/aborted → 节点失败; outcome=silent(agent 选择不回复)是合法结果,节点成功、输出空串。

示例:两路 agent 并行调研 → 第三个 agent 聚合(管道传值):

yaml
id: research-and-summarize
trigger: { type: manual }
vars:
  topic: "向量数据库选型"
nodes:
  - id: scout_a
    type: agent
    instruction: "从性能角度调研:{{vars.topic}}"
    out: a
  - id: scout_b
    type: agent
    instruction: "从成本角度调研:{{vars.topic}}"
    out: b
  - id: summarize
    type: agent
    deps: [scout_a, scout_b]
    instruction: "综合下面两份调研给出结论:\n性能:{{outputs.a}}\n成本:{{outputs.b}}"
    out: report

注册工具

工具说明
workflow_define定义/覆盖工作流(完整 YAML)
workflow_run手动触发一次运行
workflow_list列出全部定义
workflow_get_runs查询最近运行历史
workflow_remove删除定义(含磁盘文件)

事件

事件说明
trigger:fired订阅外部触发事件:仅当事件带 workflowId 时运行对应 workflow,payload 并入运行变量;plugin-scheduler 广播的该事件不含 workflowId,不会触发工作流
workflow:run:start / :done / :error运行生命周期
workflow:node:done单节点完成(含 NodeRunInfo

相关