9.大模型如何实现会话记忆隔离?

目录

一.目前存在的问题

1.先看一个现象:会话没有实现隔离

2.原因

二.实现会话隔离的思路

三.具体实现步骤

1.定义会话记忆对象提供者

2.配置会话记忆对象提供者

3.ConsultantService接口方法中添加参数memoryId

4.Controller中chat接口接收memoryId

5.前端页面请求时传递memoryId

四.验证效果

五.补充:查看生成"新的对话"的逻辑

1.查看逻辑

2.验证


一.目前存在的问题

1.先看一个现象:会话没有实现隔离

我们通过上篇文章,实现了大模型的会话记忆功能,但是目前存在如下问题:
使用浏览器A,模拟用户1,打开前端页面进行对话:

先使用微软浏览器,问大模型"姚明多高?"

再使用浏览器B,模拟用户2,打开前端页面进行对话:

可见此时,用户2问的问题"艾弗森呢?",受到了用户1刚刚问的问题影响了,知道我们问的是身高。

2.原因

因为两个浏览器都请求一个后端,而我们后端又没有对会话进行隔离,说白了两个用户的会话记录此时存到了同一个存储对象(用于让大模型实现会话记忆功能,存储会话记录的容器)中。

可见此时两个用户的会话记录确实存到一起了,我们本篇文章的目标就是将其分开,即:分别存到两个存储对象(容器)中。说白了就是用户1的会话记录存到一个容器,用户2的会话记录存到另一个容器。

二.实现会话隔离的思路

后端应该有一个大的容器(蓝色部分),用于盛放所有存储对象(可以理解为小容器,用于存储会话记录)。

当用户1发送消息"aaa"(会话id为1),先去大容器中找memoryId=1的存储对象(小容器),没找到,所以要创建一个存储对象,后续再来会话id为1的消息,会先找memoryId=1的存储对象,找到就直接往里存,而不会创建重复的存储对象,因此后续所有memoryId=1的消息都往这个存储对象中存放。

当用户2发送消息"bbb"(会话id为2),先去大容器中找memoryId=2的存储对象(小容器),没找到,所以要再创建一个存储对象,后续再来会话id为2的消息,会先找memoryId=2的存储对象,找到就直接往里存,而不会创建重复的存储对象,因此后续所有memoryId=2的消息都往这个存储对象中存放。

后续以此类推,规律很明显了,无需多言......

三.具体实现步骤

1.定义会话记忆对象提供者

还在刚才的配置类中,添加下面的代码

java 复制代码
// 使用 @Bean 注解声明这是一个 Spring Bean 定义方法
// Spring 容器会自动调用此方法并将返回值注册为 Bean
@Bean
public ChatMemoryProvider chatMemoryProvider() {
    
    // 创建 ChatMemoryProvider 接口的匿名实现类
    // ChatMemoryProvider 是用于提供聊天记忆管理的工厂接口
    ChatMemoryProvider chatMemoryProvider = new ChatMemoryProvider() {
        
        // 实现 get 方法,根据 memoryId 获取对应的 ChatMemory 实例
        // memoryId 通常是会话标识符(如用户ID、会话ID等)
        @Override
        public ChatMemory get(Object memoryId) {
            
            // 使用 MessageWindowChatMemory 构建器模式创建聊天记忆实例
            // MessageWindowChatMemory 是一种基于滑动窗口的记忆实现
            // 它只保留最近的一定数量的消息,避免内存无限增长
            return MessageWindowChatMemory.builder()
                    // 设置记忆的唯一标识符,用于区分不同会话的记忆
                    .id(memoryId)
                    // 配置最大消息保留数量,这里设置为保留最近的20条消息
                    // 当消息超过20条时,最旧的消息会被自动移除
                    .maxMessages(20)
                    // 完成构建并返回 ChatMemory 实例
                    .build();
        }
    };
    
    // 返回 ChatMemoryProvider 实例,Spring 会将其纳入容器管理
    return chatMemoryProvider;
}

2.配置会话记忆对象提供者

注意:该配置的值(引号里的值),就是上面配置类中的方法名。

3.ConsultantService接口方法中添加参数memoryId

注意一个小细节:当我们在service新加一个参数后,message就不是第一个参数了,因此为了让系统识别这个变量代表用户消息(用户问的具体问题),需要加上@UserMessage注解。

4.Controller中chat接口接收memoryId

在controller中,也加一个memoryId参数,代表会话id。

5.前端页面请求时传递memoryId

四.验证效果

先在浏览器A,测试一下:

可见会话记忆功能完好,没有被破坏。

再去浏览器B,测试一下:

此时大模型没有意会到我们的具体问题,因此说明会话成功被隔离,所以我们的目的达到了。

五.补充:查看生成"新的对话"的逻辑

1.查看逻辑

这就说明新的对话,是和之前的对话隔离的。

2.验证

如下图所示,可见当点击"+"以后,会生成新的会话id传到后端,也就是和之前的会话记录就不是存放到同一个存储对象了,说白了就是互相隔离了。这也印证了我们的猜想!

说白了,这里实现了两种隔离:

①不同用户的会话记忆相互隔离

②同一用户的不同轮对话(按+就会新建一轮对话)的会话记忆相互隔离

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

相关推荐
WWZZ20252 小时前
Isaac Sim安装
机器人·大模型·具身智能·isaac sim·四足·人形
白云千载尽3 小时前
cosmos系列模型的推理使用——cosmos transfer2.5
算法·大模型·世界模型·自动驾驶仿真·navsim
Java后端的Ai之路4 小时前
【AI应用开发工程师】-阿里百炼模型平台使用教程(保姆级)
大模型·使用教程·阿里云百炼·ai应用开发工程师
WWZZ20254 小时前
C++:STL(容器deque)
开发语言·c++·算法·大模型·具身智能
CoderJia程序员甲15 小时前
GitHub 热榜项目 - 日榜(2026-01-22)
ai·开源·大模型·github·ai教程
递归尽头是星辰16 小时前
大模型与向量检索的融合:从核心原理到 Spring AI 落地
人工智能·大模型·向量检索·rag·spring ai·向量库
CoderJia程序员甲17 小时前
GitHub 热榜项目 - 日榜(2026-01-25)
开源·大模型·llm·github·ai教程
AI 菌19 小时前
DeepSeek-OCR 解读
人工智能·算法·计算机视觉·大模型·ocr
山顶夕景19 小时前
【RL】Absolute Zero: Reinforced Self-play Reasoning with Zero Data
大模型·llm·强化学习·rl