RAG 实战:用 DeepSeek + 本地知识库搭专属 AI 问答(2026) 读完你能得到一个跑在本机、能读你自己 Markdown/txt 文档、用 DeepSeek 回答问题并给出引用来源的命令行问答程序。全套代码可直接复制运行基于 2026 最新依赖实测。「直接问大模型」最大的问题是它不知道你的私有资料——你公司的文档、你项目的 README、你整理的笔记。RAG检索增强生成就是解决这个的先把你的文档切片、向量化存起来提问时先检索最相关的几段再把这几段喂给大模型作答。这篇带你从 0 跑通一个最小但完整的 RAG。一、RAG 到底在干什么一张图讲清你的文档 ──切分── 文本块 ──嵌入模型── 向量 ──存入── 向量库 │ 提问 ──嵌入── 问题向量 ──相似度检索── Top-K 相关块 ──┘ │ [相关块 问题] ── DeepSeek ── 带引用的答案记住两条主线入库文档→块→向量→库和问答问题→检索→拼上下文→大模型。二、前置环境项要求Python3.10 – 3.12操作系统Windows / macOS / Linux 均可DeepSeek API Key官方平台申请新用户通常有免费额度显卡不强制嵌入用本地 CPU 模型也能跑本文嵌入用开源的BAAI/bge-small-zh中文向量模型本地跑、免费生成用 DeepSeek 官方 API。三、最短可跑通路径python-mvenv .venv .venv\Scripts\activate# macOS/Linux: source .venv/bin/activatepipinstalllangchain langchain-community langchain-openai sentence-transformers faiss-cpu装好后准备一个docs/目录扔几个.md或.txt进去就用你手头的笔记然后跑后面的两个脚本。四、分步详解 完整代码4.1 第一步把文档切分并建向量库ingest.pyimportosfromlangchain_community.document_loadersimportDirectoryLoader,TextLoaderfromlangchain.text_splitterimportRecursiveCharacterTextSplitterfromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportFAISS DOCS_DIRdocsINDEX_DIRfaiss_indexdefbuild_index():# 1) 读取 docs/ 下所有 txt 与 mdloaderDirectoryLoader(DOCS_DIR,glob**/*.*,loader_clsTextLoader,loader_kwargs{encoding:utf-8},)docsloader.load()print(floaded{len(docs)}documents)# 2) 切分每块 500 字符重叠 80避免把一句话切断splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap80,separators[\n\n,\n,。,,, ,],)chunkssplitter.split_documents(docs)print(fsplit into{len(chunks)}chunks)# 3) 中文向量模型首次会自动下载约百 MBembHuggingFaceEmbeddings(model_nameBAAI/bge-small-zh-v1.5)# 4) 建 FAISS 向量库并落盘vsFAISS.from_documents(chunks,emb)vs.save_local(INDEX_DIR)print(findex saved to{INDEX_DIR}/)if__name____main__:build_index()运行python ingest.py看到index saved to faiss_index/即建库成功。4.2 第二步检索 调用 DeepSeek 作答ask.pyimportosfromlangchain_community.embeddingsimportHuggingFaceEmbeddingsfromlangchain_community.vectorstoresimportFAISSfromlangchain_openaiimportChatOpenAI INDEX_DIRfaiss_indexdefload_retriever(k4):embHuggingFaceEmbeddings(model_nameBAAI/bge-small-zh-v1.5)vsFAISS.load_local(INDEX_DIR,emb,allow_dangerous_deserializationTrue,)returnvs.as_retriever(search_kwargs{k:k})defmake_llm():# DeepSeek 兼容 OpenAI 协议改 base_url 模型名即可returnChatOpenAI(modeldeepseek-chat,base_urlhttps://api.deepseek.com,api_keyos.environ[DEEPSEEK_API_KEY],temperature0.2,)PROMPT你是严谨的问答助手。只依据下面的「资料」回答问题 资料里没有的内容就说「资料中未提及」不要编造。 资料 {context} 问题{question} 请用中文回答并在结尾用 [来源N] 标注你用到的资料段编号。defask(question:str):retrieverload_retriever()docsretriever.invoke(question)context\n\n.join(f[来源{i1}]{d.page_content}fori,dinenumerate(docs))llmmake_llm()msgPROMPT.format(contextcontext,questionquestion)respllm.invoke(msg)print(\n 答案 \nresp.content)print(\n 命中来源 )fori,dinenumerate(docs):srcd.metadata.get(source,?)print(f[来源{i1}]{src})if__name____main__:importsys qsys.argv[1]iflen(sys.argv)1else这些资料讲了什么ask(q)先设置 Key 再运行setDEEPSEEK_API_KEYsk-xxxx# macOS/Linux: export DEEPSEEK_API_KEYsk-xxxxpython ask.py我的文档里关于X是怎么说的你会看到一段只基于你文档的答案外加它实际命中的来源文件。这就是一个完整的 RAG 问答。五、常见报错与解决收藏级报错 1allow_dangerous_deserialization相关报错根因新版 FAISS 加载本地索引默认禁止反序列化。解法FAISS.load_local(..., allow_dangerous_deserializationTrue)仅对你自己建的索引开启。报错 2首次运行卡在下载嵌入模型 / 连接超时根因BAAI/bge-small-zh-v1.5首次需下载。解法耐心等一次下完会缓存到本地之后秒加载。可配置 HuggingFace 国内镜像加速下载。报错 3KeyError: DEEPSEEK_API_KEY根因环境变量没设到当前终端会话。解法在「同一个」终端里先set/export再运行脚本别开两个窗口。报错 4答案总是「资料中未提及」根因切分块太大或检索 k 太小相关内容没被召回。解法把chunk_size调小到 300–400k调到 6–8重建索引再试。报错 5中文文档加载报 UnicodeDecodeError根因文件不是 UTF-8。解法本文已在 loader 指定encodingutf-8若仍报错把源文件另存为 UTF-8。六、验证成功的标志ingest.py输出了 chunk 数量并保存了faiss_index/ask.py能针对你文档里的内容给出正确答案并列出命中来源问一个文档里没有的问题它会回答「资料中未提及」而不是编造。三条都满足你的专属知识库问答就跑通了。七、从 Demo 到生产下一步这个最小 RAG 还能往上加换更强的重排模型提精度、把 FAISS 换成可持久化的向量数据库、给问答套个 Web 界面。这些我会在后续文章里讲关注大鹏AI教育持续更新 AI 实战。完整代码本文的ingest.py与ask.py已在上文逐段给全直接复制即可跑通无需额外下载。建议收藏下次搭知识库问答直接照这套改。卡在哪一步把报错原文贴评论区我帮你看。