【LangChain】Memory
概要
大多数LLM
应用都有对话界面。对话的一个重要组成部分是能够引用对话中先前介绍的信息。至少,对话系统应该能够直接访问过去消息的某些窗口。更复杂的系统需要有一个不断更新的世界模型,这使得它能够执行诸如维护有关实体及其关系的信息之类的事情。
我们将这种存储过去交互信息的能力称为“记忆”。 LangChain
提供了许多用于向系统添加记忆
的实用程序。这些实用程序可以单独使用,也可以无缝地合并到链中。
记忆
系统需要支持两个基本操作:读和写。回想一下,每个链都定义了一些需要某些输入的核心执行逻辑。其中一些输入直接来自用户,但其中一些输入可以来自用户。在给定的运行中,一条链将与其记忆
系统交互两次。
-
在收到初始用户输入之后但在执行核心逻辑之前,链将从其
记忆
系统中读取并增加用户输入。 -
在执行核心逻辑之后但在返回答案之前,链会将当前运行的输入和输出写入
记忆
,以便在将来的运行中引用它们。
将记忆构建到系统中
任何记忆
系统中的两个核心设计决策是:
- 状态如何存储
- 如何查询状态
存储:聊天消息列表(Storing: List of chat messages)
任何记忆的基础都是所有聊天交互的历史记录。即使这些不全部直接使用,也需要以某种形式存储。
LangChain
记忆模块的关键部分之一就是用于存储这些聊天消息的一系列集成,从记忆列表到持久数据库。
聊天消息存储:如何使用聊天消息以及提供的各种集成
查询:聊天消息之上的数据结构和算法(Querying: Data structures and algorithms on top of chat messages)
保留聊天消息列表相当简单。不太直接的是建立在聊天消息之上的数据结构和算法,它们提供了最有用的消息的视图。
一个非常简单的记忆系统可能只返回每次运行的最新消息。稍微复杂一点的记忆系统可能会返回过去 K 条消息的简洁摘要。更复杂的系统可能会从存储的消息中提取实体,并且仅返回有关当前运行中引用的实体的信息。
每个应用程序对于如何查询记忆可能有不同的要求。记忆模块应该可以轻松地开始使用简单的记忆系统,并在需要时编写您自己的自定义系统。
记忆类型:构成
LangChain
支持的记忆类型的各种数据结构和算法
开始使用
我们来看看LangChain
中的记忆到底是什么样子的。在这里,我们将介绍与任意记忆类交互的基础知识。
我们来看看如何在链中使用ConversationBufferMemory
。 ConversationBufferMemory
是一种极其简单的内存形式,它仅将聊天消息列表保存在缓冲区中并将其传递到提示模板中。
from langchain.memory import ConversationBufferMemorymemory = ConversationBufferMemory()
memory.chat_memory.add_user_message("hi!")
memory.chat_memory.add_ai_message("whats up?")
从memory中返回哪些变量(What variables get returned from memory)
在进入链之前,从内存中读取各种变量。它有特定的名称,需要与链期望的变量保持一致。你可以通过调用memory.load_memory_variables({})
来查看这些变量是什么。
请注意,我们传入的空字典只是实际变量的占位符。如果您使用的memory类型取决于输入变量,您可能需要传入一些变量。
memory.load_memory_variables({})
结果:
{'chat_history': "Human: hi!\nAI: whats up?"}
在本例中,您可以看到 load_memory_variables
返回单个key: history。这意味着您的链(可能还有您的提示)期望输入名为:history
的key。
通常可以通过memory
类上的参数来控制此变量。例如,如果我们希望memory
变量key为 chat_history
,您可以执行以下操作:
memory = ConversationBufferMemory(memory_key="chat_history")
memory.chat_memory.add_user_message("hi!")
memory.chat_memory.add_ai_message("whats up?")
结果:
{'chat_history': "Human: hi!\nAI: whats up?"}
控制这些键的参数名称可能因memory
类型而异,但重要的是要了解:
(1) 这是可控的,
(2) 如何控制它。
记忆是字符串还是消息列表
最常见的记忆类型之一涉及返回聊天消息列表。这些可以作为单个字符串返回,全部连接在一起(当它们在 LLM 中传递时有用)或 ChatMessages 列表(当传递到 ChatModels 中时有用)。
默认情况下,它们作为单个字符串返回。为了作为消息列表返回,您可以设置 return_messages=True
memory = ConversationBufferMemory(return_messages=True)
memory.chat_memory.add_user_message("hi!")
memory.chat_memory.add_ai_message("whats up?")
结果:
{'history': [HumanMessage(content='hi!', additional_kwargs={}, example=False),AIMessage(content='whats up?', additional_kwargs={}, example=False)]}
哪些key被保存到记忆中(What keys are saved to memory)
通常,链会接收或返回多个输入/输出键。在这些情况下,我们如何知道要将哪些键保存到聊天消息历史记录中?这通常可以通过记忆类型上的 input_key
和 output_key
参数来控制。
如果只有一个输入/输出键,则可以不用写 input_key
和 output_key
参数。但是,如果有多个输入/输出键,那么您必须指定要使用哪个输入/输出键的名称
端到端示例(End to end example)
最后,让我们看一下在链中使用它。我们将使用 LLMChain
,并展示如何使用 LLM
和 ChatModel
。
使用LLM
的例子:
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemoryllm = OpenAI(temperature=0)
# 请注意,提示模板中存在“chat_history”
template = """你是一个很好的聊天机器人,正在与人类交谈。之前的对话:
{chat_history}新的人类问题: {question}
回复:"""
prompt = PromptTemplate.from_template(template)
# 请注意,我们需要对齐“memory_key”
memory = ConversationBufferMemory(memory_key="chat_history")
conversation = LLMChain(llm=llm,prompt=prompt,verbose=True,memory=memory
)
结果:
# 请注意,我们只是传入“question”变量 - “chat_history”由memory填充
conversation({"question": "hi"})
使用ChatModel
from langchain.chat_models import ChatOpenAI
from langchain.prompts import (ChatPromptTemplate,MessagesPlaceholder,SystemMessagePromptTemplate,HumanMessagePromptTemplate,
)
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemoryllm = ChatOpenAI()
prompt = ChatPromptTemplate(messages=[SystemMessagePromptTemplate.from_template("你是一个很好的聊天机器人,正在与人类交谈。"),# 这里的“variable_name”必须与memory对齐MessagesPlaceholder(variable_name="chat_history"),HumanMessagePromptTemplate.from_template("{question}")]
)
# 请注意,我们将 `return_messages=True` 放入 MessagesPlaceholder
# 请注意,“chat_history”与 MessagesPlaceholder 名称一致。
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conversation = LLMChain(llm=llm,prompt=prompt,verbose=True,memory=memory
)
结果:
# 请注意,我们只是传入“question”变量 - “chat_history”由memory填充
conversation({"question": "hi"})
总结
本篇讲解 聊天的历史记录: 如何存储、如何查询。
这里是使用ConversationBufferMemory
类来完成存储和查询的。
也就是关键下面这段代码:
# 构建一个memory
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
# 关联大模型
conversation = LLMChain(llm=llm,prompt=prompt,verbose=True,memory=memory
)
# 查询
# 请注意,我们只是传入“question”变量 - “chat_history”由memory填充
conversation({"question": "hi"})
ChatMessageHistory
公开两种方法和一个属性。
它公开的两个方法是 add_user_message
和 add_ai_message
,用于存储来自用户的消息和相应的 AI 响应。
它公开的属性是message
属性,用于访问所有以前的消息。
参考地址:
https://python.langchain.com/docs/modules/memory.html
相关文章:

【LangChain】Memory
概要 大多数LLM应用都有对话界面。对话的一个重要组成部分是能够引用对话中先前介绍的信息。至少,对话系统应该能够直接访问过去消息的某些窗口。更复杂的系统需要有一个不断更新的世界模型,这使得它能够执行诸如维护有关实体及其关系的信息之类的事情。…...

Java并发编程(六)线程池[Executor体系]
概述 在处理大量任务时,重复利用线程可以提高程序执行效率,因此线程池应运而生。 它是一种重用线程的机制,可以有效降低内存资源消耗提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行线程池可以帮助我们更好地管理线程的生命周期和资源使用,…...

macOS CLion 使用 bits/stdc++.h
macOS 下 CLion 使用 bits/stdc.h 头文件 terminal运行 brew install gccCLion里配置 -D CMAKE_CXX_COMPILER/usr/local/bin/g-11...

PS出现的问题——为什么PS另存的格式少了很多
在WIN11系统里面新安装的22和23版本PS会出现另存格式少的情况 解决方式:编辑——首选项——文件处理——开启旧版储存为 解决...
【Linux】进程通信篇Ⅱ:共享内存、消息队列、信号量
文章目录 一、共享内存1.1 一些接口1. shmget 函数:申请一个 system v 的共享内存块2. ftok 函数:设置唯一标识码3. shmctl 函数:控制 system v 的共享内存块(可以删除、查看...)4. shmat 函数:将进程与共享…...
8.14 校招 内推 面经
绿泡泡: neituijunsir 交流裙,内推/实习/校招汇总表格 1、半导体芯片一周资讯 - 小米OPPO之后,星纪魅族调整芯片业务,今年应届生或被全部优化,英伟达2024推出比H100更快的芯片 半导体芯片一周资讯 - 小米OPPO之后&…...

阿里云服务器安装部署Docker使用教程
本文阿里云百科分享如何在云服务ECS实例上,部署并使用Docker。Docker是一款开源的应用容器引擎,具有可移植性、可扩展性、高安全性和可管理性等优势。开发者可将应用程序和依赖项打包到一个可移植的容器中,快速发布到Linux机器上并实现虚拟化…...

WebRTC | ICE详解
目录 一、Candidate种类与优先级 二、ICE策略 1. iceServers 2. iceTransportPolicy 三、P2P连接 1.Nat类型 (1)完全锥型NAT (2)IP限制锥型NAT (3)端口限制锥型NAT (4)对称…...

网络设备(防火墙、路由器、交换机)日志分析监控
外围网络设备(如防火墙、路由器、交换机等)是关键组件,因为它们控制进出公司网络的流量。因此,监视这些设备的活动有助于 IT 管理员解决操作问题,并保护网络免受攻击者的攻击。通过收集和分析这些设备的日志来监控这些…...

2023年国赛数学建模思路 - 复盘:人力资源安排的最优化模型
文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 描述 …...

Compute shader SV 理解图
本图转子:【Computeshader】个人总结_蒋伟博的博客-CSDN博客...

生信豆芽菜-多种算法计算免疫浸润
网址:http://www.sxdyc.com/immuneInfiltration 一、使用方法 1、数据准备 一个全编码蛋白的表达谱基因,其中行为基因,列为样本 第一列为基因为行名,不能重复 2、选择计算的方法(这里提供了5种免疫计算的方法&#x…...

逆向破解学习-单机斗地主
试玩 破解思路 9000 是成功的代码 Hook代码 import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookComJuneGameDouDiZhu extends HookImpl{ Override p…...

matplotlib绘制位置-时序甘特图
文章目录 1 前言2 知识点2.1 matplotlib.pyplot.barh2.2 matplotlib.legend的handles参数 3 代码实现4 绘制效果5 总结参考 1 前言 这篇文章的目的是,总结记录一次使用matplotlib绘制时序甘特图的经历。之所以要绘制这个时序甘特图,是因为22年数模研赛C…...

数据库概述、部署MySQL服务、必备命令、密码管理、安装图形软件、SELECT语法 、筛选条件
Top NSD DBA DAY01 案例1:构建MySQL服务器案例2:密码管理案例3:安装图形软件案例4:筛选条件 1 案例1:构建MySQL服务器 1.1 问题 在IP地址192.168.88.50主机和192.168.88.51主机上部署mysql服务练习必备命令的使用 …...

概率论与数理统计:第四章:随机变量的数字特征
文章目录 Ch4. 随机变量的数字特征1. 数学期望E(X)(1)数学期望的概念1.离散型①一维离散型随机变量X的数学期望: E X EX EX②一维离散型随机变量的函数的期望: E [ g ( X ) ] E[g(X)] E[g(X)]③二维离散型随机变量的函数的期望: E [ g ( X , …...
解决饿了么ui的对话框缩放和移动
import Vue from "vue";// v-dialogDrag: 弹窗拖拽水平方向伸缩 /** 使用方法* 将以下代码复制到一个js文件中,然后在入口文件main.js中import引入即可;* 给elementUI的dialog上加上 v-dialogDrag 指令就可以实现弹窗的全屏和拉伸了。* 给…...
Linux 中复制文件并保持修改时间等属性
一、遇到的问题 Linux使用cp命令复制文件备份时,发现文件的修改时间变成当前时间了,想要保留备份文件原有的修改时间及其它文件属性。 二、实现 1、cp命令 在 Linux 中,你可以使用 cp 命令来复制文件,并通过 -p 或 --preserve…...

Hugging News #0814: Llama 2 学习资源大汇总
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息࿰…...
可视化绘图技巧100篇进阶篇(五)-阶梯线图(Step Chart)
目录 前言 图表类型特征 适用场景 图例 绘图工具及代码实现 ECharts SMARTBI...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...