引言
在现代问答应用中,实现人与机器间的流畅对话是一个充满挑战的任务。为了在对话中保持上下文记忆,提升用户体验,我们需要结合检索增强生成(RAG)技术,利用历史消息来优化模型表现。本文将为您深入讲解如何在多轮对话中有效应用RAG技术。
主要内容
理解RAG及其在多轮对话中的应用
检索增强生成(RAG)结合了大型语言模型(LLM)和向量存储器,以便在生成答案时能根据外部知识进行检索。这在需要多轮对话记忆的场景中尤为重要。
多轮对话记忆的两种方法
- 链式方法:在每次对话中执行检索步骤。
- 代理方法:通过代理赋予LLM决定执行检索步骤的自主权。
环境设置
开发者需要确保安装以下包:
%pip install --upgrade --quiet langchain langchain-community langchainhub langchain-chroma bs4
另外,几乎所有API服务都需要相应的API_KEY,并且可能需要API代理服务以提高访问稳定性,特别是在某些网络限制地区。
构建多轮对话应用
构建检索器和文档存储
我们使用Chroma作为向量存储,OpenAI嵌入用于文档向量化。
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
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()
使用检索增强生成模型
我们创建一个带有会话记忆的检索增强生成链:
from langchain.chains import create_retrieval_chain, create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
system_prompt = (
"You are an assistant for question-answering tasks."
"{context}"
)
qa_prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
]
)
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
history_aware_retriever = create_history_aware_retriever(llm, retriever, qa_prompt)
rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)
代码示例
以下是一个基于RAG的对话示例:
from langchain_core.messages import AIMessage, HumanMessage
chat_history = []
question = "What is Task Decomposition?"
ai_msg_1 = rag_chain.invoke({"input": question, "chat_history": chat_history})
chat_history.extend(
[
HumanMessage(content=question),
AIMessage(content=ai_msg_1["answer"]),
]
)
second_question = "What are common ways of doing it?"
ai_msg_2 = rag_chain.invoke({"input": second_question, "chat_history": chat_history})
print(ai_msg_2["answer"])
常见问题和解决方案
- 如何处理网络限制?
- 使用API代理服务提高访问稳定性。
- 如何持久化会话历史?
- 可以使用数据库或其他存储服务来存储会话历史。
总结和进一步学习资源
本文介绍了如何在多轮对话中应用RAG技术,以保持对话上下文。对于有兴趣进一步探索的开发者,可以查看以下资源:
参考资料
- LangChain 使用指南
- LangGraph 使用指南
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---