Spring AI 流程编排:AI时代,你需要一个更轻量的 Spring 流程编排框架

前言: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 运行时的方式重新出现。

相关推荐
孙启超1 天前
【AI应用开发】 RAG篇(一):概述与核心架构
llm·embedding·向量数据库·rag·向量化·ai应用开发·chunking
再让我睡两分钟15 天前
【无标题】
android·java·数据库·人工智能·prompt·ai应用开发
小饼干在学嘎瓦25 天前
Harness Engineering
ai应用开发·harness
腾飞开源1 个月前
06_Dify接入阿里云百炼API大模型
人工智能·项目实战·dify·ai智能体·ai应用开发·阿里云百炼·接入大模型
至乐活着2 个月前
用DeepSeek打造你自己的智能问答系统:从零到一的完整指南
python·deepseek·ai应用开发·智能问答系统·api教程
Jing_jing_X2 个月前
我做了一个 Agent Learning Lab:把 AI 应用开发过程做成白盒实验台
ai·agent·个人开发·ai应用开发
再让我睡两分钟2 个月前
【系列预告】AI应用开发实战课:26篇教程覆盖 Prompt、RAG、Agent 与工程化
aigc·ai应用开发
Jing_jing_X2 个月前
我用 Claude Code 搭了一个远程 Claude web:手机发指令,本地电脑自己写代码
ai·agent·个人开发·ai应用开发
Jing_jing_X2 个月前
AI 产品模型评测工具怎么选?用 Promptfoo / DeepEval / Ragas 找到最低可用模型
大模型·agent·ai应用开发