08|记忆:通过Memory记住客户上次买花时的对话细节

无论是LLM还是代理都是无状态的,每次模型的调用都是独立于其他交互的。也就是说,我们每次通过API开始和大语言模型展开一次新的对话,它都不知道你其实昨天或者前天曾经和它聊过天了。

使用ConversationChain

from langchain import OpenAI
from langchain.chains import ConversationChain# 初始化大语言模型
llm = OpenAI(temperature=0.5,model_name="text-davinci-003"
)# 初始化对话链
conv_chain = ConversationChain(llm=llm)# 打印对话的模板
print(conv_chain.prompt.template)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:
{history}
Human: {input}
AI:
  • {history} 是存储会话记忆的地方,也就是人类和人工智能之间对话历史的信息。
  • {input} 是新输入的地方,你可以把它看成是和ChatGPT对话时,文本框中的输入

image.png

使用ConversationBufferMemory

在LangChain中,通过ConversationBufferMemory(缓冲记忆)可以实现最简单的记忆机制。

from langchain import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferMemory# 初始化大语言模型
llm = OpenAI(temperature=0.5,model_name="text-davinci-003")# 初始化对话链
conversation = ConversationChain(llm=llm,memory=ConversationBufferMemory()
)# 第一天的对话
# 回合1
conversation("我姐姐明天要过生日,我需要一束生日花束。")
print("第一次对话后的记忆:", conversation.memory.buffer)#输出:
第一次对话后的记忆: 
Human: 我姐姐明天要过生日,我需要一束生日花束。
AI:  哦,你姐姐明天要过生日,那太棒了!我可以帮你推荐一些生日花束,你想要什么样的?我知道有很多种,比如玫瑰、康乃馨、郁金香等等。
# 回合2
conversation("她喜欢粉色玫瑰,颜色是粉色的。")
print("第二次对话后的记忆:", conversation.memory.buffer)#输出
第二次对话后的记忆: 
Human: 我姐姐明天要过生日,我需要一束生日花束。
AI:  哦,你姐姐明天要过生日,那太棒了!我可以帮你推荐一些生日花束,你想要什么样的?我知道有很多种,比如玫瑰、康乃馨、郁金香等等。
Human: 她喜欢粉色玫瑰,颜色是粉色的。
AI:  好的,那我可以推荐一束粉色玫瑰的生日花束给你。你想要多少朵?我可以帮你定制一束,比如说十朵、二十朵或者更多?

实际上,这些聊天历史信息,都被传入了ConversationChain的提示模板中的 {history} 参数,构建出了包含聊天记录的新的提示输入。
有了记忆机制,LLM能够了解之前的对话内容,这样简单直接地存储所有内容为LLM提供了最大量的信息,但是新输入中也包含了更多的Token(所有的聊天历史记录),这意味着响应时间变慢和更高的成本。
但是token太长,也是需要解决。

使用ConversationBufferWindowMemory

ConversationBufferWindowMemory 是缓冲窗口记忆,它的思路就是只保存最新最近的几次人类和AI的互动。

from langchain import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferWindowMemory# 创建大语言模型实例
llm = OpenAI(temperature=0.5,model_name="text-davinci-003")# 初始化对话链
conversation = ConversationChain(llm=llm,memory=ConversationBufferWindowMemory(k=1)
)# 第一天的对话
# 回合1
result = conversation("我姐姐明天要过生日,我需要一束生日花束。")
print(result)
# 回合2
result = conversation("她喜欢粉色玫瑰,颜色是粉色的。")
# print("\n第二次对话后的记忆:\n", conversation.memory.buffer)
print(result)# 第二天的对话
# 回合3
result = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(result)第三回合的输出:
{'input': '我又来了,还记得我昨天为什么要来买花吗?', 
'history': 'Human: 她喜欢粉色玫瑰,颜色是粉色的。\nAI:  好的,那粉色玫瑰花束怎么样?我可以帮你找到一束非常漂亮的粉色玫瑰花束,你觉得怎么样?', 
'response': '  当然记得,你昨天来买花是为了给你喜欢的人送一束粉色玫瑰花束,表达你对TA的爱意。'}

如果设置 k=1,这意味着窗口只会记住与AI之间的最新的互动,即只保留上一次的人类回应和AI的回应。

使用ConversationSummaryMemory

上面说了,如果模型在第二轮回答的时候,能够说出“我可以帮你为你姐姐找到…”,那么在第三轮回答时,即使窗口大小 k=1,还是能够回答出正确答案。
因为模型在回答新问题的时候,对之前的问题进行了总结性的重述
ConversationSummaryMemory(对话总结记忆)的思路就是将对话历史进行汇总,然后再传递给 {history} 参数。这种方法旨在通过对之前的对话进行汇总来避免过度使用 Token。
ConversationSummaryMemory有这么几个核心特点

  1. 汇总对话:此方法不是保存整个对话历史,而是每次新的互动发生时对其进行汇总,然后将其添加到之前所有互动的“运行汇总”中。
  2. 使用LLM进行汇总:该汇总功能由另一个LLM驱动,这意味着对话的汇总实际上是由AI自己进行的。
  3. 适合长对话:对于长对话,此方法的优势尤为明显。虽然最初使用的 Token 数量较多,但随着对话的进展,汇总方法的增长速度会减慢。与此同时,常规的缓冲内存模型会继续线性增长。
from langchain.chains.conversation.memory import ConversationSummaryMemory# 初始化对话链
conversation = ConversationChain(llm=llm,memory=ConversationSummaryMemory(llm=llm)
)第一回合的输出:
{'input': '我姐姐明天要过生日,我需要一束生日花束。', 
'history': '', 
'response': ' 我明白,你需要一束生日花束。我可以为你提供一些建议吗?我可以推荐一些花束给你,比如玫瑰,康乃馨,百合,仙客来,郁金香,满天星等等。挑选一束最适合你姐姐的生日花束吧!'}
第二回合的输出:
{'input': '她喜欢粉色玫瑰,颜色是粉色的。', 
'history': "\nThe human asked what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential. The human then asked the AI for advice on what type of flower bouquet to get for their sister's birthday, to which the AI provided a variety of suggestions.", 
'response': ' 为了为你的姐姐的生日准备一束花,我建议你搭配粉色玫瑰和白色康乃馨。你可以在玫瑰花束中添加一些紫色的满天星,或者添加一些绿叶以增加颜色对比。这将是一束可爱的花束,让你姐姐的生日更加特别。'}
第三回合的输出:
{'input': '我又来了,还记得我昨天为什么要来买花吗?', 
'history': "\n\nThe human asked what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential. The human then asked the AI for advice on what type of flower bouquet to get for their sister's birthday, to which the AI suggested pink roses and white carnations with the addition of purple aster flowers and green leaves for contrast. This would make a lovely bouquet to make the sister's birthday extra special.",
'response': ' 确实,我记得你昨天想买一束花给你的姐姐作为生日礼物。我建议你买粉红色的玫瑰花和白色的康乃馨花,再加上紫色的雏菊花和绿叶,这样可以让你的姐姐的生日更加特别。'}

这里,我们不仅仅利用了LLM来回答每轮问题,还利用LLM来对之前的对话进行总结性的陈述,以节约Token数量
通过对话历史的汇总来优化和管理 Token 的使用,ConversationSummaryMemory 为那些预期会有多轮的、长时间对话的场景提供了一种很好的方法。然而,这种方法仍然受到 Token 数量的限制。在一段时间后,我们仍然会超过大模型的上下文窗口限制

使用ConversationSummaryBufferMemory

对话总结缓冲记忆,它是一种混合记忆模型,结合了上述各种记忆机制,包括ConversationSummaryMemory 和 ConversationBufferWindowMemory的特点。这种模型旨在在对话中总结早期的互动,同时尽量保留最近互动中的原始内容。
它是通过max_token_limit这个参数做到这一点的。当最新的对话文字长度在300字之内的时候,LangChain会记忆原始对话内容;当对话文字超出了这个参数的长度,那么模型就会把所有超过预设长度的内容进行总结,以节省Token数量。

from langchain.chains.conversation.memory import ConversationSummaryBufferMemory# 初始化对话链
conversation = ConversationChain(llm=llm,memory=ConversationSummaryBufferMemory(llm=llm,max_token_limit=300))

image.png

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言例:表达式 45-35+1^2 的值

代码如下&#xff1a; #include<stdio.h> int main(void) {int a;a 4&5-3&&51^2;printf("4&5-3&&51^2 %d\n",a);return 0; } 结果如下&#xff1a;

18 优先级队列

priority_queue介绍 1.优先级队列是一种容器适配器&#xff0c;根据弱排序标准&#xff0c;它的第一个元素总是最大的 2.此上下文类似于堆&#xff0c;堆中可以随时插入元素&#xff0c;检索最大堆元素 3.优先队列实现为容器适配器&#xff0c;容器适配器即将特定容器类封装作…

代码随想录|Day23|回溯03|39.组合总和、40.组合总和II、131.分割回文串

39.组合总和 本题和 216.组合总和III 类似&#xff0c;但有几个区别&#xff1a; 没有元素个数限制&#xff1a;树的深度并不固定&#xff0c;因此递归终止条件有所变化每个元素可以使用多次&#xff1a;下层递归的起始位置和上层相同&#xff08;startIndex不需要改动&#xf…

PostgreSQL中vacuum 物理文件truncate发生的条件

与我联系&#xff1a; 微信公众号&#xff1a;数据库杂记 个人微信: iiihero 我是iihero. 也可以叫我Sean. iiheroCSDN(https://blog.csdn.net/iihero) Sean墨天轮 (https://www.modb.pro/u/16258) 数据库领域的资深爱好者一枚。 水木早期数据库论坛发起人 db2smth就是俺&am…

特约撰稿 | 李杰:2024快消品牌企业如何赢在数字化?

随着用户群体、消费场景的细分&#xff0c;以及渠道的进一步多元化&#xff0c;让快消品企业遇到了一些机遇与挑战&#xff0c;在这样的大趋势之下&#xff0c;2024年快消品牌企业&#xff0c;要脱颖而出赢得增长&#xff0c;必须要把握战略上的机会。 作者&#xff5c;纷享销…

苍穹外卖-day09:用户端历史订单模块(理解业务逻辑),商家端订单管理模块(理解业务逻辑),校验收货地址是否超出配送范围(相关API)

用户端历史订单模块 1. 查询历史订单&#xff08;分页查询&#xff09; 1.1 需求分析和设计 产品原型&#xff1a; 业务规则 分页查询历史订单可以根据订单状态查询展示订单数据时&#xff0c;需要展示的数据包括&#xff1a;下单时间、订单状态、订单金额、订单明细&#…

探寻源码宝藏:介绍开源项目“source-code-hunter“

最近处于金三银四的面试黄金期&#xff0c;许多同学在面试中反映现在要求非常高&#xff0c;阅读源码几乎是必问项。然而&#xff0c;阅读源码时常常觉得晦涩难懂&#xff0c;令人头疼。今天在浏览 GitHub 时&#xff0c;我发现了一个名为 source-code-hunter 的宝藏项目。这个…

苍穹外卖-day06:HttpClient、微信小程序开发、微信登录(业务流程)、导入商品浏览功能代码(业务逻辑)

苍穹外卖-day06 课程内容 HttpClient微信小程序开发微信登录导入商品浏览功能代码 功能实现&#xff1a;微信登录、商品浏览 微信登录效果图&#xff1a; 商品浏览效果图&#xff1a; 1. HttpClient 1.1 介绍 HttpClient 是Apache Jakarta Common 下的子项目&#xff0c;…

在Linux系统中如何查询日志?

在工作中&#xff0c;我们有时候会定位问题&#xff0c;这时候就需要查询日志了&#xff0c;那么查询日志的命令有哪些呢&#xff1f; cat 查看某个日志文件中的所有内容。 使用示例&#xff1a;cat file.txt 显示 file.txt 文件的所有内容。 如果要对查询的结果进行筛选&am…

代码随想录算法训练营第11天| 20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

系列文章目录 目录 系列文章目录20. 有效的括号利用栈对称匹配将栈中元素弹出与判断栈顶元素是否匹配分开&#xff0c;比较耗时&#xff08;2ms)&#xff1a;若将栈中元素弹出与判断栈顶元素是否匹配放一起&#xff0c;比较节省时间(1ms)&#xff1a; 1047. 删除字符串中的所有…

解决:visio导出公式为pdf图片乱码问题

今天需要将Visio编辑好的以后的图输出pdf&#xff0c;但是点击保存后公式部分一直乱码&#xff0c;如下图所示 保存为pdf后会变成&#xff1a; 解决方案&#xff1a;保存时点击文件下方的快速打印&#xff0c;存到桌面&#xff0c;不要直接点击保存