WRICD 实现 deepseek
所谓 WRICD 指的是 WebBaseLoader RecursiveCharacterTextSplitter InMemoryVectorStore ChatPromptTemplate Deepseek 技术栈实现 RAG.一个完整的 RAG(Retrieval-Augmented Generation,检索增强生成)流程,就像是为大模型配备了一位专属的“即时知识库管理员”。下面,一步步搭
所谓 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 |
提供 InMemoryVectorStore 和 ChatPromptTemplate 等核心组件 |
(通常作为其他 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" 本地路径加载。 |
| 黑神话:悟空百度百科 | 教程中用作示例知识源的网页。 | 作为 WebBaseLoader 的 web_paths 参数传入。 |
这个表格版是不是看起来更清楚了?如果你想把它们整理成文档或代码注释,我可以帮你导出成 Markdown 或适合复制粘贴的格式。
四、使用其他 llm
前面的步骤都不需要改变只需要改变步骤 8 中的 llm 就可以方便的使用各种不同的大模型。
- 使用 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
)
- 使用 openai
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")
- 使用 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)
- 使用本地 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)
五、使用不同的词嵌入模型
- 使用 openai 的词嵌入模型
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
- 使用 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}
)
更多推荐




所有评论(0)