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传到后端,也就是和之前的会话记录就不是存放到同一个存储对象了,说白了就是互相隔离了。这也印证了我们的猜想!

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

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

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

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

相关推荐
小田学Python19 小时前
Dify+Ollama模型搭建攻略:本地环境实战指南
大模型·qwen·dify·ollama
非社会人士20 小时前
verl 中序列长度相关配置梳理:理清数据、Rollout 与 PPO 训练边界
大模型·强化学习·verl
Shining059620 小时前
前沿模型系列(三)《检索增强的语言模型》
人工智能·学习·其他·语言模型·自然语言处理·大模型·rag
翔云12345621 小时前
OpenClaw与Claude Code的Skill比较
ai·大模型·openclaw
李白你好21 小时前
一款基于大语言模型 (LLM) 的网络安全纸上推演靶场生成工具
大模型
草莓泰面包1 天前
虚拟机VMware安装OpenClaw
人工智能·ai·大模型·openclaw
Shining05962 天前
前沿模型系列(四)《大模型前沿架构》
人工智能·学习·其他·ai·架构·大模型·infinitensor
晨欣2 天前
如何根据 config.json 核对 MoE 模型的激活参数:以 gpt-oss-120b 为例(GPT-5.4-high 生成)
gpt·大模型·json·openai
Pyeako2 天前
大模型--模型部署
人工智能·python·大模型·客户端·模型部署·服务端·路由-端口
圣殿骑士-Khtangc2 天前
【论文精读】《A Survey of Vibe Coding with Large Language Models》| 通俗解读+核心提炼
人工智能·大模型·vibe coding