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

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

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

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

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

相关推荐
寒水馨2 小时前
Windows 11下载、安装openclaw-v2026.7.1(附安装包OpenClawCompanion-Setup-x64.exe)
windows·大模型·开源软件·ai助手·openclaw·个人ai·中文版
战族狼魂17 小时前
高频面试题精选:分治与AI Agent架构
人工智能·算法·大模型·大语言模型
GPUStack1 天前
Day 0 实测|在 GPUStack 上部署 Inkling-BF16:8 卡 H20-141G 推理性能测试
ai·大模型·llm·gpu·vllm·gpu集群·sglang·gpustack
Tbisnic1 天前
28.NLP 三大预训练模型 ELMo/BERT/GPT + HuggingFace Transformers
gpt·自然语言处理·大模型·nlp·bert·预训练模型
hhzz1 天前
CNN图像分类入门:基于TensorFlow+Keras的CIFAR-10数据集全流程实战
图像处理·计算机视觉·ai·cnn·大模型
视***间1 天前
端侧20B级推理标杆:视程空间Pandora,让GPT-OSS 20B在边缘原生落地
人工智能·gpt·大模型·本地部署·大模型本地部署·视程空间
冷小鱼2 天前
Agent 大模型的后训练、微调、评估与迭代优化:从理论到工程实践
大模型·微调·优化·迭代·评估
程序员-李俞2 天前
向量引擎接入自研 API 中转网关:鉴权、限流、熔断和审计日志复盘
服务器·人工智能·大模型·api·ai编程·ai api
山顶夕景2 天前
【Audio】Audio encoder相关Benchmark
大模型·音视频·多模态·audio·检索·全模态
一个天蝎座 白勺 程序猿2 天前
从电网改造踩坑说起:深度拆解时序大模型TimechoAI的自主可控与安全合规底气
大数据·运维·服务器·大模型·timechoai