大家好,我是雨飞。今天给大家介绍下,如何使用 langchain 实现一个带有记忆功能的 chatbot。
采用的大模型,依旧是之前的 Yi-34B,毕竟 token 挺多的,不能浪费。
记忆功能 Memory
langchain 内置了 memory 的模块,可以存储我们和大模型的历史对话,这样就可以让大模型记住和我们的聊天记录了。下图就是 langchain 中对 memory 模块的示意图,
memory 主要实现两个步骤,在收到用户初始输入后,但在执行核心逻辑之前,langchian 会从内存系统中读取历史信息并增加用户输入。在执行核心逻辑后、返回答案前,langchian 会将当前运行的输入和输出写入内存,以便在以后的运行中参考。
一、手动聊天记录管理
我们采用占位符 MessagePlaceholder 去作为用户输入的占位符。然后使用 langchain 的 LCEL语法去实现一个 llm chain。
使用 invoke 方法就可以调用 llm 了,这个时候,我们手动把历史信息放在一个 list 里面,然后去获取最后结果。
完整代码如下:
from langchain_core.messages import AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 手动聊天记录管理
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful assistant. Answer all questions to the best of your ability.",
),
MessagesPlaceholder(variable_name="messages"),
]
)
chain = prompt | yi_llm
result = chain.invoke(
{
"messages": [
HumanMessage(
content="Translate this sentence from English to French: I love programming."
),
AIMessage(content="J'adore la programmation."),
HumanMessage(content="What did you just say?"),
],
}
)
print(result)
二、ChatMessageHistory 手动调用
ChatMessageHistory 是 langchain 中自己封装的 memory 的一个类,可以手动将对话信息添加到这个类里面并进行调用。
我们可以调用这个类的 add_ai_message 和 add_user_message 去分别把 AI 和用户输出的信息添加到内存记忆中。
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful assistant. Answer all questions to the best of your ability.",
),
MessagesPlaceholder(variable_name="messages"),
]
)
chain = prompt | yi_llm
from langchain.memory import ChatMessageHistory
demo_ephemeral_chat_history = ChatMessageHistory()
input1 = "Translate this sentence from English to French: I love programming."
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 = "What did I just ask you?"
demo_ephemeral_chat_history.add_user_message(input2)
result = chain.invoke(
{
"messages": demo_ephemeral_chat_history.messages,
}
)
print(response)
print(result)
三、 ChatMessageHistory 自动调用
前面两种方法都需要自己管理历史的对话信息,非常麻烦,langchain 也提供了自己的管理机制可以帮助我们更好的管理历史对话。这样就使用 RunnableWithMessageHistory 对原始的 llm 进行封装。
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.memory import ChatMessageHistory
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful assistant. Answer all questions to the best of your ability.",
),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{input}"),
]
)
chain = prompt | yi_llm
from langchain_core.runnables.history import RunnableWithMessageHistory
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",
)
result =chain_with_message_history.invoke(
{"input": "Translate this sentence from English to French: I love programming."},
{"configurable": {"session_id": "unused"}},
)
print(result)
result =chain_with_message_history.invoke(
{"input": "What did you just say?"},
{"configurable": {"session_id": "unused"}},
)
print(result)
print(demo_ephemeral_chat_history_for_chain.messages)
好了,这篇文章到此结束,如果对你有所感悟,欢迎点赞,评论 。
雨飞同行
- 雨飞
- 主业是推荐算法
- 希望通过自媒体开启自己不上班只工作的美好愿景
- 微信:1060687688
- 欢迎和我交朋友🫰