Spring AI框架
开篇:Java 开发者的 AI 框架首选
Python 有 LangChain,Java 有什么?Spring AI 是 Spring 官方推出的 AI 应用开发框架(2025年5月发布 1.0),它通过标准化的 API 封装,让 Java 开发者也能轻松对接大模型、实现 RAG、Function Calling 和对话记忆。如果你的项目是 Spring Boot 技术栈,Spring AI 就是最自然的选择。
Q: 了解Spring AI吗,他都能干什么?
典型回答
Spring ai是Spring官方推出的ai应用开发框架,最近(2025年5月20)刚刚发布1.0版本,他的主要作用就是通过提供各种API的封装来降低用Java开发大模型应用的门槛。
与大型语言模型集成
Spring通过简单的配置快速集成 OpenAI、Azure OpenAI、HuggingFace、Ollama、Mistral、Google Gemini 等主流 LLM 服务。
ChatClient chatClient = ... // 自动注入或配置
ChatResponse response = chatClient.call("帮我写一个天气查询的API");
System.out.println(response.getResult().getOutput());提供了ChatClient和ChatModel和大模型进行对话
ChatModel API 让应用开发者可以非常方便的与 AI 模型进行文本交互,它抽象了应用与模型交互的过程,包括使用 Prompt 作为输入,使用 ChatResponse 作为输出等。
@RestController
public class ChatModelController {
private final ChatModel chatModel;
public ChatModelController(ChatModel chatModel) {
this.chatModel = chatModel;
}
@RequestMapping("/chat")
public String chat(String input) {
ChatResponse response = chatModel.call(new Prompt(input));
return response.getResult().getOutput().getContent();
}
}ChatClient 提供了与 AI 模型通信的 Fluent API,它支持同步和反应式(Reactive)编程模型。与 ChatModel、Message、ChatMemory 等原子 API 相比,更加灵活,代码更精简。
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/chat")
public String chat(String input) {
return this.chatClient.prompt()
.user(input)
.call()
.content();
}
}Prompt 模板支持
可以定义 prompt 模板,使用变量动态生成 prompt。使用类似 Spring Boot 配置和注入方式加载模板。
PromptTemplate template = new PromptTemplate("请用Java写一个{task}的例子");
String prompt = template.render(Map.of("task", "文件读取"));支持RAG
支持将文本向量化后存储到向量数据库(如 Redis, Pinecone, PostgreSQL with pgvector, Milvus 等)。可用于构建 RAG 应用,实现文档问答、知识库问答等。
EmbeddingClient embeddingClient = ...;
VectorStore vectorStore = new PgVectorStore(...);
vectorStore.add(List.of(new Document("Spring 是什么框架?", metadata)));支持对话记忆
支持基于chat memory的对话记忆,也就是不需要调用显示的记录每一轮的对话历史。
//初始化基于内存的对话记忆
ChatMemory chatMemory = new InMemoryChatMemory();
DashScopeChatModel chatModel = ...;
ChatClient chatClient = ChatClient.builder(dashscopeChatModel)
.defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
.build();
//对话记忆的唯一标识
String conversantId = UUID.randomUUID().toString();
ChatResponse response = chatClient
.prompt()
.user("我想去新疆")
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversantId)
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
.call()
.chatResponse();
String content = response.getResult().getOutput().getContent();
Assertions.assertNotNull(content);
logger.info("content: {}", content);
response = chatClient
.prompt()
.user("可以帮我推荐一些美食吗")
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversantId)
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
.call()
.chatResponse();
content = response.getResult().getOutput().getContent();
Assertions.assertNotNull(content);
logger.info("content: {}", content);支持Function Calling
详见 AI Agent 与工具生态章节中的 Function Calling 介绍。
官方文档:<https://docs.spring.io/spring-ai/reference/api/tools.html>
支持MCP
详见 AI Agent 与工具生态章节中的 MCP 介绍。
官方文档:<https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html>
Q: SpringAI中ChatModel和ChatClient有啥区别?
典型回答
在 Spring AI 框架中,ChatModel 和 ChatClient 是构建LLM应用的两个核心抽象概念,它们分别代表了底层驱动能力和高层应用编排。
- ChatModel 是引擎:负责直接与 AI 模型提供商(如 OpenAI、Azure、本地模型)通信,处理底层的请求和响应。
- ChatClient 是驾驶舱/控制台:建立在
ChatModel之上,为开发者提供流畅的 API(Fluent API),用于编排对话流、管理上下文、调用工具(Function Calling)以及处理响应转换。
ChatModel是 Spring AI 的核心API,直接对接具体的 LLM 提供商,如有具体的实现: OpenAiChatModel, AzureAiChatModel,负责将 Spring AI 统一的 ChatRequest 转换为特定厂商的 API 请求格式。负责接收厂商的原始响应并转换为统一的 ChatResponse。
他就像 JDBC 中的 Connection 或 Statement,或者 HTTP 客户端中的 RestTemplate/WebClient 底层执行器。它只管“发出去”和“收回来”,不管业务逻辑怎么串。
@Autowired
private ChatModel chatModel; // 注入具体的实现,如 OpenAiChatModel
public String getWeather(String city) {
// 1. 手动构建消息列表
List<Message> messages = new ArrayList<>();
messages.add(new UserMessage("今天 " + city + " 的天气怎么样?"));
// 2. 构建请求
ChatRequest request = ChatRequest.builder()
.messages(messages)
.build();
// 3. 调用底层模型
ChatResponse response = chatModel.call(request);
// 4. 手动解析响应内容
return response.getResult().getOutput().getText();
}ChatClient 是基于 ChatModel 构建的高级抽象,旨在简化应用开发。提供 .prompt(), .system(), .user(), .call() 等链式调用方法。好包括:
- **记忆管理**:内置对 `ChatMemory`(对话记忆)的支持,自动处理多轮对话的历史记录。
- **工具调用 (Function Calling)**:极其便捷地注册和绑定 Java 方法作为 AI 的工具(Tools),自动处理参数提取和方法 invocation。
- **结构化输出**:支持直接将响应转换为 POJO (Java 对象)、String 或 Flux (流式响应),无需手动解析 JSON。
- **观察性 (Observability)**:内置对 Micrometer Tracing 的支持,方便监控链路。
- **扩展机制(Advisor)**:可以用于拦截、修改和增强 Spring 应用中的 AI 交互功能,那就是Advisor,通过利用Advisor,开发者可以创建更复杂、可重用且易于维护的 AI 组件。@Autowired
private ChatClient chatClient; // 通常通过 ChatClient.builder(chatModel).build() 创建
// 场景1:简单对话 + 自动转对象
public WeatherInfo getWeatherInfo(String city) {
return chatClient.prompt()
.user("查询 " + city + " 的天气")
.call()
.entity(WeatherInfo.class); // 自动将 JSON 转为 Java 对象
}
// 场景2:带工具调用 (Function Calling)
public String chatWithTools(String input) {
return chatClient.prompt()
.tools(weatherService::getWeather) // 一键绑定 Java 方法为工具
.user(input)
.call()
.content();
}
// 场景3:带上下文记忆
public String chatWithMemory(String sessionId, String input) {
return chatClient.prompt()
.advisors(a -> a.param("chatMemoryId", sessionId)) // 自动加载/保存历史
.user(input)
.call()
.content();
}ChatClient 内部持有一个 ChatModel 实例。当你调用 chatClient.call() 时,它最终会委托给内部的 chatModel.call() 去执行真正的网络请求。通常你先从 Spring 容器中获取一个配置好的 ChatModel Bean(例如 openAiChatModel),然后利用它来构建 ChatClient。
ChatClient client = ChatClient.builder(chatModel)
.defaultAdvisors(...) // 配置默认的记忆或拦截器
.build();Q: Spring AI中的advisor机制了解吗?
典型回答
(本文内容来自我出的AI课,详细的代码演示和视频讲解可以从课程中学习。)
Spring AI 中提供了一个灵活且强大的方式,可以用于拦截、修改和增强 Spring 应用中的 AI 交互功能,那就是Advisor,通过利用Advisor,开发者可以创建更复杂、可重用且易于维护的 AI 组件。
可以把Advisor理解为插件,比如我们想要实现记忆功能,就可以用到Memory相关的Advisor

实现日志记录相关的功能,我们就可以添加一个日志的Advisor:

Spring AI中也提供了一些列内置的Advisor

我们看一下Advisor接口的定义,其实没啥东西,主要是他继承自Ordered,需要在他的所有视线中实现int getOrder(); 这个方法。这个方法主要是用来设置各个Advisor的顺序的。
public interface Advisor extends Ordered {
int DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER = -2147482648;
String getName();
}他还有几个子接口。主要就是CallAdvisor、StreamAdvisor以及BaseAdvisor。

其中最基础的两个接口,一个是CallAdvisor一个是StreamAdvisor,一个是给同步调用使用的,另一个是给流式调用使用的。别贴提供了adviseCall和adviseStream方法。
public interface CallAdvisor extends Advisor {
ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain);
}
public interface StreamAdvisor extends Advisor {
Flux<ChatClientResponse> adviseStream(ChatClientRequest chatClientRequest, StreamAdvisorChain streamAdvisorChain);
}其实Advisor的执行过程,就和AOP是一样的,他会把所有注册到一个chatClient上的Advisor都找出来,然后按顺序执行。
在DefaultChatClient中会有一个advisorChain,这里面就是所有注册进来的advisor,以此调用这些advisor的adviseCall方法。(如果是流式调用,就是调用adviseStream方法)


这个adviseCall方法是怎么实现的呢(adviseStream类似,拿adviseCall为例)?其实主要分4类:

- ChatModelCallAdvisor
- SimpleLoggerAdvisor
- SafeGuardAdvisor
- BaseAdvisor
ChatModelCallAdvisor
ChatModelCallAdvisor的adviseCall的实现很简单,就是直接调用chatModel的call方法,可以理解为直接和大模型交互了。

因为直接直接要和大模型交互,其实这个advisor的话理论上应该是最后执行的,所以他的getOrder设置的是最低优先级。
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}SimpleLoggerAdvisor
这个是一个内置的日志打印的advisor,adviseCall实现如下:

其实就是在调用下一个advisor之前先记录一下request的日志,在调用之后,再记录一下response的日志。
SafeGuardAdvisor
这是一个spring ai内置的安全审查的advisor,其实主要的实现内容就是做敏感词拦截:

BaseAdvisor
这个是除了以上几个advisor之外,所有其他advisor的接口,他的实现充分的体现了AOP的机制:

在调用下一个advisor之前,先调用自己的before方法,再调用拿到结果之后,再调用自己的after方法。
那么也就是说,我们可以自定义advisor的话,如果想在模型调用前或者调用后做一些其他事情,都可以实现这个接口,比如我们前面用到过很多次的MessageChatMemoryAdvisor
他的before和after实现如下,就是做记忆的记录。

最后,再贴一张spring ai官方给出的advisor的调用流程图:

Q: 在Java项目中集成大模型,用什么框架?
典型回答
在Java应用中想要集成LLM,一般有以下几个选择:
1、自己手撕,直接调用API
2、使用Spring AI
3、使用LangChain4j
4、使用Spring AI Alibaba
5、使用agentscope-java
首先第一个肯定不建议,因为LLM开发的话,一般不仅需要对接模型,还需要做对话记忆、工具调用、RAG等等的,这些如果要自己对接模型API的话,都要从头写一遍,成本太高了。
另外几个框架,Spring AI是比较基础的一个框架,是Spring官方的一个LLM集成框架,但是他的功能非常有限,只有简单的chatMode、ChatClient等基础封装。适合做一些简单的项目使用。
LangChain4j是一个对标Python中的LangChain的框架,但是功能肯定不如LangChain,很多功能都是阉割的,但是他在RAG这方面的支持,比Spring AI要强得的多。如果你想在Java中做一个rag,建议使用LangChain4j
如果你要做Agent开发,尤其是多智能体、复杂的Agent的话,建议使用Spring AI Alibaba或者agentscope-java,这两个都是alibaba推出的智能体框架,方便java开发者构建智能体的,主要区别是Spring AI Alibaba是基于Spring AI做的扩展,主要是为了完善spring ai的能力。agentscope是致力于做智能体搭建的。
以下是我的AI实战课中给大家做的简单总结(暂不包含agentscope):
| 能力 | LangChain4j | Spring AI | Spring AI Alibaba |
| 是否依赖 Spring | ❌ 可独立使用 | ✔️ 深度集成 | ✔️ 深度集成 |
| 模型调用复杂度 | ✔️ 支持高层次API,快速实现LLM调用 | ❌只支持ChatModel和ChatClient | ✔️ 除Spring AI功能外,有更多增强API |
| 结构化输出 | ✔️ 强(JSON Schema) | ✔️ 基础支持 | ✔️ 增强版 |
| RAG 支持 | ✔️ 全链路 | ✔️ 基础 | ✔️ 企业级增强 |
| 智能体(Agent) | ❌ 需手动实现 | ❌ 需手动实现 | ✔️ 基于Graph实现了ReAct,支持 Multi-Agent等。 |
| 工作流编排 | ⚠️ 简单 Chain | ❌ 无 | ✔️ Graph 引擎(核心优势) |
| 阿里云集成 | ✔️ Qwen/DashScope | ❌ 无官方支持 | ✔️ 深度集成(百炼、OSS、Nacos) |
| 生产可观测性 | ⚠️ 需自行集成 | ✔️ Micrometer | ✔️ ARMS/SLS 原生 |
| 生态依赖 | ✔️ 我依赖要求 | ✔️ 我依赖要求 | ⚠️依赖阿里百炼 |
非 Spring/或者Spring Boot版本低于3.0,纯Java项目项目→ 选 LangChain4j
**需要快速原型验证,且熟悉 LangChain 概念 **→ 选 LangChain4j
已有 Spring Boot 项目,只需简单 LLM 调用→ 选 Spring AI
构建企业级RAG→ 选LangChain4j
构建企业级、多步骤、多角色协作的 AI 应用/Agent → 选 Spring AI Alibaba
想用 Java 但又想要接近 Python LangChain 的体验 → LangChain4j 是最佳选择