888974111 发表于 2025-2-9 15:47:09

使用 DeepSeek R1 和 Ollama 开发 RAG 系统(包含完整代码)

是否想过直接向PDF文档或技术手册提问?本文将演示如何通过开源推理工具DeepSeek R1与本地AI模型框架Ollama搭建检索增强生成(RAG)系统。
高效工具推荐:用Apidog简化API测试流程

图片
Apidog作为一体化API解决方案,可实现:

[*]零脚本自动化核心流程
[*]无缝对接CI/CD管道
[*]精准定位性能瓶颈
[*]可视化接口管理
https://apidog.com
DeepSeek R1核心优势

相比OpenAI o1模型成本降低95%,具备:

[*]精准检索:每次仅调用3个文档片段
[*]严谨输出:未知问题主动返回"暂不了解"
[*]本地运行:彻底消除云端API延迟
环境准备

1. Ollama本地部署

# 安装基础框架ollama run deepseek-r1# 默认使用7B模型

[*]1.
[*]2.





Ollama官网下载:https://ollama.ai
图片
2. 模型选择策略

# 轻量级场景推荐1.5B版本ollama run deepseek-r1:1.5b

[*]1.
[*]2.





硬件建议:70B大模型需32GB内存支持
RAG系统构建全流程

Step 1: 导入依赖库


[*]用于文档处理和检索的 LangChain。
[*]流利使用用户友好的Web界面。
import streamlit as stfrom langchain_community.document_loaders import PDFPlumberLoaderfrom langchain_experimental.text_splitter import SemanticChunkerfrom langchain_community.embeddings import HuggingFaceEmbeddingsfrom langchain_community.vectorstores import FAISSfrom langchain_community.llms import Ollama

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.





图片
Step 2: PDF文件上传与解析

利用 Streamlit 的文件上传器选择本地 PDF。使用 PDFPlumberLoader 高效提取文本,无需手动解析。
# 创建Streamlit文件上传组件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()

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.
[*]8.
[*]9.
[*]10.
[*]11.





Step 3: 文档语义分块

利用 Streamlit 的文件上传器选择本地 PDF。使用 PDFPlumberLoader 高效提取文本,无需手动解析。
# 初始化语义分块器text_splitter = SemanticChunker(    HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2"))# 执行分块操作documents = text_splitter.split_documents(docs)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.





图片


Step 4: 构建向量数据库

# 生成文本嵌入embeddings = HuggingFaceEmbeddings()vector_store = FAISS.from_documents(documents, embeddings)# 配置检索器retriever = vector_store.as_retriever(search_kwargs={"k": 3})

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.





Step 5: 配置DeepSeek R1模型

# 初始化本地模型llm = Ollama(model="deepseek-r1:1.5b")# 定义提示模板prompt_template = """根据以下上下文:{context}问题:{question}回答要求:1. 仅使用给定上下文2. 不确定时回答"暂不了解"3. 答案控制在四句话内最终答案:"""QA_PROMPT = PromptTemplate.from_template(prompt_template)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.
[*]8.
[*]9.
[*]10.
[*]11.
[*]12.
[*]13.
[*]14.
[*]15.
[*]16.
[*]17.
[*]18.





Step 6: 组装RAG处理链

# 创建LLM处理链llm_chain = LLMChain(llm=llm, prompt=QA_PROMPT)# 配置文档组合模板document_prompt = PromptTemplate(    template="上下文内容:\n{page_content}\n来源:{source}",    input_variables=["page_content", "source"])# 构建完整RAG管道qa = RetrievalQA(    combine_documents_chain=StuffDocumentsChain(      llm_chain=llm_chain,      document_prompt=document_prompt    ),    retriever=retriever)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.
[*]8.
[*]9.
[*]10.
[*]11.
[*]12.
[*]13.
[*]14.
[*]15.
[*]16.
[*]17.





Step 7: 启动交互界面

# 创建问题输入框user_question = st.text_input("输入您的问题:")if user_question:    with st.spinner("正在生成答案..."):      # 执行查询并显示结果      response = qa(user_question)["result"]      st.success(response)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.
[*]8.





完整的代码:https://gist.github.com/lisakim0/0204d7504d17cefceaf2d37261c1b7d5.js
技术实现要点

语义分块优化:采用SemanticChunker替代传统滑动窗口,提升上下文连贯性
# 示例:调整分块策略text_splitter = SemanticChunker(    embeddings,   breakpoint_threshold=0.85# 调整语义分割阈值)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.





检索优化配置:动态调整检索数量
# 根据问题复杂度动态调整k值def dynamic_retriever(question):    complexity = len(question.split())    return vector_store.as_retriever(search_kwargs={"k": min(complexity, 5)})

[*]1.
[*]2.
[*]3.
[*]4.





混合检索策略:结合关键词与向量搜索
from langchain.retrievers import BM25Retriever, EnsembleRetrieverbm25_retriever = BM25Retriever.from_documents(documents)ensemble_retriever = EnsembleRetriever(    retrievers=,    weights=)

[*]1.
[*]2.
[*]3.
[*]4.
[*]5.
[*]6.
[*]7.





最后

DeepSeek R1 只是一个开始。凭借即将推出的自我验证和多跳推理等功能,未来的 RAG 系统可以自主辩论和完善其逻辑。
页: [1]
查看完整版本: 使用 DeepSeek R1 和 Ollama 开发 RAG 系统(包含完整代码)