前言:AI应用正在从模型调用变成流程系统
早期开发一个 AI 功能,通常只有三步:
text
构造 Prompt
↓
调用大模型
↓
返回结果
但当 AI 真正进入业务系统后,流程很快会变得复杂:
text
用户输入
↓
意图识别
↓
知识库检索
↓
大模型生成
↓
工具调用
↓
结果校验
↓
流式返回
再加入 Agent、多模型路由、并行任务、失败重试和异步通知后,开发者面对的已经不再是一次模型调用,而是一条完整的执行流程。
这也是 AI 时代流程编排重新变得重要的原因。
只是,这类流程往往不需要一整套重量级工作流平台。
它更需要一种能够直接嵌入 Spring Boot、使用 Java 代码描述、支持运行时组合的轻量编排方式。
一、AI应用的核心复杂度正在转向编排
1. 大模型只是流程中的一个节点
一个真实的 RAG 问答系统,可能包含:
text
问题改写
→ 向量检索
→ 文档重排
→ Prompt 构建
→ 模型生成
→ 输出解析
一个 ReAct Agent 则可能包含:
text
模型推理
→ 选择工具
→ 执行工具
→ 写回观察结果
→ 再次推理
→ 判断是否结束
一个多 Agent 系统还可能包含:
text
┌─ 搜索 Agent ─┐
用户任务 → 拆解 ──┼─ 分析 Agent ─┼→ 汇总 Agent
└─ 风险 Agent ─┘
这些能力名称不同,但底层都在处理相同问题:
- 节点按照什么顺序执行;
- 哪些节点可以并行;
- 什么条件下进入某个分支;
- 中间结果如何传递;
- 循环什么时候结束;
- 失败以后如何处理。
因此,AI 应用越成熟,越不是在调用一个模型,而是在编排模型、工具、数据和业务系统。
2. 没有流程抽象,代码会逐渐失控
假设我们开发一个智能客服。
第一版可能只是:
java
public String chat(String question) {
return llm.invoke(question);
}
加入知识库以后:
java
if (needKnowledge(question)) {
List<Document> documents = retriever.search(question);
return llm.invoke(buildPrompt(question, documents));
}
再加入订单查询、物流查询、内容审核、模型降级和工具重试后,代码会逐渐出现:
- 多层
if-else; - 大量
try-catch; - 手写
CompletableFuture; - 手写 Agent 循环;
- 不断膨胀的上下文 Map;
- 分散在各处的超时和停止逻辑。
真正的问题不是代码行数变多,而是:
流程已经成为系统的核心结构,却仍然隐藏在普通方法调用中。
当顺序、条件、并发和循环成为主要业务结构时,就应该将它们显式表达出来。
二、为什么不是直接使用传统工作流平台
1. 传统工作流解决的是另一类问题
Flowable、Camunda 等工作流平台更擅长:
- 审批与人工任务;
- 跨部门流程;
- 长事务;
- 流程实例持久化;
- BPMN 可视化建模;
- 跨天甚至跨月运行;
- 流程版本和历史管理。
这些能力非常重要,但并不是所有流程都需要。
2. AI运行时流程通常更轻、更短
AI 应用中的大量流程可能只执行几秒或几分钟。
其中的节点可能只是:
- 一个 Spring Bean;
- 一个 Lambda;
- 一个 Prompt 模板;
- 一个 LLM 客户端;
- 一个 Retriever;
- 一个 Tool;
- 一个 Agent;
- 一个子流程。
它们通常不需要:
- 独立流程服务器;
- 流程实例数据库;
- BPMN 文件;
- 可视化审批界面;
- 业务人员拖拽建模。
如果只是编排一条:
text
Prompt → LLM → Parser
或者:
text
多个 Agent 并行 → 汇总结果
却引入一整套重量级平台,基础设施复杂度可能会超过业务本身。
因此,流程问题需要进一步区分:
text
长期、持久化、人工参与的业务流程
→ BPMN 工作流平台
应用内部、短生命周期执行流程
→ 轻量级内存流程编排
Salt Function Flow 主要解决的是后一类问题。
它将业务逻辑拆分为可组合函数节点,并通过统一 DSL 表达顺序、条件、并行、异步、等待和循环等执行关系。
三、轻量级Spring流程编排应该是什么样
1. 不改变原有Spring开发方式
轻量流程引擎不应该要求开发者把业务迁移到另一个平台。
更自然的结构是:
text
Spring Boot 应用
├─ Service
├─ Repository
├─ LLM
├─ Retriever
├─ Agent
└─ FlowEngine
流程节点仍然可以调用现有的:
- Spring Bean;
- 数据库;
- Redis;
- Feign;
- Dubbo;
- MQ;
- 大模型;
- 向量数据库。
流程能力只是嵌入现有应用,而不是取代现有架构。
2. 使用Java原生DSL描述流程
例如,一条 AI 内容生成流程可以写成:
java
FlowInstance flow = flowEngine.builder()
.next(InputNormalizeNode.class)
.next(PromptBuildNode.class)
.next(LlmGenerateNode.class)
.next(OutputParseNode.class)
.next(ContentAuditNode.class)
.notify(MetricsNode.class)
.build();
它对应的业务结构一目了然:
text
输入处理
→ 构建 Prompt
→ 模型生成
→ 结果解析
→ 内容审核
同时异步记录指标
流程定义负责描述结构,节点负责完成业务。
3. 节点不应该只有一种形式
真实项目中,不是所有逻辑都值得专门创建一个类。
Salt Function Flow 支持通过多种方式引用节点:
- 节点 ID;
- Class;
- 实例;
- Lambda;
- 方法引用;
- 子流程;
- 带条件的
Info节点。
例如:
java
flowEngine.builder()
.next("query_user")
.next(UserProfileNode.class)
.next(input -> normalize(input))
.next(this::parseResult)
.next(ragSubFlow)
.build();
这使流程框架可以逐步进入现有项目,而不是要求开发者一次性重构所有代码。
四、Salt Function Flow如何对应AI流程
Salt Function Flow 提供七类核心网关:
| API | 流程含义 | AI应用场景 |
|---|---|---|
next |
顺序执行或排他分支 | Prompt → LLM → Parser |
all |
多个命中节点依次执行 | 多条审核规则 |
concurrent |
并行执行并聚合结果 | 多模型、多 Agent |
future |
提前启动异步任务 | 提前加载知识或画像 |
wait |
等待异步结果 | 异步任务汇合 |
notify |
异步执行且不阻塞 | 日志、埋点、通知 |
loop |
根据条件重复执行 | ReAct、重试、自我修正 |
这些 API 对应的并不是某个特定 AI 概念,而是程序执行中的通用控制结构。
1. Chain就是顺序流程
text
PromptTemplate
↓
LLM
↓
OutputParser
可以直接表达为:
java
FlowInstance chain = chainActor.builder()
.next(promptTemplate)
.next(llm)
.next(outputParser)
.build();
2. 多Agent就是并行与汇总
java
FlowInstance researchFlow = chainActor.builder()
.concurrent(
cAlias("market", marketAgent),
cAlias("technology", technologyAgent),
cAlias("risk", riskAgent)
)
.next(summaryAgent)
.build();
这里 concurrent 负责并行执行,next 负责将聚合结果交给 Summary Agent。
3. ReAct就是带退出条件的循环
text
Reason
→ Tool
→ Observation
→ 判断是否结束
→ 未结束则继续
模型负责推理和选择工具,流程负责:
- 控制循环;
- 限制最大步数;
- 传递上下文;
- 处理停止;
- 管理失败。
这说明 Agent 的智能来自模型,而 Agent 的可控执行仍然依赖流程结构。
五、J-LangChain证明了这种思路可以落地
1. 流程编排是第一架构原则
J-LangChain 是一个面向 Java 和 Spring Boot 的 AI 应用框架,支持:
- 多家 LLM;
- Chain;
- RAG;
- Agent;
- MCP;
- Tool;
- Skill;
- SubAgent;
- 多 Agent;
- 流式输出。
它将"Flow Orchestration as First-Class Citizen"列为首要架构原则。
Prompt、LLM、Agent、Tool 和 RAG 都被视为可组合流程节点,统一参与顺序、并行、条件和循环编排。
J-LangChain 的 Maven 配置也直接依赖 Salt Function Flow。
这意味着 Salt Function Flow 并不是一个只用于演示订单流程的 DSL。
它已经被用于构建真实的 Java AI 框架。
2. Prompt、LLM和Parser都可以成为节点
J-LangChain 的基础 Chain 可以这样定义:
java
FlowInstance chain = chainActor.builder()
.next(PromptTemplate.fromTemplate(
"Tell me a joke about ${topic}"
))
.next(ChatAliyun.builder()
.model("qwen-plus")
.build())
.next(new StrOutputParser())
.build();
其执行结构就是:
text
Map参数
→ PromptTemplate
→ ChatAliyun
→ StrOutputParser
→ String结果
Prompt、模型和解析器职责完全不同,但从执行角度看,都符合:
text
Input → Process → Output
因此它们可以共享同一套流程模型。
3. 多Agent同样可以统一编排
J-LangChain 还展示了多个专业 Agent 并行执行,再由一个 Agent 汇总的模式:
java
FlowInstance researchChain = chainActor.builder()
.concurrent(
cAlias("flights", flightAgent),
cAlias("hotels", hotelAgent),
cAlias("weather", weatherAgent)
)
.next(summaryAgent)
.build();
这条流程表达的是:
text
┌─ 航班 Agent ─┐
研究任务 ─────┼─ 酒店 Agent ─┼→ 汇总 Agent
└─ 天气 Agent ─┘
多 Agent 不需要一套完全独立的执行机制。
它仍然可以被理解为流程中的并行节点和汇总节点。
六、轻量流程编排真正解决了什么
1. 让执行结构变得可见
流程定义本身就是一份可执行架构图。
开发者不必阅读每个节点的内部代码,就能理解:
- 谁先执行;
- 谁可以并行;
- 哪个节点负责汇总;
- 哪个任务不阻塞主流程;
- 哪些条件会进入不同分支。
2. 让AI节点和业务节点进入同一条流程
AI 系统不会只包含 AI。
它还需要调用:
- 用户系统;
- 订单系统;
- 权限系统;
- 支付系统;
- 消息系统。
如果 LLM、RAG 和 Agent 使用一套执行机制,普通业务节点使用另一套机制,系统最终会出现两套上下文和两套生命周期。
更自然的方式是让它们统一进入流程:
text
Prompt节点
LLM节点
RAG节点
Agent节点
订单查询节点
权限校验节点
消息通知节点
流程引擎不需要判断某个节点是否"智能"。
它只需要管理节点如何连接和执行。
3. 让执行控制从业务代码中分离
节点负责业务,流程负责:
- 条件;
- 并行;
- 循环;
- 等待;
- 停止;
- 超时;
- 补偿;
- 生命周期事件。
这比单纯让代码变短更重要。
七、它适合什么,又不适合什么
1. 更适合的场景
Salt Function Flow 更适合:
- Spring Boot 应用内部短流程;
- 复杂 Service 调用链;
- AI Chain;
- RAG Pipeline;
- 多 Agent 并行;
- 条件路由;
- 异步任务;
- 重试和循环;
- 不需要完整 BPMN 平台的业务。
2. 不应该替代的场景
如果系统需要:
- 跨天或跨月运行;
- 服务重启后恢复流程;
- 人工审批;
- 会签与驳回;
- BPMN 可视化设计;
- 完整流程历史;
- 分布式流程实例;
- 强持久化检查点;
那么 Flowable、Camunda 或带持久化能力的状态图框架通常更加合适。
轻量框架的价值并不是替代所有流程产品,而是解决一个长期被忽略的中间场景:
业务已经复杂到需要显式编排,但还没有复杂到需要部署一整套工作流平台。
结语:AI时代,流程正在重新成为基础设施
AI 给软件系统带来了更多不确定性。
模型输出可能变化,Agent 可能选择不同工具,RAG 可能检索出不同文档。
但生产系统仍然需要确定的执行边界:
- 哪些节点可以调用;
- 按什么顺序执行;
- 哪些任务可以并行;
- 循环什么时候结束;
- 失败以后如何处理;
- 用户取消后如何停止。
因此,一个成熟的 AI 系统通常会形成三层结构:
text
大模型
负责理解、推理和生成
↓
Agent
负责规划、选择和决策
↓
流程引擎
负责连接、约束和执行
可以将其概括为:
大模型负责生成,Agent 负责决策,流程引擎负责让一切有序发生。
Salt Function Flow 并不试图成为庞大的 AI Agent 平台,也不试图替代传统 BPMN 工作流。
它解决的是一个更具体的问题:
当 Spring Boot 应用已经需要流程能力,但还不值得引入重量级工作流平台时,如何获得一种足够清晰、灵活且轻量的编排方式?
J-LangChain 的实践说明,这套方式不仅能编排普通业务节点,也能够承载 Prompt、LLM、RAG、Tool 和多 Agent。
AI 时代没有让流程引擎消失。
它只是让流程编排以一种更轻量、更代码化、更贴近 Spring 运行时的方式重新出现。