从0到1搭建本地RAG知识库:完全离线的AI问答系统实操
2025 年以来,大语言模型(LLM)在企业落地中最成功的范式莫过于 RAG(Retrieval-Augmented Generation,检索增强生成)。然而,大多数 RAG 方案依赖 OpenAI / 百度文心等云端 API,存在数据外泄风险、网络延迟和按量计费三大痛点。本文手把手教你用 LangChain + Chroma(本地向量数据库)+ 开源嵌入模型 + 本地 LLM,从零搭建一套完全离线的知识问答系统。
一、架构概览
一个完整的本地 RAG 系统包含以下组件:
- 文档加载与切分 —— 读取 PDF、Markdown、TXT 等格式,按语义切块(Chunk)
- 嵌入模型(Embedding Model) —— 将文本块转为向量,纯本地运行
- 向量数据库(Chroma) —— 存储向量并支持近似搜索
- 大语言模型(LLM) —— 基于检索结果生成最终答案
- LangChain 编排层 —— 串联检索 → 生成流程
全链路数据不出本机,彻底杜绝隐私泄露。
二、环境准备
推荐 Python 3.10+,操作系统不限(Windows / macOS / Linux 均可)。
# 创建虚拟环境(推荐) python3 -m venv rag_env source rag_env/bin/activate # Linux/macOS # 安装核心依赖 pip install langchain langchain-community \ chromadb sentence-transformers \ transformers torch # 如需解析 PDF 等文档 pip install pypdf python-docx markdown
pip install torch --index-url https://download.pytorch.org/whl/cu121三、文档加载与分块
假设我们有一批公司内部技术文档(Markdown 格式),放在 ./docs/ 目录下:
from langchain_community.document_loaders import DirectoryLoader from langchain.text_splitter import RecursiveCharacterTextSplitter # 1. 加载目录下所有 .md 文件 loader = DirectoryLoader("./docs", glob="**/*.md") docs = loader.load() print(f"已加载 {len(docs)} 个文档") # 2. 按语义分块:每块 512 字符,重叠 64 splitter = RecursiveCharacterTextSplitter( chunk_size=512, chunk_overlap=64, separators=["\n## ", "\n### ", "\n\n", "\n", " ", ""] ) chunks = splitter.split_documents(docs) print(f"共切分为 {len(chunks)} 个文本块")
RecursiveCharacterTextSplitter 会按 Markdown 标题层级优先切分,保证同一段落的内容不被割裂。chunk_size 可根据文档长度动态调整,建议 256–1024 之间。
四、初始化嵌入模型与向量库
嵌入模型选择 BAAI/bge-base-zh-v1.5(中文语义效果优秀,仅 300MB+),完全本地加载:
from langchain_community.embeddings import HuggingFaceBgeEmbeddings from langchain_community.vectorstores import Chroma # 加载本地嵌入模型 embedding_model = HuggingFaceBgeEmbeddings( model_name="BAAI/bge-base-zh-v1.5", model_kwargs={ "device": "cpu" }, # 改为 "cuda" 使用 GPU encode_kwargs={ "normalize_embeddings": "true" } ) # 创建 Chroma 向量库并写入 vector_store = Chroma.from_documents( documents=chunks, embedding=embedding_model, persist_directory="./chroma_db" # 持久化到本地磁盘 ) vector_store.persist() print("✅ 向量库已构建,保存在 ./chroma_db/")
首次运行会自动下载模型(约 300MB),后续加载直接从缓存读取。Chroma 默认将向量数据持久化到本地目录,重启程序无需重新构建索引。
shibing324/m3e-base、infgrad/stella-base-zh-v3-1792d,效果各有侧重,建议用自己的数据集对比 Recall@K。五、接入本地 LLM
LLM 选用开源的 Qwen2.5-7B-Instruct(通义千问),通过 llama.cpp 或 Ollama 本地推理。此处使用 Ollama 方案,最省心:
# 终端安装 Ollama(Linux / macOS) curl -fsSL https://ollama.com/install.sh | sh # 拉取模型(约 4.1GB) ollama pull qwen2.5:7b # 测试 ollama run qwen2.5:7b "你好,请用中文回复"
然后在 Python 中通过 LangChain 调用:
from langchain_community.llms import Ollama llm = Ollama( model="qwen2.5:7b", temperature=0.3, # 低温度保证回答稳定性 num_predict=2048 # 最大生成长度 ) # 简单测试 resp = llm.invoke("请介绍一下 RAG 技术") print(resp)
硬件要求:7B 模型在 CPU 上约 4–6 token/s(够用),推荐 16GB 内存以上;GPU 量化后可跑 20+ token/s。显存不足可选 qwen2.5:1.5b 或 qwen2.5:3b。
六、搭建 RAG 问答链
核心环节:用 LangChain 的 RetrievalQA 把向量检索与 LLM 生成串成一条链:
from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate # 自定义提示词模板,让 LLM 基于检索内容回答 prompt_template = """ 你是一个专业的技术支持助手。 请根据以下资料,用中文简洁准确地回答问题。 【已知资料】 {context} 【问题】 {question} 请基于上述资料回答。如果资料中找不到答案, 请说"资料中未找到相关信息",不要编造。 """ QA_CHAIN_PROMPT = PromptTemplate.from_template(prompt_template) # 构建检索器:返回前 4 个最相关文本块 retriever = vector_store.as_retriever(search_kwargs={ "k": 4 }) # 组装问答链 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", # 所有检索结果拼入 context retriever=retriever, chain_type_kwargs={ "prompt": QA_CHAIN_PROMPT }, return_source_documents="true" # 返回引用来源 ) # 开始问答 query = "我们的系统如何配置日志级别?" result = qa_chain.invoke({ "query": query }) print("🤖 回答:", result["result"]) print("📄 参考来源:", [d.metadata.get("source") for d in result["source_documents"]])
这里 chain_type="stuff" 是将所有检索结果拼入提示词,适合文本块总量不超过 LLM 上下文窗口的场景。如果知识库庞大,可改用 map_reduce 或 refine 策略。
七、完整运行与效果测试
将以上代码整合为一个脚本 rag_qa.py,执行一次即可完成索引构建 + 问答:
# 运行 python rag_qa.py # 输出示例 已加载 12 个文档 共切分为 246 个文本块 ✅ 向量库已构建,保存在 ./chroma_db/ 🤖 回答:系统日志级别在 config.yaml 中的 logger.level 字段配置,支持 DEBUG / INFO / WARNING / ERROR 四级。 📄 参考来源:['./docs/运维手册.md', './docs/config-guide.md']
如果回答质量不理想,可以:
- 调整
chunk_size与chunk_overlap - 增大检索的
k值(如设为 6–8) - 换用更大或更适配领域的嵌入模型
- 在 Prompt 中加入 CoT(思维链)指令
八、进阶方向
基础 RAG 跑通后,还可以继续优化:
- HyDE(假设文档嵌入):先用 LLM 生成假设回答,再以回答为查询检索,提高召回准确率
- Reranker(重排序):检索后用小模型对结果重新排序,把最相关的排到前面
- 多轮对话记忆:引入
ConversationBufferMemory,实现上下文连续问答 - Web UI 界面:用 Gradio / Streamlit 包装为可视化聊天页面
- 多模态 RAG:结合图片向量检索,实现图文混合问答
下一篇文章将详解 Reranker 重排序 + HyDE 技术如何让 RAG 准确率提升 30%,欢迎持续关注乾坤Bot 实战宝典系列。