# 引言
在构建问答或聊天应用时,允许用户进行连续对话是至关重要的。这需要应用具备对过去问题和回答的“记忆”能力,并且能够将这些历史信息融入当前的对话处理中。本文旨在探讨如何添加逻辑,以便在对话应用中有效管理和利用聊天历史。
# 主要内容
## 1. 历史信息集成的两种方法
我们将讨论两种主要的方法来处理聊天历史信息:
### Chains(链)
在这种方法中,我们每次都执行一个检索步骤,确保查询被历史信息所增强。LangChain提供了一个`create_history_aware_retriever`构造器,帮助简化这一过程。
### Agents(代理)
使用代理方法,可以让大型语言模型(LLM)在执行检索步骤的过程中拥有更大的自主权,灵活应对用户的多样化请求。
## 2. 设置与依赖项
在这篇教程中,我们将使用OpenAI的嵌入服务和Chroma向量存储,并通过以下命令安装所需的Python库。
```shell
%pip install --upgrade --quiet langchain langchain-community langchain-chroma bs4
千万别忘了配置OPENAI_API_KEY
环境变量。以下是设置代码示例:
import os
import getpass
if not os.environ.get("OPENAI_API_KEY"):
os.environ["OPENAI_API_KEY"] = getpass.getpass()
3. 构建历史感知检索器
在构建历史感知检索器时,你需要准备LLM、检索器和Prompt。以下是使用LangChain创建历史感知检索器的简单示例:
from langchain.chains import create_history_aware_retriever
from langchain_core.prompts import MessagesPlaceholder
# 系统提示模版
contextualize_q_system_prompt = (
"Given a chat history and the latest user question "
"which might reference context in the chat history, "
"formulate a standalone question which can be understood "
"without the chat history. Do NOT answer the question, "
"just reformulate it if needed and otherwise return it as is."
)
# 创建Prompt
contextualize_q_prompt = ChatPromptTemplate.from_messages(
[
("system", contextualize_q_system_prompt),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
]
)
# 创建检索器
history_aware_retriever = create_history_aware_retriever(
llm, retriever, contextualize_q_prompt
)
4. 构建问答链与管理会话历史
通过RunnableWithMessageHistory
来实现对会话历史的管理。以下是示例代码:
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
conversational_rag_chain = RunnableWithMessageHistory(
rag_chain,
get_session_history,
input_messages_key="input",
history_messages_key="chat_history",
output_messages_key="answer",
)
代码示例
以下展示了如何使用上面的链管理会话历史,并进行多轮对话:
answer = conversational_rag_chain.invoke(
{"input": "What is Task Decomposition?"},
config={"configurable": {"session_id": "abc123"}}
)
print(answer)
常见问题和解决方案
在使用API时,由于某些地区的网络限制,开发者可能需要考虑使用API代理服务以提高访问的稳定性。此外,对于历史数据的存储,应考虑持久化存储方案,如Redis。
总结与进一步学习资源
无论使用链还是代理方法,能有效管理并利用聊天历史都是提升对话应用的关键。在进一步学习中,可以探索不同的检索策略和代理模块。
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---