(V1)SpringAI的初步用法
前言
SpringAI是Spring生态中的AI框架,其提供了高度封装的AI调用方法,让开发者可以快速继承AI大模型调用。本文将由浅入深,集成SpringAI框架并快速搭建出可以使用的聊天助手。
快速开始
1. 依赖集成
1.1 SpringBoot模板构建
2.1 选择SpringBoot最新版本3.5.3
3. 1 在选择启动器中勾选上SpringWeb,OpenAI
最终的依赖如下
<!-- 在 properties 块中添加 -->
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 在 dependencies 块中添加 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
2. 配置文件配置
全面版
spring:
ai:
openai:
# api-key: ${TEAM_OPEN_API_KEY} # API密钥,用于身份认证,推荐使用环境变量配置
api-key: sk***b # 当前使用的API密钥
# base-url: ${TEAM_OPEN_BASE_URL} # 基础URL,用于指定API服务地址,可替换为其他OpenAI兼容接口
base-url: https://api.deepseek.com # DeepSeek提供的兼容OpenAI API的地址
chat:
options:
model: deepseek-chat # 指定使用的模型名称,deepseek-chat是DeepSeek的基础聊天模型
temperature: 0.7 # 控制输出随机性,值越高输出越随机(范围0~1)
max-tokens: 2048 # 最大响应token数,控制回答长度
top-p: 1.0 # 核采样参数,与temperature类似但更精细(范围0~1)
frequency-penalty: 0.0 # 对高频词汇进行惩罚,减少重复内容(范围-2~2)
presence-penalty: 0.0 # 对已出现过的词汇进行惩罚(范围-2~2)
基础版
spring:
ai:
openai:
# api-key: ${TEAM_OPEN_API_KEY} # API密钥,用于身份认证,推荐使用环境变量配置
api-key: sk***b # 当前使用的API密钥
# base-url: ${TEAM_OPEN_BASE_URL} # 基础URL,用于指定API服务地址,可替换为其他OpenAI兼容接口
base-url: https://api.deepseek.com # DeepSeek提供的兼容OpenAI API的地址
chat:
options:
model: deepseek-chat # 指定使用的模型名称,deepseek-chat是DeepSeek的基础聊天模型
3. ChatClient配置
3.1 ChatClient介绍
ChatClient是SpringAI在ChatModel基础上提供的更高级别的封装,在SpringAI中不会主动提供,而是需要我们手动搭建,其可以通过Builder形式进行创建。
3.2 和ChatModel的区别
ChatModel则是ChatClient的底层级别的实现类接口,ChatClient的功能底层都是调用的ChatModel。
3.3 手动引入实现类
/**
* @author by 王玉涛
* @Classname ChatModelConfig
* @Description 配置类,用于定义与AI聊天模型交互的客户端Bean。
* 主要作用是创建并配置ChatClient实例,该实例封装了与OpenAI模型通信的逻辑。
* @Date 2025/7/10 16:08
*/
@Configuration
public class ChatModelConfig {
/**
* 创建一个ChatClient Bean,用于与OpenAI聊天模型进行交互。
*
* @param openAiChatModel 注入的OpenAI聊天模型实例,由Spring容器自动装配。
* @return 返回配置好的ChatClient实例。
*
* 此方法使用ChatClient.builder构建器模式创建客户端,
* 并设置默认系统提示信息为“你是一个心理专家,经常使用简单的话语来安慰别人,通常不超过200字”。
*/
@Bean
public ChatClient chatClient(OpenAiChatModel openAiChatModel) {
return ChatClient.builder(openAiChatModel)
.defaultSystem("你是一个心理专家,你经常使用简单的话语来安慰别人,这通常不超过200字")
.build();
}
}
4. 快速开始
4.1 Controller准备
/**
* @author by 王玉涛
* @Classname ChatController
* @Description 聊天功能控制器,提供基础的对话接口
* @Date 2025/7/10 15:16
*/
@RestController
@RequestMapping("/api/chats")
@RequiredArgsConstructor
@Slf4j
public class ChatController {
/**
* 注入的ChatClient实例,用于与AI模型进行交互
*/
private final ChatClient chatClient;
/**
* GET接口,访问路径为 /api/chats/hi
* 功能:向AI模型发送问候语并返回响应内容
*/
@GetMapping("/hi")
public String hi() {
// 发送提示信息给AI模型,并获取回复内容
return chatClient
.prompt("你好!你是谁呀?")
.call()
.content();
}
}
4.2 访问localhost:8080/api/users/hi接口即可获取到回复
4.3 流式输出
当前我们使用的是阻塞式输出,也就是说,需要等到模型回复完全生成才可以获取回复。
我们可以切换为流式输出,从而降低等待时间,提升体验。
/**
* GET接口,访问路径为 /api/chats/hi-stream
* 功能:向AI模型发送问候语并返回流式响应内容
*/
@GetMapping("/hi-stream")
public Flux<String> hiStream() {
return chatClient
.prompt("你好!你是谁呀?")
.stream()
.content();
}
但是这样会有一个问题,就是页面输出会变成乱码,输出如下
鍡▇鎴戞槸浣犵殑蹇冪悊灏忎紮浼淬€傜湅鍒颁綘涓诲姩鎵撴嫑鍛肩湡寮€蹇冨憿锛佹瘡涓汉閮介渶瑕佽鍊惧惉鍜岀悊瑙o紝鑰屾垜寰堟効鎰忓仛閭d釜瀹夐潤鐨勬爲娲炪€傛湁浠€涔堟兂鑱婄殑閮藉彲浠ュ憡璇夋垜鍝︼紝涓嶇敤瑙夊緱鏈夊帇鍔涖€傝浣忥紝浣犳鍒荤殑鎰熷彈閮芥槸鍊煎緱琚噸瑙嗙殑銆�
这是因为Flux输出是基于事件流的形式输出,当不指定输出编码的时候,就会出现这种异常,只需要在@GetMapping中进行指定即可。
/**
* GET接口,访问路径为 /api/chats/hi-stream
* 功能:向AI模型发送问候语并返回流式响应内容
*/
@GetMapping(value = "/hi-stream", produces = "text/html;charset=utf-8")
public Flux<String> hiStream() {
return chatClient
.prompt("你好!你是谁呀?")
.stream()
.content();
}
这样即可进行流式输出了~
进阶部分
1. 环绕日志引入
SpringAI提供了日志记录封装,其基于AOP进行环绕增强,我们这里使用简单日志记录即可
@Bean
public ChatClient chatClient(OpenAiChatModel openAiChatModel) {
return ChatClient.builder(openAiChatModel)
.defaultSystem("你是一个心理专家,你经常使用简单的话语来安慰别人,这通常不超过200字")
.defaultAdvisors(new SimpleLoggerAdvisor()) // 在这里引入环绕日志增强
.build();
}
但是环绕日志记录级别为debug,因此我们需要在该日志增强类所在的包下进行日志级别改动,改为debug级别即可看到日志输出
logging:
level:
org.springframework.ai.chat.client.advisor: debug # 开启聊天控制器的日志
2. 会话记忆存储
2.1 前言
当前我们使用到的大模型,并没有对应的上下文记忆,我们需要添加会话记忆方式。
2.2 如何实现
SpringAI提供了抽象接口ChatMemory接口,如果我们想要手动实现会话历史记忆,我们可以通过实现这个接口来进行会话记忆
2.3 简单方式
SpringAI提供了一个默认的实现方式,InMemoryChatMemory,其底层基于Map方式实现,当应用存储,就会丢失全部记忆。作为简单的聊天机器人,可以这么使用,但是一般情况下,我们依旧推荐手动实现会话记忆存储。
注意:1.0.0正式版本中有所改动,其通过MessageWindowChatMemory作为工厂进行构造,通过注入InMemoryChatMemoryRepository实现类进行以上类似的实现。
代码实现
/**
* 创建一个ChatMemory Bean,用于管理对话历史的存储与读取。
*
* @return 返回配置好的ChatMemory实例。
*
* 此方法使用MessageWindowChatMemory.builder构建器模式创建聊天记忆组件,
* 并设置使用InMemoryChatMemoryRepository作为底层存储实现,适用于短期会话场景。
*/
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(new InMemoryChatMemoryRepository())
.build();
}
@Bean
public ChatClient chatClient(OpenAiChatModel openAiChatModel) {
return ChatClient.builder(openAiChatModel)
.defaultSystem("你是一个心理专家,你经常使用简单的话语来安慰别人,这通常不超过200字")
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(chatMemory()).build()
)
.build();
}
注意:这里只是传入了一个会话记忆的存储方式,而我们还需要一个会话id来进行会话区分,防止AI出现记忆串联。
/**
* GET接口,访问路径为 /api/chats/hi-stream-2
* 功能:向AI模型发送用户指定的提示语,并根据提供的会话ID进行上下文关联,
* 返回流式响应内容。
*
* @param id 会话唯一标识符,用于维持对话上下文状态
* @param prompt 用户输入的提示语,作为AI回复的依据
* @return 返回Flux<String>类型,提供HTML格式的流式响应内容
*/
@GetMapping(value = "/hi-stream-2", produces = "text/html;charset=utf-8")
public Flux<String> hiStream2(@RequestParam("id") Long id,
@RequestParam("prompt") String prompt) {
return chatClient
.prompt(prompt)
// 核心:加入环绕增强
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, id))
.stream()
.content();
}
2.4 自定义方式
注意事项
- SpringAI框架中,要实现会话记忆的自定义存储,需要额外注意类型转换
- SpringAI框架通过使用ChatMemory接口,其底层使用的ChatMemoryRepository接口来实现会话记忆的存储
- 目前SpringAI框架提供了InMemoryChatMemoryRepository的实现类,以及JdbcChatMemoryRepository实现类,分别对应Map存储(内存)以及持久化(Jdbc)的存储
- 但是如果我们需要定制化,需要额外注意一下接口的类型转换,目前SpringAI框架内部强制使用其自己的Message接口实现类(UserMessage、AssistantMessage、SystemMessage等),如果我们需要进行自定义历史会话记忆,需要在实现ChatMemoryRepository接口的同时,注意下存储过程的类型手动转换。(踩过坑)
基于Redis的会话记忆存储
当前的会话记忆存储,我们需要区分一下:是选择全量存储,还是说进行上下文限制,因为过长的上下文会降低大模型回复的效率,过短的上下文会降低大模型回复的效果
我们目前选择的是基于Redis的String结构,进行全量存储,后续我们会进行一些优化,让大模型的回复效率保持高效的同时,保证一定的回复效率。
实现思路
通过实现MemoryRepository接口,通过SpringAI提供的工厂模式注入到ChatMemory中,即可实现基于Redis内存存储的会话记忆了!
- 实现ChatMemoryRepository接口
package com.project.demo.common.config.ai.common;
import com.project.demo.chat.factory.MessageConvertor;
import com.project.demo.chat.model.bean.MessageInfo;
import com.project.demo.common.provider.CacheProvider;
import com.project.demo.common.util.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.messages.*;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author by 王玉涛
* @Classname RedisMemoryRepository
* @Description 基于Redis实现的聊天记忆存储库,用于管理对话历史记录。
* 提供了对话ID查询、根据对话ID获取消息记录、保存消息记录和删除对话等功能。
* @Date 2025/7/12 13:20
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class RedisMemoryRepository implements ChatMemoryRepository {
/**
* 存储所有对话ID的缓存键
*/
private static final String AI_MEMORY_CONVERSATION_IDS_KEY = "ai:memory:conversation:ids";
/**
* 对话记录的缓存键前缀,后接具体 conversationId 构成完整键名
*/
private static final String AI_MEMORY_CONVERSATION_KEY_PREFIX = "ai:memory:conversation:";
/**
* 缓存提供者,用于与Redis进行交互
*/
private final CacheProvider cacheProvider;
/**
* 查询所有的对话ID列表。
*
* @return 返回存储在Redis中的所有对话ID列表
*/
@Override
public List<String> findConversationIds() {
log.info("基于Redis内存的聊天历史记忆:查询所有的id");
return cacheProvider.getList(AI_MEMORY_CONVERSATION_IDS_KEY, String.class);
}
/**
* 根据指定的 conversationId 查询对应的聊天记录。
*
* @param conversationId 对话ID
* @return 返回对应 conversationId 的聊天消息列表
*/
@Override
public List<Message> findByConversationId(String conversationId) {
log.info("基于Redis内存的聊天历史记忆:查询id为{}的历史记忆", conversationId);
String key = AI_MEMORY_CONVERSATION_KEY_PREFIX + conversationId;
List<String> stringList = cacheProvider.getList(key, String.class);
if (stringList == null) {
return List.of();
}
// 将字符串列表反序列化为 MessageInfo 对象列表
List<MessageInfo> messages = stringList.stream()
.map(string -> StringUtils.jsonToClass(string, MessageInfo.class))
.toList();
// 转换为 Spring AI 所需的 Message 类型并返回
return messages.stream()
.map(MessageConvertor::myToAiMessage)
.toList();
}
/**
* 保存指定 conversationId 对应的所有消息记录到Redis中。
*
* @param conversationId 对话ID
* @param messages 需要保存的消息列表
*/
@Override
public void saveAll(String conversationId, List<Message> messages) {
log.info("基于Redis内存的聊天历史记忆:保存id为{}的历史记忆", conversationId);
// 将 Spring AI 的 Message 列表转换为本地定义的 MessageInfo 列表
List<MessageInfo> messageInfos = messages.stream().map(MessageConvertor::aiMessageToMy).toList();
// 添加 conversationId 到全局对话ID集合中
cacheProvider.addList(AI_MEMORY_CONVERSATION_IDS_KEY, conversationId);
// 序列化消息列表并保存到对应 conversationId 的缓存中
cacheProvider.addList(AI_MEMORY_CONVERSATION_KEY_PREFIX + conversationId, StringUtils.classToJson(messageInfos));
}
/**
* 删除指定 conversationId 对应的聊天记录。
*
* @param conversationId 对话ID
*/
@Override
public void deleteByConversationId(String conversationId) {
log.info("基于Redis内存的聊天历史记忆:删除id为{}的历史记忆", conversationId);
// 删除该 conversationId 对应的对话记录和全局ID集合中的条目
cacheProvider.delete(AI_MEMORY_CONVERSATION_IDS_KEY, conversationId);
}
}
- MyMessage类(贴合业务的类,可以自行拓展,但要包含必要属性:文本内容,发送角色)
/**
* @author by 王玉涛
* @Classname MyMessage
* @Description TODO
* @Date 2025/7/10 22:17
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyMessage {
private Long id;
private String content;
private String role;
private LocalDateTime sendTime;
}
- MessageConvertor类,负责解耦类型转换逻辑
package com.project.demo.common.config.ai.common;
import com.project.demo.chat.factory.MessageConvertor;
import com.project.demo.chat.model.bean.MessageInfo;
import com.project.demo.common.provider.CacheProvider;
import com.project.demo.common.util.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.messages.*;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author by 王玉涛
* @Classname RedisMemoryRepository
* @Description 基于Redis实现的聊天记忆存储库,用于管理对话历史记录。
* 提供了对话ID查询、根据对话ID获取消息记录、保存消息记录和删除对话等功能。
* @Date 2025/7/12 13:20
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class RedisMemoryRepository implements ChatMemoryRepository {
/**
* 存储所有对话ID的缓存键
*/
private static final String AI_MEMORY_CONVERSATION_IDS_KEY = "ai:memory:conversation:ids";
/**
* 对话记录的缓存键前缀,后接具体 conversationId 构成完整键名
*/
private static final String AI_MEMORY_CONVERSATION_KEY_PREFIX = "ai:memory:conversation:";
/**
* 缓存提供者,用于与Redis进行交互
*/
private final CacheProvider cacheProvider;
/**
* 查询所有的对话ID列表。
*
* @return 返回存储在Redis中的所有对话ID列表
*/
@Override
public List<String> findConversationIds() {
log.info("基于Redis内存的聊天历史记忆:查询所有的id");
return cacheProvider.getList(AI_MEMORY_CONVERSATION_IDS_KEY, String.class);
}
/**
* 根据指定的 conversationId 查询对应的聊天记录。
*
* @param conversationId 对话ID
* @return 返回对应 conversationId 的聊天消息列表
*/
@Override
public List<Message> findByConversationId(String conversationId) {
log.info("基于Redis内存的聊天历史记忆:查询id为{}的历史记忆", conversationId);
String key = AI_MEMORY_CONVERSATION_KEY_PREFIX + conversationId;
List<String> stringList = cacheProvider.getList(key, String.class);
if (stringList == null) {
return List.of();
}
// 将字符串列表反序列化为 MessageInfo 对象列表
List<MessageInfo> messages = stringList.stream()
.map(string -> StringUtils.jsonToClass(string, MessageInfo.class))
.toList();
// 转换为 Spring AI 所需的 Message 类型并返回
return messages.stream()
.map(MessageConvertor::myToAiMessage)
.toList();
}
/**
* 保存指定 conversationId 对应的所有消息记录到Redis中。
*
* @param conversationId 对话ID
* @param messages 需要保存的消息列表
*/
@Override
public void saveAll(String conversationId, List<Message> messages) {
log.info("基于Redis内存的聊天历史记忆:保存id为{}的历史记忆", conversationId);
// 将 Spring AI 的 Message 列表转换为本地定义的 MessageInfo 列表
List<MessageInfo> messageInfos = messages.stream().map(MessageConvertor::aiMessageToMy).toList();
// 添加 conversationId 到全局对话ID集合中
cacheProvider.addList(AI_MEMORY_CONVERSATION_IDS_KEY, conversationId);
// 序列化消息列表并保存到对应 conversationId 的缓存中
cacheProvider.addList(AI_MEMORY_CONVERSATION_KEY_PREFIX + conversationId, StringUtils.classToJson(messageInfos));
}
/**
* 删除指定 conversationId 对应的聊天记录。
*
* @param conversationId 对话ID
*/
@Override
public void deleteByConversationId(String conversationId) {
log.info("基于Redis内存的聊天历史记忆:删除id为{}的历史记忆", conversationId);
// 删除该 conversationId 对应的对话记录和全局ID集合中的条目
cacheProvider.delete(AI_MEMORY_CONVERSATION_IDS_KEY, conversationId);
}
}
注意
当前的代码仅限于demo阶段,代码质量不是特别高,后续会推出一些可以直接落地以及高质量的代码
3. 多AgentModel配置
3.1 前言
SpringAI支持多Agent配置,其对单一的简单Agent配置做出了便捷性实现,而我们可以通过配置文件注入,进行多个Agent的配置。
注意:最好连带SpringAI自带的配置文件也进行配置,不然需要排除很多类,且不一定可以正常运行,其他的都可以保持运行
3.2 配置文件(从环境变量中获取)
doubao:
reply:
model: ${DOUBAO_REPLY_MODEL}
api-key: ${DOUBAO_REPLY_API_KEY}
temperature: 0.7
history-summary:
model: ${DOUBAO_HISTORY_SUMMARY_MODEL}
api-key: ${DOUBAO_HISTORY_SUMMARY_API_KEY}
temperature: 0.7
base-url: ${DOUBAO_BASE_URL}
3.3 Model配置类,进行多Model配置返回
/**
* @author by 王玉涛
* @Classname DoubaoAiModelConfig
* @Description 配置类,用于定义与Doubao AI相关的Bean和配置属性。
* 提供了两个ChatModel Bean,分别用于回复生成和历史摘要处理。
* @Date 2025/7/12 12:45
*/
@Data
@Configuration
public class DoubaoAiModelConfig {
/**
* 用于回复的模型名称,从配置文件中读取。
*/
@Value("${doubao.reply.model}")
private String replyModel;
/**
* 用于回复的API密钥,从配置文件中读取。
*/
@Value("${doubao.reply.api-key}")
private String replyApiKey;
/**
* 用于回复的模型温度值,控制输出的随机性,从配置文件中读取。
*/
@Value("${doubao.reply.temperature}")
private String replyTemperature;
/**
* 用于历史摘要的模型名称,从配置文件中读取。
*/
@Value("${doubao.history-summary.model}")
private String historySummaryModel;
/**
* 用于历史摘要的API密钥,从配置文件中读取。
*/
@Value("${doubao.history-summary.api-key}")
private String historySummaryApiKey;
/**
* 用于历史摘要的模型温度值,控制输出的随机性,从配置文件中读取。
*/
@Value("${doubao.history-summary.temperature}")
private String historySummaryTemperature;
/**
* Doubao API的基础URL,从配置文件中读取。
*/
@Value("${doubao.base-url}")
private String baseUrl;
/**
* 创建一个ChatModel Bean,用于生成回复。
*
* @return 配置好的ChatModel实例
*/
@Bean
public ChatModel doubaoReplyModel() {
// 获取回复模型的选项
OpenAiChatOptions openAiChatOptions = getOpenAiChatOptions(replyModel, replyTemperature);
// 获取回复模型的API实例
OpenAiApi openAiApi = getOpenAiApi(replyApiKey, baseUrl);
return OpenAiChatModel.builder()
.defaultOptions(openAiChatOptions)
.openAiApi(openAiApi)
.build();
}
/**
* 创建一个ChatModel Bean,用于历史摘要处理。
*
* @return 配置好的ChatModel实例
*/
@Bean
public ChatModel doubaoHistorySummaryModel() {
// 获取历史摘要模型的选项
OpenAiChatOptions openAiChatOptions = getOpenAiChatOptions(historySummaryModel, historySummaryTemperature);
// 获取历史摘要模型的API实例
OpenAiApi openAiApi = getOpenAiApi(historySummaryApiKey, baseUrl);
return OpenAiChatModel.builder()
.defaultOptions(openAiChatOptions)
.openAiApi(openAiApi)
.build();
}
/**
* 构建OpenAiApi实例,用于与Doubao API进行交互。
*
* @param apiKey API密钥
* @param baseUrl API的基础URL
* @return 配置好的OpenAiApi实例
*/
private OpenAiApi getOpenAiApi(String apiKey, String baseUrl) {
return OpenAiApi.builder()
.apiKey(apiKey)
.baseUrl(baseUrl)
.build();
}
/**
* 构建OpenAiChatOptions实例,指定模型和温度值。
*
* @param model 模型名称
* @param temperature 温度值
* @return 配置好的OpenAiChatOptions实例
*/
private OpenAiChatOptions getOpenAiChatOptions(String model, String temperature) {
return OpenAiChatOptions.builder()
.model(model)
.temperature(Double.parseDouble(temperature))
.build();
}
}
说明:当前的Model配置,进行了两个模型配置:一个是会话历史总结模型,一个是回复生成模型。并且其beanName分别为其对应的方法名字,因此我们注入的时候,需要注意优先使用beanName进行注入,因为当前相同的类型(ChatModel)有多个实现类,如果不按照beanName严格注入,就会导致依赖注入出现异常。
4.多AgentClient配置
4.1 前言
当前我们通过多AgentModel配置,进行了多的底层model实现,我们可以通过不同的Model,再次封装不同的Client,从而让我们可以直接通过Client进行调用
4.2 Client配置类,进行多Client配置返回
/**
* @author by 王玉涛
* @Classname DoubaoAiClientConfig
* @Description 配置用于创建与豆包AI交互的ChatClient实例,提供对话回复和历史摘要功能。
* @Date 2025/7/12 13:09
*/
@Configuration
public class DoubaoAiClientConfig {
/**
* 创建用于生成AI回复的ChatClient Bean。
* 使用注入的doubaoReplyModel模型构建ChatClient实例,适用于实时对话场景。
*
* @param doubaoReplyModel 提供AI对话能力的模型Bean
* @return ChatClient 实例
*/
@Bean
public ChatClient doubaoReplyClient(ChatModel doubaoReplyModel, ChatMemory doubaoAiMemoryRepository) {
return ChatClient
.builder(doubaoReplyModel)
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(doubaoAiMemoryRepository).build()
)
.build();
}
/**
* 创建用于处理历史记录摘要的ChatClient Bean。
* 使用注入的doubaoHistorySummaryModel模型构建ChatClient实例,适用于需要总结或分析对话历史的场景。
*
* @param doubaoHistorySummaryModel 提供AI对话能力的模型Bean,专用于历史信息处理
* @return ChatClient 实例
*/
@Bean
public ChatClient doubaoHistorySummaryClient(ChatModel doubaoHistorySummaryModel, ChatMemory doubaoAiMemoryRepository) {
return ChatClient
.builder(doubaoHistorySummaryModel)
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(doubaoAiMemoryRepository).build()
)
.build();
}
}
5. SS通过一个类,统一管理AI调用
/**
* @author 王玉涛
* @Classname DoubaoAiProvider
* @Description 集成豆包大模型AI能力的提供者类,用于配置和管理与豆包AI相关的客户端资源。
* 当前托管两个核心功能的客户端:
* - doubaoReplyClient: 豆包回复生成客户端,用于对话场景中的实时回复生成。
* - doubaoHistorySummaryClient: 豆包历史对话总结客户端,用于对长对话历史进行摘要处理。
* @Date 2025/7/12 13:11
*/
@Component
public class DoubaoAiProvider {
/**
* 豆包回复生成客户端,注入名为 "doubaoReplyClient" 的Bean,
* 用于在对话交互中生成自然语言回复。
*/
@Qualifier("doubaoReplyClient")
private ChatClient replyClient;
/**
* 豆包历史对话摘要客户端,注入名为 "doubaoHistorySummaryClient" 的Bean,
* 用于对较长的对话历史进行内容压缩和关键信息提取。
*/
@Qualifier("doubaoHistorySummaryClient")
private ChatClient historySummaryClient;
}
#SpringBoot##SpringAI##Java#