工作流
创建、修改和验证工作流,说明节点类型、连线规则、启动和执行记录。 数据声明统一采用 Type14 JSON Schema。
工作流的输入、输出、变量和节点结果统一使用 Type14。数据使用 JsonSchema,数据引用写在 Schema 的 $ref 中;RefType 仅用于接口。完整规则见统一类型系统。
工作流用于把多个业务步骤串成可追踪、可重试的自动化流程。它适合审批、线索跟进、报表生成、消息通知、跨系统同步,以及需要把智能体、模块方法和人工确认组合起来的场景。
机器可读入口
本页同时发布为 Markdown。不要从 HTML 内嵌数据反推结构。本页完整 JSON 示例使用当前 Type14 作者格式。人工节点请使用IssueDefinition 开发教程的定义和节点示例,不要混用旧 Schema:
- Workflow 作者 Schema 7.0.0 与 完整示例(适用于 Engine 62.0.0 及后续兼容版本)
- 全站 AI 索引 与 结构化页面清单
当前作者定义通过所属 Bundle 的领域目录选择对象:Module 使用 module: {resourceLocator},Agent 使用 agent: {resourceLocator},子流程使用 workflow: {resourceLocator}。人工事项单独使用 Owner 返回的精确 issueDefinitionReference URI。resourceLocator 由来源环境、Bundle、资源类型和目录返回的 resourceKey 组成,例如 baijimu/example-operations/AGENT/operations-analyst,不能从显示名称推导。Module、Agent 和子流程节点只能引用 Workflow 所属环境、所属 Bundle 内的资源,嵌套节点和属性来源也遵循这一规则。这些 Locator 引用不得包含 sourceBundleVersionId 或 semanticVersion;资源精确版本只由本包清单选择。Bundle Service 读取数据库定义及实际修订,核验资源归属并读取所选精确版本的合同,交给 Workflow Engine 做语义校验和编译;Git Bundle 作者入口已退役。CLI 和 Workflow Engine 不接收 bundleSourceGitCommitId。
方法名和参数合同来自清单选中的不可变 Module 版本;开发和创建 Workflow 版本时完成同包引用、方法、Interface、表达式与类型校验。安装读取已验证的版本并交付执行产物,不重复远程语义校验,也不要求外部服务已安装。创建 Workflow 版本前只需为其实际引用的对象创建不可变版本;Bundle 中尚未引用的应用或模块不会阻塞这一步。
外部服务通过本包 Module 的 Interface 属性选择。service 可使用 service_reference_expression,其中 references 的属性来源必须是本包 Module 的完整 Resource Locator;不能把外部 Module 或其属性直接写成来源。属性配置仍按既有规则维护 Workflow 自身的调用授权。执行时,Workflow 将原属性路径、方法及业务参数直接交给 Gateway;Gateway 按当前生效配置解析属性并校验最终目标权限。Workflow 不读取当前绑定,不把原属性替换为外部模块 businessId,也不经 Backend 解析或转发。未绑定时相关调用明确失败,不新增 Workflow 启用步骤。历史直接跨包 Module 引用应迁移为内部属性引用并创建新版本,已有不可变版本和运行实例不改写。详见 Bundle 安装与资源绑定。
同一 Bundle 中,每个稳定 resourceKey 只有一份可变作者定义。服务端 revision 只用于乐观并发控制和审计,不是作者字段、资源版本或 CLI 查询选择器;不可变版本使用严格 SemVer:
baijimu bundle resource workflow list --workspace-id <WORKSPACE_ID> <bundle> --json
baijimu bundle resource workflow get --workspace-id <WORKSPACE_ID> <bundle> <resourceKey> --json
baijimu bundle resource workflow create --workspace-id <WORKSPACE_ID> <bundle> <resourceKey> --definition @workflow.json --json
baijimu bundle resource workflow update --workspace-id <WORKSPACE_ID> <bundle> <resourceKey> --definition @workflow.json --json
baijimu bundle resource workflow version create --workspace-id <WORKSPACE_ID> <bundle> <resourceKey> <semanticVersion> --json创建和更新都必须显式传入 <resourceKey>,与 Bundle 标识分别指定。
创建时它是定义外的 resourceKey,更新时它是资源路径中的标识;作者定义内不得包含 code,CLI 不会从旧字段猜测身份或自动兼容迁移。
get --json 返回标准 CModel 响应,完整定义位于顶层 data 字段中的 definition;同层的 object 包含 type: "RESOURCE"、resourceType: "WORKFLOW" 与 Owner 返回的 resourceKey。本页示例描述 create/update --definition 接受的可写文档,不包含响应 envelope 以及 id、bundleId、时间戳、当前 Plan 等只读字段;从 get 结果生成更新文件时,完整复制 definition,不复制 envelope 或内部 ID。Runtime 模块方法 getBundleObject 使用不同的传输合同:定义以 definitionSource JSON 字符串返回,须解析后读取字段。
创建工作流
创建工作流时,先确定流程的输入、输出和触发方式,再设计节点。
- 进入目标工作区,确认当前账号具备工作流管理权限。
- 新建工作流,填写名称、稳定编码和描述。
- 定义启动输入,例如客户信息、表单数据、订单 ID、触发来源。
- 添加
start节点和业务节点。 - 使用连线连接节点,并在需要分支的位置设置连线条件。
- 设置各节点的输出合同和稳定
id;Agent 保留result.type,Human 输出类型由 IssueDefinition 声明。下游用context.<nodeId>读取结果。 - 保存作者定义后创建不可变版本,完成目标 Runtime 交付,再启动测试实例并查看执行记录。
条件写在连线上
工作流不再使用独立的 condition 节点表达分支。分支判断应写在节点之间的连线条件里,避免流程图出现只负责转发的判断节点。
作者定义与编译结果
definition 完整保存作者提交的业务结构,包括节点引用、输入输出、布局和标签,保留省略字段、显式 null 和原始文字。get 直接读取作者修订,不从编译节点反向恢复。resourceKey 只出现在请求外层、资源路径或返回的 object 中;code、workflowKey、workspaceId、内部 ID 和编译 Plan 均不得写入定义。
创建和更新只保存完整作者文档,不读取 Git、清单或资源合同,也不以编译成功为前提。保存成功不代表可执行。当前 Schema 7.0.0 不提交 status 和 startNodeId;入口由唯一 start 节点确定,资源是否采用由版本发布与安装决定。新作者修订使当前派生编译结果失效,不改变已发布版本、Runtime 配置或运行实例。
先读取作者对象返回的 revision,再通过 CLI 的条件更新保存已审定稿件:
baijimu bundle resource workflow update example-operations daily-review \
--workspace-id "$WORKSPACE_ID" \
--expected-revision "$AUTHOR_REVISION" \
--definition @workflow.json--expected-revision 只用于更新,必须为正整数。bundle object update 的 Workflow 入口也支持此参数。冲突时重新核对作者稿,不自动重试覆盖。
Workflow 作者对象读取返回 revision;更新请求可带正整数 expectedRevision,不匹配时明确冲突,适合编辑器和受审定迁移使用。保存的作者 JSON 不会被插入缺省字段。编译时才产生精确引用及类型解析结果。创建不可变资源版本时,Bundle Service 重新读取当前作者修订并解析清单,Engine 校验修订未变后冻结编译结果。引用缺失、版本不匹配或作者稿已改变时明确失败,不猜测版本、不重试旧合同。已有不可变版本与运行中的执行快照保持原样。
旧稿必须从核实过的项目源码显式迁移,并逐项核对旧节点版本选择与本包清单。迁移到 Schema 7.0.0 时,先审定 startNodeId 与唯一 start 节点一致,再移除作者 startNodeId 和 status,使用读取到的 expectedRevision 保存为新修订;历史修订和不可变版本保留。CLI 0.158.2 修复了新合同稿件的本地必填校验及 finally 转发;旧版 CLI 的本地报错不代表保存接口要求旧字段。版本冲突、跨包或跨环境引用、清单缺失或无法唯一确定时停止迁移并报告,不能静默删除旧选择字段。不能把编译产物当作作者源,也不能在 get 时自动转换。公开存档中的旧 Schema 仅用于历史审计,当前编写请使用本页作者示例。
创建或读取失败时,CLI 会显示服务端返回的 requestId;--json 保留完整错误响应。提交排查信息时附上请求标识、工作区、Bundle 与 resourceKey。
节点类型
| 节点类型 | 用途 | 关键配置 |
|---|---|---|
start | 流程入口。 | 节点 ID、名称、启动输入约定。 |
end | 流程结束并整理输出。 | output 构造最终返回值。 |
http | 调用外部 HTTP 接口。 | 请求方法、URL、请求头、请求体、超时、重试。 |
wait | 等待外部 signal(推荐)或按计划轮询 HTTP/Runtime 状态。 | signal 或 state + until 二选一、超时、结果按节点 ID 写入。 |
module_method | 调用已安装 Bundle Module 的方法。 | module.resourceLocator、方法名、参数、超时、重试。 |
emit_event | 调用已安装 Bundle Module 声明的事件方法。 | module.resourceLocator、事件名、事件体、幂等键。 |
agent | 调用 Bundle 中的智能体资源。 | agent.resourceLocator、任务消息、结构化结果合同、完成等待策略。 |
human | 按 IssueDefinition 创建并等待人工事项。 | issueDefinitionReference、显式输入、候选主体。 |
subflow | 调用并等待子流程完成,使用子流程结果。 | workflow.resourceLocator、输入、元数据、超时、结果按节点 ID 写入。 |
join | 汇合并发分支。 | 汇合策略、output。 |
for_each | 顺序遍历数组并运行内嵌节点。 | 数组路径、迭代变量、上限、失败策略、内嵌节点。 |
类型、配置与输出合同
节点的 type 表示处理或执行类型,例如 human、http、agent;它不等于节点的业务输出类型。4.0.0 删除了 runtimeKind 和 scope,4.1.0 为公开 wait 增加了 signal 模式,5.0.0 把 Agent 节点统一为 message + result + executionPolicy;合同继续使用封闭的强类型节点集合,未知节点类型和未知字段由 Workflow Engine 的作者合同拒绝。signal_wait 仅存在于编译后的内部 Plan,作者定义和管理界面都不得直接创建它。
6.0.0 统一使用节点 id 作为结果身份:结果写入 context.<nodeId>。作者定义拒绝所有节点的 outputPath、Agent 的 result.path 和 Human 的整个 result 字段。Agent 仍须声明 result.type,Human 的结果类型由精确 IssueDefinition 的 outputType 决定。
id 必须是非空的 ASCII 字母、数字、下划线或连字符组合;主图、finally 和所有循环内部全局唯一且稳定。CEL 引用带连字符或数字开头的 ID 时使用合法索引表达式。循环内部节点结果只在循环作用域内有效,对外读取 ForEach 聚合结果。生产者必须在所有到达消费节点的路径上完成,类型和字段由创建版本时的语义校验核对。
End/Join/Wait 的 output 和 ForEach 的 itemOutput 是结果构造,继续保留。建议显式填写 End output 并符合 outputSchema;省略时返回整个 context,迁移别名会改变其中的键,须单独检查消费者。历史不可变版本和在途快照保持原样;存量作者稿须迁移引用后保存并创建新版本。
入口、重试与收尾
7.0.0 删除作者 status 和 startNodeId。资源是否采用由版本发布与安装决定;主图和 finally 图各自必须有且只有一个 type: "start" 节点,由平台推导入口。实例运行状态仍然存在。
Agent 可声明 retryPolicy,省略时不自动重试。maxAttempts 计算整次 Agent 运行;每次尝试创建新等待和新会话。失败信号或不符合 result.type 的结果可以重试;STOPPED、CANCELLED、等待超时及消息是否已投递无法确定时不自动重试。显式重试失败 Agent 同样创建新会话。Agent 支持放入 ForEach,各迭代和尝试隔离。
Workflow 顶层可选 finally: {nodes, edges, timeoutSecs}。主图成功、失败或取消后执行收尾,收尾不能改写主图输出;主图失败时保留原错误,主图成功但收尾失败时实例失败。finally 支持 Start、HTTP、ModuleMethod、EmitEvent、Join、Subflow 和不带 output 的 End。它可以读取 input、只读 workflow.outcome 及本收尾图已完成节点的结果,不能读取主图 context。workflow.outcome.status 为 completed、failed 或 cancelled;成功时含 output,失败时含 error,应按 status 分支后读取对应字段。
取消带 finally 的实例会先进入非终态 cancelling,主图停止后继续收尾,结束才写 cancelled 和 completedAt。重复取消不打断收尾;timeoutSecs 默认 300 秒,从进入 cancelling 起计时。取消收尾失败或超时仍为 cancelled,错误保留在执行记录。finally 中新启动的子流程不参加主图的取消传播。
显式重试主图只重做失败步骤,保留已完成步骤;主图再次结束后执行一次新的 finally。只有 finally 失败时,显式重试保留已完成主图和收尾步骤。外部副作用需由目标业务提供幂等,finally 不承诺外部调用必然成功。
subflow:等待子流程结果
subflow 是流程内的组合调用:子流程完成后,父流程才继续该节点的后续连线,context.<nodeId> 接收子流程结果。
子流程包含 human 时,父流程也必须等待人工处理结束。timeoutSecs 控制等待超时,不表示后台执行。
节点不接受 waitForCompletion,不论值是 true 还是 false。
{
"type": "subflow",
"id": "review_report",
"workflow": {
"resourceLocator": "baijimu/operations/WORKFLOW/report-review"
},
"input": {
"reportId": "{{input.reportId}}"
}
}示例中的 Bundle 和工作流身份必须替换为领域目录返回值。
如果主检查流程在报告落库后就应结束,应在报告落库后发布业务事件,由 Event Trigger 的 action.type=workflow 直接向 Workflow Owner 启动独立的人工处理流程,无需 executor 模块。
完整配置、输入映射和安装步骤见 Event Trigger 绑定工作流与输入映射。
发布节点成功表示事件发布调用成功,不表示人工待办已经创建或处理完成。人工处理失败由其独立流程记录和处置。
迁移旧定义时,显式 waitForCompletion: true 可移除;false 必须先改成事件触发的独立流程。
已有不可变版本的资源应从作者源修改后创建后继版本并重新安装,不直接改写不可变定义或运行中的快照。
human:先创建业务事项定义,再引用
human 创建事项后异步等待人工提交;异步表示等待状态可以持久化和恢复,并不表示节点或所在 Workflow 已完成。
如果业务要求报告生成后当前 Workflow 就结束,人工处理应由业务事件触发独立流程。并发分支、join 或 wait.signal 都不能替代这一业务边界。
没有合适的定义时,开发者应创建工作区独立事项包并发布精确版本。事项包不属于 Bundle。
完整步骤和配套 JSON 见人工事项定义开发:
声明 inputType/outputType → 发布事项包精确版本 → 配置 human 的精确成员引用 → 按 Workflow 自身的 Bundle 交付流程安装 → 验证人工提交与下游结果。事项包不进入 Bundle Manifest。
workflow.human_task 不是默认依赖。通用定义的输出合同不可见,不应阻塞创建自己的业务定义。
issueDefinitionReference使用 Owner 返回的baijimu-issue://<environmentKey>/<packageId>@<semanticVersion>#<memberKey>精确引用;不得用显示名称或自行拼出的身份代替目录结果。input显式映射到事项输入,不会隐式发送整个 Workflow 输入和上下文。assignment.mode为candidates时,assignment.candidates必须非空。对工作区成员开放领取须显式使用workspace_members。- 候选主体支持
user / department / group / role。identityType: "user"的identityId来自有效用户目录;identityType: "role"的identityId对 Bundle 角色使用完整ROLELocator,对工作区角色使用该工作区的roleKey;Bundle 角色匹配必须绑定实际 Runtime,按当前有效关系解析。历史 5.0.0 示例的裸 Bundle 角色身份需要显式迁移。部门候选不自动包含子部门。 - 候选池决定谁可领取,领取或转交后的唯一处理者记录在
Issue.assignee。 - 输出结构由所引用 IssueDefinition 的
outputType拥有。结果写入context.<nodeId>,不配置result或节点级outputSchema。 - 不使用旧的
formSchema、role、instructions、plannerProjection、顶层candidates/outputPath字段。 - 人工等待期限使用
executionPolicy.completionTimeoutSecs,与 HTTP 超时不同。
assignment.candidates 支持用户 ID 字符串数组、候选主体对象数组,或完整的
{{input.userIds}} / {{context.ownerLookup.userIds}} 数组引用。整组引用必须解析为当前工作区的
有效用户 ID 字符串数组;主体对象中的 identityId 也可以引用单个主体 ID。
平台校验并去重后,只有一个明确用户时直接设置 Issue.assignee,该用户无需先领取;多个明确用户
进入同一个候选池,由其中一人领取。含角色、部门或群组时始终按候选范围处理,即使只配置一个角色,
也不代表已经确定一个负责人。多候选不等于会签,不会自动创建多份事项。
空名单、错误类型或无效用户会使 human 执行失败,不会自动开放领取或丢弃无效用户继续分配。
human 重试复用原 Issue,不覆盖已领取或转交后的负责人。作者无需增加直接分配开关或节点级
assignee;完整输入形式、分配规则和示例以
人工事项定义:一个候选入口,统一分配规则
为准。
下面展示角色候选节点;实际领域身份和版本应替换为业务资源版本创建结果:
{
"type": "human",
"id": "approve_order",
"input": {
"orderId": "{{input.orderId}}"
},
"assignment": {
"mode": "candidates",
"candidates": [
{
"identityType": "role",
"identityId": "example-origin/example-crm/ROLE/sales"
}
]
},
"issueDefinitionReference": "baijimu-issue://example-origin/00000000-0000-4000-8000-000000000001@1.0.0#order.approval"
}Issue 服务按资源版本的 inputType 校验输入、按 outputType 校验人工提交的 resultPayload。
校验通过后由平台回传结果,写入 context.approve_order 并推进节点;下游消费该定义实际声明的字段。
不存在通用的“批准/拒绝”输出约定,不通过公开 wait.signal 接口绕过人工事项。
wait 的两种模式
公开的 wait 节点保留一个类型,但配置必须二选一:
- signal 模式(推荐):配置
signal和可选timeoutSecs。worker 持久化等待状态后释放执行资源,由有权限的业务动作提交 signal 唤醒,不持续占用线程,也不产生周期性 HTTP 请求。 - 轮询模式:配置
state、until、可选failWhen与schedule。只用于目标系统不能主动通知、也不能可靠产生事件的兼容场景;每次探测都会形成实际执行成本。
signal 名称分为成功、失败和取消三组,同一个名称不能跨组重复。successSignalNames 为空表示任何发往该节点的 signal 都成功完成等待;生产定义通常应填写明确名称,避免业务事件含义不清。signal payload 会成为等待节点的输出,并按节点 id 写入上下文。
{
"type": "wait",
"id": "wait_for_inspection_review",
"signal": {
"successSignalNames": [
"COMPLETED"
],
"failureSignalNames": [
"FAILED"
],
"cancellationSignalNames": [
"CANCELLED",
"STOPPED"
]
},
"timeoutSecs": 3600
}向公开 signal 等待节点提交消息时,调用当前工作区的 POST /workflow-engine/workspaces/{workspaceId}/workflow/signals,不要填写或保存 worker 主机地址:
{
"namespace": "workflow.node",
"correlationKey": "instance:{instanceId}:node:{nodeId}",
"signalName": "COMPLETED",
"payload": {
"decision": "approved"
},
"dedupeKey": "inspection-review:{businessEventId}"
}workspaceId 来自当前授权工作区,instanceId 和 nodeId 来自实例执行记录,dedupeKey 必须稳定标识同一次业务提交。服务端会校验实例属于该工作区、目标确实是作者定义中的 wait.signal,并拒绝借此唤醒 Agent、Human 或其他平台内部等待。调用方不能自选内网地址、内部 namespace 或伪造其他工作区目标。
Agent 节点也使用同一持久化等待原语,但其 signal 由 agent-session 的事务 outbox 自动投递。workflow-engine 在编译时只生成平台内部逻辑节点;agent-session 到 workflow-worker 的地址来自环境资源登记和服务依赖注入,不写入 Workflow 定义,也不在编译时固化某台主机。Agent 完成、失败、停止或取消后都会触发对应终态 signal,worker 恢复流程并只读取一次最终消息。Capability Signal 合同 1.1.0 使用 nodeId 定位节点、signalName 表示事件名称;旧调用未传 nodeId 时仍按原合同解释。
agent 配置合同
数据声明统一使用 Type14 的 JsonSchema 包装;嵌套数据约束使用标准 JSON Schema 2020-12,见当前类型规范。
| 字段 | 必填 | 含义 |
|---|---|---|
type | 是 | 固定为 agent。 |
id | 是 | 工作流定义内唯一且稳定的节点 ID;运行时为每次尝试分配独立等待和会话身份。 |
agent | 是 | 从目录选择的 {resourceLocator}。 |
message | 是 | 发给 Agent 的任务消息,可引用 input 和 context。 |
result.type | 是 | 平台统一的低代码 Type;使用 JsonSchema 内联数据约束或通过 Schema $ref 引用命名数据。 |
retryPolicy | 否 | 整次 Agent 运行的尝试上限与退避,省略不自动重试。 |
executionPolicy.completionTimeoutSecs | 否 | 等待 Agent 会话进入终态的最长秒数,默认 300;不表示单次 HTTP 请求超时。 |
result.type 与模块 Interface 使用的是同一个平台 Type 合同,不是 Workflow 自定义 Schema。
创建 Runtime Projection 时,平台按已授权的精确类型资源解析 Schema $ref;
Agent 接收 Type14 数据合同,由适配层验证模型厂商支持的严格输出子集,并在执行返回后校验结果。
对象的 required 与 additionalProperties: false 必须由作者明确声明,适配层不能静默修改合同。解析结果属于 Workflow Runtime Projection,
不会再写入 Bundle Runtime Plan,也不会引入第二套类型定义。
workspaceId、userId 和 sessionId 均由运行时从受信上下文确定,不是工作流作者参数。
Agent 节点只创建工作区级会话,不支持 projectId 或 projectIdPath。项目 ID 如属于任务业务
数据,可以在 message 中引用,但不会改变会话归属、身份、计费主体或授权边界。
4.x Schema 中的 promptTemplate、outputFormat、projectIdPath、workspaceIdPath、userIdPath、
sessionIdTemplate 和节点级 timeoutSecs 已被 5.0.0 删除,不存在双读、别名或兼容优先级。
Agent 资源的创建、版本创建和 Manifest 引用见
Bundle Agent 定义、版本创建与 Workflow 引用。
{
"type": "agent",
"id": "review_order",
"message": "审核订单 {{input.orderId}}",
"result": {
"type": {
"@type": "JsonSchema",
"schema": {
"type": "object",
"properties": {
"approved": {
"type": "boolean"
},
"reason": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"approved",
"reason"
]
}
}
},
"executionPolicy": {
"completionTimeoutSecs": 600
},
"agent": {
"resourceLocator": "baijimu/example/AGENT/order-reviewer"
}
}module_method 配置合同
| 字段 | 必填 | 含义 |
|---|---|---|
type | 是 | 固定为 module_method。 |
id | 是 | 工作流定义内唯一且稳定的节点 ID。 |
module | 是 | 从目录选择的 {resourceLocator}。 |
method | 是 | 该服务当前 methodDefinition 中声明的方法名。 |
params | 否 | 与当前方法参数合同一致的 JSON;可引用运行时数据。 |
timeoutSecs | 否 | 非负整数超时秒数。 |
retryPolicy | 否 | maxAttempts、初始/最大延迟和退避倍数。 |
下面是可保存为 workflow.json 的完整作者定义。示例对象身份、方法和参数均为占位值;真正提交前必须替换为目录返回的对象身份和目标 Runtime 返回的精确方法合同。本例使用作者 Schema 7.0.0,历史 Schema 保留供旧版本查询。
{
"name": "运营分析示例",
"description": "演示 module_method 整理输入、Agent 生成结构化分析报告并由 end 输出的完整流程。",
"inputSchema": [
{
"name": "period",
"type": {
"@type": "JsonSchema",
"schema": {
"type": "string"
}
},
"description": "分析周期"
}
],
"outputSchema": {
"@type": "JsonSchema",
"schema": {
"type": "object",
"properties": {
"analysis": {
"type": "object"
}
},
"required": [
"analysis"
],
"additionalProperties": false
}
},
"nodes": [
{
"type": "start",
"id": "start",
"name": "开始"
},
{
"type": "module_method",
"id": "collect_analysis_input",
"name": "获取并整理分析输入",
"method": "buildAnalysisInput",
"params": {
"period": "{{input.period}}"
},
"timeoutSecs": 30,
"retryPolicy": {
"maxAttempts": 3,
"initialDelayMs": 1000,
"maxDelayMs": 5000,
"backoffMultiplier": 2
},
"module": {
"resourceLocator": "baijimu/example-operations/MODULE/operations-data"
}
},
{
"type": "agent",
"id": "analyze_operations",
"name": "生成分析、建议和报告",
"message": "请基于 {{context.collect_analysis_input}} 完成分析,给出建议并生成可供后续节点消费的报告。",
"result": {
"type": {
"@type": "JsonSchema",
"schema": {
"type": "object",
"properties": {
"summary": {
"type": "string"
},
"recommendations": {
"type": "array",
"items": {
"type": "string"
}
},
"report": {
"type": "string"
}
},
"required": [
"summary",
"recommendations",
"report"
],
"additionalProperties": false
}
}
},
"executionPolicy": {
"completionTimeoutSecs": 600
},
"agent": {
"resourceLocator": "baijimu/example-operations/AGENT/operations-analyst"
},
"retryPolicy": {
"maxAttempts": 3,
"initialDelayMs": 1000,
"maxDelayMs": 5000,
"backoffMultiplier": 2
}
},
{
"type": "end",
"id": "end",
"name": "结束",
"output": {
"analysis": "{{context.analyze_operations}}"
}
}
],
"edges": [
{
"from": "start",
"to": "collect_analysis_input"
},
{
"from": "collect_analysis_input",
"to": "analyze_operations"
},
{
"from": "analyze_operations",
"to": "end"
}
],
"tags": [
"example",
"agent"
],
"finally": {
"nodes": [
{
"type": "start",
"id": "cleanup_start"
},
{
"type": "join",
"id": "cleanup_outcome",
"joinPolicy": {
"mode": "all"
},
"output": "{{workflow.outcome.status}}"
},
{
"type": "end",
"id": "cleanup_end"
}
],
"edges": [
{
"from": "cleanup_start",
"to": "cleanup_outcome"
},
{
"from": "cleanup_outcome",
"to": "cleanup_end"
}
],
"timeoutSecs": 300
}
}emit_event 配置合同
emit_event 发布已安装 Module 声明的类型化事件。它与模块后端使用的是同一个 Runtime 事件方法,不保存
或调用固定主机地址:
| 字段 | 必填 | 含义 |
|---|---|---|
type | 是 | 固定为 emit_event。 |
id | 是 | 工作流定义内唯一且稳定的节点 ID。 |
module | 是 | 从目录选择的 {resourceLocator}。 |
eventName | 是 | 目标 Module 当前版本声明的事件名。 |
payload | 否 | 与事件 paramDefinitions 一致的 JSON,可引用运行时数据。 |
idempotencyKey | 否 | 同一次业务发布的稳定幂等键。 |
timeoutSecs | 否 | 事件方法调用的超时秒数。 |
{
"type": "emit_event",
"id": "emit_inspection_submitted",
"eventName": "inspectionTaskSubmitted",
"payload": {
"taskId": "{{input.taskId}}",
"submittedAt": "{{context.inspection.submittedAt}}"
},
"idempotencyKey": "inspection:{{input.taskId}}:submitted",
"timeoutSecs": 30,
"module": {
"resourceLocator": "baijimu/example-supervision/MODULE/supervision"
}
}Workflow 作者不得填写 Runtime businessId、HTTP URL、内部主机或 Authorization。安装物化会从当前
Runtime 的 Bundle 安装资源解析服务并生成授权;通用 http 节点不能替代这一步。Module 事件声明、独立
后端回调发布和订阅触发的完整边界见
模块事件与发布机制。
节点数据引用
节点配置可以引用运行时根对象中的数据:
| 引用 | 含义 |
|---|---|
input | 启动流程实例时传入的数据。 |
context | 前序节点写入的输出和流程运行状态。 |
signal | 等待节点收到的运行时提交消息;它不是输出结构的定义来源。 |
instance | 当前流程实例元信息。 |
node | 当前节点元信息,例如节点 ID 和类型。 |
例如模块方法节点可以把 input.customerName 传给创建线索方法,再把结果写入 context.crm.createLead,后续节点再读取该路径。
配置连线
连线决定节点执行顺序。普通顺序流只需要连接前后节点;分支流需要设置条件;并发流需要在多个分支后使用 join 汇合。
设计连线时注意:
- 每个流程必须有且只有一个清晰的起点。
- 除
end节点外,业务节点应有明确后继节点。 - 分支条件要互斥或有默认路径,避免流程停在无匹配路径。
- 并发分支需要明确汇合策略,避免部分分支失败后状态不清。
修改工作流
修改工作流前,先确认变更是否影响已经运行中的实例。
- 只改名称、描述、节点展示文案,通常可以直接保存。
- 改节点 ID、输出路径、方法名、参数结构,会影响后续节点读取数据,应重新跑完整测试。
- 改分支条件、人工节点引用的 IssueDefinition 或外部调用,必须覆盖成功、拒绝、超时、失败重试等路径。
- 已经有线上实例运行时,不要直接删除它们正在等待的
human或join节点。
完成修改并验证后,以新的精确 SemVer 创建不可变资源版本,由后续安装或升级引用新版本;已启动实例继续使用其固定的执行快照,不回读后来修改的作者定义。
启动和推进实例
工作流完成不可变版本创建与目标 Runtime 交付后,可以从页面、后端服务、模块方法、定时任务、Webhook 或外部 API 启动实例。作者保存本身不会生成可运行版本。启动时传入的 input 应包含业务主键、工作区上下文和触发来源,方便排查日志。
手动启动和查询示例:
baijimu runtime bundle resource workflow start --workspace-id <WORKSPACE_ID> \
<APPLICATION_RUNTIME_ID> <environmentKey/bundleId/WORKFLOW/resourceKey> \
--input @input.json --metadata '{"source":"manual"}' --json
baijimu runtime bundle resource workflow list --workspace-id <WORKSPACE_ID> \
--application-runtime-id <APPLICATION_RUNTIME_ID> --json
baijimu runtime bundle resource workflow get --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json
baijimu runtime bundle resource workflow executions --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json执行用户来自平台验证后的可信请求上下文,并作为 executionSubjectUserId 固定在 Workflow 实例上。
Timer 链路中,这个用户来自安装时生成的 ServiceReference 授权绑定;后续 module_method 调用继续
使用实例保存的执行用户。--metadata 只传递触发来源等可观测信息,其中的
metadata.requestUserId 会被删除,不能声明或覆盖执行用户。
当流程停在 human 节点时,在对应人工事项中提交符合精确版本 IssueDefinition.outputType 的结果。平台校验后回传 signal,并按 human 的 id 写入 context;用户不直接调用公开 signal 接口推进 human。
查看执行记录
每次实例运行都会生成节点执行记录。排查问题时按这个顺序看:
- 实例状态:运行中、等待人工、取消收尾中(cancelling)、失败、完成或取消。
- 当前节点或失败节点。
- 节点入参和输出。
- HTTP、模块方法、事件或智能体调用日志。
- 重试记录和错误信息。
失败实例应从失败节点重试,而不是重新启动一个无关联的新实例。等待人工的实例必须通过 signal 推进,不能用普通恢复动作绕过人工决策。
查询权限
| 查询对象 | CLI | 权限规则 |
|---|---|---|
| Bundle Workflow 作者定义 | bundle workflow list/get | 目标工作区的有效成员可查询;创建、修改、删除和创建版本仍要求 Bundle 所有者或工作区 owner / admin |
| 已安装 Bundle 和 Workflow 资源台账 | bundle list/get/resources | list 对工作区有效成员返回其可见的活跃安装;get 和 resources 要求工作区 owner 或 admin |
| Workflow 实例 | runtime workflow list/get | 有效签名用户必须是目标工作区成员;实例必须属于该工作区 |
| 节点执行记录 | runtime workflow executions | 与实例查询相同;实例必须属于目标工作区 |
| Timer 状态和执行记录 | runtime app timer status/executions | 有效签名用户必须是目标工作区成员;Application Runtime 必须属于该工作区 |
这些接口不接受调用方自报的 userId 作为权限凭据。CLI 登录凭证必须有效,--workspace-id 必须
指向当前用户已经加入的工作区;需要查看完整安装详情或资源台账时,由工作区所有者把用户设为
owner 或 admin。
创建版本前检查
- 每个节点 ID 稳定、可读,不与其他节点重复。
- 所有模块方法对应的模块已经由目标 Bundle 在工作区 Runtime 中物化成功;不要单独安装模块。
- 所有 HTTP 节点的鉴权、超时和错误返回可追踪。
- 所有人工节点都选择了正确且已有不可变版本的
IssueDefinition,其表单、处理规则和提交结果合同清楚。 - 所有分支至少覆盖成功、失败和默认路径。
- 测试实例能完成一遍真实业务路径,并能在执行记录中看到每个节点的结果。
调用组织级基础能力
工作流可通过 module_method 查询成员、角色、联系方式和渠道会话。共同调用约定见
组织级基础能力,完整的企微私聊发送节点见
向同事发送企业微信私聊。
需要对方处理并提交结果时,使用事项与人工协作,不能仅用消息发送成功判断处理完成。