之前我们聊过如何使用LangChain给LLM(大模型)装上记忆,里面提到对话链ConversationChain
和MessagesPlaceholder
,可以简化安装记忆的流程。下文来拆解基于LangChain的大模型记忆方案。
1. 安装记忆的原理
1.1. 核心步骤
给LLM安装记忆的核心步骤就3个:
- 在对话之前调取之前的历史消息。
- 将历史消息填充到Prompt里。
- 对话结束后,继续将历史消息保存到到memory记忆中。
1.2. 常规使用方法的弊端
了解这3个核心步骤后,在开发过程中,就需要手动写代码实现这3步,这也比较麻烦,不仅代码冗余,而且容易遗漏这些模板代码。
为了让开发者聚焦于业务实现,LangChain贴心地封装了这一整套实现。使用方式如下。
2. 记忆的种类
记忆分为 短时记忆 和 长时记忆。
在LangChain中使用ConversationBufferMemory
作为短时记忆的组件,实际上就是以键值对的方式将消息存在内存中。
如果碰到较长的对话,一般使用ConversationSummaryMemory
对上下文进行总结,再交给大模型。或者使用ConversationTokenBufferMemory
基于固定的token数量进行内存刷新。
如果想对记忆进行长时间的存储,则可以使用向量数据库进行存储(比如FAISS、Chroma等),或者存储到Redis、Elasticsearch中。
下面以ConversationBufferMemory
为例,对如何快速安装记忆做个实践。
3. 给LLM安装记忆 — 非MessagesPlaceholder
3.1. ConversationBufferMemory使用示例
使用ConversationBufferMemory
进行记住上下文:
memory = ConversationBufferMemory()
memory.save_context(
{"input": "你好,我的名字是半支烟,我是一个程序员"}, {"output": "你好,半支烟"}
)
memory.load_memory_variables({})
3.2. LLMChain+ConversationBufferMemory使用示例
# prompt模板
template = """
你是一个对话机器人,以下<history>标签中是AI与人类的历史对话记录,请你参考历史上下文,回答用户输入的问题。
历史对话:
<history>
{customize_chat_history}
</history>
人类:{human_input}
机器人:
"""
prompt = PromptTemplate(
template=template,
input_variables=["customize_chat_history", "human_input"],
)
memory = ConversationBufferMemory(
memory_key="customize_chat_history",
)
model = ChatOpenAI(
model="gpt-3.5-turbo",
)
chain = LLMChain(
llm=model,
memory=memory,
prompt=prompt,
verbose=True,
)
chain.predict(human_input="你知道我的名字吗?")
# chain.predict(human_input="我叫半支烟,我是一名程序员")
# chain.predict(human_input="你知道我的名字吗?")
此时,已经给LLM安装上记忆了,免去了我们写那3步核心的模板代码。
对于PromptTemplate
使用以上方式,但ChatPromptTemplate
因为有多角色,所以需要使用MessagesPlaceholder
。具体使用方式如下。
4. 给LLM安装记忆 — MessagesPlaceholder
MessagesPlaceholder
主要就是用于ChatPromptTemplate
场景。ChatPromptTemplate
模式下,需要有固定的格式。
4.1. PromptTemplate和ChatPromptTemplate区别
ChatPromptTemplate
主要用于聊天场景。ChatPromptTemplate
有多角色,第一个是System角色,后续的是Human与AI角色。因为需要有记忆,所以之前的历史消息要放在最新问题的上方。
4.2. 使用MessagesPlaceholder安装
最终的ChatPromptTemplate + MessagesPlaceholder代码如下:
chat_prompt = ChatPromptTemplate.from_messages(
[
("system", "你是一个乐于助人的助手。"),
MessagesPlaceholder(variable_name="customize_chat_history"),
("human", "{human_input}"),
]
)
memory = ConversationBufferMemory(
memory_key="customize_chat_history",
return_messages=True,
)
model = ChatOpenAI(
model="gpt-3.5-turbo",
)
chain = LLMChain(
llm=model,
memory=memory,
prompt=chat_prompt,
verbose=True,
)
chain.predict(human_input="你好,我叫半支烟,我是一名程序员。")
至此,我们使用了ChatPromptTemplate
简化了构建prompt的过程。
5. 使用对话链ConversationChain
如果连ChatPromptTemplate
都懒得写了,那直接使用对话链ConversationChain
,让一切变得更简单。实践代码如下:
memory = ConversationBufferMemory(
memory_key="history", # 此处的占位符必须是history
return_messages=True,
)
model = ChatOpenAI(
model="gpt-3.5-turbo",
)
chain = ConversationChain(
llm=model,
memory=memory,
verbose=True,
)
chain.predict(input="你好,我叫半支烟,我是一名程序员。") # 此处的变量必须是input
ConversationChain提供了包含AI角色和人类角色的对话摘要格式。ConversationChain实际上是对Memory和LLMChain和ChatPrompt进行了封装,简化了初始化Memory和构建ChatPromptTemplate的步骤。
6. ConversationBufferMemory
6.1. memory_key
ConversationBufferMemory
有一个入参是memory_key
,表示内存中存储的本轮对话的键
,后续可以根据键
找到对应的值。
6.2. 使用"chat_history"还是"history"
ConversationBufferMemory
的memory_key
,有些资料里是设置是memory_key="history"
,有些资料里是"chat_history"
。
这里有2个规则,如下:
- 在使用
MessagesPlaceholder
和ConversationBufferMemory
时,MessagesPlaceholder
的variable_name
和ConversationBufferMemory
的memory_key
可以自定义,只要相同就可以。比如这样:
chat_prompt = ChatPromptTemplate.from_messages(
[
("system", "你是一个乐于助人的助手。"),
MessagesPlaceholder(variable_name="customize_chat_history"),
("human", "{input}"),
]
)
memory = ConversationBufferMemory(
memory_key="customize_chat_history", # 此处的占位符可以是自定义
return_messages=True,
)
model = ChatOpenAI(
model="gpt-3.5-turbo",
)
chain = ConversationChain(
llm=model,
memory=memory,
prompt=chat_prompt,
verbose=True,
)
chain.predict(input="你好,我叫半支烟,我是一名程序员。") # 此处的变量必须是input
- 如果只是使用
ConversationChain
,又没有使用MessagesPlaceholder
的场景下,ConversationBufferMemory的memory_key,必须用history
。
7. MessagesPlaceholder的使用场景
MessagesPlaceholder
其实就是在与AI对话过程中的Prompt
的一部分,它代表Prompt
中的历史消息这部分。它提供了一种结构化和可配置的方式来处理这些消息列表,使得在构建复杂Prompt
时更加灵活和高效。
说白了它就是个占位符,相当于把从memory读取的历史消息插入到这个占位符里了。
比如这样,就可以表示之前的历史对话消息:
chat_prompt = ChatPromptTemplate.from_messages(
[ ("system", "你是一个乐于助人的助手。"), MessagesPlaceholder(variable_name="customize_chat_history"), ("human", "{human_input}"), ]
)
是否需要使用MessagesPlaceholder,记住2个原则:
-
PromptTemplate
类型的模板,无需使用MessagesPlaceholder -
ChatPromptTemplate
类型的聊天模板,需要使用MessagesPlaceholder。但是在使用ConversationChain时,可以省去创建ChatPromptTemplate的过程(也可以不省去)。省去和不省去在输出过程中有些区别,如下:
8. 总结
本文主要聊了安装记忆的基本原理、快速给LLM安装记忆、ConversationBufferMemory
、MessagesPlaceholder
的使用、对话链ConversationChain
的使用和原理。希望对你有帮助!
如何学习AI大模型?
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;
第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;
第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;
第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;
第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;
第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;
第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集
👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓