langchain 记忆力(memory),让语言大模型拥有记忆

news2024/11/18 2:41:32

1,简介

存储对话历史中的信息的能力称之为’记忆‘,这种工具可以单独使用,也可以无缝的集成到一条链中,记忆的存储长度是程序执行到结束,执行一次的所有记忆。
记忆的主要应用场景就是聊天机器人,聊天机器人的一个关键功能是它们能够使用先前对话的内容作为上下文。
记忆力在实际使用的逻辑:
在这里插入图片描述
记忆力在使用中可以分一下几个场景:
在这里插入图片描述
记忆力的几个重要的类:
ConversationBufferMemory会话缓冲区
如实的记录列表中记录的对话历史消息,并且是记录所有的历史消息,随着历史记录的增加,运行会越来越慢,直到大模型无法处理.适用于交互次数少,输入输出字符量不大的情况下
ConversationBufferWindowMemory会话缓冲窗口
持续记录对话历史,但只使用最近的k个交互。确保缓存大小不会过大,运行速度比较稳定
ConversationSummaryMemory会话摘要
随着时间的推移总结对话内容,并且将摘要存储在记忆中,需要的时候将摘要注入提示词或链中,缓存不会过大,运行稳定,但是运行速度比ConversationBufferWindowMemory慢很多,因为他在写入记忆的时候,做了一个摘要的操作.这使得她可以记住很长的交互记忆,不过随着交互的增加,摘要的内容不断迭代更换,使得某些内容会遗失.
VectorStoreRetrieverMemory向量存储
将记忆存储在向量存储中,并在每次调用时查询前K个最"显著"的文档。 与大多数其他记忆类不同的是,它不明确跟踪交互的顺序。 在这种情况下,"文档"是先前对话片段。这对于提及AI在对话中早些时候被告知的相关信息可能是有用的。这段话是官方文档的描述,猜测应该是将记忆做成了一个文档,使用文档阅读器来进行读取

2,使用代码示例

下面的示例没有使用上面四个重要的类,下面的示例主要使用让我们更加直观理解记忆力的运行逻辑。
手动一个简单聊天记录消息的记忆聊天
通过手动添加聊天消息,实现记忆力功能。

import os
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from langchain_community.chat_models import QianfanChatEndpoint
from langchain_core.messages import AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder



os.environ["QIANFAN_AK"] = "*****"  # 这里需要修改为自己的实际值
os.environ["QIANFAN_SK"] = "*****"  # 这里需要修改为自己的实际值

def load_embedding_mode():
    return HuggingFaceEmbeddings(model_name='text2vec-base-chinese',
                                   model_kwargs={'device': 'cpu'})

model = QianfanChatEndpoint(
    streaming=True,
    model="ERNIE-Bot",
)

##手动一个简单聊天记录消息的记忆聊天
##占位符
prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一个乐于助人的助手。尽你所能回答所有的问题。",
        ),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

chain = prompt | model
rep = chain.invoke(
    {
        "messages": [
            HumanMessage(content="将这句话从汉语翻译成英语:我喜欢编程。"),
            AIMessage(content="I love programming"),
            HumanMessage(content="你刚刚说什么?"),
        ]
    }
)

print(rep)
#content='我刚刚说的是:“I love programming”,意思是“我喜欢编程”。如果您有任何其他问题或需要进一步的解释,请随时告诉我。' additional_kwargs={} response_metadata={'token_usage': {'input_tokens': 30, 'output_tokens': 24, 'total_tokens': 54}, 'model_name': 'ERNIE-Bot', 'finish_reason': 'stop'} id='run-215d46b1-c8bf-4f7b-bbf3-50afaceb947e-0' usage_metadata={'input_tokens': 30, 'output_tokens': 24, 'total_tokens': 54}

聊天记录储存和加载
将聊天记录储存在内存中,读取内存的中记录实现记忆力聊天功能。

import os
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from langchain_community.chat_models import QianfanChatEndpoint
from langchain_core.messages import AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder



os.environ["QIANFAN_AK"] = "*****"  # 这里需要修改为自己的实际值
os.environ["QIANFAN_SK"] = "*****"  # 这里需要修改为自己的实际值

def load_embedding_mode():
    return HuggingFaceEmbeddings(model_name='text2vec-base-chinese',
                                   model_kwargs={'device': 'cpu'})

model = QianfanChatEndpoint(
    streaming=True,
    model="ERNIE-Bot",
)
from langchain_community.chat_message_histories import ChatMessageHistory

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一个乐于助人的助手。尽你所能回答所有的问题。",
        ),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

chain = prompt | model

demo_ephemeral_chat_history = ChatMessageHistory()
input1 = "这里的天气非常好,空气也干净"
demo_ephemeral_chat_history.add_user_message(input1)

response = chain.invoke(
    {
        "messages": demo_ephemeral_chat_history.messages
    }
)
demo_ephemeral_chat_history.add_ai_message(response)

input2 = "你刚刚说了什么?"

demo_ephemeral_chat_history.add_user_message(input2)

rep = chain.invoke(
    {
        "messages": demo_ephemeral_chat_history.messages
    }
)
print(rep)
#content='我刚刚说听起来你所在的地方天气很好,空气也很干净,是个适合居住的好地方。我还问了你是否有什么计划或者想法,想要在这样的好天气里做些什么。' additional_kwargs={} response_metadata={'token_usage': {'input_tokens': 61, 'output_tokens': 34, 'total_tokens': 95}, 'model_name': 'ERNIE-Bot', 'finish_reason': 'stop'} id='run-02d24630-5c6a-466a-83be-c1133bab7f70-0' usage_metadata={'input_tokens': 61, 'output_tokens': 34, 'total_tokens': 95}

自动聊天历史记录管理
这里加上了一个session_id用于区分不同的用户的消息记录,在实际中使用不可能都是一个人在使用。那么就要使用人加上id用以区分聊天记录。

import os
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from langchain_community.chat_models import QianfanChatEndpoint
from langchain_core.messages import AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder



os.environ["QIANFAN_AK"] = "*****"  # 这里需要修改为自己的实际值
os.environ["QIANFAN_SK"] = "*****"  # 这里需要修改为自己的实际值

def load_embedding_mode():
    return HuggingFaceEmbeddings(model_name='text2vec-base-chinese',
                                   model_kwargs={'device': 'cpu'})

model = QianfanChatEndpoint(
    streaming=True,
    model="ERNIE-Bot",
)
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "你是一个乐于助人的助手。尽你所能回答所有的问题。",
        ),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}")
    ]
)

chain = prompt | model

demo_ephemeral_chat_history_for_chain = ChatMessageHistory()
chain_with_message_history = RunnableWithMessageHistory(
    chain,
    lambda session_id: demo_ephemeral_chat_history_for_chain,
    input_messages_key="input",
    history_messages_key="chat_history",
)
rep = chain_with_message_history.invoke(
    {"input": "这里的天气非常好,空气也干净"},
    {"configurable": {"session_id": "9999"}}
)
print(rep)
#content='那真是太好了!好的天气和清新的空气可以让人心情愉悦,也有益于身体健康。你可以享受这样的好天气,做些户外活动,比如散步、跑步或者骑自行车。这些活动不仅可以锻炼身体,还可以让你更加接近自然,感受大自然的美好。' additional_kwargs={} response_metadata={'token_usage': {'input_tokens': 21, 'output_tokens': 48, 'total_tokens': 69}, 'model_name': 'ERNIE-Bot', 'finish_reason': 'stop'} id='run-7d37d6da-96dd-4d9c-8198-d40992e3f51c-0' usage_metadata={'input_tokens': 21, 'output_tokens': 48, 'total_tokens': 69}

rep1 = chain_with_message_history.invoke(
    {"input": "刚刚说了什么?"},
    {"configurable": {"session_id": "9999"}}
)
print(rep1)
#content='您刚刚说:“这里的天气非常好,空气也干净。” 这是一个很好的观察,好的天气和清新的空气确实能给人带来愉悦和舒适的感觉。' additional_kwargs={} response_metadata={'token_usage': {'input_tokens': 73, 'output_tokens': 31, 'total_tokens': 104}, 'model_name': 'ERNIE-Bot', 'finish_reason': 'stop'} id='run-115dafff-81f1-4165-8d5b-ce16f0915349-0' usage_metadata={'input_tokens': 73, 'output_tokens': 31, 'total_tokens': 104}

以上就是记忆力的简单介绍和使用,为日后的使用中添加深入的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第429题N叉树的层序遍历

题目: 题解: func levelOrder(root *Node) (ans [][]int) {if root nil {return}q : []*Node{root}for q ! nil {level : []int{}tmp : qq nilfor _, node : range tmp {level append(level, node.Val)q append(q, node.Children...)}ans append(a…

误删回收站的文件怎么恢复正常,不小心删除回收站的文件怎么找回

现如今,电脑在工作中承担着很重要的角色,里面往往存储着很多重要的工作资料文件,而回收站作为电脑对数据文件的最后保护,往往能够避免数据文件的丢失。下面就给大家详细讲解有关,误删回收站的文件怎么恢复,…

AI日常绘画【国庆海报】:盛世迎华诞,最强AI绘图大模型Flux国庆节海报制作教程

大家好,我是画画的小强 马上就要到祖国母亲的节日了,想想心里都美滋滋的,终于可以放松一下了。相信AI绘画关于国庆主题肯定也会精彩纷呈吧,今天和大家分享几组关于国庆海报的制作教程。 本文使用基于Flux的相关Lora模型。 Loar1…

Docker快速部署RabbitMq教程

1、拉取RabbitMQ镜像 docker pull rabbitmq:management RabbitMQ Management 插件为 RabbitMQ 提供了一个基于 Web 的用户界面(Management UI),允许你通过浏览器来监控、管理 RabbitMQ 实例。 因为docker默认是使用的是Docker Hub的官方镜…

Matlab进阶绘图第69期—同步坐标图

同步坐标是指将同一figure上的两个或两个以上的子图,用相同的X轴、Y轴或XY轴表示,以方便同步分析。 话不多说,先来看一下同步坐标图的成品效果: 特别提示:本期内容『数据代码』已上传资源群中,加群的朋友请…

RocketMQ 常用命令mqadmin与控制面板

使⽤发送和接收消息验证MQ 验证生产者: 配置 nameserver 的环境变量 ,在发送/ 接收消息之前,需要告诉客户端 nameserver 的位置。配置环境变量 NAMESRV_ADDR : vim /etc/profileexport NAMESRV_ADDR"192.168.136.66:9876;1…

虚幻引擎第三人称和第一人称任意切换

虚幻引擎想要在第三人称和第一人称之间任意切换 , 就需要创建两个摄像机 第一人称摄像机 默认激活 去掉勾选 然后添加一个增强输入 双击进去绑定 设置成已按下 , 这样长按只会生效一次 打开第三人称事件图表 , 按如图所示设置即可 , 记得设置第一人称用控制器旋转Yaw , 这…

【机器学习】音乐生成——AI如何创作个性化音乐与配乐

我的主页:2的n次方_ 音乐是人类文化的重要组成部分,它具有极强的情感表达和艺术价值。近年来,随着人工智能技术的飞速发展,AI已经能够自动生成音乐,甚至根据用户需求创作个性化配乐。AI生成音乐的应用场景广泛&…

antd嵌套表单验证

好久之前写的,但是突然想起来没写到这里,还是写一下吧~, 也没啥技术含量,就是有需要的同学要是能一下子看到就方便了~ 嵌套表单项精髓就是在shouldUpdate属性 注意这句,当 shouldUpdate 为 true 时,Form 的任意变化都…

LVS-NAT实战案例,实现四层负载均衡

工作原理 架构概述: 在LVS-NAT架构中,客户端的请求首先到达负载均衡器(LVS服务器),然后由LVS根据一定的算法将请求转发到后端的真实服务器。负载均衡器会通过NAT技术修改数据包的源地址和目标地址。 数据流转&#xff…

C++之STL—常用遍历算法

算法头文件 <algorithm>是所有STL头文件中最大的一个&#xff0c;范围涉及到比较、 交换、查找、遍历操作、复制、修改等等 <numeric>体积很小&#xff0c;只包括几个在序列上面进行简单数学运算的模板函数 <functional>定义了一些模板类,用以声明函数对象…

Blob数据类型报错时如何获取错误信息

const pdfOrg async (record) > {// 假设 transferExportPdf是结构 result 返回的错误信息let result await transferExportPdf({ batchId: record.batchId });//blob 结构const blob new Blob([result], {type: result.type,});if (blob.type "application/json&q…

【EPLAN】解决ELM与ELC授权不匹配问题

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决EPLAN授权-ELM与ELC授权不匹配问题&#xff1b; 2、 问题场景 用于解决在EPLAN 服务器端 ELM 授权进行了更新激活&#xff0c;客户端授权连接后&#xff0c;客户端 ELC 授权信息没有变更的情况&#xff0c;尝试…

02 图结构

目录 图的基本概念图的存储结构图的遍历最小生成树最短路径问题 1.图的基本概念 图是由顶点集合及顶点间的关系组成的一种数据结构&#xff1a;G&#xff08;V&#xff0c;E&#xff09;&#xff0c;其中&#xff1a; 顶点集合V{x | x属于某个数据对象集} 是有穷非空集合 E {…

无人机之侦测技术篇

无人机的侦测技术是综合利用多种传感器来“发现”或“找到”无人机目标&#xff0c;并通过分析其物理属性&#xff08;如光学特性、热学特性、声学特性、磁学特性&#xff09;来进行识别和跟踪。 一、雷达探测 原理&#xff1a;雷达系统通过发射电磁波&#xff0c;利用无人机…

15年408计算机网络

第一题&#xff1a; 解析&#xff1a; 接收方使用POP3向邮件服务器读取邮件&#xff0c;使用的TCP连接&#xff0c;TCP向上层提供的是面向连接的&#xff0c;可靠的数据传输服务。 第二题&#xff1a; 解析&#xff1a;物理层-不归零编码和曼彻斯特编码 编码1&#xff1a;电平在…

【小程序 - 大智慧】Expareser 组件渲染框架

目录 问题思考课程目标Web Component类型说明定义组件属性添加 Shadow DOMTemplate and SlotExparser 框架原理自定义组件内置组件 下周计划 问题思考 首先&#xff0c;给大家抛出去几个问题&#xff1a; 前端框架 Vue React 都有自己的组件库&#xff0c;但是并不兼容&#…

Vxe UI vue vxe-table vxe-grid 单元格与表尾单元格如何格式化数据

Vxe UI vue vxe-table vxe-grid 单元格与表尾单元格如何格式化数据 查看 github vxe-table 官网 单元格内容格式化 通过 formatter 属性自定义格式化方法 <template><div><vxe-grid v-bind"gridOptions"></vxe-grid></div> </t…

软考高级:SOA 和微服务 AI 解读

概念讲解 SOA&#xff08;面向服务架构&#xff09;和微服务虽然都是服务架构的设计模式&#xff0c;但它们的侧重点和实现方式有很大区别。为了帮助你理解这两个概念&#xff0c;我们可以从生活中的例子、概念本身的讲解以及记忆方法三方面入手。 生活化例子 **SOA&#xf…

python高级用法_闭包

闭包 在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包 简单闭包 def outer(logo):def inner(msg):print("<%s>%s<%s>" % (logo, msg, …