






















Slickflow.NET 作为基于 .NET 的开源工作流引擎,除了支持传统的人工审批流程(用户任务、会签、加签等),还提供了流程自动化运行能力。与需要人工介入的审批流程不同,自动化运行流程在启动后可按预定义顺序自动执行所有节点,直至流程结束,无需人工参与。
本文面向 Slickflow 引擎开发人员,重点讲解:
Workflow 类在内存中构建 BPMN 流程WorkflowExecutor 及 UseProcess(workflow) 执行| 维度 | 人工审批流程 | 流程自动化运行 |
|---|---|---|
自动化运行流程的核心是:引擎在启动流程后,循环执行“获取下一可执行活动 → 执行活动 → 推进流程”,直到没有可执行活动(流程结束)或达到步数上限。
简化伪代码:
启动流程 -> 创建流程实例
while (存在可执行活动) {
获取下一可执行活动列表
foreach (活动 in 活动列表)
执行活动(调用 Service / AI / Script 执行器)
推进流程(Run)-> 更新当前节点、流转到下一节点
}
返回执行结果
与人工审批流程的区别在于:
WorkflowService.Run(runner) 时传入下一节点办理人,或由用户在前端签收后再继续。┌─────────────────────────────────────────────────────────────────┐
│ Workflow(流程定义层) │
│ Slickflow.Graph.Model.Workflow │
│ .Start() .ServiceTask() .RagService() .End() │
└───────────────────────────┬─────────────────────────────────────┘
│ BuildInMemory()
▼
┌─────────────────────────────────────────────────────────────────┐
│ ProcessEntity(内存流程实体) │
│ ProcessXmlBuilder 序列化为 BPMN XML,不写入数据库 │
└───────────────────────────┬─────────────────────────────────────┘
│ UseProcess(workflow)
▼
┌─────────────────────────────────────────────────────────────────┐
│ WorkflowExecutor(执行器) │
│ UseApp / UseProcess / AddVariable / Run │
└───────────────────────────┬─────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ ServiceTask │ │ RagService │ │ LocalService │
│ (LocalMethod) │ │ (AI/RAG) │ │ (服务类) │
│ 委托注册表解析 │ │ 大模型调用 │ │ 反射实例化 │
└───────────────┘ └───────────────┘ └───────────────┘
| 组件 | 职责 |
|---|---|
using Slickflow.Graph.Model;
var wf = new Workflow("ProcessName", "ProcessCode");
wf.Start("Start")
.ServiceTask("服务节点名", "ActivityCode", "DelegateKey") // LocalMethod
.RagService("RAG 回答", "RAG001") // RAG 节点
.LlmService("LLM 智能节点", "LLM001") // 通用 LLM 节点
.ServiceTask<MyService>("保存", "Save001") // LocalService 服务类
.End("End");
new Workflow(string name, string code):name 为流程名称,code 为流程编码;内部会自动生成 ProcessId = "process_xxx" 与默认版本号 Version = "1"。Start("Start"):开始事件ServiceTask(name, code, delegateKey):绑定 LocalMethod,delegateKey 对应委托注册表中的 keyRagService(name, code):RAG 增强的 AI 服务任务LlmService(name, code):通用大模型服务任务节点(如 DeepSeek、通义千问等)ServiceTask<TService>(name, code):绑定本地服务类End("End"):结束事件最新的 Workflow 支持更简洁的并行与分支语法,例如:
// 简单并行:开始 -> 并行三个任务 -> 汇聚 -> 结束
wf.Start("Start")
.AndSplit("并行网关")
.Parallels(
("任务A", "TaskA"),
("任务B", "TaskB"),
("任务C", "TaskC"))
.AndJoin("并行汇聚")
.End("End");
复杂分支可以通过 Branch + Lambda 定义分支内部节点:
wf.Start("Start")
.Split("条件网关")
.Branch(
() => wf.Task("条件1处理", "Cond1"),
() => wf.Task("条件2处理", "Cond2"))
.End("End");
| 方法 | 作用 | 数据库 |
|---|---|---|
使用 UseProcess(workflow) 时,内部调用 BuildInMemory(),并按 ProcessId:Version 将 ProcessEntity 缓存到内存中,不产生数据库写入,适合单元测试、Demo、嵌入式场景;同一进程内多次调用会复用缓存的流程定义。
using Slickflow.Engine.Executor;
using Slickflow.Engine.Core.Result;
var wfe = new WorkflowExecutor();
var result = await wfe
.UseApp("App-001", "AppName", "AppCode")
.UseProcess(wf) // 直接传入 Workflow 实例
.AddVariable("key", value)
.Run();
if (result.Status == WfExecutedStatus.Success)
Console.WriteLine(result.Message);
AddVariable("key", value) 传入流程变量context.Variables["VarName"] = result 写回IEventService.GetVariable 读取、SaveVariable 或返回值写入流程:开始 → 校验订单 → 计算金额 → 通知结果 → 结束。其中「校验订单」「计算金额」「通知结果」均使用 LocalMethod 绑定本地方法。
using Slickflow.Engine.Executor;
using Slickflow.Engine.Event;
using Slickflow.Engine.Common;
// 校验订单:检查必填变量
void ValidateOrder(IEventService ctx)
{
var orderId = ctx.GetVariable(ProcessVariableScopeEnum.Process, "OrderId")?.ToString();
var quantity = ctx.GetVariable(ProcessVariableScopeEnum.Process, "Quantity")?.ToString();
if (string.IsNullOrEmpty(orderId) || string.IsNullOrEmpty(quantity))
throw new InvalidOperationException("OrderId and Quantity are required.");
}
// 计算金额:单价 * 数量,返回 ServiceTaskResult 指定输出变量名
object CalcAmount(IEventService ctx)
{
var price = decimal.Parse(ctx.GetVariable(ProcessVariableScopeEnum.Process, "UnitPrice")?.ToString() ?? "0");
var qty = int.Parse(ctx.GetVariable(ProcessVariableScopeEnum.Process, "Quantity")?.ToString() ?? "0");
var total = price * qty;
return ServiceTaskResult.WithVariable("Var_OrderTotal", total);
}
// 通知结果:打印到控制台
void NotifyResult(IEventService ctx)
{
var total = ctx.GetVariable(ProcessVariableScopeEnum.Process, "Var_OrderTotal");
Console.WriteLine($"[NotifyResult] 订单总金额: {total}");
}
// 注册到全局委托表
ServiceTaskDelegateRegistry.Global.Register("ValidateOrder", ValidateOrder);
ServiceTaskDelegateRegistry.Global.Register("CalcAmount", CalcAmount);
ServiceTaskDelegateRegistry.Global.Register("NotifyResult", NotifyResult);
using Slickflow.Graph.Model;
var wf = new Workflow("OrderCalcProcess", "OrderCalcProcess_Code");
wf.Start("Start")
.ServiceTask("校验订单", "Validate001", "ValidateOrder")
.ServiceTask("计算金额", "Calc001", "CalcAmount")
.ServiceTask("通知结果", "Notify001", "NotifyResult")
.End("End");
var result = await new WorkflowExecutor()
.UseApp("OrderApp-001", "OrderApp")
.UseProcess(wf)
.AddVariable("OrderId", "ORD-2025-001")
.AddVariable("Quantity", "3")
.AddVariable("UnitPrice", "99.50")
.Run();
Console.WriteLine($"Status: {result.Status}");
Console.WriteLine($"Message: {result.Message}");
// 从返回结果中获取输出变量(若引擎支持)
var vars = result.Variables; // 或通过 result 的扩展属性获取
if (vars != null && vars.TryGetValue("Var_OrderTotal", out var total))
Console.WriteLine($"OrderTotal: {total}");
[NotifyResult] 订单总金额: 298.50
Status: Success
Message: 流程执行成功
OrderTotal: 298.50
流程:开始 → RAG 智能回复 → 提取联系方式 → 保存客户 → 保存对话 → 结束。其中 RAG 节点调用大模型实现多轮问答,后续节点处理结构化数据。
using Slickflow.Graph.Model;
using Slickflow.Module.External.Customer;
var wf = new Workflow("ChatAppProcess", "ChatAppProcess_Code");
wf.Start("Start")
.RagService("RAG 智能回复", "RAG001")
.ServiceTask<ContactExtractService>("提取联系方式", "Extract001")
.ServiceTask<ContactSaveService>("保存客户", "Save001")
.ServiceTask<ConversationService>("保存对话记录", "Msg001")
.End("End");
var messageId = Guid.NewGuid().ToString("N");
var sessionId = "sess-001";
var userMessage = "你好,我想了解一下你们的产品,我叫张三,手机 13812345678";
var result = await new WorkflowExecutor()
.UseApp($"ChatApp-{messageId}-{sessionId}", "ChatAppMessage")
.UseProcess(wf)
.AddVariable("user_message", userMessage)
.AddVariable("customer_id", "cust-xxx")
.AddVariable("session_id", sessionId)
.AddVariable("industry_id", "1")
.SetNotifyClient(sessionId, (sid, data) => Console.WriteLine($"[Notify] {sid}: {data}"))
.Run();
// RAG 节点会将 AI 回复写入 ai_response
var aiResponse = result.AiResponse;
Console.WriteLine($"AI 回复: {aiResponse}");
| 变量 | 来源 | 用途 |
|---|---|---|
WorkflowExecutor.Run 推进到 ServiceTask 节点WorkflowActivityExecutor 识别 ServiceDetail.Method == LocalMethodServiceDetail.Expression 取出 delegateKey(如 "CalcAmount")ServiceTaskDelegateRegistry 按 key 解析委托ExecuteLocalMethodInExecutor 执行委托,传入 IEventService 上下文ServiceTaskResult,按其中指定的变量名写回;否则写回默认变量// 默认写回 ServiceResult
return total;
// 自定义变量名
return ServiceTaskResult.WithVariable("Var_OrderTotal", total);
ai_activity_config 或扩展属性读取 AI 配置(SystemPrompt、Temperature 等)context.Variables 构建 prompt(如 user_message、历史对话)ai_response 或配置的输出变量SetNotifyClient 可实时推送流式输出到前端UseProcess(workflow) 避免数据库依赖ServiceTaskDelegateRegistry 或 WithDelegateRegistry(customRegistry) 注入 Mock 委托result.Status 与 result.Variables 中的关键变量ServiceTaskDelegateRegistry,通过 WithDelegateRegistry 注入同一流程中可混用自动节点与用户任务:自动节点执行完毕后引擎自动推进;遇到用户任务时流程暂停,等待人工办理后再调用 Run 继续。
Slickflow 流程自动化运行通过以下机制实现:
Workflow 类支持 ServiceTask、RagService 等自动节点,BuildInMemory() 生成内存 ProcessEntityWorkflowExecutor.UseProcess(workflow) 直接使用内存流程,无需数据库ServiceTaskDelegateRegistry 注册本地方法,实现快速原型与嵌入式场景本文所述两个测试用例(订单金额计算、AI 智能客服)可直接在 Slickflow.ConsoleTest 或自建控制台项目中运行,供引擎开发人员参考与扩展。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。