目录
一.目前存在的问题
1.正常情况下,大模型具有会话记忆功能
2.问一个问题,后端突然异常重启,再问下一个问题
二.分析上述现象的原因
1.大白话解释
2.解决办法
三.具体步骤
1.在项目中,配置redis环境
2.创建自定义类,实现ChatMemoryStore接口
3.编写自定义类的具体代码
4.配置一下我们自定义的类
四.效果展示
五.细节解读
1.为什么创建的东西,和注入的东西,貌似不是同一个?
一.目前存在的问题
1.正常情况下,大模型具有会话记忆功能
下图是正常状态下的情况,会话记忆功能可用。

2.问一个问题,后端突然异常重启,再问下一个问题



可见,如果两个问题之间,后端发生过重启,那么会话记忆将丢失,大模型也就不能根据上文揣测我们的意图。
二.分析上述现象的原因
1.大白话解释
原来是靠MessageWindowChatMemory实现的会话记忆,它往根上倒,是用一个List集合(消息对象组成的集合)来存储所有历史会话。而List集合是内存层面的,那项目重启肯定会导致list集合的内容消失啊,很简单的道理。

2.解决办法
要想历史会话重启后不消失,那就不能存在list集合中,而是存到数据库(就是所谓的持久化),这里我们打算存到redis中。
三.具体步骤
1.在项目中,配置redis环境
我们在之前文章讲过了,此处就不赘述
2.创建自定义类,实现ChatMemoryStore接口


注意:这三个方法的Object o,其实就是会话id(即messageId),因此改一个参数名比较好,把o改成messageId吧,防止后面不理解o是什么意思。

3.编写自定义类的具体代码
@Repository
public class RedisChatMemoryStore implements ChatMemoryStore {
//注入RedisTemplate
@Autowired
private StringRedisTemplate redisTemplate;
//查询会话记忆
public List<ChatMessage> getMessages(Object memoryId) {
//1.获取会话记忆
String json = redisTemplate.opsForValue().get(memoryId);
//2.将json字符串转化成List<ChatMessage>
List<ChatMessage> list = ChatMessageDeserializer.messagesFromJson(json);
return list;
}
//更新会话记忆
public void updateMessages(Object memoryId, List<ChatMessage> list) {
//1.把list转成json数据
String json = ChatMessageSerializer.messagesToJson(list);
//2.把json数据存储到redis中(将会话消息,存入会话id为memoryId的存储对象,有效期为一天)
redisTemplate.opsForValue().set(memoryId.toString(), json, Duration.ofDays(1));
}
//删除会话记忆
public void deleteMessages(Object memoryId) {
redisTemplate.delete(memoryId.toString());
}
}
4.配置一下我们自定义的类


四.效果展示
下图表示,大模型的基本会话记忆功能依旧正常运行。

重启,再问相关问题


五.细节解读
1.为什么创建的东西,和注入的东西,貌似不是同一个?
先表明:是同一个!解释如下:
// 你定义的类
@Repository
public class RedisChatMemoryStore implements ChatMemoryStore {
// 实现接口
}
// 注入时使用的类型
@Autowired
private ChatMemoryStore redisChatMemoryStore; // 注意:这里用的是接口类型!
关键点:Spring 是根据 类型 来匹配 Bean 的,而不是根据变量名。
为什么能正常工作?
类型匹配原则:
- Spring 容器中有且仅有一个实现了 ChatMemoryStore 接口的 Bean
- 这个 Bean 就是 RedisChatMemoryStore 的实例
- Spring 会自动将实现类的实例注入到接口类型的变量中
以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~~~
网硕互联帮助中心


评论前必须登录!
注册