-
面试官:如何实现大模型连续对话?(面试官英语对话情景模拟)
- 网站名称:面试官:如何实现大模型连续对话?(面试官英语对话情景模拟)
- 网站分类:技术文章
- 收录时间:2025-08-03 01:41
- 网站地址:
“面试官:如何实现大模型连续对话?(面试官英语对话情景模拟)” 网站介绍
所有的大模型本身是不进行信息存储的,也不提供连续对话功能,所以想要实现连续对话功能需要开发者自己写代码才能实现。那怎么才能实现大模型的连续对话功能呢?
大模型连续对话功能不同的框架实现也是不同的,以行业使用最多的 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>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>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>
<artifactId>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](https://www.javacn.site),其中包含的内容有:场景题、SpringAI、SpringAIAlibaba、并发编程、MySQL、Redis、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、JVM、设计模式、消息队列、AI常见面试题等。
更多相关网站
- 10个SQL优化技巧,性能提升300%(sql优化从哪几方面入手)
- 面试官问你 MySQL 的线上执行 DDL 该怎么做?...
- MySQL 8.0 的隐藏索引:索引管理的利器,还是性能陷阱?
- MySQL实战:Json字段类型详解(mysql中json类型)
- Spring事务失效的12种解决方案!15年踩坑经验浓缩成这份避雷指南
- 面试官:select语句和update语句分别是怎么执行的?
- 详细了解 InnoDB 内存结构及其原理
- 深度剖析 Spring Boot3 中事务失效的场景与解决方案
- java 使用Jdbc连接mysql数据库以及其存在的问题
- 百万订单背后的架构生死局:SpringCloud Alibaba拯救我们的微服务
- 面试官:20 亿手机号存储选 int 还是 string?varchar 还是 char?
- 面试官:MySQL的自增ID用完了,怎么办?
- 别再用雪花算法生成ID了!试试这个吧
- # mysql 中文乱码问题分析(#mysql5.0中文乱码)
- MySQL分页到了后面越来越慢,有什么好的解决办法?
- Spring Boot3 中实现树表结构数据查询及返回全解析
- SQL外连接优化:经过验证的性能提升
- zPaaS低代码平台使用介绍:第一个功能开发
- 最近发表
- 标签列表
-
- mydisktest_v298 (35)
- sql 日期比较 (33)
- document.appendchild (35)
- 头像打包下载 (35)
- 二调符号库 (23)
- acmecadconverter_8.52绿色版 (25)
- 梦幻诛仙表情包 (36)
- java面试宝典2019pdf (26)
- disk++ (30)
- 加密与解密第四版pdf (29)
- iteye (26)
- centos7.4下载 (32)
- intouch2014r2sp1永久授权 (33)
- usb2.0-serial驱动下载 (24)
- jdk1.8.0_191下载 (27)
- axure9注册码 (30)
- virtualdrivemaster (26)
- 数据结构c语言版严蔚敏pdf (25)
- 兔兔工程量计算软件下载 (27)
- 代码整洁之道 pdf (26)
- ccproxy破解版 (31)
- aida64模板 (28)
- engine=innodb (33)
- shiro jwt (28)
- 方格子excel破解版补丁 (25)