把 Spring AI 放进 2026 年的智能体框架版图里看,一个反直觉的事实是:Spring 团队刻意没把它做成一个 agent framework。这个项目的官方使命是"connecting your enterprise Data and APIs with the AI Models"——不是"让你的 Java 系统拥有自主智能体",而是"让 LLM 像 JDBC、JMS、WebClient 那样成为企业系统里一个可插拔的中间件"。理解这一刻意克制,才能理解 Spring AI 与 LangChain4j 的差异、Spring AI 与 Spring AI Alibaba 的分工、以及为什么 Java 圈的智能体路线天然分成"原子能力 SDK"与"行为预设 framework"两层。

本文以 Spring AI 1.x 为主轴,覆盖 LangChain4j、Spring AI Alibaba、Microsoft Semantic Kernel 在 JVM 生态里的实际位置,给出 Java 工程团队选型时真正要考虑的问题。横评的另一边——Python 阵营的 AgentScope / LangGraph / CrewAI / MAF——单独成文(《AgentScope 深度解析:Python 智能体框架的 ReAct 与 MsgHub 范式》)。

Spring AI 与 Java 智能体框架分层图

一、命名先去重:Spring AI ≠ Spring AI Alibaba ≠ Semantic Kernel Java

智能体框架领域名字混乱程度仅次于"Hermes"。讨论之前先把以下五个 JVM 实体的所指锁死,否则后面所有判断都建立在错位的概念上。

名字 是什么 与本文的关系
Spring AI spring-projects/spring-ai,Spring 团队官方仓库,Apache-2.0 本文研究对象
Spring AI Alibaba alibaba/spring-ai-alibaba,阿里在 Spring AI 之上叠的 agentic framework Spring AI 生态的下游扩展,不是替代
LangChain4j langchain4j/langchain4j,由 Dmytro Liubarskyi 等人主导的 Java LLM 库 README 明确"是为 Java 而生,不是从 Python 翻译来的"——和 LangChain 公司没有从属关系
Semantic Kernel microsoft/semantic-kernel,微软多语言(C#/Python/Java)AI orchestration 项目 已被 MAF(Microsoft Agent Framework)吸收
Semantic Kernel Java microsoft/semantic-kernel-java,SK 的 Java 端口 距离 .NET / Python 主线落后近一年

[PATTERN] 处理框架命名漂移:写作和阅读时凡是涉及"Spring AI"、“AutoGen”、"AgentScope"这类高歧义名词,第一件事是声明本文采用的具体仓库 URL 与版本号。半年前"AutoGen"指 v0.2 的 ConversableAgent,今天可能指 MAF——同一个名字背后是完全不同的代码。

本文用到的版本(2026-05 截至日):

  • Spring AI 1.1.6(2026-05-08 发布;与 1.0.7 / 2.0.0-M6 同日 GA),下一代 2.0.x 在 Milestone 阶段
  • Spring AI Alibaba 1.0.x,GitHub Stars 已反超主仓
  • LangChain4j 1.15.0(2026-05-16 在 Maven Central 发布);1.14.x 是 4 月主线
  • Semantic Kernel Java 1.4.4-RC1(2025 年 5 月),距离主线落后近一年
  • Microsoft Agent Framework .NET 1.0.0(2026-04-02 GA)——SK + AutoGen 同班人马合并而成,但没有 Java 端口

二、Spring AI:把 LLM 当成新一代 JDBC

Spring AI 的官方使命陈述放在 Spring 三十年的语境里读才能听出弦外之音——Spring 一直做的事就是把异构外部系统抽象成可移植的接口:JDBC 抽象数据库、JMS 抽象消息中间件、Spring Cloud 抽象服务注册中心。Spring AI 想做的是把 LLM 抽象成一种新的中间件

抽象层叠:从 ChatModel 到 ChatClient 到 Advisor

Spring AI 的 chat 层有两个高度:

  • ChatModel 接口位于底层(spring-ai-model),暴露 provider 原生能力
  • ChatClientspring-ai-client-chat)是一个 fluent API,刻意对齐 WebClient / RestClient 的风格

ChatClient 不立刻发请求,调 .call() 也不发——直到调 .content().chatResponse().entity(Class) 才真正打到 provider。这种"延迟触发"的设计让上层可以串很多 AdvisorAdvisor 是 Spring AI 的 interceptor 抽象,对应 Spring 体系里的 HandlerInterceptor / AOP,承担横切关注:RAG 注入、记忆注入、日志、安全、reasoning capture。框架内置的 advisor 包括 MessageChatMemoryAdvisorQuestionAnswerAdvisorRetrievalAugmentationAdvisorSimpleLoggerAdvisor

Modular RAG:把检索拆成 LEGO

Spring AI 1.0 起把 RAG 改造成 Modular RAG 架构(出处是同名论文 Modular RAG: Transforming RAG Systems into LEGO-like Reconfigurable Frameworks)。四个阶段——Pre-Retrieval / Retrieval / Post-Retrieval / Generation——每一阶段都有可替换的组件接口:QueryTransformerCompressionQueryTransformerRewriteQueryTransformerTranslationQueryTransformer)、MultiQueryExpanderDocumentRetrieverVectorStoreDocumentRetriever,支持 topKsimilarityThreshold、动态 Supplier<FilterExpression> 多租户过滤)、DocumentJoinerDocumentPostProcessorQueryAugmenter

这种拆法在 Java 圈是新颖的,在 Python 圈(LlamaIndex 已有 router/transformer/aggregator/postprocessor 多年)则属于追平。

关键 QueryTransformer 的内部实现

把三个 QueryTransformer 实现的实际行为剖一剖,能看到 Modular RAG 在每个阶段的设计姿态:

CompressionQueryTransformer:用于"多轮对话压缩"。前提是历史轮次的对话太长不适合直接做 retrieval query。它的内部逻辑是用一个轻量 LLM 调用把多轮对话压缩成单条 standalone query:

1
2
3
input  : <历史对话 N 轮>  + 当前用户输入"那它的退货政策是什么"
output : "ORD-2026-0001 这个订单的退货政策是什么"
(把"它"指代回 ORD-2026-0001)

实现关键是它不影响 chat 主流程的 prompt——压缩只用于生成 retrieval query。这避免了"把整段对话历史塞进 retrieval embedding 模型"导致召回退化。

RewriteQueryTransformer:用于"用户口语化输入 → retrieval-friendly 正式查询"。同样是用一次 LLM 调用做改写:

1
2
input  : "我那个单子还没收到能不能退"
output : "订单未送达情况下的退款流程 / 退货政策"

改写后的 query 用于 retrieval;原始 query 仍然用于最终回答的 prompt。这种"两份 query"的设计是 Modular RAG 与传统 RAG 最重要的差异。

TranslationQueryTransformer:跨语言场景下用一次 LLM 调用做翻译,保证 retrieval embedding 与文档库语言一致。这对中文文档库 + 英文查询、或反之的场景必要。

MultiQueryExpander:单查询变多查询

不同于上面三个"1 → 1"的 transformer,MultiQueryExpander 是"1 → N"——把单个用户 query 扩展成 3-5 条不同表述的等价 query:

1
2
3
4
5
6
7
MultiQueryExpander expander = MultiQueryExpander.builder()
.chatClientBuilder(builder)
.numberOfQueries(4)
.build();

List<Query> expanded = expander.expand(originalQuery);
// → [original, "...的退货流程?", "...怎么退货?", "...退货政策具体怎么写?"]

每条 query 独立 retrieval,结果由后续的 DocumentJoiner 合并去重。这种 query expansion 本质上是用更多 LLM token 换更高 retrieval 召回——典型场景下 recall 能从 0.6 提到 0.85,代价是 LLM 调用量翻 4 倍。

DocumentJoinerDocumentPostProcessor

MultiQueryExpander 产生的多组结果需要合并。DocumentJoiner 默认实现 ConcatenationDocumentJoiner 简单 concat 后按 score 排序去重;高级实现 RankFusionDocumentJoiner 用 Reciprocal Rank Fusion 算法(来自经典 IR 文献)合并多路结果。

DocumentPostProcessor 是后处理钩子——典型场景是用 cross-encoder 模型对 top-50 文档重排得到 top-5。Spring AI 没有内置 reranker(cross-encoder 不在 Spring AI 抽象之内),用户需要自己实现 DocumentPostProcessor 接 Cohere Rerank / Jina Rerank / 本地 BGE-Reranker。

Generation 阶段的 QueryAugmenter

最后一个阶段 QueryAugmenter 把检索回的文档拼接进 system prompt。默认实现 ContextualQueryAugmenter 提供两种模式——allowEmptyContext=true 让 LLM 在没有相关文档时也回答(fallback to model knowledge),allowEmptyContext=false 让 LLM 在 retrieval 为空时直接告诉用户"没找到相关资料"。这个开关对企业合规场景很关键——金融、医疗领域通常要 allowEmptyContext=false 杜绝 hallucination。

[PATTERN] Modular RAG 的真正价值在每个阶段的可替换性:很多团队上手 Spring AI 时只用了默认的 RetrievalAugmentationAdvisor,跳过了 query transformer 和 expander 的配置——这等于浪费了 Modular RAG 80% 的能力。生产 RAG 系统的 retrieval 召回率通常要靠 RewriteQueryTransformer + MultiQueryExpander + 自实现的 reranker DocumentPostProcessor 三层叠加才能达到可接受水平。

跨 20 种 VectorStore 的 portable filter DSL

VectorStore 接口配上一套 SQL-like 的 filter expression language,跨 PGVector、Pinecone、Qdrant、Milvus、Chroma、Weaviate、Redis、Neo4j、Oracle、MariaDB、MongoDB Atlas、Cassandra、Elasticsearch、OpenSearch、Couchbase、Typesense、Azure Cosmos DB、Azure AI Search、GemFire 等 20 种后端。每个 store 有 native fallback,不能表达的复杂条件下沉到底层。这是把"换 vector DB 等同于换 JDBC driver"的承诺真正落到代码里——业务代码不动,依赖换 starter。

具体的 filter DSL 用 fluent builder 写出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 多租户 + 时间窗 + 标签过滤
FilterExpressionBuilder b = new FilterExpressionBuilder();
Filter.Expression filter = b.and(
b.and(
b.eq("tenant_id", currentTenant),
b.gte("indexed_at", Instant.now().minus(30, ChronoUnit.DAYS).getEpochSecond())
),
b.in("category", List.of("policy", "compliance", "legal"))
).build();

List<Document> docs = vectorStore.similaritySearch(
SearchRequest.builder()
.query(userQuery)
.topK(8)
.similarityThreshold(0.65)
.filterExpression(filter)
.build()
);

这段代码在不同 vector store 上的执行路径如下:

后端 DSL 翻译策略 native fallback 触发条件
PGVector 翻译为 SQL WHERE 子句(tenant_id = ? AND indexed_at >= ?),与向量索引联合查询 复杂正则 / JSON path 条件下沉到原生 SQL
Pinecone 翻译为 metadata filter JSON({"tenant_id": "...", "$and": [...]} Pinecone 不支持的算子(如 like)抛 UnsupportedOperationException
Milvus 翻译为 boolean expression string(tenant_id == "..." && category in ["policy"] 字符串数组的 contains_all 等高级算子下沉
Qdrant 翻译为 Filter Protobuf(must / must_not / should 三段) 部分聚合算子下沉
Elasticsearch 翻译为 bool queryfilter clause 用于精确匹配) 自定义 scoring function 下沉到 script_score
Redis Search 翻译为 RediSearch query string(@tenant_id:{...} @indexed_at:[NOW-30d NOW] 复杂正则下沉

[PATTERN] portable DSL 不等于全功能等价:Spring AI 的 filter DSL 提供的是 80% 通用算子(eq / ne / gt / gte / lt / lte / in / nin / and / or / not)的可移植封装,剩下 20% 的高级算子让开发者用 native fallback 直接写。这种设计姿态承认"vector store 的能力差异本来就大",与试图做 100% 可移植的"通用 ORM"路线相反——后者通常以最弱后端的能力为分母,反而限制了开发者。

Tool calling 与 MCP 的工程化

Spring AI 1.x 的 tool 体系收敛到 @Tool 注解 + ToolCallback 接口,旧的 FunctionCallback 已经 deprecated。注册方式有三种:.tools(obj).toolCallbacks(cb).toolNames("beanName"),最后一种允许通过 Spring bean name 动态解析——这一点对企业里"工具实例由 Spring 容器管理"的场景非常顺手。

MCP 是 Spring AI 在 2025-2026 最重投入的方向。Spring 团队把孵化项目 spring-projects-experimental/spring-ai-mcp graduated 后捐给了 MCP 官方组织 modelcontextprotocol/java-sdk(不是直接捐给 Anthropic 公司账号),并继续作为协作维护方。这是它在 agent 协议标准化领域罕见的话语权——MCP Java SDK 的协作维护权落在 Spring 团队手里。

更大的协议生态事件是 2025-12-09 Anthropic 把 MCP 协议本身捐给 Linux 基金会下的 Agentic AI Foundation(AAIF),与 OpenAI 的 AGENTS.md、Block 的 goose 同批捐赠。这次捐赠把 MCP 从"Anthropic 主导的协议"变成"基金会治理的中立标准",Spring AI 与 MCP 官方组织的协作关系从此进入基金会治理框架。

Spring AI 1.1 的 MCP 工程化能力具体覆盖:

  • 注解模型@McpTool@McpResource@McpPrompt@McpComplete(server 侧)和 @McpLogging@McpSampling@McpElicitation@McpProgress(client 侧),从 2.0.0-M3 起进入 core
  • MCP Java SDK 升级到 v0.12.1:兼容 2025-03-26 Streamable HTTP + 2024-11-05 SSE + 2025-06-18 部分特性
  • Docker Compose / Testcontainers 集成:本地起 MCP server 像起 Postgres 容器一样简单
  • OAuth2 保护 MCP server:复用 Spring Security 的 OAuth2 Resource Server / Client 注册中心,把企业 SSO 直接接到 MCP 鉴权

这套工程化能力把 MCP 从"协议规范文档"变成"Spring Boot 应用里就能落地的中间件"——这与 Spring AI 一直以来"把 LLM 抽象成中间件"的定位是同一种取向。

分层视图:从应用代码到 Provider

把上面这些抽象按依赖方向画一遍,可以看出 Spring AI 是一个标准的"分层 SDK"——应用代码只看 ChatClient,Advisor 链承担横切关注,ChatModel 屏蔽 provider 差异,VectorStore / ChatMemory / ToolCallback 都是被 Advisor 在合适时机调用的旁路依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌─────────────────────────────────────────────────────────────┐
│ 应用层(Spring Boot 业务代码) │
│ @Service / @RestController / @Bean ChatClient │
└────────────────────────────┬────────────────────────────────┘
│ chatClient.prompt()...call().entity(X.class)
┌────────────────────────────▼────────────────────────────────┐
│ ChatClient(spring-ai-client-chat) │
│ fluent API,对齐 WebClient / RestClient │
│ defaultSystem · defaultAdvisors · defaultTools · 输出类型 │
└────────────────────────────┬────────────────────────────────┘
│ 进入 Advisor 链(按 order 拦截)
┌────────────────────────────▼────────────────────────────────┐
│ Advisor 链(cross-cutting interceptors) │
│ ├─ MessageChatMemoryAdvisor(按 CONVERSATION_ID 拉历史) │
│ ├─ RetrievalAugmentationAdvisor(Modular RAG 4 阶段) │
│ │ ├─ Pre-Retrieval:QueryTransformer / MultiQueryExpander │
│ │ ├─ Retrieval:VectorStoreDocumentRetriever │
│ │ ├─ Post-Retrieval:DocumentJoiner / PostProcessor │
│ │ └─ Generation:QueryAugmenter │
│ ├─ SimpleLoggerAdvisor / SafeGuardAdvisor / ... │
│ └─ <自定义 Advisor>
└────────────────────────────┬────────────────────────────────┘
│ 包装为 Prompt + Tools 后下发
┌────────────────────────────▼────────────────────────────────┐
│ ChatModel(spring-ai-model) │
│ provider-neutral 接口,按 starter 替换底层实现 │
└────────────────────────────┬────────────────────────────────┘
│ HTTP / SDK

┌──────────────────────┐
│ 外部 LLM Provider │
│ OpenAI / Anthropic /
│ Bedrock / Ollama /...
└──────────────────────┘

旁路依赖(被 Advisor 在合适时机调用):
VectorStore(PGVector / Pinecone / Qdrant / Milvus / ... 共 20+
一套 portable filter DSL,复杂条件下沉到 native fallback)
ChatMemory(MessageWindow / TokenWindow + JdbcChatMemoryRepository)
ToolCallback(@Tool POJO,可经 Spring bean name 在容器里动态解析)
MCP Server / Client(@McpTool / @McpResource / @McpPrompt / ...)

读这张图最关键的是看清三件事:业务代码只 import ChatClient,看不到也不需要看到 provider;Advisor 是 Spring AI 的"AOP 替身",RAG / 记忆 / 日志 / 安全这些横切关注全在这一层完成而不污染业务代码;VectorStore / ChatMemory / Tool 是"被使用而不是被继承"的旁路依赖,换 vector DB 就是换 starter。这三条加起来,Spring AI 就是 JDBC / JPA / WebClient 的同代抽象,只是这次抽象的对象换成了 LLM。

一段典型代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Bean
ChatClient chatClient(ChatClient.Builder builder, ChatMemory memory, VectorStore vs) {
return builder
.defaultSystem("You are an enterprise support assistant.")
.defaultAdvisors(
MessageChatMemoryAdvisor.builder(memory).build(),
RetrievalAugmentationAdvisor.builder()
.queryTransformers(RewriteQueryTransformer.builder()
.chatClientBuilder(builder).build())
.documentRetriever(VectorStoreDocumentRetriever.builder()
.vectorStore(vs).similarityThreshold(0.7).topK(5).build())
.build())
.defaultTools(new OrderTools(), new InventoryTools()) // @Tool-annotated POJOs
.build();
}

OrderSummary answer = chatClient.prompt()
.user(question)
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId))
.call()
.entity(OrderSummary.class); // 强类型 POJO 出参

15 行代码同时呈现了:fluent builder、双 Advisor 链(memory 先于 RAG)、Modular RAG with query rewriting、@Tool POJO 注册、structured output 落 record。Java 工程师读这段代码不需要任何额外解释——它就是普通 Spring 代码。

请求路径:那 15 行代码背后的时序

这段代码触发的 runtime 时序展开如下,能更清楚地看到 Advisor 链是怎么在调用 LLM 之前后两次拦截的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Caller        ChatClient    MemoryAdv    RAGAdv      VectorStore   ChatMemory   ChatModel    Provider
│ prompt() │
│ ──────────▶ │
│ user(q) / │ build context
│ advisors │ ⤵ enter advisor chain (pre-call)
│ entity(X) │ ──────────▶ │
│ │ │ load history ────────────────────────────▶ │
│ │ │ ◀─────────── messages ─────────────────── │
│ │ ──────────────────▶ │
│ │ │ Pre-Retrieval: rewrite query
│ │ │ Retrieval ─────────▶ │
│ │ │ ◀── topK docs ───── │
│ │ │ Post-Retrieval: join + filter
│ │ │ Generation: augment prompt
│ │
│ │ ChatModel.call(Prompt + Tools) ───────────────────────────────────▶ │
│ │ send ─▶ Provider
│ │ ◀ tool_call ─
│ │ resolve @Tool POJO via Spring bean
│ │ invoke tool method ─▶ result
│ │ send result ─▶ Prov.
│ │ ◀ final ans ─
│ │ ⤵ reverse advisor chain (post-call)
│ │ │ persist new turn ───▶ │
│ │ │ append to history
│ │ ◀─── ChatResponse / entity(X.class) ──
│ ◀ X object ─│

整条链路是同步阻塞的——调用线程要等所有 Advisor 退出 + LLM 返回 final answer 才解封。这与"agent runtime"派的协程异步范式(AgentScope / AutoGen / MAF)是两种心智模型。Spring AI 的同步阻塞决定了它在企业 Web 容器里就是一段普通的请求处理逻辑:可以放进 @Transactional 方法里、可以被 Servlet filter 包住、可以被 Spring Security 拦截。这种"和现有企业基础设施零摩擦兼容"是 Spring AI 选择不做 agent runtime 的另一个动机。

三、Spring AI 对 agent 的态度:刻意克制

最关键的差异化判断在这里。Spring AI 1.x 没有独立的 Agent class,只给出五种 workflow pattern 的参考实现(出自 Anthropic Building Effective Agents):Chain、Parallelization、Routing、Orchestrator-Workers、Evaluator-Optimizer。自治 agent 走 incubating 的 Spring MCP Agent。

这是 Spring AI 与所有"agent runtime"路线最根本的哲学分歧:Spring AI 是 SDK,不是 agent framework。文档里直接采用 Anthropic 的二分法——Workflows(预定义代码路径)vs Agents(LLM 自主调度)——并明确"对 well-scoped enterprise tasks,workflows 更可预测"。

社区抱怨 Spring AI"agent 能力滞后"的人,其实是在抱怨 Spring AI 没把它本来就不打算做的事做了。这是产品定位问题,不是能力问题。需要 multi-agent 编排的人,被 Spring 团队默认转介到下游的 Spring AI Alibaba。

2.0.x Milestone 路线:Spring AI 在准备什么

讨论 Spring AI 不能不看正在路上的 2.0.x。当前已发布到 2.0.0-M6,从 GitHub Milestone 与 commit 历史能看出几条主要投入方向:

Reactive ChatClient:1.x 的 ChatClient 是同步阻塞的,2.0 引入 ChatClient.reactive()Flux<ChatResponse> 流式返回,对齐 Spring WebFlux 生态。这对长程 agent / streaming response 场景是必要补全——1.x 的 chatClient.prompt().stream() 有 SSE 但不是真 reactive。

Spring MCP Agent(incubating):这是 Spring AI 第一次承认要做"agent 抽象"的官方信号。spring-ai-mcp-agent 模块在 2.0.0-M3 进入 incubation,提供 McpAgent 接口与 McpAgentBuilder,把 MCP server 直接装配成可调用的 agent。但仍然不是 multi-agent runtime——它的目标是"让单个 agent 用 MCP 工具的开发体验不那么繁琐",不是"做 LangGraph 替代品"。

Advisor 模型扩展:2.0.x 新增 BaseAdvisor 抽象类与 AdvisorChain 显式编排,让自定义 Advisor 的实现成本降低。1.x 的 Advisor 接口在某些场景需要 boilerplate,2.0 简化掉了。

Structured Output 强化:从 record-only 扩展到 sealed interfaces 与 pattern matching,让"LLM 输出 → Java 类型"的转换支持更复杂的产品场景(如 union type)。

OpenTelemetry 完整接入:1.x 通过 Micrometer 间接接 OTel,2.0 提供原生 OTel exporter,trace 一等公民。这是与 Python 阵营 LangSmith / AgentScope Studio 对位的努力。

[PATTERN] Spring AI 2.0 的 incubating 路线决定了它的边界:把 McpAgent 标 incubating 而不是直接进 core,是 Spring 团队"先看市场反应再做长期承诺"的典型姿态。如果 2.0.x 期内 McpAgent 不被生产级用户采用,下一个大版本它可能就被砍掉——Spring 主仓的 grad / deprecate 决策一向激进。这与 Spring AI Alibaba 的"叠加做 agent"路线形成对比,后者已经 GA 不会回头。

四、Spring AI Alibaba:在 Spring AI 之上加一层 framework

阿里仓库 alibaba/spring-ai-alibaba 的 Stars 已经反超主仓(约 9.6k vs 8.7k)。它不是 fork,而是叠加:

  • 内置 Workflow Agents:SequentialAgentParallelAgentRoutingAgentLoopAgent
  • Graph Runtimespring-ai-alibaba-graph):持久化 / 工作流编排 / streaming,支持 conditional routing、nested graphs、parallel execution、state management,可导出 PlantUML / Mermaid
  • Admin platform 可视化开发 + Dify DSL 迁移工具
  • A2A(Agent-to-Agent)+ Nacos 做分布式协调
  • DashScope(通义/Qwen)一等公民

Graph Runtime 的实际形态

spring-ai-alibaba-graph 是这个项目里最值得展开的部分——它在 Spring AI 的 ChatClient 之上做了一层 LangGraph 风格的状态图。一段典型代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
StateGraph<OrderState> graph = StateGraph.builder(OrderState.class)
.addNode("classify", new ClassifyOrderNode(chatClient))
.addNode("verify", new VerifyOrderNode(orderService))
.addNode("refund_eval", new RefundEvalNode(chatClient))
.addNode("approve_or_reject", new ApprovalNode(chatClient))
.addEdge(START, "classify")
.addConditionalEdges("classify", state -> switch (state.intent()) {
case REFUND -> "verify";
case STATUS_QUERY -> "verify";
case OTHER -> END;
})
.addEdge("verify", "refund_eval")
.addEdge("refund_eval", "approve_or_reject")
.addEdge("approve_or_reject", END)
.checkpointer(new JdbcCheckpointer(dataSource))
.build();

OrderState result = graph.invoke(
OrderState.fromUser(userQuery),
RunnableConfig.builder().threadId(sessionId).build()
);

这套 API 与 LangGraph 在概念层面完全对齐——StateGraph / addNode / addEdge / addConditionalEdges / checkpointer 一个不缺,连参数名都是直译。差异在于:

  • 状态对象是强类型 Java POJOOrderState 是普通 record/class),不是 TypedDict——这让 IDE 能做完整的类型检查与重构
  • checkpointer 默认 JDBC + 可换 Redis:与企业 Java 应用已有的数据库基础设施直接复用,不必额外引入 Postgres for checkpoint
  • 图导出graph.exportToPlantUML() / graph.exportToMermaid() 直接生成可渲染的图源——这对企业项目的"架构图自动同步"场景有用

图运行时与 Spring AI 主仓的关系

这里有一个工程上的微妙点:Spring AI Alibaba 的 Graph Runtime 不依赖 Spring AI 的 Advisor 链——它走的是另一条 invocation path,每个 node 内部直接持有 ChatClient 自己调。这意味着你不能简单地"在 Graph node 里复用已有的 Advisor 配置",要么重新组装 Advisor 在 node 里、要么把 Advisor 逻辑下沉到工具层。

这种"上下游不复用 invocation chain"的现象在 Spring 全家桶里其实很常见——@Transactional@Async 也存在类似的不互通问题。Spring AI Alibaba 的设计取向显然是"先做完整的 Graph 能力,复用问题以后再说",与 Spring 主仓"先稳定接口再加能力"的姿态不同。

[PATTERN] 主仓克制 + 下游叠加:当一个上游框架明确选择"做 SDK 不做 framework"时,社区会自然长出下游 framework。Spring AI / Spring AI Alibaba 与 LangChain / LangGraph 是同一种生态分工:上游守住"原子能力"和"接口稳定",下游做"行为预设"和"产品化"。Spring AI Alibaba 的 Graph Runtime 是 LangGraph 在 Java 圈的等价物——但因为绑定 DashScope/Qwen,它的影响力被锁在中文生态内。

五、LangChain4j:Java 圈的 AiServices 路线

langchain4j/langchain4j 与 Spring AI 是 JVM 生态最直接的两个竞品。它最显眼的特征是 AiServices——把"AI 接口"做成 JDK dynamic proxy 的声明式接口:

1
2
3
4
5
6
7
interface Assistant {
@SystemMessage("You are a helpful assistant. Answer concisely.")
String chat(@UserMessage String message);
}

Assistant assistant = AiServices.create(Assistant.class, model);
String reply = assistant.chat("Hello");

文档原话:“very similar to Spring Data JPA or Retrofit: you declaratively define an interface with the desired API, and LangChain4j provides an object (proxy) that implements this interface.” 这是把 LLM 行为完全放在类型化 Java 契约背后——AI 服务可以被 mock、可以走 if/switch/for、可以混合大小模型、可以做单元测试。

AiServices 进阶注解

最简形态只用了 @SystemMessage@UserMessage。AiServices 的真实表达力来自一组进阶注解,它们让"AI 接口"达到 JPA repository 的复杂度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
interface SupportAssistant {
// @MemoryId:按用户 ID 隔离对话历史,框架自动管理 ChatMemory
// @V:把方法参数注入 prompt 模板变量
// @StructuredPrompt:用外部模板而不是注解 attribute
@SystemMessage("You are a {{role}} assistant focused on {{domain}}.")
@UserMessage("""
User question: {{question}}

Recent context: {{context}}
Constraints: {{constraints}}
""")
OrderAssessment assess(
@MemoryId String userId,
@V("role") String role,
@V("domain") String domain,
@V("question") String question,
@V("context") String context,
@V("constraints") List<String> constraints
);

// @Tool:方法直接成为可调用工具,Java 类型签名自动生成 JSON Schema
@Tool("Look up the latest order status by id.")
OrderStatus lookupOrder(@P("ORD-prefixed order id") String orderId);

// @Moderate:自动应用内容审核(接 OpenAI Moderation API 或自建 moderator)
@Moderate
@SystemMessage("...")
String reply(@UserMessage String input);
}

SupportAssistant svc = AiServices.builder(SupportAssistant.class)
.chatLanguageModel(model)
.chatMemoryProvider(userId -> MessageWindowChatMemory.withMaxMessages(20))
.tools(new OrderTools(), new InventoryTools())
.moderationModel(moderationModel)
.build();

OrderAssessment result = svc.assess(
"user-1234", "support", "post-sale", question, context, constraints
);

这段代码里六个注解(@SystemMessage / @UserMessage / @MemoryId / @V / @Tool / @Moderate / @P)覆盖了 LLM 应用的完整工程关切:身份、模板、记忆、工具、安全、参数描述。LangChain4j 的设计取向是把这些关切都放在类型化接口的注解层而不是分散在 fluent builder 调用里——这是它与 Spring AI 在 API 风格上最深的差异。

类型化 vs Fluent:哪个更适合大型团队

LangChain4j 的注解风格在大型团队里有一个明显优势——接口定义可以独立于实现存在。前端团队可以基于 SupportAssistant 接口生成 Mock,后端团队负责接 LangChain4j 实现,两边并行开发不互相阻塞。Spring AI 的 fluent 风格做不到这一点——chatClient.prompt()...call().entity(X.class) 是命令式调用,没有可独立的接口契约。

代价是 LangChain4j 的注解风格对调试不友好——@SystemMessage + @V 的模板渲染发生在 proxy 内部,出错时栈信息不直接指向你的代码。Spring AI 的 fluent 链路反而更容易 step-by-step 调试。

[PATTERN] 选 Spring AI 还是 LangChain4j 不是技术选型,是组织选型:单团队 + 全栈写代码 + Spring 重度依赖 → Spring AI(fluent 风格 + Advisor 链路清晰);多团队 + 接口先行 + 多框架兼容 → LangChain4j(类型化契约 + 可独立 mock)。两个项目在能力上几乎平级,决定的是组织结构是否能从"接口先行"中受益。

LangChain4j 与 Spring AI 的差异不在能力上,在风格上:

维度 Spring AI LangChain4j
项目归属 Spring portfolio 内部 Open Collective 资助的社区项目
核心抽象 ChatClient + Advisor(fluent + interceptor) AiServices(typed declarative interface)
跨框架覆盖 只做 Spring Boot 一等支持 Spring Boot、Quarkus(注解处理器无反射)、Helidon、Micronaut
Provider 广度 主流 provider 完整覆盖 显式宣称 20+ chat-model provider 和 30+ embedding store
Agent 模块 主仓不提供,转介 Spring AI Alibaba 已有独立 langchain4j-agentic / -agentic-patterns / -agentic-a2a / -agentic-mcp,提供 SupervisorAgent、Workflow Agent、AgenticScope
构建周期 季度发版 月度发版

LangChain4j 的 agent 路线在 2026 年比 Spring AI 主仓激进——它选择把 agent 抽象内置在主仓而不是转介下游。这意味着 LangChain4j 用户在 Java 端不需要 Spring AI Alibaba 那种"再叠一层"的依赖关系。代价是 LangChain4j 的 agent 抽象在生态里没有 Spring 那种"协议合作伙伴"地位(MCP Java SDK 是 Spring AI 主导)。

[PATTERN] Java 圈选 Spring AI 还是 LangChain4j:Spring 重度用户(已经在用 Spring Boot 3.x)选 Spring AI 直接,autoconfigure 一键到位;多框架(Quarkus / Micronaut / 纯 Java)或希望"AI 服务像 JPA repository 一样写"的团队选 LangChain4j。两者能力近乎打平,差异在风格。

六、Semantic Kernel Java:不要选

microsoft/semantic-kernel-java 仓库存在,license MIT,最新可见版本 java-1.4.4-RC1(2025 年 5 月),距离 .NET / Python 主线落后近一年,没有 Spring Boot starter,没有 Quarkus 集成。Java 用户选 SK 实质上是给自己挖坑——Spring AI 与 LangChain4j 都是更优解。

这一点连第三方 2026 年 Java GenAI 框架对比文章都已经形成共识。SK 主线本身在 2026-04 已经被 Microsoft Agent Framework(MAF)吸纳进去,但 MAF 只覆盖 Python + .NET,没有 Java 端口。微软的 Java 投入显然不在 AI 这条赛道上。

存量用户(已经写过 SK Java 代码)的处理建议:

  • 短期保持现状,等 Microsoft Agent Framework 是否补 Java 端口(不乐观)
  • 中期迁移到 LangChain4j——它的 ChatModel 抽象与 SK 的 ChatCompletionService 心智模型最接近
  • 不要迁移到 Spring AI,除非你的应用本身要重构成 Spring Boot

七、综合判断:Java 智能体框架选型决策点

把以上四个项目(Spring AI、Spring AI Alibaba、LangChain4j、SK Java)按真实工程语境而非功能勾选打分,得到的指引是:

1. 你的代码主体在 Spring Boot 上

  • 默认选 Spring AI 主仓。autoconfigure 一键到位,starter 化的 vector store 切换,与现有 @Transactional / @Service / Spring Security 零摩擦
  • 需要 multi-agent / graph / 可视化编排:再加 Spring AI Alibaba。注意它是叠加不是替代——Spring AI 的 ChatClient 仍在
  • 不要纠结"Spring AI 还没有原生 multi-agent"——这是产品定位,不是能力短板

2. 你的代码主体不在 Spring Boot 上(Quarkus / Micronaut / 纯 Java)

  • 默认选 LangChain4j。它对多框架的支持是一等的(Quarkus 走注解处理器无反射,对 native image 友好)
  • 已经在用 Spring Boot 但希望"AI 服务像 JPA repository 一样写",也可以用 LangChain4j——它的 Spring Boot starter 与 Spring AI 不冲突,可以在同一个项目里共存

3. 你想用微软栈或要跨语言(C# + Java)

  • C# 端默认选 Microsoft Agent Framework(2026-04 GA)。SK 1.x 与 AutoGen 都已被它吸收
  • Java 端不要选 SK Java——选 Spring AI 或 LangChain4j 接 Azure OpenAI starter,跨语言协议靠 MCP / A2A 而不是框架统一

4. 你需要 RAG,且后端是 Postgres / Pinecone / Milvus 这类常见 vector store

  • Spring AI 的 Modular RAG 已经把 RAG 拆成 LEGO,开箱即用。20+ vector store 一套 portable filter DSL,换后端就是换 starter
  • LangChain4j 的 RAG 抽象同样成熟,差异主要在 API 风格(Spring AI fluent + Advisor,LangChain4j AiServices declarative)

5. 你需要 MCP(model context protocol)一等支持

  • Spring AI 是 MCP Java SDK 的事实持有者(已 donate 给 Anthropic)。@McpTool / @McpResource / @McpPrompt 从 2.0.0-M3 起进入 core
  • LangChain4j 通过 langchain4j-agentic-mcp 模块提供,能力相近但生态地位不同

6. 你在意"框架的长期演进风险"

  • 风险最低:Spring AI 主仓(克制、迭代慢、向后兼容好)、LangChain4j(社区治理、月度发版稳定)
  • 风险中等:Spring AI Alibaba(紧跟 Spring AI 主仓但商业方向受阿里 DashScope 战略牵动)
  • 风险较高:Semantic Kernel Java(事实上的弃维护状态)

[PATTERN] 选框架的最终判据是"和你在解什么问题对齐":Spring AI 解的是"企业 Java 系统怎么把 LLM 接进来";LangChain4j 解的是"Java 应用怎么用类型化的方式调 LLM";Spring AI Alibaba 解的是"Spring AI 之上怎么搭多 agent";SK Java 解的是已经回答不上来的问题。所有"我应该选哪个 Java 框架"的问题,本质上是"我在解哪一道题"的问题。

八、对位 Python 阵营:跨语言协议是唯一现实方案

讨论 Java 智能体框架不能不提 Python 阵营——大量真实场景是"Java 业务系统 + Python agent 编排服务"的混合部署。把两边的代表项目放在一张表里看,差异更清楚:

维度 Spring AI(Java) AgentScope(Python)
出身 Spring 团队(Broadcom) 阿里通义实验室 SysML 团队
抽象密度 低(SDK 路线,刻意不做 agent runtime) 高(runtime 路线,全 async ReAct + MsgHub)
运行模型 同步阻塞 + 显式编排 协程异步 + 消息驱动
长期记忆 不内置(要自己拼 VectorStore) 内置 Mem0 / ReMe 多层
Agent 抽象 不提供(推荐 5 种 workflow pattern) ReActAgent + MsgHub 多 agent 工作流
部署形态 Spring Boot starter / autoconfigure 普通 Python 包 + Studio 远端 UI
典型用户 Java 企业团队,要把 LLM 接进现有业务系统 Python 研究/产品团队,做多 agent 应用或 agentic RL

互补关系而非竞争关系。Java 企业团队选 AgentScope 没有路径——它是 Python 库;Python 研究团队选 Spring AI 没有意义——他们要的是 agent 行为实验空间,不是 starter。把它们放进同一张评分卡比较,主要是为了把"agent 框架的 design space"勾勒出来。

跨语言场景的现实方案是协议层互通——A2A(Agent-to-Agent)+ MCP(Model Context Protocol)。Spring AI 和 AgentScope 都已是 A2A / MCP 一等公民,跨语言的 agent 协作不再依赖框架统一,而是依赖协议标准。这也是为什么本文不再推荐"为了跨语言而选 Semantic Kernel"——协议合作时代不需要语言层的统一框架。

AgentScope 这一侧的细节单独成文,参见 《AgentScope 深度解析:Python 智能体框架的 ReAct 与 MsgHub 范式》 与上手实战 《AgentScope 上手教程:从空仓库到 Multi-Agent 工单系统》

九、写在最后:Java 智能体框架的两条主线

把 Spring AI、Spring AI Alibaba、LangChain4j 放在一起看,2026 年 Java 智能体框架的真实分裂线非常清楚:

第一条分裂线:SDK 派 vs Framework 派。Spring AI 主仓和 LangChain4j 都是 SDK,把"agent 行为"留给开发者;Spring AI Alibaba 是 framework,把"agent 行为"做成预设。这条分裂线决定了你是要灵活性还是要开箱即用。

第二条分裂线:Spring 重度依赖 vs 多框架兼容。Spring AI 只做 Spring Boot,绑定深;LangChain4j 一等支持 Spring Boot / Quarkus / Micronaut / 纯 Java,绑定浅。这条分裂线决定了你的应用栈是否能保持灵活。

短期看不到统一——Spring AI 不会兼容 Quarkus 注解处理器,LangChain4j 不会让出 Quarkus / Micronaut 这条赛道。Java 智能体框架的两条主线会继续并存。

跨过 JVM 边界往 Python 看,分裂线还会再多两条(同步阻塞 vs 协程异步、个体协作 vs 团队隐喻)——但那是另一篇文章的话题。


主要引用源

版本快照(2026-05-18 截止日):Spring AI 1.1.6(2026-05-08)/ Spring AI Alibaba 1.0.x / LangChain4j 1.15.0(2026-05-16)/ SK Java 1.4.4-RC1(2025-05)/ MAF .NET 1.0.0(2026-04-02 GA,无 Java 端口)/ MCP Java SDK v0.12.1 / MCP 协议规范 2025-06-18