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

【LangChain】2 储存

LangChain 的储存模块(Memory)旨在解决语言模型(LLM)在多轮对话中无法保留历史上下文的问题。通过外部储存机制,这些模块帮助 LLM 实现短期记忆的持久化,从而提升对话连贯性和智能性。

储存模块保存用户与模型的交互记录,避免上下文丢失。支持动态更新和检索对话内容。

不同储存类型可单独或组合使用,适应多样化场景需求。与其他 LangChain 组件(如链、代理)无缝集成。

LLM 本身仅保留当前会话的临时记忆,外部储存扩展了记忆保留时间。


四种主要储存类型

对话缓存储存(ConversationBufferMemory)
  • 保存完整的对话历史,适用于需要全局上下文的场景。
  • 示例代码:
对话缓存窗口储存(ConversationBufferWindowMemory)
  • 仅保留最近 k 轮对话,避免历史过长导致资源浪费。
  • 参数 k 控制窗口大小。
对话令牌缓存储存(ConversationTokenBufferMemory)
  • 基于令牌数限制历史内容,适用于模型有输入长度限制的场景(如 GPT-3)。
  • 参数 max_token_limit 设定最大令牌数。
对话摘要缓存储存(ConversationSummaryBufferMemory)
  • 对历史对话生成摘要,平衡信息压缩与上下文保留。
  • 需配合摘要生成模型(如 OpenAI)使用。

一、设置Key

import osfrom zhipuai import ZhipuAI
from dotenv import find_dotenv, load_dotenv# 读取本地/项目的环境变量。# find_dotenv()寻找并定位.env文件的路径
# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中
# 如果你设置的是全局的环境变量,这行代码则没有任何作用。
_ = load_dotenv(find_dotenv())# 获取环境变量 OPENAI_API_KEY
key = "f5cd91f2528fed334b9dfd75015791c3.GuLdvM9tXWrGQnAg"
client = ZhipuAI(api_key = key)

二、对话缓存储存

初始化对话模型
from langchain.chains.conversation.base import ConversationChain
from langchain_community.chat_models.zhipuai import ChatZhipuAI
from langchain.memory import ConversationBufferMemory
llm = ChatZhipuAI(temperature=0.0,zhipuai_api_key=key) 
memory = ConversationBufferMemory()conversation = ConversationChain(llm=llm, memory = memory, verbose=True )
第一轮对话
conversation.predict(input="你好, 我叫皮皮鲁")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: 你好, 我叫皮皮鲁
AI:
> Finished chain.
'你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊'
第二轮对话
conversation.predict(input="1+1等于多少?")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.Current conversation:
Human: 你好, 我叫皮皮鲁
AI: 你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊
Human: 1+1等于多少?
AI:> Finished chain.
'1+1等于2。这是一个基础的数学问题。如果你有更复杂的问题,也可以问我哦!😉'
第三轮对话
conversation.predict(input="我叫什么名字?")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.Current conversation:
Human: 你好, 我叫皮皮鲁
AI: 你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊
Human: 1+1等于多少?
AI: 1+1等于2。这是一个基础的数学问题。如果你有更复杂的问题,也可以问我哦!😉
Human: 我叫什么名字?
AI:> Finished chain.
'你叫皮皮鲁。如果你需要我帮你回忆我们的对话中的其他内容,也可以告诉我。😊'

 查看储存缓存

print(memory.buffer) 
Human: 你好, 我叫皮皮鲁
AI: 你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊
Human: 1+1等于多少?
AI: 1+1等于2。这是一个基础的数学问题。如果你有更复杂的问题,也可以问我哦!😉
Human: 我叫什么名字?
AI: 你叫皮皮鲁。如果你需要我帮你回忆我们的对话中的其他内容,也可以告诉我。😊
print(memory.load_memory_variables({}))
{'history': 'Human: 你好, 我叫皮皮鲁\nAI: 你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊\nHuman: 1+1等于多少?\nAI: 1+1等于2。这是一个基础的数学问题。如果你有更复杂的问题,也可以问我哦!😉\nHuman: 我叫什么名字?\nAI: 你叫皮皮鲁。如果你需要我帮你回忆我们的对话中的其他内容,也可以告诉我。😊'}
直接添加内容到储存缓存
memory = ConversationBufferMemory()
memory.save_context({"input": "你好,我叫皮皮鲁"}, {"output": "你好啊,我叫鲁西西"})
memory.load_memory_variables({})
memory.save_context({"input": "Not much, just hanging"}, {"output": "Cool"})
memory.save_context({"input": "很高兴和你成为朋友!"}, {"output": "是的,让我们一起去冒险吧!"})
memory.load_memory_variables({})
{'history': 'Human: 你好,我叫皮皮鲁\nAI: 你好啊,我叫鲁西西\nHuman: Not much, just hanging\nAI: Cool\nHuman: 很高兴和你成为朋友!\nAI: 是的,让我们一起去冒险吧!'}

当我们在使用大型语言模型进行聊天对话时,大型语言模型本身实际上是无状态的。语言模型本身并不记得到目前为止的历史对话。每次调用API结点都是独立的。储存(Memory)可以储存到目前为止的所有术语或对话,并将其输入或附加上下文到LLM中用于生成输出。如此看起来就好像它在进行下一轮对话的时候,记得之前说过什么。

三、对话缓存窗口储存

随着对话变得越来越长,所需的内存量也变得非常长。将大量的tokens发送到LLM的成本,也会变得更加昂贵,这也就是为什么API的调用费用,通常是基于它需要处理的tokens数量而收费的。

针对以上问题,LangChain也提供了几种方便的储存方式来保存历史对话。其中,对话缓存窗口储存只保留一个窗口大小的对话。它只使用最近的n次交互。这可以用于保持最近交互的滑动窗口,以便缓冲区不会过大

添加两轮对话到窗口储存
from langchain.memory import ConversationBufferWindowMemory# k=1表明只保留一个对话记忆
memory = ConversationBufferWindowMemory(k=1)  
memory.save_context({"input": "你好,我叫皮皮鲁"}, {"output": "你好啊,我叫鲁西西"})
memory.save_context({"input": "很高兴和你成为朋友!"}, {"output": "是的,让我们一起去冒险吧!"})
memory.load_memory_variables({})
{'history': 'Human: 很高兴和你成为朋友!\nAI: 是的,让我们一起去冒险吧!'}
在对话链中应用窗口储存
llm = ChatZhipuAI(temperature=0,zhipuai_api_key=key)
memory = ConversationBufferWindowMemory(k=1)
conversation = ConversationChain(llm=llm, memory=memory, verbose=False  )
print(conversation.predict(input="你好, 我叫皮皮鲁"))
print(conversation.predict(input="1+1等于多少?"))
print(conversation.predict(input="我叫什么名字?"))
你好,皮皮鲁,很高兴认识你!有什么我可以帮助你的吗?无论是生活中的小事,还是你感兴趣的知识点,都可以和我聊聊。😊
1+1等于2。这是一个基础的数学问题。如果你有更复杂的问题,也可以问我哦!😉
对不起,我还不知道你的名字。如果你愿意告诉我,我们可以继续进行更个性化的对话。😊

四、对话token缓存储存

使用对话token缓存记忆,内存将限制保存的token数量。如果token数量超出指定数目,它会切掉这个对话的早期部分 以保留与最近的交流相对应的token数量,但不超过token限制。

from langchain.memory import ConversationTokenBufferMemory
memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)
memory.save_context({"input": "朝辞白帝彩云间,"}, {"output": "千里江陵一日还。"})
memory.save_context({"input": "两岸猿声啼不住,"}, {"output": "轻舟已过万重山。"})
memory.load_memory_variables({})
{'history': 'AI: 轻舟已过万重山。'}

五、对话摘要缓存储存

对话摘要缓存储存,使用LLM编写到目前为止历史对话的摘要,并将其保存

from langchain.memory import ConversationSummaryBufferMemory

 使用对话摘要缓存储存

创建一个长字符串,其中包含某人的日程安排

# 创建一个长字符串
schedule = "在八点你和你的产品团队有一个会议。 \
你需要做一个PPT。 \
上午9点到12点你需要忙于LangChain。\
Langchain是一个有用的工具,因此你的项目进展的非常快。\
中午,在意大利餐厅与一位开车来的顾客共进午餐 \
走了一个多小时的路程与你见面,只为了解最新的 AI。 \
确保你带了笔记本电脑可以展示最新的 LLM 样例."llm = ChatZhipuAI(temperature=0,zhipuai_api_key=key)
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)
memory.save_context({"input": "你好,我叫皮皮鲁"}, {"output": "你好啊,我叫鲁西西"})
memory.save_context({"input": "很高兴和你成为朋友!"}, {"output": "是的,让我们一起去冒险吧!"})
memory.save_context({"input": "今天的日程安排是什么?"}, {"output": f"{schedule}"})
print(memory.load_memory_variables({})['history'])
基于对话摘要缓存储存的对话链

基于上面的对话摘要缓存储存,新建一个对话链

conversation = ConversationChain(llm=llm, memory=memory, verbose=True)
conversation.predict(input="展示什么样的样例最好呢?")
memory.load_memory_variables({})  # 摘要记录更新了

相关文章:

  • 三星手机Galaxy S24 Ultra使用adb工具关闭和开启系统更新
  • 小白学Pinia状态管理
  • 撤销Git合并操作方法总结
  • AI Engine Kernel and Graph Programming--知识分享9
  • 卷积神经网络(一)
  • JVM面试基础篇
  • 界面控件Kendo UI在实战应用——打通数据链路,重塑业务效率
  • leetcode0684. 冗余连接-medium
  • 3 Studying《深入理解Android卷(邓凡平)》1
  • [特殊字符] React 与 Vue 源码级对比:5大核心差异与实战选择指南
  • 盒模型小全
  • HTML5 浮动
  • ACL 2025 | 多维阅卷,智识觉醒:打开多模态大模型看图写作评估的认知之门
  • 湖北理元理律师事务所债务优化实践:法律框架下的生活重建方案
  • Java@Data 与 @NotNull 注解冲突问题
  • StackOverflowError
  • spring:使用注解@获取第三方bean实例
  • 表格里的图片链接怎么变成图片【附工具+源码演示】
  • 如何彻底删除Neo4j中的所有数据:完整指南
  • Java八股文——Spring「Spring 篇」
  • 大连手机自适应网站建设/营销策划方案ppt范文
  • 如何建设网站/萝卜建站
  • 商会网站怎么做/无锡网站优化
  • com域名网站排名优先/网站seo平台
  • 国外网站页头设计图片/湖南正规关键词优化首选
  • 北京大型网站开发/百度一下网页版浏览器