大家好,我是橙哥!如果你是开发者或AI爱好者,可能希望能从庞大的文档中快速提取答案,而不需要翻阅每一页。今天,我将带你了解如何通过构建一个本地化的检索增强生成(RAG)系统,直接从文档中获取精准答案。通过结合 DeepSeek R1 和 Ollama ,你可以轻松实现这一目标,而无需依赖云服务,也能避免云 API 延迟的困扰。 完整代码请见文末。
了解 DeepSeek R1
DeepSeek R1 作为一款开源推理模型,凭借其超高性价比,它迅速成为了许多开发者的首选。与 OpenAI 的模型相比,DeepSeek R1 具有约 95% 更低的费用,但在推理性能上也丝毫不逊色。最重要的是,它能够直接在本地运行,大大提高了效率与数据安全性。使用 DeepSeek R1,你可以从 PDF 中提取最相关的信息,并且在不依赖外部 API 的情况下进行推理。
本地化 RAG 系统的核心要素
要构建一个有效的本地化 RAG 系统,首先需要准备以下几个关键组件:
-
Ollama :这是一个轻量级框架,允许你在本地运行 DeepSeek R1 模型。它支持多种不同的模型变体,可以根据需求选择合适的大小与参数。
PDF 文档处理 :由于 RAG 系统的核心是文档检索与生成,因此你需要一个工具来高效地处理 PDF 文件并提取其内容。我们将利用 PDFPlumberLoader 来加载 PDF 并提取文本。
文本切分与嵌入 :为了提高检索的准确性,我们需要将文档内容分割成语义块,并生成向量嵌入,利用 FAISS 向量数据库来实现快速搜索。
检索问答链 :最终,我们将构建一个能够理解和回答问题的问答链,通过 DeepSeek R1 模型来生成高质量的答案。
从 PDF 文档提取数据
首先,我们通过 Streamlit 创建一个简单的用户界面,让用户能够上传 PDF 文件。接下来,我们使用 PDFPlumberLoader 来加载文档,并提取其中的文本内容。以下是相关的代码:
import streamlit as st
from langchain_community.document_loaders importPDFPlumberLoader
uploaded_file = st.file_uploader("上传一个 PDF 文件", type="pdf")
if uploaded_file:
# 临时保存 PDF 文件
with open("temp.pdf", "wb") as f:
f.write(uploaded_file.getvalue())
# 加载 PDF 内容
loader = PDFPlumberLoader("temp.pdf")
docs = loader.load()
这段代码实现了一个简单的文件上传功能,将 PDF 文件保存到本地并使用 PDFPlumberLoader 加载文件内容。接下来,我们可以对文档进行切分,以便进行高效检索。
文本切分与向量嵌入
为了能够快速检索到相关内容,我们将文档文本切分成较小的语义块。 SemanticChunker 是我们用来切分文本的工具,它能够根据语义将文本划分为合理的片段,以便后续处理。
from langchain_experimental.text_splitter importSemanticChunker
from langchain_community.embeddings importHuggingFaceEmbeddings
text_splitter = SemanticChunker(HuggingFaceEmbeddings())
documents = text_splitter.split_documents(docs)
接下来,我们将这些切分出来的文本片段转换为向量嵌入,并将其存储在 FAISS 向量数据库中,这样就可以实现快速检索了。
from langchain_community.vectorstores import FAISS
embeddings = HuggingFaceEmbeddings()
vector_store = FAISS.from_documents(documents, embeddings)
retriever = vector_store.as_retriever(search_kwargs={"k": 3}) # 检索最相关的 3 个片段
构建问答链
在这一步,我们将 DeepSeek R1 模型与文本检索系统结合,创建一个问答链。通过构建合适的提示模板,我们可以确保模型的回答是基于文档内容的,而不是模型自身的训练数据。
from langchain_community.llms importOllama
from langchain.prompts importPromptTemplate
llm = Ollama(model="deepseek-r1:1.5b") # 使用 DeepSeek R1 1.5B 参数模型
# 创建提示模板
prompt = """
1.只使用以下上下文。
2.如果不确定,回答“我不知道”。
3.保持答案不超过 4句话。
上下文:{context}
问题:{question}
答案:
"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(prompt)
在提示模板中,我们要求模型仅仅依赖文档中的上下文来回答问题,这样可以有效避免错误或不准确的回答。
整合 RAG 流程
现在,我们将前面所有的步骤整合成一个完整的 RAG 流程。用户输入的问题将被传递给检索器,检索到的相关文档片段将被传递给 DeepSeek R1 模型生成答案。以下是流程代码:
from langchain.chains importLLMChain
from langchain_community.chains importRetrievalQA
from langchain_community.chains importStuffDocumentsChain
llm_chain = LLMChain(llm=llm, prompt=QA_CHAIN_PROMPT)
document_prompt = PromptTemplate(
template="上下文:\n内容:{page_content}\n来源:{source}",
input_variables=["page_content", "source"]
)
qa = RetrievalQA(
combine_documents_chain=StuffDocumentsChain(
llm_chain=llm_chain,
document_prompt=document_prompt
),
retriever=retriever
)
启动 Web 界面
最后,我们使用 Streamlit 创建一个简单的 Web 界面,让用户可以直接向文档提问并得到即时回答。以下是实现这一功能的代码:
user_input = st.text_input("向你的 PDF 提问:")
if user_input:
with st.spinner("思考中..."):
response = qa(user_input)["result"]
st.write(response)
通过这段代码,用户可以在 Web 界面上输入问题,系统会根据文档中的内容生成准确的回答,并实时显示。
未来展望:DeepSeek 的 RAG 系统
DeepSeek R1 只是开始,未来的 RAG 系统将引入更多创新功能。例如,DeepSeek 的自我验证功能和多跳推理能力,将使得模型能够独立进行逻辑推理和改进,甚至与用户进行辩论,完善其推理过程。这意味着未来的 RAG 系统不仅能提供答案,还能自我验证答案的正确性,从而提高其可信度和智能化水平。
长按下方扫码 获取本文完整源码 :
点击阅读原文加入AI技术变现训练营