探索多轮对话中的RAG模型:利用历史记忆增强检索生成

1,087 阅读2分钟

引言

在现代问答应用中,实现人与机器间的流畅对话是一个充满挑战的任务。为了在对话中保持上下文记忆,提升用户体验,我们需要结合检索增强生成(RAG)技术,利用历史消息来优化模型表现。本文将为您深入讲解如何在多轮对话中有效应用RAG技术。

主要内容

理解RAG及其在多轮对话中的应用

检索增强生成(RAG)结合了大型语言模型(LLM)和向量存储器,以便在生成答案时能根据外部知识进行检索。这在需要多轮对话记忆的场景中尤为重要。

多轮对话记忆的两种方法

  1. 链式方法:在每次对话中执行检索步骤。
  2. 代理方法:通过代理赋予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"])

常见问题和解决方案

  1. 如何处理网络限制?
    • 使用API代理服务提高访问稳定性。
  2. 如何持久化会话历史?
    • 可以使用数据库或其他存储服务来存储会话历史。

总结和进一步学习资源

本文介绍了如何在多轮对话中应用RAG技术,以保持对话上下文。对于有兴趣进一步探索的开发者,可以查看以下资源:

参考资料

  • LangChain 使用指南
  • LangGraph 使用指南

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---