当前位置: 首页 > news >正文

Spring AI 会话记忆(笔记)

    现在我们与前端对接了,能够实现基本的对话功能以及基本的日志输出,那么现在还有个问题就是前面用户说的话后面再提问就忘了,用户体验效果很差

这个就跟OpenAI规范有关系了,如果每次只发送messages的system和role的提示词,大模型只能基于这两个回答,丝毫没有记忆,要把以前的对话也要封装在里面,现在要多出一个角色,assistant

message数组,用assistant表示大模型回复的内容,按顺序排列,先放用户的提问,然后放assistant中大模型的回复消息以及用户提问的问题,依次循环不断把以前的记录封装进去,最后一个肯定是用户最新一个提问,一起发送给大模型,大模型基于聊天历史和最新提问回答,这样就有了记忆

解决:使用springAI封装好的会话环绕增强advisor,能够帮助我们记录所有的会话历史,在发送的时候把记录拼接进去

定义会话存储方式:要有个会话存储方式,Spring AI定好了标准一套接口,例如:第一个就是前端要传给我们的会话ID,第二个就是集合存储的消息,该消息包含角色和内容(基于ID去存储),clear()根据ID清除,可以自己去实现这个接口保存到Redis或者是MySQL,然后可以把项目中的UserID和会话ID拼接在一起,然后去查

不过Spring AI有帮我们实现了这套接口,不过服务一重启会话记忆就没了,可以根据企业要求去实现持久化

@Configuration
public class ClientCofig {//    定义会话记忆存储的方式 如果企业要求持久化自己实现接口,存储在库里面@Beanpublic ChatMemory chatMemory(){return new InMemoryChatMemory();}}

配置会话记忆:负责拦截请求做会话记录,提示词拼接

@Configuration
public class ClientCofig {//    定义会话记忆存储的方式 如果企业要求持久化在这里自己实现接口,存储在库里面@Beanpublic ChatMemory chatMemory(){return new InMemoryChatMemory();}//    配置客户端 新:注入会话存储方式@Beanpublic ChatClient chatClient(OpenAiChatModel chatModel,ChatMemory chatMemory){
//        传一个模型,并且先设定一下systemreturn ChatClient.builder(chatModel).defaultSystem("你是一名虚构的动漫里小熊的智能客服,你的名字叫一二。请以友好、热情、可爱的方式回答用户问题。")
//                配置日志环绕增强 还要开启日志级别以及配置 默认debug级别 新:传进去后,将来通过环绕增强,拦截对话,把会话记录保存到chaMemory,将来发新的请求重新拼接进去.defaultAdvisors(new SimpleLoggerAdvisor(), new MessageChatMemoryAdvisor(chatMemory)).build();}}

添加会话ID:每次发请求,不一定都是同一个人,都需要做会话记忆,不加以管理就会很容易造成混乱。会话都要有个ID,用户跟大模型多轮对话都是同一个ID,不同新的对话再有新的对话ID。可以让前端生成ID,不同新的页面就不同的ID,同一个页面就同一个ID。

我们如何把ID传递给Advisor帮我们管理:
需要发请求的时候传递,环绕增强:.param:向advisor添加上下文,一组键值对,Key-Valve

Key已经帮我们定义好了


 

   @RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")public Flux<String> get(String prompt,String chatId){//现在有个问题无法区分是否同一个人,不管谁来聊都会认为同一个人(区分不同的人,用会话ID)return chatClient.prompt().user(prompt)
//                将来会根据这个key找会话ID.advisors(a-> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId)).stream().content();}

结果:不同会话有不同的记忆了

上一次的对话存储:

[UserMessage{content='你好,我叫布布', properties={messageType=USER}, messageType=USER}, AssistantMessage [messageType=ASSISTANT, toolCalls=[], textContent=你好呀,布布!我是你的智能客服一二,很高兴见到你!今天有什么我可以帮你的吗?无论是关于动漫的问题还是其他任何疑问,我都在这里哦!😊, metadata={refusal=, finishReason=STOP, index=0, id=chatcmpl-f86f5315-c2e7-9880-9d5a-a876d85acdff, role=ASSISTANT, messageType=ASSISTANT}]]
XXXXXXXXXXXXXX

新的页面(新的对话窗口):没有跟前面产生联系了,是新的对话,新的会话ID

http://www.xdnf.cn/news/108577.html

相关文章:

  • 【3.2】pod详解—— Pod的相位(phase)状态(status)
  • Linux常用指令
  • 小刚说C语言刷题——1338求圆环的面积
  • C++二分法详解
  • el-table 目录树列表本地实现模糊查询
  • Linux部署Redis主从
  • 天梯-零头就抹了吧
  • 实操Obsidian+Ollama+deepseek构建本地知识库
  • C语言五子棋项目
  • [计算机科学#1]:计算机的前世今生,从算盘到IBM的演变之路
  • flex布局说明
  • 百万点数组下memset、memcpy与for循环效率对比及原理分析
  • 经典算法 小数点后的第n位
  • 语音合成之四基于LLM的语音合成
  • Sql刷题日志(day5)
  • JVM理解(通俗易懂)
  • 2025年渗透测试面试题总结-拷打题库14(题目+回答)
  • 时间自动填写——电子表格公式的遗憾(DeepSeek)
  • A13 自定义系统服务使用总结
  • Kafka集群
  • ABP-Book Store Application中文讲解 - Part 0:开发环境搭建
  • 意见反馈留言二维码制作
  • leetcode-枚举
  • Langchain coercion简介
  • deeplab语义分割训练自定数据集
  • leve1.4
  • LLama Factory从入门到放弃
  • iThenticate英文查重系统怎么用?
  • 【AI论文】在非政策指导下学习推理
  • 中药企业数字化转型:从传统制造到智能制药的跨越