基于规则引擎的 AI 工作流编排
基于规则引擎的 AI 工作流编排
学习目标
读完本章后,你将能够:
- 理解基于规则引擎的 AI 工作流架构与节点编排模式
- 设计支持多节点类型(AI / 知识库 / 代码 / HTTP)的流程引擎
- 实现流式响应透传与流程上下文管理
- 掌握流程动态脚本扩展(Python / JavaScript / Groovy / Kotlin / Aviator)
- 理解流程停止机制与超时处理策略
核心概念
为什么选择规则引擎而非自研
AI 工作流编排有两种常见实现路径:
| 方案 | 代表 | 优势 | 代价 |
|---|---|---|---|
| 自研图引擎 | LangGraph | 完全可控、与代码深度集成 | 开发成本高、节点扩展需改代码 |
| 规则引擎 | LiteFlow / Flowable | 可视化编排、热更新、多脚本语言 | 学习成本、额外依赖 |
选择规则引擎的核心考量:业务人员可配置。通过可视化画布拖拽节点,非开发人员也能组装 AI 流程,这是低代码平台的关键差异化能力。
流程引擎架构
节点类型体系
标准节点分类
AI 工作流的节点按功能可分为三大类:
1. 流程控制节点
| 节点 | 职责 | 特点 |
|---|---|---|
| 开始节点 | 流程入口,接收输入参数 | 定义流程入参 schema |
| 结束节点 | 流程出口,输出最终结果 | 支持多出口(不同分支不同输出) |
| 分支节点 | 条件判断,路由到不同分支 | 支持 if/else 或多路分支 |
| 分类节点 | 语义分类,AI 判断走哪个分支 | 基于 LLM 意图识别 |
| 子流程节点 | 嵌套调用另一个流程 | 实现流程复用与模块化 |
2. AI 能力节点
| 节点 | 职责 | 特点 |
|---|---|---|
| AI 节点 | 调用 LLM 进行对话/生成 | 支持模型选择、提示词、参数配置 |
| 知识库节点 | RAG 检索增强 | 绑定知识库、配置 topK / 相似度 |
| 记忆节点 | 持久化记忆读写 | 支持 add_memory / query_memory 工具 |
3. 扩展节点
| 节点 | 职责 | 特点 |
|---|---|---|
| Java 节点 | 执行业务 Java 代码 | 直接调用系统 API |
| 脚本节点 | 执行 Python/JS/Groovy/Kotlin | 多语言支持,GraalJS 沙箱 |
| HTTP 节点 | 调用外部 REST API | 支持 GET/POST、认证、超时 |
| 直接回复节点 | 直接返回固定内容 | 无需 AI 参与 |
节点扩展设计
扩展机制:新增节点类型只需实现统一的 FlowNode 接口,在节点注册表中声明即可,无需修改引擎核心。
流程上下文与生命周期
流程上下文(FlowContext)
流程上下文是贯穿整个流程执行过程的状态容器:
FlowContext├── requestId # 本次请求唯一标识├── flowId # 流程定义 ID├── conversationId # 会话 ID├── topicId # 话题 ID├── inputParams # 流程输入参数├── outputResult # 流程输出结果├── stopped (AtomicBoolean) # 停止标志(支持中途终止)├── eventCallback # 事件回调(SSE 推送)└── currentNodeId # 当前执行节点关键设计:stopped 标志使用 AtomicBoolean,确保多线程环境下的可见性。当用户点击”停止”按钮时,设置该标志,正在执行的节点检测到后主动终止。
流程执行生命周期
事件类型体系
流程执行过程中的事件通过 SSE 实时推送,事件类型定义了完整的生命周期:
| 事件类型 | 时机 | 数据内容 |
|---|---|---|
EVENT_INIT_REQUEST_ID | 流程初始化 | requestId, conversationId, topicId |
EVENT_MESSAGE | 节点输出内容 | 流式 token 或完整文本 |
EVENT_THINKING | 推理模型思考开始 | thinking token |
EVENT_THINKING_END | 推理模型思考结束 | 空 |
EVENT_TOOL_EXEC_BEFORE | 工具调用前 | 工具名称、参数 |
EVENT_TOOL_EXEC_DONE | 工具调用完成 | 工具名称、结果 |
EVENT_FLOW_ERROR | 流程执行异常 | 异常信息 |
EVENT_FLOW_FINISHED | 流程执行完成 | 最终输出 |
EVENT_MESSAGE_END | 消息推送结束 | 空 |
流式响应透传
问题背景
在 AI 流程中,LLM 的响应是流式的(SSE token-by-token)。如果流程引擎等到所有节点执行完才返回结果,用户体验会很差(长时间等待)。
解决方案:事件回调透传
流程引擎提供一个 eventCallback 钩子,每个节点在执行时将中间结果通过回调推送:
// 伪代码flowRunParams.setEventCallback(eventData -> { if (EVENT_FLOW_FINISHED.equals(eventData.getEvent())) { // 流程完成,处理最终输出 String output = data.getOutputs(); appendAiMessage(output); saveConversation(); }});优势:
- 前端实时看到每个节点的执行结果(“正在调用知识库…” → “正在调用 AI…” → 输出内容)
- 支持中途停止(通过 FlowContext.stopped 标志)
- 超时自动关闭 SSE(防止连接泄漏)
陷阱:
- SSE 连接超时:默认设置
-0L(无超时),但需要配合心跳或超时计时器防止连接泄漏 - 并发控制:流程执行线程池限制(固定 10 线程),超出排队
- 异常传播:节点异常需要通过 EVENT_FLOW_ERROR 推送,而非直接抛出异常中断 SSE
动态脚本扩展
多语言脚本引擎
基于 LiteFlow 的脚本节点支持多种语言:
| 脚本语言 | 引擎 | 用途 |
|---|---|---|
| Python | liteflow-script-python | 数据处理、文件操作 |
| JavaScript | GraalJS | Web API 调用、JSON 处理 |
| Groovy | liteflow-script-groovy | 业务逻辑扩展 |
| Kotlin | liteflow-script-kotlin | 类型安全的脚本编写 |
| Aviator | liteflow-script-aviator | 轻量级表达式计算 |
设计取舍:脚本引擎标记为 provided 或 runtime scope(每个约 50MB),按需加载,避免增加基础包的体积。
脚本执行安全
- 沙箱隔离:GraalJS 提供沙箱环境,限制文件系统访问
- 超时控制:每个脚本节点可配置超时时间,超时自动终止
- 资源限制:脚本执行限制 CPU / 内存使用(通过容器或 JVM 参数)
设计取舍与替代方案
为什么选 LiteFlow
| 对比维度 | LiteFlow | LangGraph | Spring State Machine |
|---|---|---|---|
| 可视化编排 | 支持(JSON 定义) | 需自建 UI | 不支持 |
| 热更新 | 支持 | 需重启 | 不支持 |
| 多脚本语言 | 5 种 | 仅 Python | 不支持 |
| 学习成本 | 中 | 低 | 高 |
| 社区活跃度 | 中(国内) | 高(全球) | 中 |
选择 LiteFlow 的核心理由:低代码平台需要业务人员可配置的可视化编排能力,LiteFlow 的 JSON 定义 + 可视化画布组合最符合这一场景。
替代方案
- 自研轻量流程引擎:适合简单场景(3-5 个节点),但不支持可视化
- BPMN 标准(Flowable/Camunda):适合传统 OA 审批流,但 AI 场景支持弱
- LangGraph:适合 Python 生态的 AI 工作流,但 Java 生态不兼容