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

LangChain让LLM带上记忆

最近两年,我们见识了“百模大战”,领略到了大型语言模型(LLM)的风采,但它们也存在一个显著的缺陷:没有记忆。

在对话中,无法记住上下文的 LLM 常常会让用户感到困扰。本文探讨如何利用 LangChain,快速为 LLM 添加记忆能力,提升对话体验。

LangChain 是 LLM 应用开发领域的最大社区和最重要的框架。

1. LLM 固有缺陷,没有记忆

当前的 LLM 非常智能,在理解和生成自然语言方面表现优异,但是有一个显著的缺陷:没有记忆

LLM 的本质是基于统计和概率来生成文本,对于每次请求,它们都将上下文视为独立事件。这意味着当你与 LLM 进行对话时,它不会记住你之前说过的话,这就导致了 LLM 有时表现得不够智能。

这种“无记忆”属性使得 LLM 无法在长期对话中有效跟踪上下文,也无法积累历史信息。比如,当你在聊天过程中提到一个人名,后续再次提及该人时,LLM 可能会忘记你之前的描述。

本着发现问题解决问题的原则,既然没有记忆,那就给 LLM 装上记忆吧。

2. 记忆组件的原理

2.1. 没有记忆的烦恼

当我们与 LLM 聊天时,它们无法记住上下文信息,比如下图的示例:

img

2.2. 原理

如果将已有信息放入到 memory 中,每次跟 LLM 对话时,把已有的信息丢给 LLM,那么 LLM 就能够正确回答,见如下示例:

img

目前业内解决 LLM 记忆问题就是采用了类似上图的方案,即:将每次的对话记录再次丢入到 Prompt 里,这样 LLM 每次对话时,就拥有了之前的历史对话信息。

但如果每次对话,都需要自己手动将本次对话信息继续加入到history信息中,那未免太繁琐。有没有轻松一些的方式呢?有,LangChain!LangChain 对记忆组件做了高度封装,开箱即用。

2.3. 长期记忆和短期记忆

在解决 LLM 的记忆问题时,有两种记忆方案,长期记忆和短期记忆。

  • 短期记忆:基于内存的存储,容量有限,用于存储临时对话内容。
  • 长期记忆:基于硬盘或者外部数据库等方式,容量较大,用于存储需要持久的信息。

3. LangChain 让 LLM 记住上下文

LangChain 提供了灵活的内存组件工具来帮助开发者为 LLM 添加记忆能力。

3.1. 单独用 ConversationBufferMemory 做短期记忆

Langchain 提供了 ConversationBufferMemory 类,可以用来存储和管理对话。

ConversationBufferMemory 包含input变量和output变量,input代表人类输入,output代表 AI 输出。

每次往ConversationBufferMemory组件里存入对话信息时,都会存储到history的变量里。

img

3.2. 利用 MessagesPlaceholder 手动添加 history

python复制代码from langchain.memory import ConversationBufferMemorymemory = ConversationBufferMemory(return_messages=True)
memory.load_memory_variables({})memory.save_context({"input": "我的名字叫张三"}, {"output": "你好,张三"})
memory.load_memory_variables({})memory.save_context({"input": "我是一名 IT 程序员"}, {"output": "好的,我知道了"})
memory.load_memory_variables({})from langchain.prompts import ChatPromptTemplate
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholderprompt = ChatPromptTemplate.from_messages([("system", "你是一个乐于助人的助手。"),MessagesPlaceholder(variable_name="history"),("human", "{user_input}"),]
)
chain = prompt | modeluser_input = "你知道我的名字吗?"
history = memory.load_memory_variables({})["history"]chain.invoke({"user_input": user_input, "history": history})user_input = "中国最高的山是什么山?"
res = chain.invoke({"user_input": user_input, "history": history})
memory.save_context({"input": user_input}, {"output": res.content})res = chain.invoke({"user_input": "我们聊得最后一个问题是什么?", "history": history})

执行结果如下:

img

3.3. 利用 ConversationChain 自动添加 history

我们利用 LangChain 的ConversationChain对话链,自动添加history的方式添加临时记忆,无需手动添加。一个实际上就是将一部分繁琐的小功能做了高度封装,这样多个链就可以组合形成易用的强大功能。这里的优势一下子就体现出来了:

ini复制代码from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholdermemory = ConversationBufferMemory(return_messages=True)
chain = ConversationChain(llm=model, memory=memory)
res = chain.invoke({"input": "你好,我的名字是张三,我是一名程序员。"})
res['response']res = chain.invoke({"input":"南京是哪个省?"})
res['response']res = chain.invoke({"input":"我告诉过你我的名字,是什么?,我的职业是什么?"})
res['response']

执行结果如下,可以看到利用ConversationChain对话链,可以让 LLM 快速拥有记忆:

img

3.4. 对话链结合 PromptTemplate 和 MessagesPlaceholder

在 Langchain 中,MessagesPlaceholder是一个占位符,用于在对话模板中动态插入上下文信息。它可以帮助我们灵活地管理对话内容,确保 LLM 能够使用最上下文来生成响应。

采用ConversationChain对话链结合PromptTemplateMessagesPlaceholder,几行代码就可以轻松让 LLM 拥有短时记忆。

ini复制代码prompt = ChatPromptTemplate.from_messages([("system", "你是一个爱撒娇的女助手,喜欢用可爱的语气回答问题。"),MessagesPlaceholder(variable_name="history"),("human", "{input}"),]
)
memory = ConversationBufferMemory(return_messages=True)
chain = ConversationChain(llm=model, memory=memory, prompt=prompt)res = chain.invoke({"input": "今天你好,我的名字是张三,我是你的老板"})
res['response']res = chain.invoke({"input": "帮我安排一场今天晚上的高规格的晚饭"})
res['response']res = chain.invoke({"input": "你还记得我叫什么名字吗?"})
res['response']

img

4. 使用长期记忆

短期记忆在会话关闭或者服务器重启后,就会丢失。如果想长期记住对话信息,只能采用长期记忆组件。

LangChain 支持多种长期记忆组件,比如ElasticsearchMongoDBRedis等,下面以Redis为例,演示如何使用长期记忆。

ini复制代码from langchain_community.chat_message_histories import RedisChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAImodel = ChatOpenAI(model="gpt-3.5-turbo",openai_api_key="sk-xxxxxxxxxxxxxxxxxxx",openai_api_base="https://api.aigc369.com/v1",
)prompt = ChatPromptTemplate.from_messages([("system", "你是一个擅长{ability}的助手"),MessagesPlaceholder(variable_name="history"),("human", "{question}"),]
)chain = prompt | modelchain_with_history = RunnableWithMessageHistory(chain,# 使用redis存储聊天记录lambda session_id: RedisChatMessageHistory(session_id, url="redis://10.22.11.110:6379/3"),input_messages_key="question",history_messages_key="history",
)# 每次调用都会保存聊天记录,需要有对应的session_id
chain_with_history.invoke({"ability": "物理", "question": "地球到月球的距离是多少?"},config={"configurable": {"session_id": "baily_question"}},
)chain_with_history.invoke({"ability": "物理", "question": "地球到太阳的距离是多少?"},config={"configurable": {"session_id": "baily_question"}},
)chain_with_history.invoke({"ability": "物理", "question": "地球到他俩之间谁更近"},config={"configurable": {"session_id": "baily_question"}},
)

LLM 的回答如下,同时关闭 session 后,直接再次提问最后一个问题,LLM 仍然能给出正确答案。

只要configurable配置的session_id能对应上,LLM 就能给出正确答案。

img

然后,继续查看redis存储的数据,可以看到数据在 redis 中是以 list的数据结构存储的。

img

5. 总结

本文介绍了 LLM 缺乏记忆功能的固有缺陷,以及记忆组件的原理,还讨论了如何利用 LangChain 给 LLM 装上记忆组件,让 LLM 能够在对话中更好地保持上下文。希望对你有帮助!

读者福利:如果大家对大模型感兴趣,这套大模型学习资料一定对你有用

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

资源分享

图片

大模型AGI学习包

图片

图片

资料目录

  1. 成长路线图&学习规划
  2. 配套视频教程
  3. 实战LLM
  4. 人工智能比赛资料
  5. AI人工智能必读书单
  6. 面试题合集

人工智能\大模型入门学习大礼包》,可以扫描下方二维码免费领取

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

图片

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩

图片

3.LLM

大家最喜欢也是最关心的LLM(大语言模型)

图片

人工智能\大模型入门学习大礼包》,可以扫描下方二维码免费领取

相关文章:

LangChain让LLM带上记忆

最近两年,我们见识了“百模大战”,领略到了大型语言模型(LLM)的风采,但它们也存在一个显著的缺陷:没有记忆。 在对话中,无法记住上下文的 LLM 常常会让用户感到困扰。本文探讨如何利用 LangCha…...

Word恢复历史文档,记好4个方法就足够

“我正在准备一个重要的报告,但是电脑突然就崩溃了,导致我的文档还没保存就被关闭了,大家有什么方法可以恢复Word历史文档吗?快给我出出主意吧!” 在数字化时代,文档编辑和保存已经成为我们日常工作和学习中…...

收银系统源码-千呼新零售2.0【线上营销】

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看&a…...

OnlyOffice测评

官方链接: https://www.onlyoffice.com/zh/office-suite.aspx https://www.onlyoffice.com/zh/pdf-editor.aspx OnlyOffice:引领办公效率的新标杆 在数字化时代的浪潮中,办公软件已经成为我们日常工作中不可或缺的一部分。然而,…...

UDS - 8 Application layer protocol

8 应用层协议 来自:ISO 14229-1-2020.pdf 8.1 一般定义 应用层协议应始终是确认消息传输,这意味着对于从客户端发送的每个服务请求,服务器应发送一个或多个相应的响应。 此规则的唯一例外是使用功能寻址或请求/指示指定不生成响应/确认的少数情况。为了不给系统带来许多不…...

二叉树公共最近祖先

文章目录 1. **二叉搜索树(Binary Search Tree, BST)**2. **一般二叉树****递归方法**:**迭代方法**: 案例展示二叉搜索树(BST)中查找LCA一般二叉树中查找LCA1. **使用哈希表存储父节点信息**2. **处理多个查询**3. **异常处理**结…...

智慧运维系统指导规范

随着信息技术的迅猛发展,智慧运维系统在现代企业中扮演着越来越重要的角色。为了提高运维效率、保障系统稳定运行,并制定一套科学、合理的智慧运维系统指导规范至关重要。本规范旨在为企业提供一套全面、系统的智慧运维管理方法和操作准则,以…...

最新自助下单彩虹云商城系统源码,含小储云商城模板免授权

最新彩虹商城源码,含小储云商城模板免授权,试用了一下还行,具体的大家可以看看 源码下载:https://download.csdn.net/download/m0_66047725/89405387 更多资源下载:关注我。...

头条系统-05-延迟队列精准发布文章-概述添加任务(db和redis实现延迟任务)、取消拉取任务定时刷新(redis管道、分布式锁setNx)

文章目录 延迟任务精准发布文章1)文章定时发布2)延迟任务概述2.1)什么是延迟任务2.2)技术对比2.2.1)DelayQueue2.2.2)RabbitMQ实现延迟任务2.2.3)redis实现 3)redis实现延迟任务4)延迟任务服务实现4.1)搭建heima-leadnews-schedule模块4.2)数据库准备4.3)安装redis4.4)项目集成…...

.gitignore git添加忽略文件

在项目的根目录下创建一个名为 .gitignore 的文件。在这个文件中,列出您希望Git忽略的文件和文件夹的名称或模式。 下面是一些基本的步骤和规则: 创建 .gitignore 文件:在项目根目录下创建一个名为 .gitignore 的文件。如果没有这个文件&…...

面向遥感图像的多阶段特征融合目标检测方法

源自:电子学报 作者:陈立 张帆 郭威 黄赟 注:若出现无法显示完全的情况,可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 遥感图像目标具有多尺度、大横纵比、多角度等特性,给传统的目标检测方法带来了新的…...

操作系统面试篇一

很多读者抱怨计算操作系统的知识点比较繁杂,自己也没有多少耐心去看,但是面试的时候又经常会遇到。所以,我带着我整理好的操作系统的常见问题来啦!这篇文章总结了一些我觉得比较重要的操作系统相关的问题比如 用户态和内核态、系统…...

OPenFast软件中的NRELOffshrBsline5MW_Onshore_ServoDyn.dat文件详解

我先简单概括一下,后续我再详细总结:文件“NRELOffshrBsline5MW_Onshore_ServoDyn.dat”是用于NREL 5.0 MW基准风力发电机的ServoDyn模块的输入文件。它定义了仿真控制、变桨控制、发电机和扭矩控制、偏航控制以及输出设置等各种参数。以下是主要内容的总…...

搭建rtmp/rtsp流媒体服务器的步骤

很多文章介绍使用ffmpeg推送和拉流,执行推流命令: D:\software\ffmpeg-7.0.1-full_build\bin\ffmpeg.exe -re -stream_loop -1 -i "D:\Video\汪汪队立大功\S07\001.mp4" -vcodec h264 -acodec aac -f flv rtmp://127.0.0.1/live/test110 经常…...

vue自定义事件传递数据

页面应用一个组件,采用自定义事件来传递参数 $emit是Vue实例的一个方法,它用于触发自定义事件。这些事件可以被父组件监听到,从而实现子组件向父组件的通信。 这种方法的好处在于,它可以让数据的流动保持单向,有助于…...

TensorBoard 安装与启动

安装&#xff1a;pip install tensorboard启动&#xff1a;tensorboard --logdir<events_directory_name> events_directory_name 为运行 tensorboard 后&#xff0c;产生的 events 文件所在的路径 博客参考&#xff1a;TensorBoard最全使用教程...

云计算运维工程师的突发状况处理

云计算运维工程师在应对突发的故障和紧急情况时,需要采取一系列迅速而有效的措施来最小化服务中断的时间并恢复系统的稳定性。 以下是一些关键步骤和策略: 快速响应: 立即识别并确认故障的性质和范围。通知团队成员和相关的利益相关者,确保所有人了解当前情况。故障诊断:…...

【CSS in Depth 2 精译】1.6 本章小结

1.6 本章小结 浏览器遵循层叠规则来确定哪些样式在哪些元素上生效&#xff1b;选择器优先级由选择器中的 id 数、class 类的个数以及标签名的个数来共同确定。优先级更高的声明将覆盖较低声明&#xff1b;当某些属性没有层叠值时&#xff0c;它们会从父元素继承一个样式值。这…...

FFmpeg源码:ff_h2645_extract_rbsp函数分析

一、ff_h2645_extract_rbsp函数的声明 ff_h2645_extract_rbsp函数的声明放在FFmpeg源码&#xff08;本文演示用的FFmpeg源码版本为5.0.3&#xff0c;该ffmpeg在CentOS 7.5上通过10.2.1版本的gcc编译&#xff09;的头文件libavcodec/h2645_parse.h中。 /*** Extract the raw (u…...

关于 AD21导入电子元器件放置“3D体”STEP模型失去3D纹理贴图 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139969415 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

DownKyi哔哩下载姬:5步快速掌握B站视频下载完整教程

DownKyi哔哩下载姬&#xff1a;5步快速掌握B站视频下载完整教程 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xf…...

如何用拯救者工具箱完全掌控联想笔记本:开源硬件管理终极指南

如何用拯救者工具箱完全掌控联想笔记本&#xff1a;开源硬件管理终极指南 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit 你…...

卷积运算:数字信号处理的核心原理与实践

1. 卷积在数字信号处理中的核心地位第一次接触卷积这个概念时&#xff0c;我正坐在实验室里调试一个音频滤波器。示波器上的波形始终无法达到预期效果&#xff0c;直到导师走过来画了那个著名的"翻转滑动"示意图。那一刻我突然明白&#xff0c;卷积不是抽象的数学运算…...

企业智能体架构解析:从LLM集成到自动化管理实践

1. 项目概述&#xff1a;一个面向企业管理的智能体架构最近在开源社区里&#xff0c;我注意到一个挺有意思的项目&#xff1a;kernelshreyak/company-manager-agent。光看这个名字&#xff0c;你可能会联想到一个简单的任务管理工具&#xff0c;但深入研究后&#xff0c;我发现…...

我花三天实测了DeepSeek V4,发现它根本不是来跟GPT-4o打架的

2026年4月24号&#xff0c;DeepSeek V4发布。 同一天&#xff0c;GPT-5.5也发布了。 这不是巧合&#xff0c;这是宣战。 但测了三天之后&#xff0c;我发现一个反直觉的结论&#xff0c;DeepSeek V4的真正对手根本不是GPT-4o&#xff0c;也不是Claude 3.5。 它要干掉的&#xf…...

有机颜料哪个更前沿

下游行业不断升级&#xff0c;从环保要求到个性化着色需求都在提升&#xff0c;很多采购和技术负责人都会问&#xff1a;现在有机颜料哪个方向更前沿&#xff1f;其实有机颜料的技术迭代始终围绕下游需求走&#xff0c;没有绝对的“最优前沿”&#xff0c;只有更适配自身需求的…...

HFSS主从边界条件实战:用周期性边界快速搞定天线阵列仿真(附微带贴片案例)

HFSS主从边界条件实战&#xff1a;周期性边界在天线阵列仿真中的高效应用 在射频工程领域&#xff0c;天线阵列的仿真往往面临计算资源消耗大、耗时长的问题。传统全阵列建模方式对硬件性能要求极高&#xff0c;尤其当单元数量超过数十个时&#xff0c;仿真时间可能呈指数级增长…...

AI产品经理 VS 传统产品经理:不是技术升级,而是物种进化!你准备好了吗?

文章指出&#xff0c;AI时代的产品经理并非仅仅是懂点AI技术的传统产品经理升级版&#xff0c;而是完全不同的“物种”。文章从产品经理的职责、核心能力、与AI的协作模式等方面对比了传统产品经理和AI产品经理的区别&#xff0c;强调AI产品经理需要具备处理意图模糊性、设计失…...

【仅限首批内测团队获取】AI Agent Serverless标准化交付套件(含Terraform模块+OpenTelemetry追踪模板+合规审计清单)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI Agent Serverless应用的演进逻辑与范式跃迁 AI Agent 与 Serverless 的融合并非技术堆叠&#xff0c;而是计算范式在智能体自治性、事件驱动粒度和资源契约关系三重维度上的结构性重构。早期云函数仅…...

Cron表达式智能解析与生成工具:提升定时任务开发效率

1. 项目概述&#xff1a;一个为Cron表达式减负的智能助手 如果你是一名运维工程师、后端开发者&#xff0c;或者任何需要与定时任务打交道的人&#xff0c;那么你一定对Cron表达式又爱又恨。爱的是它那套简洁而强大的语法&#xff0c;能精准地定义“每月的第一个星期一的凌晨3…...