Spring AI 官方文档地址:
https://docs.springframework.org.cn/spring-ai/reference/index.html
Spring AI 的依赖管理:
-
在 Spring AI 中有一个依赖管理器
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.1.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> -
常用的阿里云的依赖管理
<dependencyManagement> <!-- 阿里百炼的版本管理 --> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-bom</artifactId> <version>1.0.0.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
常用的 Spring AI 的接口:
- ChatClient 是面向"聊天模型"最核心的统一接口
|-------------------------|-------------------------------------------------------------------------------------------------|
| 能力 | 说明 |
| 同步单轮 | call(String) 直接拿到字符串答案,适合最简单场景。 |
| 多轮/系统提示 | Prompt 可以塞 List<Message> (UserMessage 、SystemMessage 、AssistantMessage ...),天然支持多轮会话。 |
| 流式 SSE | stream() 返回 Flux<String> ,前端边接收边渲染,体验跟官网一样。 |
| 高级参数 | Prompt 里可携带 ChatOptions (温度、top-k、stopSequences、responseFormat、tools...)。 |
| 函数调用 / Tool Calling | 通过 Prompt 携带 ToolDefinition ,模型返回 tool_calls ,再由框架反序列化回调 Java 方法。 |
| 多候选 / 打分 | ChatResponse.getChoices() 可一次性拿 N 条候选,并带 finishReason 、index 、safetyRating 等元数据。 |
Spring AI 继承不同的模型和平台
-
把不同的模型和平台注入 Bean 中
package com.spring.springaionejava.springailearn01.config;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/**
*使用多个 AI 模型时,您可以为每个模型定义单独的 ChatClient bean
*/
@Configuration
public class ChatClientConfig {/** * 创建一个 ChatClient bean * 阿里平台 * @param chatModel * @return */ @Bean public ChatClient aliyuChatClient(DashScopeChatModel chatModel) { System.out.println("创建一个 ChatClient bean,名字叫aliyuChatClient"); return ChatClient.create(chatModel); } /** * 创建一个 ChatClient bean * deepseek平台 */ @Bean public ChatClient deepSeekChatClient(DeepSeekChatModel chatModel) { System.out.println("创建一个 ChatClient bean,名字叫deepSeekChatClient"); return ChatClient.create(chatModel); }}
-
使用可以通过@Qualifier 用于精确指定要注入的 Bean
|-------------------|-------------------------|
| 场景 | 是否需要 @Qualifier |
| 只有一个该类型的 Bean | ❌不需要 |
| 有多个该类型的 Bean | ✅必须使用 |
-
测试类
@Autowired @Qualifier("aliyuChatClient") private ChatClient aliyuChatClient; @Test public void test01(){ try { String content = aliyuChatClient.prompt("你是谁").call().content(); System.out.println(content); } catch (Exception e) { System.err.println("调用 AI 接口失败: " + e.getMessage()); if (e.getMessage() != null && e.getMessage().contains("InvalidApiKey")) { System.err.println("错误原因: API Key 无效或已过期,请检查 application-dev.properties 中的 spring.ai.dashscope.api-key 配置"); } throw e; // 重新抛出异常,让测试失败,但会显示更清晰的错误信息 } }
Spring AI 多模型的切换
- 在一个系统里可以同时接入多个大模型,并根据需要随时切换调用。就像你的程序可以随时选择用「deepseek」、或「qwen」、或「openai」来回答问题。
代码实例:
-
首先需要将你的模型注入到 spring 容器中
package com.spring.springaionejava.springaiagriculture.config;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/**
*多模型配置类-
@Author: 空门:门主
*/
@Slf4j
@Configuration
public class MultipleModelsChatClientConfig {/**
- 创建一个 ChatClient bean
- 阿里平台
- @param chatModel
- @return
*/
@Bean
public ChatClient qwenPlus(DashScopeChatModel chatModel, ChatMemory chatMemory) {
log.warn("qwenPlus模型以注入");
return ChatClient.builder(chatModel)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) // 初始化,将chatMemory注册到ChatClient中去
.build();
}
/**
- 创建一个 ChatClient bean
- deepseek平台
*/
@Bean
public ChatClient deepSeekV3(DeepSeekChatModel chatModel) {
log.warn("deepSeekV3模型以注入");
return ChatClient.create(chatModel);
}
}
-
-
注入一个 Map 用来接收模型名称
@Resource private Map<String, ChatClient> chatClientMap; @Test public void testPromptTemplates() { /** * text:是输入的文本内容 param:是要替换的参数 (占位符) */ String conversationId = "007"; String result = chatClientMap.get("qwenPlus").prompt()// .system(systemAgricultureMessage) //系统提示语
.user(u->u.text("现在是什么时间,{time}").param("time","12:00")) //用户输入
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId))//保存聊天记忆
.call()
.content();
System.out.println(result);}
Spring AI 中的 ChatClient 是什么?主要能做什么?(正式学习 Spring AI)
简单说: ChatClient 是 Spring AI 用来「调用大模型」的核心客户端
概括:ChatClient 就是你在 Spring 框架里用来和大模型(LLM)对话的"客户端工具"。它负责把你的 Prompt 发给模型,并把模型的回答返回给你
你可以把它理解为:
- Spring AI 里的大模型调用入口
- 封装好的统一聊天接口
- 调用 OpenAI /DeepSeek /Qwen 等模型的标准通道
上面代码出现了 chatModel 有人会问chatModel 又是什么?
概括:ChatModel 是具体的模型 api
ChatClient 和 ChatModel 的区别
|----------------|--------------------------------------------------|--------------------------------|
| 组件 | 是什么 | 作用 |
| ChatModel | 对接具体模型的 API,例如 DeepSeekChatModel、OpenAiChatModel | 底层"模型驱动引擎" |
| ChatClient | 封装调用接口 | 统一操作入口(Prompt、Memory、RAG、流式输出) |
简单理解:
👉 ChatModel = 发起请求的 driver
👉 ChatClient = 真正用起来的工具、入口
ChatClient 主要做什么?
- 发送用户消息给大模型
- 统一不同大模型的调用方式
- 支持系统提示词(system prompt)
- 支持聊天记忆(ChatMemory)
- 支持知识库 QA(Vector Store) 也就是 RAG 功能
- 支持流式输出(SSE / WebFlux
Chat Client API (聊天客户端 API)
创建多个聊天模型:
- 就是将每个模型定义单独的
ChatClientBean; ChatClient是一个接口类,提供了create 和builder 模型的方法
实例:
package com.spring.springaionejava.springailearn01.config;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*使用多个 AI 模型时,您可以为每个模型定义单独的 ChatClient bean
*/
@Configuration
public class ChatClientConfig {
/**
* 创建一个 ChatClient bean
* 阿里平台
* @param chatModel
* @return
*/
@Bean(name = "aliyuChatClient")
public ChatClient aliyuChatClient(DashScopeChatModel chatModel) {
System.out.println("创建一个 ChatClient bean,名字叫aliyuChatClient");
return ChatClient.create(chatModel);
}
/**
* 创建一个 ChatClient bean
* deepseek平台
*/
@Bean
public ChatClient deepSeekChatClient(DeepSeekChatModel chatModel) {
System.out.println("创建一个 ChatClient bean,名字叫deepSeekChatClient");
return ChatClient.create(chatModel);
}
}
介绍一下ChatClient 接口类中的prompt 接口:
一句话总结:
prompt()是 ChatClient 用来构建对话请求(Prompt)的入口,它返回一个 PromptSpec,允许你设置 system、user、assistant 内容,并最终发起模型调用。
Spring AI 提供的 prompt() 方法,允许你一步步设置:
- system(系统角色)
- user(用户输入)
- assistant(上一次对话)
- metadata(额外信息)
- advisors(记忆、RAG)
- options(模型参数)
ChatClient Responses ChatClient 响应
- 返回 ChatResponse;不仅有文本回答,还会包含:
-
token 使用情况
-
模型名称
-
响应消息(带角色)
-
附加的 diagnostic 信息
-
多轮消息结构
-
可能包含多个候选回答(choices)
ChatResponse chatResponse = chatClient.prompt()
.user("Tell me a joke")
.call()
.chatResponse();
- Returning an Entity 返回实体
-
返回的是一个结构化、可扩展、可序列化、可持久化的数据对象。
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);
- Streaming Responses 流式响应
-
流式响应返回实体(Streaming Response Entity)是为了让服务器能够以"分段、实时、不断推送"的方式,把大模型的回答一块一块地发给前端,而不是一次性返回。
-
stream()方法允许您获得异步响应。Flux<String> output = chatClient.prompt()
.user("Tell me a joke")
.stream()
.content();
Prompt Templates 提示模板
1. text、param 、metadata 的用法
- text(消息内容):
-
实际是发送给大模型的文本内容;可以用在 system 和 user 中;
-
text 一般是和param 一起用的
.prompt()
.system(s -> s.text("你是一名农业专家"))
.user(u -> u.text("什么是玉米锈病?"))
- param(参数变量)
-
param 是用来做提示词模板变量替换的
-
用于替换 text 中的变量值
.prompt()
.system(s -> s
.text("你是一名{{profession}}专家")
.param("profession", "农业"))
- metadata(额外附加信息)
- 不会发送给大模型,只供程序员/Adcisor 使用的元数据
- 作用:可以用来对消息进行标记或者过滤;控制不同提示词版本等
注意:1.1.0 之前的版本没有 metadata
.system(s -> s.text("你是专家").metadata("version", "1.0"))
.user(u -> u.text("天气怎么样").metadata("requestId", "abc123"))