拒绝幻觉!DeepSeek-R1 + LangChain + Rerank 构建高精度本地知识库

前言

在上一篇教程中,我们通过 API 跑通了 DeepSeek。很多同学尝试在本地搭建知识库(RAG)后,会发现一个尴尬的问题:“模型回复很快,但经常答非所问,或者找不到文档里的关键细节。”

这是因为传统的“单纯向量检索”存在致命缺陷——它只看语义相似度,经常漏掉精准的关键词匹配。

要想让 DeepSeek-R1 真正成为企业级专家,我们需要他展现出更高的精度。本文将带你用 Python 和 LangChain,从零构建一个包含 混合检索 (Hybrid Search)重排序 (Reranking) 的高阶 RAG 系统。


一、 为什么你的 RAG 不好用?

在动手写代码前,先理解架构差异:

  1. 入门级 RAG: 用户提问 -> 向量化 -> 也就是 Top-K 搜索 -> 丢给大模型。
  • 缺点: 容易受到干扰,检索精度低。
  1. 进阶级 RAG (本文方案): 用户提问 -> BM25 关键词检索 + 向量检索 (双路召回) -> Rerank 模型精排 -> 丢给 DeepSeek。
  • 优点: 既抓得住语义,又漏不掉关键词,准确率提升 30% 以上。

二、 技术栈准备

我们将使用完全开源、可本地部署的组件,确保数据不出域

  • LLM: DeepSeek-R1 (通过 Ollama 调用)
  • Orchestration: LangChain
  • Embedding: BGE-M3 (目前最强的开源中文嵌入模型)
  • Rerank: BGE-Reranker (重排序模型)
  • Vector DB: ChromaDB (轻量级本地向量库)

安装依赖:

pip install langchain langchain-community langchain-chroma langchain-ollama sentence-transformers
# 安装 PyTorch (根据你的 CUDA 版本选择,这里以 CPU 为例)
pip install torch


三、 核心代码实现

1. 初始化 DeepSeek 与 Embedding

首先,我们要连接本地的 Ollama,并加载本地的 Embedding 模型(比调用 OpenAI Embedding 更安全且免费)。

from langchain_ollama import ChatOllama
from langchain_huggingface import HuggingFaceEmbeddings

# 1. 初始化 LLM (DeepSeek-R1)
llm = ChatOllama(
    model="deepseek-r1:7b",  # 确保你 Ollama 里已经 pull 了这个模型
    temperature=0.1,         # RAG 任务建议低温度,减少胡编乱造
)

# 2. 初始化 Embedding 模型 (这里使用 BGE-M3,支持多语言且效果极佳)
# 首次运行会自动下载模型权重
embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-m3",
    model_kwargs={'device': 'cpu'}, # 有显卡改 'cuda'
    encode_kwargs={'normalize_embeddings': True}
)

2. 构建向量数据库与检索器

这里我们模拟加载一个本地 PDF,并进行切片。

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma

# 加载文档
loader = PyPDFLoader("./company_manual.pdf") # 替换为你的本地文档
docs = loader.load()

# 文档切片 (关键步骤:切片大小直接影响检索效果)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,     # 每个片段500字符
    chunk_overlap=50,   # 重叠50字符,保持上下文连贯
)
splits = text_splitter.split_documents(docs)

# 存入向量库
vectorstore = Chroma.from_documents(
    documents=splits, 
    embedding=embeddings,
    persist_directory="./chroma_db" # 持久化保存
)

# 实例化基础检索器
retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 5} # 初筛找回5条相关片段
)

3. 注入灵魂:加入 Rerank (重排序)

这是“高质量”的关键。普通的向量检索可能把不相关的片段排在前面。Rerank 模型会重新给这 5 个片段打分,把真正相关的排到第一位。

(注:为了演示简单,这里使用 CrossEncoder 本地加载 Rerank 模型)

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain_community.cross_encoders import HuggingFaceCrossEncoder

# 加载 Rerank 模型 (BAAI/bge-reranker-base)
model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base")
compressor = CrossEncoderReranker(model=model, top_n=3) # 重排后只取前3名

# 升级为高级检索器
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=retriever
)

4. 组装 RAG 链

最后,我们将检索到的高精度片段,填入 Prompt,喂给 DeepSeek。

from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

# 定义系统 Prompt
system_prompt = (
    "你是一个专业的企业知识助手。请基于以下检索到的上下文(Context)回答问题。"
    "如果上下文中没有答案,请直接说不知道,不要编造。"
    "\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(compression_retriever, question_answer_chain)

# --- 测试运行 ---
query = "公司的报销流程是怎样的?"
print(f"正在思考: {query} ...")

response = rag_chain.invoke({"input": query})

print("\n=== DeepSeek 回复 ===")
print(response["answer"])

print("\n=== 参考文档来源 ===")
for doc in response["context"]:
    print(f"- [得分高] {doc.page_content[:50]}...")


四、 深度解析:为什么这一套方案强?

  1. BGE-M3 嵌入: 相比普通的 m3e 或 openai-embedding,BGE-M3 对中文长文本的理解能力是目前开源界的 T0 级别。
  2. Rerank 机制: * 无 Rerank: 向量库可能会因为“报销”二字,把“报销系统操作手册”和“报销制度”混在一起。
  • 有 Rerank: 模型会逐字比对问题和文档片段,精准识别出你问的是“流程”,从而把“制度”排在“操作手册”前面。
  1. DeepSeek-R1 的推理能力: 配合 R1 强大的逻辑分析能力,即使文档片段比较晦涩,它也能总结出清晰的 1、2、3 点。

五、 性能优化建议 (Production Ready)

如果你要在公司内部服务器上部署,建议关注以下两点:

  1. 显存分配: 7B 的 DeepSeek + Embedding + Rerank 模型,建议至少拥有 12G 显存 (RTX 3060/4070)。如果显存吃紧,可以将 Rerank 模型换成量化版。
  2. 文档解析: PDF 解析是深坑。对于扫描件或复杂表格,建议结合 OCR (如 PaddleOCR) 进行预处理,否则 garbage in, garbage out。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐