10.会话记忆持久化

目录

一.目前存在的问题

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.编写自定义类的具体代码

java 复制代码
@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.为什么创建的东西,和注入的东西,貌似不是同一个?

先表明:是同一个!解释如下:

java 复制代码
// 你定义的类
@Repository
public class RedisChatMemoryStore implements ChatMemoryStore {
    // 实现接口
}

// 注入时使用的类型
@Autowired
private ChatMemoryStore redisChatMemoryStore;  // 注意:这里用的是接口类型!

关键点 :Spring 是根据 类型 来匹配 Bean 的,而不是根据变量名。

为什么能正常工作?

类型匹配原则:

  • Spring 容器中有且仅有一个实现了 ChatMemoryStore 接口的 Bean
  • 这个 Bean 就是 RedisChatMemoryStore 的实例
  • Spring 会自动将实现类的实例注入到接口类型的变量中

以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~~~

相关推荐
用户094248568033 小时前
第22章:Redis 持久化 RDB 与 AOF:数据不丢的底线
redis·架构·源码
没有气的汽水3 小时前
升级完客户端,redis 又开始大量返回 MOVED:一个埋了七个月的本地配置
redis
csdn_aspnet3 小时前
如何在本地 Docker 容器中运行 Redis,并使用 Redis Insight 和 Redis CLI 进行管理
redis·docker·容器
todoitbo4 小时前
我在 Mac 上用 Docker 部署 Nexent:从拉取镜像到接入模型
macos·docker·大模型·ai智能体·nexent·快速入门与环境准备
承渊政道4 小时前
Open-LLM-VTuber本地部署教程:大模型、语音交互、Live2D与远程访问
大模型·内网穿透·数字人·cpolar·语音交互·open-llm-vtuber
香吧香5 小时前
当系统开始自己做判断:智能运维里的日志,为什么不能照搬传统那套
大模型
nice_lcj5207 小时前
【从零理解 Spring AI · 03】Spring AI 在 Spring 生态里的位置
java·spring boot·大模型·spring ai·ai应用开发
IT规划师7 小时前
Redis 数据类型全解 - Bitfield:99% 开发者没用过的位域操作,把内存再砍 80%(七)
redis·bitfield·位域
组工部管理能手李哥1 天前
一次政务知识库体验:AI回答之外,我更在意那行引用来源
大数据·人工智能·大模型·政务