大家好,我是小肥阳,今天将通过使用Spring AI Alibaba搭建一个聊天对话和带记忆功能的聊天对话,来跟着大家一起入门Spring AI Alibaba。
一、环境与依赖
这是我所使用的核心框架版本:
- JDK 版本:17
- Spring Boot 版本:3.5.3
- SpringAI 版本:1.0.0
- SpringAI-alibaba 版本:1.0.0.2
依赖导入
Spring AI Alibaba 是在 Spring AI 基础上进行扩展和深化的,因此我们需要同时在 pom.xml 中引入Sping AI相关依赖。以下是具体的依赖配置:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>1.0.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.5.3</version>
</dependency>
二、配置说明
在 application.yml
中配置阿里云 DashScope 的 API Key 及模型:
yaml
spring:
ai:
dashscope:
api-key: ${AI_DASHSCOPE_API_KEY}
chat:
options:
model: qwen-plus
三、简单聊天功能实现与使用
1. 实现说明
- 通过
ChatClient
Bean 实现简单的文本聊天。 - 控制器
ChatClientController
提供/client/chat
接口。
代码实现:
在配置类中配置 ChatClient
Bean:
scss
@Configuration
public class ChatClientConfig {
@Bean("chatClient")
public ChatClient chatClient(ChatModel chatModel) {
return ChatClient.builder(chatModel)
.defaultSystem("You are a helpful assistant.")
.defaultAdvisors(new SimpleLoggerAdvisor())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())
.build();
}
}
Controller层接口实现:
less
@RestController
@RequestMapping("/client")
public class ChatClientController {
@Autowired
private ChatClient chatClient;
@GetMapping("/chat")
public String chat(@RequestParam(defaultValue = "你好,我是小肥阳,你是哪位?") String prompt) {
return chatClient.prompt(prompt).call().content();
}
}
2. 使用方式
- 直接 GET 请求:
rust
curl 'http://localhost:8080/client/chat?prompt=你好,介绍一下你自己'
- 返回内容为 AI 的回复。
四、带记忆的多轮聊天功能实现与使用
1. 实现说明
- 通过
ChatClientWithMemory
Bean 结合MessageWindowChatMemory
实现多轮对话记忆。 - 控制器
ChatClientController
提供/client/memory/chat
、/client/memory/history
、/client/history
等接口。 - 记忆通过
conversationId
进行区分。
代码实现:
在配置类中配置 ChatClientWithMemory
Bean:
kotlin
package com.example.chat.controller;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatClientConfig {
@Bean
public MessageWindowChatMemory messageWindowChatMemory() {
InMemoryChatMemoryRepository inMemoryChatMemoryRepository = new InMemoryChatMemoryRepository();
return MessageWindowChatMemory.builder()
.chatMemoryRepository(inMemoryChatMemoryRepository)
.maxMessages(10)
.build();
}
@Bean("chatClientWithMemory")
public ChatClient chatClientWithMemory(ChatModel chatModel) {
return ChatClient.builder(chatModel)
.defaultSystem("You are a helpful assistant.")
.defaultAdvisors(new SimpleLoggerAdvisor())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())
.build();
}
}
在Controller中新增如下方法实现带记忆的多轮对话功能:
less
@RestController
@RequestMapping("/client")
public class ChatClientController {
@Resource(name = "chatClientWithMemory")
private ChatClient chatClientWithMemory;
@Resource
private MessageWindowChatMemory messageWindowChatMemory;
/**
* 带记忆功能的聊天接口
* 通过conversationId维护对话上下文,实现多轮对话的记忆功能
*
* @param conversationId 对话 ID,用于标识不同的对话上下文
* @param prompt 用户输入的提示词,默认值为"你好,我是小肥阳,你是哪位?"
* @return AI基于对话历史和当前提示词的回复内容
*/
@GetMapping("/memory/chat")
public String memoryChat(@RequestParam(defaultValue = "conversationId") String conversationId,
@RequestParam(defaultValue = "你好,我是小肥阳,你是哪位?") String prompt) {
return chatClientWithMemory.prompt()
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, conversationId))
.user(prompt)
.call()
.content();
}
/**
* 获取对话历史记录接口
* 根据sessionId获取该会话的所有聊天记录
*
* @param conversationId 会话ID,用于标识特定的聊天会话
* @return 该会话的历史消息列表
*/
@GetMapping("/memory/history")
public List<Message> history(@RequestParam String conversationId) {
return messageWindowChatMemory.get(conversationId);
}
/**
* 清除对话历史记录接口
* 根据conversationId清除对应的聊天记录
*
* @param conversationId 会话ID,用于标识需要清除记录的特定会话
* @return 操作结果提示信息
*/
@DeleteMapping("/history")
public String clear(@RequestParam String conversationId) {
messageWindowChatMemory.clear(conversationId);
return "聊天记录已清除~";
}
}
2. 使用方式
- 进行多轮对话:
rust
curl 'http://localhost:8080/client/memory/chat?conversationId=test1&prompt=你好,我是小肥阳,你是哪位'
curl 'http://localhost:8080/client/memory/chat?conversationId=test1&prompt=我是谁?'
- 获取对话历史:
rust
curl 'http://localhost:8080/client/memory/history?conversationId=test1'
- 清除对话历史:
rust
curl -X DELETE 'http://localhost:8080/client/history?conversationId=test1'
五、主要对象说明
为了更好地理解代码,下面对主要对象进行详细说明:
- ChatClient:SpringAI 提供的聊天客户端,封装了与大模型的交互。
- ChatClientWithMemory:集成了记忆功能的聊天客户端,支持多轮上下文。
- InMemoryChatMemoryRepository :内存型对话历史存储仓库,配合 MessageWindowChatMemory 使用,适合开发测试环境,生产建议替换为持久化实现(如
Redis、数据库等)。 - MessageWindowChatMemory:基于窗口的对话记忆管理器,可设置最大记忆消息数,自动维护最近 N 条消息,便于多轮对话上下文管理。
- Message:消息对象,表示一次对话中的一条消息,支持用户、AI等多种角色,包含文本、图片等内容。
- MessageChatMemoryAdvisor :SpringAI 的对话记忆顾问,负责将 MessageWindowChatMemory 等记忆能力集成到
ChatClient,实现多轮对话上下文自动注入。 - ChatModel :SpringAI 的核心聊天模型接口,封装了底层大模型的调用能力,支持同步、异步、流式等多种对话方式,是 ChatClient
的底层依赖。 - DashScopeChatOptions:阿里云 DashScope 聊天参数配置对象,可指定模型、温度、topP、多模态等高级参数,灵活控制对话行为。
六、项目完整代码
1. ChatClientConfig.java(配置类)
kotlin
package com.example.chat.config;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatClientConfig {
@Bean
public MessageWindowChatMemory messageWindowChatMemory() {
InMemoryChatMemoryRepository inMemoryChatMemoryRepository = new InMemoryChatMemoryRepository();
return MessageWindowChatMemory.builder()
.chatMemoryRepository(inMemoryChatMemoryRepository)
.maxMessages(10)
.build();
}
@Bean("chatClient")
public ChatClient chatClient(ChatModel chatModel) {
return ChatClient.builder(chatModel)
.defaultSystem("You are a helpful assistant.")
.defaultAdvisors(new SimpleLoggerAdvisor())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())
.build();
}
@Bean("chatClientWithMemory")
public ChatClient chatClientWithMemory(ChatModel chatModel, MessageWindowChatMemory messageWindowChatMemory) {
return ChatClient.builder(chatModel)
.defaultSystem("You are a helpful assistant.")
.defaultAdvisors(MessageChatMemoryAdvisor.builder(messageWindowChatMemory).build())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build())
.build();
}
}
2. ChatClientController.java(控制层)
less
@RestController
@RequestMapping("/client")
public class ChatClientController {
@Resource(name = "chatClient")
private ChatClient chatClient;
@Resource(name = "chatClientWithMemory")
private ChatClient chatClientWithMemory;
@Resource
private MessageWindowChatMemory messageWindowChatMemory;
/**
* 简单聊天接口
* 该接口接收用户输入的提示词,调用AI模型进行处理,并返回AI的回复内容
*
* @param prompt 用户提供的提示词,默认值为"你好,我是小肥阳,你是哪位?"
* @return AI回复的内容字符串
*/
@GetMapping("/chat")
public String chat(@RequestParam(defaultValue = "你好,我是小肥阳,你是哪位?") String prompt) {
return chatClient.prompt(prompt).call().content();
}
/**
* 流式聊天接口
* 该接口支持流式响应,适用于需要实时显示AI回复内容的场景
*
* @param prompt 用户提供的提示词,默认值为"你好,我是小肥阳,你是哪位?"
* @return 流式返回的AI回复内容
*/
@GetMapping("/stream/chat")
public Flux<String> streamChat(@RequestParam(defaultValue = "你好,我是小肥阳,你是哪位?") String prompt) {
return chatClient.prompt(prompt).stream().content();
}
/**
* 带记忆功能的聊天
* 通过conversationId维护对话上下文,实现多轮对话的记忆功能
*
* @param conversationId 对话 ID,用于标识不同的对话上下文
* @param prompt 用户输入的提示词,默认值为"你好,我是小肥阳,你是哪位?"
* @return AI基于对话历史和当前提示词的回复内容
*/
@GetMapping("/memory/chat")
public String memoryChat(@RequestParam(defaultValue = "conversationId") String conversationId,
@RequestParam(defaultValue = "你好,我是小肥阳,你是哪位?") String prompt) {
return chatClientWithMemory.prompt()
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, conversationId))
.user(prompt)
.call()
.content();
}
/**
* 获取对话历史记录
* 根据sessionId获取该会话的所有聊天记录
*
* @param conversationId 会话ID,用于标识特定的聊天会话
* @return 该会话的历史消息列表
*/
@GetMapping("/memory/history")
public List<Message> history(@RequestParam String conversationId) {
return messageWindowChatMemory.get(conversationId);
}
/**
* 清除对话历史记录
* 根据conversationId清除对应的聊天记录
*
* @param conversationId 会话ID,用于标识需要清除记录的特定会话
* @return 操作结果提示信息
*/
@DeleteMapping("/history")
public String clear(@RequestParam String conversationId) {
messageWindowChatMemory.clear(conversationId);
return "聊天记录已清除~";
}
}
七、总结与进阶
通过本文的学习,我们已经掌握了使用 Spring AI Alibaba 搭建简单聊天对话和带记忆功能的聊天对话的方法。
在今后的帖子中,我还准备了很多学习、编码的原创作品,期待大家的支持,请多多为我投票吧😄~
------ 小肥阳