tnblog
首页
视频
资源
登录

LangChain 记忆组件(学习笔记)

6088人阅读 2023/9/16 18:28 总访问:3456997 评论:0 收藏:0 手机
分类: python

LangChain 记忆组件(学习笔记)


单一的LLM对于简单的应用场景已经足够,但是更复杂的应用程序需要将LLM串联在一起,需要多LLM协同工作。

简介


大多数LLM应用都具有对话界面。
对话的一个重要组成部分是对话历史中的信息。
我们将这种存储对话历史中的信息的能力称为记忆
LangChain 提供了一系列记忆相关的实用工具。
这些工具可以单独使用,也可以无缝地集成到一条链中。

记忆组件需要支持

  • 读取
  • 写入

注:每条链定义了核心执行逻辑,期望某些输入。
一些输入来自用户,另一些可能来自记忆组件。
在一次与LLM的交互中,链将与记忆组件交互两次:
1.接收到初始用户输入之后,执行核心逻辑之前,链从记忆组件读取历史,并以此增强用户输入。
2.执行核心逻辑之后,在返回回答之前,链把当前交互的输入和输出写入到记忆中,以便更新对话历史。

LangChain的记忆组件类型


记忆组件需要解决两大问题:
历史如何存储?
历史如何查询?
本讲通过 LangChain 提供的三种基本记忆组件类型 ConversationBufferMemoryConversationBufferWindowMemoryConversationSummaryMemory,介绍它们对于上述问题的解决方案,并分享使用方法。
在此之前请写写好openai的token,并安装相关包。

  1. import os
  2. os.environ['OPENAI_API_KEY'] = ''"
  1. !pip install langchain==0.0.235 --quiet

ConversationBufferMemory


ConversationBufferMemoryLangChain 提供的记忆组件类, 它如实地在列表中记录对话历史消息。

写入一次对话


通过 save_context 函数来保存用户输入和模型输出。

  1. from langchain.memory import ConversationBufferMemory
  2. memory = ConversationBufferMemory()
  3. memory.save_context({"input": "hi"}, {"output": "whats up"})


ConversationBufferMemorychat_memory 成员变量有一个 messages 变量。这是一个消息数组。通过如下代码查看消息对象列表

  1. memory.chat_memory.messages


你应该期望看到如下输出:

当我们需要生成对话历史的文本,作为变量嵌入提示词,可以通过调用函数 load_memory_variables 获得字典对象,其中的键 history 包含了对话历史的字符串值。如下:

  1. memory.load_memory_variables({})


你应该期望看到如下输出:


ConversationBufferMemory 的实现方式简单,在交互次数少,输入输出字符量不大的情况下,非常有效。
但是当交互增加,字符数量增多,对话历史的字符数可能导致增强后的提示词tokens数超过上下文限制,最终导致模型调用失败。
因此,LangChain 还提供了其他记忆组件类型。

ConversationBufferWindowMemory


ConversationBufferWindowMemory 持续记录对话历史,但只使用最近的K个交互。
这种滑动窗口的机制,确保缓存大小不会变得过大。
我们指定滑动窗口的大小为1,表示查询时只返回最近1次交互。
用法如下:

  1. memory = ConversationBufferWindowMemory( k=1)
  2. memory.save_context({"input": "Hi, LangChain!"}, {"output": "Hey!"})
  3. memory.save_context({"input": "Where are you?"}, {"output": "By your side"})


通过 load_memory_variables 读取记忆。

  1. memory.load_memory_variables({})


你应该期望看到如下输出:


我们看看记忆组件中存储的历史交互:

  1. memory.chat_memory.messages


输出:


可见,组件记忆了所有交互,但是在查询时通过滑动窗口返回指定数量的交互(输入与输出)。

ConversationSummaryMemory

  1. # 安装openai包
  2. !pip install openai


ConversationSummaryMemory 是稍微复杂的记忆类型。
这种记忆随着时间的推移总结对话的内容,并将当前的摘要存储在记忆中,然后在需要的时候将对话摘要注入提示词或链中。
ConversationSummaryMemory 对于更长的对话交互很有用,因为将过去的历史记录逐字逐句放入提示词中会占用太多Token。

注意:由于需要对于对话历史进行总结,生成摘要,因此 ConversationSummaryMemory 需要LLM的配合。
我们在示例代码中将提供OpenAI的模型给 ConversationSummaryMemory 以生成摘要。
简单来说:它会加以思考的连贯起来,但花的钱(token)也多。


用法如下:

  1. from langchain.memory import ConversationSummaryMemory
  2. from langchain.llms import OpenAI
  3. memory = ConversationSummaryMemory(llm=OpenAI(temperature=0, openai_api_key="您的有效openai api key"))
  4. memory.save_context({"input": "Hi, LangChain!"}, {"output": "Hey!"})
  5. memory.save_context({"input": "How to start with Next.js development?"}, {"output": "You can get started with its official developer guide."})
  6. memory.save_context({"input": "Show me the link of the guide."}, {"output": "I'm looking for you now. Please stand by!"})
  7. memory.load_memory_variables({})


你应该能看到如下输出:


你可能注意到了,从记忆组件中得到的对话历史的文本,相较于原始的对话文字,并没有显著地缩短。
原因在于对话的交互只有3次,在这种情况下,摘要的优势并没有显示出来。

下图是不同记忆类型组件随着对话交互的增加,生成的对话历史信息的Token开销趋势。
可见,ConversationSummaryMemory 的Token开销相对平缓,这对于交互多的对话是更有效的。


图中,还展示了我们并没有介绍的类型 Summary Buffer Memory
顾名思义,这是结合了 SummaryBuffer 的优势的一种记忆类型。

与LLM的交互

  1. from langchain.memory import ConversationSummaryMemory, ChatMessageHistory
  2. from langchain.llms import OpenAI
  3. from langchain.prompts import PromptTemplate
  4. from langchain.chains import LLMChain
  5. # 定义对话模板
  6. template = """You are a chatbot having a conversation with a human.
  7. {conversation_history}
  8. Human: {input}
  9. Chatbot:"""
  10. # 创建对话模板对象
  11. prompt = PromptTemplate(
  12. input_variables=["conversation_history", "input"], template=template
  13. )
  14. # 创建对话历史内存对象
  15. memory = ConversationBufferMemory(memory_key="conversation_history")
  16. # 创建聊天机器人链
  17. llm_chain = LLMChain(
  18. llm=OpenAI(),
  19. prompt=prompt,
  20. verbose=True,
  21. memory=memory,
  22. )
  1. llm_chain.predict(input="Where is Paris?")
  1. llm_chain.predict(input="What did I just ask?")

总结


本节课程中,我们学习了什么是 记忆组件 ,并通过三种基本记忆组件类型 ConversationBufferMemory(不动脑壳的回忆AI回答),ConversationBufferWindowMemory(动得不多的回忆AI回答),ConversationSummaryMemory(动脑壳的回忆AI回答,但也烧脑壳),介绍它们的工作原理和使用方法。
本课只介绍了 LangChain 提供的部分记忆组件,更多类型请参考官方文档 Memory Types

相关文档资料链接:


1.Python Langchain官方文档
2.记忆组件
3.五里墩茶社


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

LangChain 简单应用(学习笔记)

LangChain 简单应用(学习笔记)[TOC] Langchain 简介大型语言模型(LLM)正在成为一种具有变革性的技术,使开发人员能够构...

LangChain 模型(学习笔记)

LangChain 模型(学习笔记)[TOC] Langchain 模型简介Langchain所封装的模型分为两类:——大语言模型 (LLM)——聊天模型 (C...

LangChain 数据连接(学习笔记)

LangChain 数据连接(学习笔记)[TOC] 什么是数据连接?LLM应用往往需要用户特定的数据,而这些数据并不属于模型的训练集。L...

LangChain 提示词(学习笔记)

LangChain 提示词(学习笔记)[TOC] 什么是提示词?提示词(Prompt)是指向模型提供的输入。这个输入通常由多个元素构成。La...

LangChain 输出解析器(学习笔记)

LangChain 输出解析器(学习笔记)[TOC] 简介LLM的输出为文本,但在程序中除了显示文本,可能希望获得更结构化的数据。这就...

LangChain 链(学习笔记)

LangChain 链(学习笔记)[TOC] 单一的LLM对于简单的应用场景已经足够,但是更复杂的应用程序需要将LLM串联在一起,需要多LL...

LangChain 代理 Agent(学习笔记)

LangChain 代理 Agent(学习笔记)[TOC] 简介Agent 也就是代理,它的核心思想是利用一个语言模型来选择一系列要执行的动作。...

LangChain 回调 (Callback)

LangChain 回调 (Callback)[TOC] 简介Callback 是 LangChain 提供的回调机制,允许我们在 LLM 应用程序的各个阶段使用 Hoo...

LangChain 一个完整的例子

LangChain 一个完整的例子[TOC] 简介这是该 LangChain 极简入门系列的最后一讲。我们将利用过去9讲学习的知识,来完成一个...
这一世以无限游戏为使命!
排名
2
文章
633
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术