多轮对话中让AI保持长期记忆的8种优化方式(附案例和代码)_ai长期记忆

这篇文章分享下在多轮对话中实现长期记忆保持的 8 种方式,欢迎一起探讨。

在基于大模型的 Agent 中,长期记忆的状态维护至关重要,在 OpenAI AI 应用研究主管 Lilian Weng 的博客《基于大模型的 Agent 构成》[1]中,将记忆视为关键的组件之一,下面我将结合 LangChain 中的代码,8 种不同的记忆维护方式在不同场景中的应用。

图片基于大模型的Agent构成

1. 获取全量历史对话

一般客服场景

在电信公司的客服聊天机器人场景中,如果用户在对话中先是询问了账单问题,接着又谈到了网络连接问题,ConversationBufferMemory 可以用来记住整个与用户的对话历史,可以帮助 AI 在回答网络问题时还记得账单问题的相关细节,从而提供更连贯的服务。

在这里插入图片描述

2. 滑动窗口获取最近部分对话内容

商品咨询场景

在一个电商平台上,如果用户询问关于特定产品的问题(如手机的电池续航时间),然后又问到了配送方式,ConversationBufferWindowMemory 可以帮助 AI 只专注于最近的一两个问题(如配送方式),而不是整个对话历史,以提供更快速和专注的答复。
在这里插入图片描述

3. 获取历史对话中实体信息

法律咨询场景

在法律咨询的场景中,客户可能会提到特定的案件名称、相关法律条款或个人信息(如“我在去年的交通事故中受了伤,想了解关于赔偿的法律建议”)。ConversationEntityMemory 可以帮助 AI 记住这些关键实体和实体关系细节,从而在整个对话过程中提供更准确、更个性化的法律建议。

在这里插入图片描述

4. 利用知识图谱获取历史对话中的实体及其联系

医疗咨询场景

在医疗咨询中,一个病人可能会描述多个症状和过去的医疗历史(如“我有糖尿病史,最近觉得经常口渴和疲劳”)。ConversationKGMemory 可以构建一个包含病人症状、疾病历史和可能的健康关联的知识图谱,从而帮助 AI 提供更全面和深入的医疗建议。
在这里插入图片描述

5. 对历史对话进行阶段性总结摘要

教育辅导场景

在一系列的教育辅导对话中,学生可能会提出不同的数学问题或理解难题(如“我不太理解二次方程的求解方法”)。ConversationSummaryMemory 可以帮助 AI 总结之前的辅导内容和学生的疑问点,以便在随后的辅导中提供更针对性的解释和练习

6. 需要获取最新对话,又要兼顾较早历史对话

技术支持场景

在处理一个长期的技术问题时(如软件故障排查),用户可能会在多次对话中提供不同的错误信息和反馈。ConversationSummaryBufferMemory 可以帮助 AI 保留最近几次交互的详细信息,同时提供历史问题处理的摘要,以便于更有效地识别和解决问题。

7. 回溯最近和最关键的对话信息

金融咨询场景

在金融咨询聊天机器人中,客户可能会提出多个问题,涉及投资、市场动态或个人财务规划(如“我想了解股市最近的趋势以及如何分配我的投资组合”)。ConversationTokenBufferMemory 可以帮助 AI 聚焦于最近和最关键的几个问题,同时避免由于记忆过多而导致的信息混淆。

8. 基于向量检索对话信息

了解最新新闻事件

用户可能会对特定新闻事件提出问题,如“最近的经济峰会有什么重要决策?” VectorStoreRetrieverMemory 能够快速从大量历史新闻数据中检索出与当前问题最相关的信息,即使这些信息在整个对话历史中不是最新的,也能提供及时准确的背景信息和详细报道。

vectorstore = Chroma(embedding_function=OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever)

memory.save_context({"input": "我喜欢吃火锅"}, {"output": "听起来很好吃"})
memory.save_context({"input": "我不喜欢看摔跤比赛"}, {"output": "我也是"})

PROMPT_TEMPLATE = """以下是人类和 AI 之间的友好对话。AI 话语多且提供了许多来自其上下文的具体细节。如果 AI 不知道问题的答案,它会诚实地说不知道。

以前对话的相关片段:
{history}
(如果不相关,你不需要使用这些信息)

当前对话:
人类:{input}
AI:
"""

prompt = PromptTemplate(input_variables=["history", "input"], template=PROMPT_TEMPLATE)
conversation_with_summary = ConversationChain(    
    llm=llm,    
    prompt=prompt,    
    memory=memory,    
    verbose=True
)
print(conversation_with_summary.predict(input="你好,我是莫尔索,你叫什么"))
print(conversation_with_summary.predict(input="我喜欢的食物是什么?"))
print(conversation_with_summary.predict(input="我提到了哪些运动?"))

​### 如何学习AI大模型?

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

想正式转到一些新兴的 AI 行业,不仅需要系统的学习AI大模型。同时也要跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。

但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高

那么针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料 分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓

👉[CSDN大礼包🎁:全网最全《LLM大模型入门+进阶学习资源包》免费分享(安全链接,放心点击)]()👈

学习路线

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

在这里插入图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

在这里插入图片描述

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

<think>我们正在讨论SpringAI框架中多轮会话的ConversationId传递问题。根据提供的引用,特别是引用[2][4],我们可以知道在SpringAI中,多轮会话的记忆功能是通过ChatMemory来实现的,而ConversationId是用来区分不同会话的关键。在引用[2]中,我们看到了一个使用MyBatis-Plus实现的ChatMemory接口,其中每个方法都接收一个conversationId参数。在引用[4]中,也提到了使用jdbc存储聊天历史信息,并且需要保存到MySQL中,其中也涉及到conversationId。因此,要传递ConversationId,我们需要在每次请求时都携带这个ID,以便能够从存储中获取对应的历史消息。在SpringAI中,这通常是在调用ChatModel的方法时,通过传递一个包含ConversationId的Prompt对象来实现的。具体步骤:1.在客户端发起请求时,需要生成或传递一个唯一的ConversationId(如果是一个新的会话,则生成一个新的ID;如果是继续已有会话,则使用已有的ID)。2.在服务端,我们将这个ConversationId与当前的用户请求一起保存到ChatMemory中(通过ChatMemoryService)。3.然后,我们使用这个ConversationId从ChatMemory中获取历史消息(通常是最近的几条),并将这些历史消息与当前用户的新消息一起构成一个Prompt,发送给AI模型。4.模型返回响应后,再将这次交互的消息(用户消息AI的响应)保存到ChatMemory中,关联到同一个ConversationId。在代码层面,我们可以参考引用[2]中的MybatisPlusChatMemory实现,它实现了ChatMemory接口,其中的方法都是基于conversationId来操作的。另外,在引用[3]中,有一个简单的内存实现InMemoryChatMemory,它使用一个Map来存储每个conversationId对应的消息列表。这说明了ConversationId的核心作用。因此,传递ConversationId的关键在于客户端每次请求都要携带这个ID,服务端则根据这个ID来存储检索历史消息。下面是一个简化的示例,说明如何在服务端使用ConversationId:假设我们有一个Controller处理用户的消息:```java@RestControllerpublicclassChatController{privatefinalChatModelchatModel;privatefinalChatMemorychatMemory;publicChatController(ChatModelchatModel,ChatMemorychatMemory){this.chatModel=chatModel;this.chatMemory=chatMemory;}@PostMapping("/chat")publicStringchat(@RequestParamStringmessage,@RequestParamStringconversationId){//将用户消息添加到当前会话的记忆中List<Message>userMessages=List.of(newHumanMessage(message));chatMemory.add(conversationId,userMessages);//获取当前会话的历史消息(例如最近的5条)List<Message>history=chatMemory.get(conversationId,5);//构建Prompt,包括历史消息当前消息Promptprompt=newPrompt(history);//调用模型ChatResponseresponse=chatModel.call(prompt);Stringresult=response.getResult().getOutput().getContent();//将AI的响应也添加到会话记忆中List<Message>aiMessages=List.of(newAiMessage(result));chatMemory.add(conversationId,aiMessages);returnresult;}}```注意:上面的代码是一个简化的示例,实际中可能需要更严谨的设计,比如消息的封装、异常处理等。另外,ConversationId的生成可以由客户端在第一次请求时生成(比如使用UUID),并在后续请求中携带。如果是Web应用,也可以使用Session等方式来维护,但如果是移动端或跨平台,通常需要客户端来维护这个ID。总结:在SpringAI中传递ConversationId的方法就是由客户端在每次请求时提供,服务端使用这个ID来关联操作对应的会话记忆。根据以上内容,我们可以生成相关问题。§§相关问题§§1.在SpringAI中,如何生成唯一的ConversationId?2.如果使用数据库存储会话记忆,如何设计数据表结构?3.除了ConversationId,还有哪些方法可以管理多轮对话的状态?4.SpringAI的ChatMemory接口支持哪些存储方式?</think>在 Spring AI 框架中实现多轮会话时,传递 `ConversationId` 是关键机制。以下是具体实现方法技术要点: ### 一、核心实现原理 1. **会话标识作用** `ConversationId` 是区分不同对话的唯一标识符,用于关联同一会话中的多次交互。大型语言模型(LLM)本身无状态,需通过此标识实现上下文关联[^4]。 2. **传递流程** ```mermaid graph LR A[客户端请求] --> B{携带 ConversationId} B -->|新会话| C[生成新ID] B -->|已有会话| D[使用现有ID] C & D --> E[ChatMemory 存储/检索] E --> F[LLM 处理] F --> G[返回响应] ``` ### 二、具体实现方法 #### 方案1:HTTP请求参数传递 ```java @RestController public class ChatController { private final ChatMemoryService memoryService; @PostMapping("/chat") public Response chat(@RequestParam String message, @RequestParam String conversationId) { // 获取历史消息 List<Message> history = memoryService.getMessages(conversationId, 10); // 构建新Prompt(含历史上下文) Prompt prompt = new Prompt(history, new HumanMessage(message)); // 调用AI模型 ChatResponse response = chatModel.call(prompt); // 存储新消息 memoryService.addMessages(conversationId, response.getMessages()); return response; } } ``` **客户端调用示例**: `POST /chat?message=你好&conversationId=session_12345` #### 方案2:Header传递(推荐) ```java @PostMapping("/chat") public Response chat(@RequestParam String message, @RequestHeader("X-Conversation-Id") String conversationId) { // 实现逻辑同方案1 } ``` **优势**: - 避免URL参数暴露 - 符合RESTful规范 - 支持中间件统一处理 ### 三、技术组件集成 1. **ChatMemory 存储实现** ```java @Component public class JdbcChatMemory implements ChatMemory { private final JdbcTemplate jdbc; @Override public void add(String conversationId, List<Message> messages) { // 存储到MySQL jdbc.update("INSERT INTO chat_history VALUES (?, ?)", conversationId, serialize(messages)); } @Override public List<Message> get(String conversationId, int lastN) { // 从DB查询最近N条 return jdbc.queryForObject( "SELECT messages FROM chat_history WHERE id=? ORDER BY time DESC LIMIT ?", (rs, row) -> deserialize(rs.getString(1)), conversationId, lastN ); } } ``` 2. **MyBatis-Plus 增强实现**(参考引用[2]) ```java @Component public class MybatisPlusChatMemory implements ChatMemory { private final ChatMemoryService service; @Override public List<Message> get(String conversationId, int lastN) { return service.getMessages(conversationId, lastN); } // 其他方法实现... } ``` ### 四、最佳实践建议 1. **ID生成策略** - 新会话:客户端生成UUID(如 `UUID.randomUUID().toString()`) - 服务端生成:使用分布式ID生成器(Snowflake等) 2. **安全考虑** - 对 `ConversationId` 签名验证防止篡改 - 设置会话过期时间(如30分钟无交互自动清除[^3]) 3. **性能优化** - 使用Redis缓存热点会话 - 限制获取的历史消息条数(如 `lastN=10`) > **关键点**:Spring AI通过 `ChatMemory` 接口抽象存储层,开发者可选择内存、JDBC、Redis等实现方式,而 `ConversationId` 始终作为会话关联的核心纽带[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值