所有的大模型本身是不进行信息存储的,也不提供连续对话功能,所以想要实现连续对话功能需要开发者自己写代码才能实现。那怎么才能实现大模型的连续对话功能呢?
大模型连续对话功能不同的框架实现也是不同的,以行业使用最多的 Java AI 框架 Spring AI 和 Spring AI Alibaba 为例,给大家演示一下它们连续对话是如何实现的。
1.SpringAI连续对话实现
Spring AI 以 MySQL 数据库为例,我们来实现一下它的连续对话功能。
PS:我们只有先讲对话存储起来,才能实现连续对话功能,所以我们需要借助数据库存储来连续对话。
1.1 准备工作
1.创建表- CREATE TABLE chat_message (
- id BIGINT AUTO_INCREMENT PRIMARY KEY,
- conversation_id VARCHAR(255) NOT NULL,
- role VARCHAR(50) NOT NULL,
- context TEXT NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
复制代码 2.添加数据库和 MyBatisPlus 依赖:- <dependency>
- <groupId>com.baomidou</groupId>
- mybatis-plus-spring-boot3-starter</artifactId>
- <version>3.5.11</version>
- </dependency>
- <dependency>
- <groupId>com.mysql</groupId>
- mysql-connector-j</artifactId>
- <scope>runtime</scope>
- </dependency>
复制代码 3.设置配置文件:- spring:
- datasource:
- url: jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8
- username: root
- password: 12345678
- driver-class-name: com.mysql.cj.jdbc.Driver
- # 配置打印 MyBatis 执行的 SQL
- mybatis-plus:
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- # 配置打印 MyBatis 执行的 SQL
- logging:
- level:
- com:
- ai:
- deepseek: debug
复制代码 4.编写实体类- import com.baomidou.mybatisplus.annotation.IdType;
- import com.baomidou.mybatisplus.annotation.TableId;
- import com.baomidou.mybatisplus.annotation.TableName;
- import lombok.Getter;
- import lombok.Setter;
- import java.io.Serializable;
- import java.util.Date;
- @Getter
- @Setter
- @TableName("chat_message")
- public class ChatMessageDO implements Serializable {
- private static final long serialVersionUID = 1L;
- @TableId(value = "id", type = IdType.AUTO)
- private Long id;
- private String conversationId;
- private String role;
- private String context;
- private Date createdAt;
- }
复制代码 5.编写 Mapper:- import com.ai.chat.entity.ChatMessageDO;
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import org.apache.ibatis.annotations.Mapper;
- @Mapper
- public interface ChatMessageMapper extends BaseMapper<ChatMessageDO> {
- }
复制代码 1.2 自定义ChatMemory类
自定义的 ChatMemory 实现类,将对话记录存储到 MySQL:- import com.ai.deepseek.entity.ChatMessageDO;
- import com.ai.deepseek.mapper.ChatMessageMapper;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import org.springframework.ai.chat.memory.ChatMemory;
- import org.springframework.ai.chat.messages.Message;
- import org.springframework.ai.chat.messages.UserMessage;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import java.util.List;
- import java.util.stream.Collectors;
- @Component
- public class MySQLChatMemory implements ChatMemory {
- @Autowired
- private ChatMessageMapper repository;
- @Override
- public void add(String conversationId, Message message) {
- ChatMessageDO entity = new ChatMessageDO();
- entity.setConversationId(conversationId);
- entity.setRole(message.getMessageType().name());
- entity.setContext(message.getText());
- repository.insert(entity);
- }
- @Override
- public void add(String conversationId, List<Message> messages) {
- messages.forEach(message -> add(conversationId, message));
- }
- @Override
- public List<Message> get(String conversationId, int lastN) {
- LambdaQueryWrapper<ChatMessageDO> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(ChatMessageDO::getConversationId, conversationId);
- // queryWrapper.orderByDesc(ChatMessageDO::getId);
- return repository.selectList(queryWrapper)
- .stream()
- .limit(lastN)
- .map(e -> new UserMessage(e.getContext()))
- .collect(Collectors.toList());
- }
- @Override
- public void clear(String conversationId) {
- LambdaQueryWrapper<ChatMessageDO> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(ChatMessageDO::getConversationId, conversationId);
- repository.delete(queryWrapper);
- }
- }
复制代码 1.3 代码调用
编写代码测试历史对话保存到 MySQL 的功能:- import com.ai.deepseek.component.MySQLChatMemory;
- import org.springframework.ai.chat.client.ChatClient;
- import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.RestController;
- import reactor.core.publisher.Flux;
- @RestController
- @RequestMapping("/multi")
- public class MultiChatController {
- @Autowired
- private ChatClient chatClient;
- @Autowired
- private MySQLChatMemory chatMemory;
- @RequestMapping("/chat")
- public Flux<String> chat(@RequestParam("msg") String msg,
- @RequestParam(defaultValue = "default") String sessionId) {
- // 添加MessageChatMemoryAdvisor,自动管理上下文
- MessageChatMemoryAdvisor advisor =
- new MessageChatMemoryAdvisor(chatMemory, sessionId, 10); // 保留最近5条历史
- return chatClient.prompt()
- .user(msg)
- .advisors(advisor) // 关键:注入记忆管理
- .stream()
- .content();
- }
- }
复制代码 以上程序执行结果如下:
2.SpringAIAlibaba实现连续对话
Spring AI Alibaba 连续对话的实现就简单很多了,因为它内置了 MySQL 和 Redis 的连续对话存储方式,接下来以 Redis 为例演示 SAA 的连续对话实现,它的实现步骤如下:
- 添加依赖。
- 设置配置文件,配置 Redis 连接信息。
- 添加 Redis 配置类,注入 RedisChatMemoryRepository 对象。
- 配置 ChatClient 实现连续对话。
具体实现如下。
2.1 添加依赖
- <dependency>
- <groupId>com.alibaba.cloud.ai</groupId>
- spring-ai-alibaba-starter-memory-redis</artifactId>
- </dependency>
复制代码 2.2 设置配置文件
设置配置文件,配置 Redis 连接信息:- spring:
- ai:
- memory:
- redis:
- host: localhost
- port: 6379
- timeout: 5000
复制代码 2.3 添加Redis配置类
添加 Redis 配置类,注入 RedisChatMemoryRepository 对象,实现 Redis 自定义存储器注入:- import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- public class RedisMemoryConfig {
- @Value("${spring.ai.memory.redis.host}")
- private String redisHost;
- @Value("${spring.ai.memory.redis.port}")
- private int redisPort;
- // @Value("${spring.ai.memory.redis.password}")
- // private String redisPassword;
- @Value("${spring.ai.memory.redis.timeout}")
- private int redisTimeout;
- @Bean
- public RedisChatMemoryRepository redisChatMemoryRepository() {
- return RedisChatMemoryRepository.builder()
- .host(redisHost)
- .port(redisPort)
- // 若没有设置密码则注释该项
- // .password(redisPassword)
- .timeout(redisTimeout)
- .build();
- }
- }
复制代码 2.4 配置ChatClient实现连续对话
- import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
- import org.springframework.ai.chat.client.ChatClient;
- import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
- import org.springframework.ai.chat.memory.MessageWindowChatMemory;
- import org.springframework.ai.chat.model.ChatModel;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import static org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID;
- @RestController
- @RequestMapping("/redis")
- public class RedisMemoryController {
- private final ChatClient chatClient;
- private final int MAXMESSAGES = 10;
- private final MessageWindowChatMemory messageWindowChatMemory;
- public RedisMemoryController(ChatModel dashscopeChatModel,
- RedisChatMemoryRepository redisChatMemoryRepository) {
- this.messageWindowChatMemory = MessageWindowChatMemory.builder()
- .chatMemoryRepository(redisChatMemoryRepository)
- .maxMessages(MAXMESSAGES)
- .build();
- this.chatClient = ChatClient.builder(dashscopeChatModel)
- .defaultAdvisors(
- MessageChatMemoryAdvisor.builder(messageWindowChatMemory)
- .build()
- )
- .build();
- }
- @GetMapping("/call")
- public String call(String msg, String cid) {
- return chatClient.prompt(msg)
- .advisors(
- a -> a.param(CONVERSATION_ID, cid)
- )
- .call().content();
- }
- }
复制代码 小结
通过以上代码大家也可以看出来,使用 Spring AI 实现连续对话是比较复杂的,需要自己实现数据库增删改查的代码,并且重写 ChatMemory 才能实现连续对话功能;而 Spring AI Alibaba 因为内置了连续对话的多种实现(Redis 和其他数据库),所以只需要简单配置就可以实现了。
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:场景题、SpringAI、SpringAIAlibaba、并发编程、MySQL、Redis、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、JVM、设计模式、消息队列、AI常见面试题等。
关注公众号(加好友):
作者: 王磊的博客
出处: http://vipstone.cnblogs.com/
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |