所谓 WRICD 指的是 WebBaseLoader RecursiveCharacterTextSplitter InMemoryVectorStore ChatPromptTemplate Deepseek 技术栈实现 RAG.

一个完整的 RAG(Retrieval-Augmented Generation,检索增强生成)流程,就像是为大模型配备了一位专属的“即时知识库管理员”。下面,一步步搭建一个基于 RAG 的应用,并用它来回答问题。

1. 加载环境变量与文档

首先,我们需要加载环境变量,并从网络上“抓取”知识,这是整个流程的起点。

import os
from dotenv import load_dotenv

# 加载环境变量(如API密钥等)
load_dotenv()

from langchain_community.document_loaders import WebBaseLoader

# 使用百度百科“黑神话:悟空”词条作为我们的知识源
loader = WebBaseLoader(
    web_paths=("https://baike.baidu.com/item/%E9%BB%91%E7%A5%9E%E8%AF%9D%EF%BC%9A%E6%82%9F%E7%A9%BA/53303078?fromModule=lemma_search-box",)
)
docs = loader.load()

这一步,做了两件事:

  • 环境准备:使用 load_dotenv() 从项目根目录的 .env 文件中加载敏感信息(例如后面会用到的 DeepSeek API Key),确保密钥不会暴露在代码中。
  • 文档加载:使用 WebBaseLoader 从百度百科抓取网页内容,并将其转化为 LangChain 标准的 Document 对象。它是构建 RAG 应用处理外部数据的第一步。

💡 小提示WebBaseLoader 默认会提取网页的全部文本,可能包含不少导航栏、广告等“噪音”。在生产环境中,你可以通过 bs_kwargs 参数来精确定位网页中的主要内容区域,从源头保证数据质量。

2. 文档分块

网页内容通常很长,超出了大模型的单次处理上限。因此,需要把长文档切分成小的、语义上相对独立的“块”。

from langchain_text_splitters import RecursiveCharacterTextSplitter

# 设置块大小为1000字符,相邻块之间有200字符的重叠
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
all_splits = text_splitter.split_documents(docs)

这里使用的 RecursiveCharacterTextSplitter 是 LangChain 官方推荐的通用文本分割器。它的核心逻辑是:按照段落换行、句子结束标点、空格等优先级递减的分隔符,递归地切分文本。chunk_overlap 参数能确保信息不会因生硬截断而丢失,最大程度地保留语义的完整性。

3. 设置嵌入模型

计算机无法直接“理解”文本,我们需要一个“翻译官”——嵌入模型(Embedding Model),将文本块转换成计算机能处理的数字向量。

from langchain_huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(
    model_name="./bge-small-zh-v1.5",  # 使用本地的中文嵌入模型
    model_kwargs={'device': 'cuda'},   # 指定在GPU上运行以加速
    encode_kwargs={'normalize_embeddings': True}
)

HuggingFaceEmbeddings 允许我们加载强大的开源模型,在本地免费、无限量地进行文本向量化,不仅节省成本,还能有效保护数据隐私。选用的 BAAI/bge-small-zh-v1.5 是一个专为中文优化、体量轻巧(仅 24M 参数)的嵌入模型,非常适合中文语义搜索任务。

4. 创建向量存储

文本转化成向量后,需要一个“仓库”把它们和原始文本一起存起来,并支持快速查找。

from langchain_core.vectorstores import InMemoryVectorStore

vector_store = InMemoryVectorStore(embeddings)
vector_store.add_documents(all_splits)

InMemoryVectorStore 是一个将向量数据直接存储在内存中的“临时仓库”。它的特点是速度极快,非常适合我们这种小规模、单次运行的演示和测试场景。如果数据量巨大或需要持久化存储,后续可以轻松替换为 Chroma、Milvus 等专业的向量数据库。

5 & 6. 构建查询并检索相关文档

现在,向这个“知识库”提出问题。

# 5. 用户提问
question = "黑悟空是哪个公司开发的?"

# 6. 语义检索:从向量库中找到与问题最相关的3个文本块
retrieved_docs = vector_store.similarity_search(question, k=3)
# 将检索到的文本块拼接成一段完整的上下文
docs_content = "\n\n".join(doc.page_content for doc in retrieved_docs)

通过 similarity_search,系统会比较问题的向量与所有文档块的向量,召回语义上最相似的 k 个片段。

7. 构建提示模板

为了让大模型更好地理解任务,需要给它一个清晰的“指令模板”。

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("""
            基于以下上下文,回答问题。如果上下文中没有相关信息,
            请说“我无法从提供的上下文中找到相关信息”。
            上下文: {context}
            问题: {question}
            回答:"""
                                        )

这个模板的核心在于明确角色和规则:它告诉大模型,回答只能基于提供的{context},如果找不到依据就坦诚告知,这能有效抑制模型“一本正经地胡说八道”。

8. 使用大语言模型生成答案

最后,我们将检索到的上下文和问题填入模板,交给大模型生成最终答案。

from langchain_deepseek import ChatDeepSeek

# 初始化DeepSeek模型
llm = ChatDeepSeek(
    model="deepseek-chat",  # DeepSeek API 支持的模型名称
    temperature=0.7,        # 控制输出的随机性
    max_tokens=2048,        # 最大输出长度
    api_key=os.getenv("DEEPSEEK_API_KEY")  # 从环境变量加载API key
)

# 将上下文和问题填入提示模板,并送给模型生成回答
answer = llm.invoke(prompt.format(question=question, context=docs_content))
print(answer.content)

这里调用的是 DeepSeek 的 API,ChatDeepSeek 是其在 LangChain 中的集成接口。通过 api_key=os.getenv("DEEPSEEK_API_KEY"),代码会自动从第一步加载的环境变量中读取密钥。

📌 注意deepseek-chat 是一个指向特定模型的代号。根据 DeepSeek 官方文档,此代号计划于 2026 年 7 月 24 日弃用,届时将对应 deepseek-v4-flash 模型的非思维模式。


以上就是使用 LangChain 和 DeepSeek 构建一个基础 RAG 应用的全过程。这门技术的核心骨架是:从文档加载、向量化、检索,到最终借助大模型生成答案。

将上面用到的核心依赖、API 和关键组件整理成表格。

附录

一、核心依赖库清单

库名称 在教程中的作用 安装命令
huggingface_hub 提供 hf 命令行工具,用于下载模型和数据集 pip install huggingface_hub
python-dotenv .env 文件加载环境变量,管理 API Key pip install python-dotenv
langchain-community 提供 WebBaseLoader 等社区贡献的文档加载器 pip install langchain-community
langchain-text-splitters 提供 RecursiveCharacterTextSplitter 文本分割器 (通常随 langchain 一起安装)
langchain-huggingface 提供 HuggingFaceEmbeddings 集成,用于加载本地嵌入模型 pip install langchain-huggingface
langchain-core 提供 InMemoryVectorStoreChatPromptTemplate 等核心组件 (通常作为其他 langchain 包的依赖自动安装)
langchain-deepseek 提供 ChatDeepSeek 集成,用于调用 DeepSeek 大模型 API pip install langchain-deepseek
sentence-transformers HuggingFaceEmbeddings 的底层依赖,用于运行嵌入模型 (通常随 langchain-huggingface 一起安装)

二、关键 API 与组件速查

组件/API 来源库 用途
WebBaseLoader langchain_community.document_loaders 从网页 URL 抓取内容,转换为 LangChain 的 Document 对象。
RecursiveCharacterTextSplitter langchain_text_splitters 递归地按段落、句子等分隔符分割长文本。
HuggingFaceEmbeddings langchain_huggingface 加载 HuggingFace 的开源嵌入模型,将文本转化为向量。
InMemoryVectorStore langchain_core.vectorstores 一个内存中的向量存储,用于临时存放和检索文档向量。
ChatPromptTemplate langchain_core.prompts 用模板构建发给大模型的提示词(Prompt),方便管理指令。
ChatDeepSeek langchain_deepseek LangChain 中专用于调用 DeepSeek 大模型 API 的接口。

三、外部 API 与模型资源

资源/API 说明 关键参数/备注
DeepSeek API 用于调用 DeepSeek 的云端大模型生成答案。 model="deepseek-chat"(计划于 2026 年 7 月弃用,届时可能对应 deepseek-v4-flash 的非思维模式);API Key 从环境变量 DEEPSEEK_API_KEY 加载。
HuggingFace Mirror (hf-mirror.com) 国内可用的 HuggingFace 镜像站,用于加速下载模型和数据集。 通过环境变量 HF_ENDPOINT=https://hf-mirror.com 设置。
BAAI/bge-small-zh-v1.5 中文轻量级嵌入模型,用于将文本转化为向量。 从 HuggingFace 下载到本地后,通过 model_name="./bge-small-zh-v1.5" 本地路径加载。
黑神话:悟空百度百科 教程中用作示例知识源的网页。 作为 WebBaseLoaderweb_paths 参数传入。

这个表格版是不是看起来更清楚了?如果你想把它们整理成文档或代码注释,我可以帮你导出成 Markdown 或适合复制粘贴的格式。

四、使用其他 llm

前面的步骤都不需要改变只需要改变步骤 8 中的 llm 就可以方便的使用各种不同的大模型。

  1. 使用 DeepSeek API
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="deepseek-reasoner",  # DeepSeek API 支持的模型名称
    base_url="https://api.deepseek.com/v1",
    temperature=0.7,        # 控制输出的随机性(0-1之间,越大越随机)
    max_tokens=2048,        # 最大输出长度
    top_p=0.95,            # 控制输出的多样性(0-1之间)
    presence_penalty=0.0,   # 重复惩罚系数(-2.0到2.0之间)
    frequency_penalty=0.0,  # 频率惩罚系数(-2.0到2.0之间)
    api_key=os.getenv("DEEPSEEK_API_KEY")  # 从环境变量加载API key
)
  1. 使用 openai
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
  1. 使用 huggingface pipe 和 千问
# 8. 使用大语言模型生成答案
from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import torch

# 加载模型和分词器
# model_name = "../qwen/Qwen2.5-3B-Instruct" # 使用本地模型
model_name = "Qwen/Qwen2.5-1.5B" # 在线下载模型 
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_name, 
                                             trust_remote_code=True, 
                                            #  device_map='auto'
                                             )

# 创建pipeline
pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    max_new_tokens=512,
    temperature=0.7,
    top_p=0.95,
    repetition_penalty=1.1,
    # low_cpu_mem_usage=True
)

# 创建LangChain的HuggingFace Pipeline包装器
llm = HuggingFacePipeline(pipeline=pipe)
  1. 使用本地 ollama
    需要本地先运行 ollama serve 同时保证端口为:11434
# 8. 使用大语言模型生成答案
from langchain_ollama import ChatOllama # pip install langchain-ollama
print(5)
llm = ChatOllama(model=os.getenv("OLLAMA_MODEL"))

或者,

# 8. 使用本地 Ollama 模型生成答案(替换部分)
from langchain_community.chat_models import ChatOllama

llm = ChatOllama(
    model="qwen2.5:7b",                 # 你已拉取的 Ollama 模型,例如 qwen2.5:7b, llama3, llava:13b 等
    base_url="http://localhost:11434",  # Ollama 默认本地地址
    temperature=0.7,
    max_tokens=2048,
    top_p=0.95,
    # api_key 不需要,留空即可
)

answer = llm.invoke(prompt.format(question=question, context=docs_content))
print(answer.content)

五、使用不同的词嵌入模型

  1. 使用 openai 的词嵌入模型
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()
  1. 使用 huggingface 的词嵌入模型(已下载到本地)
from langchain_huggingface import HuggingFaceEmbeddings # pip install langchain-huggingface

embeddings = HuggingFaceEmbeddings(
    model_name="./bge-small-zh-v1.5",
    # model_kwargs={'device': 'cpu'},
    model_kwargs={'device': 'cuda'},
    encode_kwargs={'normalize_embeddings': True}
)
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐