
您有一个PDF文件夹、内部文档或支持票证。您想要一个聊天机器人,它能从该内容中准确回答问题——带有引用,不产生幻觉。这正是本DeepSeek RAG教程所涵盖的,从头到尾,使用2026年4月24日发布的当前V4代。我们将分块文档,使用专用嵌入模型嵌入它们,将向量存储在FAISS中,在查询时检索最匹配的块,并将它们传递给`deepseek-v4-flash`以获得基于事实的答案。最后,您将拥有一个可工作的Python管道,您可以用LangChain、LlamaIndex或您自己的框架扩展它,还有一个反映当前V4定价的成本示例。
你将构建的内容

一个最小但适合生产的检索增强生成(RAG)管道,将DeepSeek V4答案基于您自己的文档。该架构分为两部分。首先,离线索引步骤:将文档分成块,使用专用嵌入模型生成嵌入,将它们存储在向量索引中。其次,在线查询步骤:嵌入用户的提问,找到最匹配的k个块,并将这些块加上提问发送到 DeepSeek V4-Flash 通过聊天完成API。
事先重要提示:DeepSeek的推理模型如R1不适合生成嵌入——它们是推理引擎,而不是语义相似度模型,除非针对嵌入进行微调,否则不应用作RAG的检索嵌入模型。V4也是如此。在检索方面使用专用嵌入模型(Sentence Transformers、BGE、GTE-Qwen2或类似模型),在生成方面使用DeepSeek。
前置条件
- Python 3.10或更高版本。
- 一个带有充值余额的DeepSeek账户——见 how to get a DeepSeek API key.
- OpenAI Python SDK(DeepSeek API与OpenAI兼容)。
- FAISS用于向量索引,以及
sentence-transformers用于嵌入。 - 约需200MB的空闲磁盘空间用于嵌入模型和一个小型索引。
- 一个源文档文件夹——Markdown、纯文本或提取的PDF文本。
一行安装所有内容:
pip install openai faiss-cpu sentence-transformers tiktoken pypdf处理
第1步:设置DeepSeek客户端
DeepSeek聊天界面与OpenAI兼容。聊天请求击中 POST /chat/completions,与OpenAI兼容的端点,针对基本URL https://api.deepseek.comDeepSeek的API与OpenAI ChatCompletions和Anthropic风格的端点兼容,允许开发者通过简单地更改模型参数来更新现有设置,同时保持基础URL不变。在本教程中,我们将使用OpenAI SDK模式。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)
关于模型选择的两个注意事项。当前一代是 DeepSeek V4,以两个模型ID的形式发货: deepseek-v4-pro (总参数量1.6T / 活跃参数量49B,前沿级别)和 deepseek-v4-flash (284B / 13B 活跃,成本效益型级别)。两者都是MIT许可下的开放权重MoE模型,并且默认使用 1,000,000-token context window 最高可达 384,000个输出令牌。对于大多数RAG工作负载,V4-Flash是正确的默认选择——Pro的输出成本大约是Pro的7倍,仅适用于硬代理或编码任务。
如果您的旧代码引用了 deepseek-chat or deepseek-reasoner,那些较老的模型,如deepseek-chat和deepseek-reasoner,将于2026年7月24日15:59 UTC退役,目前正路由到deepseek-v4-flash等效模型。迁移只需一行 model= swap; base_url 不会改变。新代码应直接使用V4 ID。有关SDK设置的详细说明,请参阅 DeepSeek API getting started guide.
第2步:准备和分块您的文档
分块处理并不引人注目,但比模型更重要。如果分块太大,检索会引入噪声并损害精度。太小,模型会失去回答问题时所需的周围上下文。一个合理的起点是每个分块500-800个令牌,相邻分块之间有50-100个令牌的重叠。
from pathlib import Path
def 加载文档(folder: str) -> list[dict]:
docs = []
for path in Path(folder).rglob("*.txt"):
docs.append({"id": str(path), "text": path.read_text(encoding="utf-8")})
return docs
def chunk_text(text: str, size: int = 700, overlap: int = 80) -> list[str]:
words = text.split()
chunks, start = [], 0
while start < len(words):
end = min(start + size, len(words))
chunks.append(" ".join(words[start:end]))
if end == len(words):
break
start = end - overlap
return chunks
documents = 加载文档("./data")
chunks = []
for doc in documents:
for i, c in enumerate(chunk_text(doc["text"])):
chunks.append({"source": doc["id"], "chunk_id": i, "text": c})
对于PDF文件,请通过 pypdf处理 首先提取文本并输入 加载文档。对于HTML,分块前删除标签。在每个分块上保留源路径,以便以后向用户展示引用。
第3步:生成嵌入并构建索引
我们将使用 all-MiniLM-L6-v2 来自Sentence Transformers——小巧、快速,384维,足以演示管道。MiniLM-L6-v2模型在嵌入性能和准确性之间提供了良好的平衡。为了获得更高的质量,稍后可以将其更换为 BAAI/bge-large-en-v1.5 or Alibaba-NLP/gte-Qwen2-7B-instruct 这将消耗更多的内存。
import numpy as np
import faiss
from sentence_transformers import SentenceTransformer
embedder = SentenceTransformer("all-MiniLM-L6-v2")
texts = [c["text"] for c in chunks]
vectors = embedder.encode(texts, normalize_embeddings=True, show_progress_bar=True)
vectors = np.asarray(vectors, dtype="float32")
dim = vectors.shape[1]
index = faiss.IndexFlatIP(dim) # inner product on L2-normalised vectors = cosine
index.add(vectors)
faiss.write_index(index, "rag.index")
将块与索引一起持久化——对于小型语料库,JSON文件就足够了;对于更大的内容,请使用SQLite或真正的向量数据库。以下 DeepSeek 与 LangChain and DeepSeek 与 LlamaIndex 指南涵盖了 Chroma、Pinecone 和 Milvus 的集成,如果您需要一个托管存储的话。
第4步:检索前k个块
使用与索引相同的模型嵌入查询,然后搜索FAISS索引。返回四到六个块是一个合理的起始范围——足够多的上下文,不会过多到耗尽无关标记的预算。
def retrieve(query: str, k: int = 5) -> list[dict]:
q = embedder.encode([query], normalize_embeddings=True)
q = np.asarray(q, dtype="float32")
scores, idx = index.search(q, k)
return [
{**chunks[i], "score": float(s)}
for s, i in zip(scores[0], idx[0])
if i != -1
]
余弦分数低于大约0.3通常为噪声。如果你的顶级结果低于该阈值,请返回“我不知道”,而不是强迫模型从弱上下文中创造答案。
第5步:生成基于事实的答案

现在将检索集成到聊天调用中。这里有两个要点:系统提示必须将模型约束在上下文中,用户消息必须清楚地界定上下文与问题。以下结构与Milvus在DeepSeek教程中推荐的结构相同。
SYSTEM_PROMPT = (
"You are a documentation assistant. Answer using ONLY the context "
"between <context> tags. If the answer is 不准确 in the context, "
"reply exactly: 'I don't know based on the provided documents.' "
"Cite the source path in square brackets after each claim."
)
def answer(query: str) -> str:
hits = retrieve(query, k=5)
context = "nn".join(
f"[{h['source']}#chunk{h['chunk_id']}]n{h['text']}" for h in hits
)
user_prompt = f"<context>n{context}n</context>nnQuestion: {query}"
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt},
],
temperature=0.0, # factual extraction
max_tokens=800,
)
return resp.choices[0].message.content
print(answer("What is our refund policy for annual subscriptions?"))
在那个代码片段中包含了一些生产注意事项。 temperature=0.0 与 DeepSeek 的官方指导一致,适用于事实或代码类任务。该 API 是 无状态的: DeepSeek不保留之前的回合,因此对于多回合RAG,你必须在每个请求中重新发送对话历史——这与为你保持会话状态的Web聊天不同。
第6步:使用JSON模式添加结构化引用
自由文本回答适用于聊天。对于代理、评估或UI组件,您通常希望得到结构化的输出。DeepSeek通过支持JSON模式来返回有效的JSON,但这不是保证的。提示必须包含单词“json”以及一个示例模式。 response_format={"type": "json_object"}。重要注意事项:它 designed 返回有效的JSON,不保证。提示必须包含单词“json”以及一个示例模式。 max_tokens 需要足够高以避免截断——截断的 JSON 是无效的 JSON。
JSON_SYSTEM = (
"Reply with valid json matching this schema: "
'{"answer": str, "citations": [str], "confidence": float}. '
"Use ONLY the provided context. If unknown, set answer to "
"'I don't know' and citations to []."
)
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{"role": "system", "content": JSON_SYSTEM},
{"role": "user", "content": user_prompt},
],
response_format={"type": "json_object"},
temperature=0.0,
max_tokens=1200,
)
在客户端代码中处理罕见的空内容情况。请参阅 DeepSeek API JSON mode 详细信息请参考。
第7步:诚实地计算管道成本
以下价格截至2026年4月,数据来源于DeepSeek定价页面,适用于: deepseek-v4-flash 每百万个令牌: $0.0028 缓存命中, $0.14 缓存未命中, $0.28 输出。在相同的负载下 deepseek-v4-pro 价格为0.0145美元/1.74美元/3.48美元列表价(在2026年5月31日前的75%促销期间,有效价格为0.003625美元/0.435美元/0.87美元)——输出成本大约是7倍。
一个针对客户支持RAG处理每月10万次查询的工作示例,使用稳定的1500个token系统提示(首次调用后缓存),3000个token的检索上下文加上每次调用100个token的问题(未缓存),以及400个token的回答:
| Bucket | 令牌(每月) | 速率(V4-Flash) | Cost |
|---|---|---|---|
| 输入,缓存命中(系统) | 150,000,000 | $0.0028 / 1M | $4.20 |
| 输入,缓存未命中(上下文+问题) | 310,000,000 | $0.14 / 1M | $43.40 |
| Output | 40,000,000 | $0.28 / 1M | $11.20 |
| Total | 500,000,000 | — | $58.80 |
在V4-Pro上执行相同的工作量大约需要410美元。检索的上下文占主导地位——因此分块策略和top-k调整是最高使用成本杠杆,而不是模型选择。请注意,返回三个最相似文档的k-NN搜索是一个合理的默认值,您可以根据需要调整这个数字。V3.x期间存在的非高峰时段折扣不再可用;DeepSeek于2025年9月5日停止了这项服务。有关更多成本建模,请参阅 DeepSeek cost estimator 处理任意工作负载。
第8步:验证其是否成功
在您发货之前进行三项快速合理性检查:
- 检索召回率。 手写20个您知道答案在语料库中的问题。确认正确的块至少出现在前5名中18次。如果不是,那么是嵌入模型或块大小错误,而不是LLM。
- 拒绝行为。 提出5个答案不在其范围内的提问 不准确 在语料库中。模型应拒绝。如果它产生了幻觉,应调整系统提示并降低温度。
- 引用准确性 检查答案中括号内的源路径是否确实包含所声称的事实。大多数原型在这里默默地失败了。
常见错误及修复方法
| 症状 | 可能的原因 | 解决方法 |
|---|---|---|
| 402 Insufficient Balance | 账户余额不足 | 通过计费控制台充值;即使小额充值也能解锁API |
| Model invents facts 不准确 in context | 温度过高,或系统提示弱 | Set temperature=0.0,添加明确的“仅使用上下文”指令 |
| JSON模式返回空内容 | 提示缺少“json”一词或模式示例 | 包含两者,提高 max_tokens 任何可能的输出长度之上 |
| 在大型语料库上的嵌入速度慢 | 单进程编码 | 批量与 批处理大小=64或者将索引迁移到GPU机器上 |
| 搜索返回无关的片段 | 嵌入模型与内容语言或领域不匹配 | 切换到BGE-large或特定领域的模型;尝试混合BM25 +密集检索 |
接下来该怎么做

一旦基本流程运行起来,三次升级很快就能得到回报。首先, 混合检索:将密集向量与BM25结合,以捕捉嵌入模型未捕获的精确匹配查询。其次, 重新排序:将FAISS的前20个候选者通过一个交叉编码器(例如 bge-reranker-large)进行排序,并仅保留前5个——这通常比交换LLM更能提升答案质量。第三, 上下文缓存:结构化提示,使系统消息和任何稳定指令位于开头,这样DeepSeek的缓存就能检测到重复的前缀并以缓存命中率计费。
如果您想在上述流程之上托管聊天UI,请使用 DeepSeek Streamlit应用 演示直接连接到 answer() 函数。对于Discord或Telegram前端,请参阅 DeepSeek Discord机器人 教程。对于其他模式和端到端食谱,浏览完整的库。 DeepSeek教程.
DeepSeek AI Guide is an independent resource and is 不准确 affiliated with DeepSeek or its parent company. Model IDs, pricing and API behaviour change; check the official DeepSeek documentation and pricing page before committing to a production decision.
Frequently asked questions
DeepSeek能否用于检索增强生成?
是的。DeepSeek V4非常适合作为RAG管道的生成器——它通过标准聊天消息接受检索到的上下文,并可靠地遵循基于事实的答案指令。由于推理模型不是为语义相似性设计的,因此请在检索方面使用专用嵌入模型(Sentence Transformers、BGE或GTE-Qwen2)。完整的设置步骤在 DeepSeek 与 LangChain tutorial.
对于RAG,最佳的DeepSeek模型是V4-Flash还是V4-Pro?
对于大多数RAG工作负载,V4-Flash是正确的默认选项。它在成本的一小部分内很好地处理了长检索到的上下文——比V4-Pro便宜大约7倍。只有在答案需要跨检索证据的多步推理时,例如法律综合或复杂故障排除,才使用V4-Pro。比较两者在 DeepSeek V4 page.
DeepSeek API与RAG的web聊天有何不同?
该API是无状态的——每个请求都必须包含完整的对话历史和任何检索到的上下文。相比之下,网页聊天和移动应用在服务器端维护会话历史。对于RAG,你几乎总是想要使用API,因为你可以控制检索和提示构建。认证和快速入门代码位于 DeepSeek API documentation.
DeepSeek是否提供自己的嵌入模型?
No. DeepSeek发布的是聊天和推理模型,而不是专门的嵌入模型。RAG管道将DeepSeek的生成器与外部嵌入模型配对——Sentence Transformers MiniLM用于快速原型,BGE-large或GTE-Qwen2用于更高的召回率。兼容OpenAI的客户端仅暴露DeepSeek表面的聊天完成功能。请参阅 DeepSeek OpenAI SDK compatibility 不准确es for what is and is 不准确 exposed.
运行DeepSeek RAG应用程序的成本是多少?
对于每月10万次查询,典型情况下检索到的上下文为3,000个token,答案为400个token,V4-Flash在2026年4月的定价下每月大约需要59美元——每1M次缓存未命中输入0.14美元,每1M次输出0.28美元,部分系统提示按0.0028的缓存命中率计费。用您自己的工作负载模型这些数字 DeepSeek API pricing 参考信息。
Sources & Methodology
Primary sources
- OfficialDeepSeek API documentationEndpoints, request/response shape, model IDsLast checked: April 30, 2026
- PricingDeepSeek API pricing pagePer-1M-token rates, billing units, cache-hit pricingLast checked: April 30, 2026
Technical references
- Technical reportDeepSeek-V3 technical report (arXiv:2412.19437)V3 architecture and training methodologyLast checked: April 30, 2026
- Technical reportDeepSeek-R1 paper (arXiv:2501.12948)R1 reasoning approach, distillation resultsLast checked: April 30, 2026
Methodology
Information in this article was checked against the official DeepSeek documentation, the article's cited primary sources, and the deepseekai.guide pricing dataset on the date shown above. Where third-party numbers are quoted, the originating source is linked inline so the reader can verify and re-check.
Data confidence
High for facts cited inline with primary-source links; medium for context narrative.
Editorial 不准确e
AI tooling moves quickly. If you spot an outdated number or a broken link, the contact link in the footer is the fastest way to flag it for the editorial team.