[保姆级教程] 0基础在Windows本地搭建“DeePseek”私人知识库 (附源码)
在这个AI爆发的时代,你是否想过把电脑里的几百份PDF、Word文档变成一个可以随时提问的“超级大脑”?而且完全免费、不用联网、数据不出本地!
今天手把手教大家利用 Ollama + DeepSeek + python 搭建一个本地 RAG(检索增强生成)系统。不用怕代码,照着做就行!
🛠️ 第一步:准备环境 (Windows篇)
我们需要两个核心工具:Ollama(运行AI的大脑)和 Python(处理文档的管家)。
1. 安装 Ollama
验证:安装完成后,打开电脑的“命令提示符”(按 Win+R,输入 cmd,回车)。
拉取模型:在黑框里输入以下命令并回车(这一步需要联网下载模型,约 9GB):
ollama pull DeepSeek-r1:14b复制代码
💡 注意:如果不差显存(12G以上)用 14b 效果最好;如果电脑配置一般(8G/16G内存),建议把命令换成 ollama pull deepseek-r1:7b,速度会快很多。
2. 安装 Python
下载:访问 Python官网 下载最新的 Python 3.10 或 3.11 版本。
关键一步:安装界面最下方一定要勾选 "Add Python to PATH" (添加到环境变量),然后点 Install Now。
📂 第二步:搭建项目文件夹 (把资料喂给AI)
这一步最关键!我们要把资料整理好,放在项目文件夹里。
DeepSeek 不挑食,你可以把文件直接散乱地堆在根目录,也可以建各种子文件夹分类存放,程序会自动把它们全部扫描出来。
1. 推荐的目录结构
在桌面上新建一个文件夹叫 MyLocalAI,建议参照下面的结构存放文件:
MyLocalAI/ (你的项目主文件夹)│├── build_kb.py <-- (等下要创建的代码文件1,负责吃书)├── chat_rag.py <-- (等下要创建的代码文件2,负责聊天)│└── 📂 知识库 (你可以随便起名,把所有资料丢这里) │ ├── 📂 2024工作总结/ │ ├── 年终汇报.pptx │ └── 部门会议纪要.docx │ ├── 📂 行业研报/ │ ├── AI发展趋势.pdf │ └── 竞品分析.pdf │ └── 📂 财务数据/ └── Q4预算表.xlsx复制代码
PDF (.pdf):各种论文、扫描件(必须是文字版,纯图片PDF读不了)。
Word (.docx):工作文档、合同、论文。
PPT (.pptx):汇报胶片、课件。
Excel (.xlsx):简单的表格数据(程序会转成文本读取)。
💻 第三步:安装依赖库
我们需要安装一些 Python 插件来处理文件。
在 MyLocalAI 文件夹的空白处,按住 Shift 键 + 点击鼠标右键,选择 “在此处打开 Powershell 窗口” (或者CMD)。
复制下面这行命令粘贴进去,回车:
pip install numpy faiss-cpu pandas pypdf python-docx python-pptx fastembed tqdm ollama openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple复制代码
(这里使用了清华镜像源,下载速度飞快)
📝 第四步:创建代码文件 (直接复制)
我们需要在文件夹里创建两个 Python 文件。
方法:新建一个文本文件 -> 粘贴代码 -> 保存 -> 重命名为 xxx.py。
文件 1:build_kb.py (构建知识库)
这个脚本负责扫描刚才那些文件夹,把文档“嚼碎”并存成AI能读懂的向量格式。
import osimport gcimport shutilimport loggingimport numpy as npimport faissimport pandas as pdfrom pypdf import PdfReaderfrom docx import Documentfrom pptx import Presentationfrom fastembed import TextEmbeddingfrom tqdm import tqdm# =========================# ⚙️ 配置区域# =========================# 设置国内镜像,解决下载慢的问题os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"logging.getLogger("pypdf").setLevel(logging.ERROR)BASE_DIR = "." # 扫描当前目录INDEX_FILE = "kb.index"CHUNKS_FILE = "kb_chunks.npy"BATCH_SIZE = 256# =========================# 📄 文档加载器# =========================def load_pdf(path): try: reader = PdfReader(path) return "\n".join([page.extract_text().strip() for page in reader.pages if page.extract_text()]) except: return ""def load_docx(path): try: doc = Document(path) return "\n".join([p.text.strip() for p in doc.paragraphs if p.text.strip()]) except: return ""def load_pptx(path): try: prs = Presentation(path) out = [] for slide in prs.slides: for shape in slide.shapes: if hasattr(shape, "text_frame"): for p in shape.text_frame.paragraphs: if p.text.strip(): out.append(p.text.strip()) return "\n".join(out) except: return ""def load_xlsx(path): try: return pd.read_excel(path).to_markdown(index=False) except: return ""def split_text(text, size=500, overlap=50): res = [] for i in range(0, len(text), size - overlap): chunk = text[i:i + size].strip() if len(chunk) > 20: res.append(chunk) return resdef scan_files(): print("📂 正在扫描当前目录及子文件夹下的文档...") chunks = [] supported_ext = ['.pdf', '.docx', '.pptx', '.xlsx'] files = [] for root, _, filenames in os.walk(BASE_DIR): for f in filenames: if any(f.lower().endswith(ext) for ext in supported_ext): files.append(os.path.join(root, f)) print(f"📄 找到 {len(files)} 个文件,开始解析...") for file_path in tqdm(files, desc="解析文件"): content = "" ext = os.path.splitext(file_path)[1].lower() if ext == '.pdf': content = load_pdf(file_path) elif ext == '.docx': content = load_docx(file_path) elif ext == '.pptx': content = load_pptx(file_path) elif ext == '.xlsx': content = load_xlsx(file_path) if content: # 在内容前加上文件名,方便AI知道出处 file_name = os.path.basename(file_path) chunk_list = split_text(content) chunks.Extend([f"【来源:{file_name}】\n{c}" for c in chunk_list]) return chunks# =========================# 🚀 主程序# =========================def main(): # 1. 扫描文件并制作切片 # 如果想强制重新扫描,删除目录下的 kb_chunks.npy 即可 if os.path.exists(CHUNKS_FILE): print("✅ 检测到旧缓存,直接加载 (如需更新请删除 kb_chunks.npy)...") chunks = np.load(CHUNKS_FILE, allow_pickle=True).tolist() else: chunks = scan_files() if not chunks: print("❌ 没有找到有效内容,请检查文件夹里有没有文档!") return np.save(CHUNKS_FILE, np.array(chunks, dtype=object)) print(f"📦 共生成 {len(chunks)} 个文本块,准备向量化...") # 2. 初始化模型 model_name = "BAAI/bge-small-zh-v1.5" try: embedder = TextEmbedding(model_name=model_name) except: print("⚠️ 模型加载受阻,尝试自动修复...") cache_dir = os.path.join(os.getcwd(), ".fastembed") if os.path.exists(cache_dir): shutil.rmtree(cache_dir) embedder = TextEmbedding(model_name=model_name) # 3. 向量化并建立索引 print("🚀 正在将文本转化为向量 (如果是第一次运行,会自动下载模型,请耐心等待)...") embeddings = list(embedder.embed(chunks)) embeddings_np = np.array([list(e) for e in embeddings]).astype('float32') dim = embeddings_np.shape[1] index = faiss.IndexFlatIP(dim) index.add(embeddings_np) faiss.write_index(index, INDEX_FILE) print(f"🎉 知识库构建完成!索引文件: {INDEX_FILE}")if __name__ == "__main__": main()复制代码
文件 2:chat_rag.py (开始对话)
这个脚本负责连接 Ollama 和刚才建好的知识库。
import osimport faissimport numpy as npimport ollamafrom fastembed import TextEmbedding# =========================# ⚙️ 配置区域# =========================os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"INDEX_FILE = "kb.index"CHUNKS_FILE = "kb_chunks.npy"# ⚠️ 如果你安装的是 7b 模型,请把下面这行改成 "deepseek-r1:7b"OLLAMA_MODEL = "deepseek-r1:14b" EMBED_MODEL = "BAAI/bge-small-zh-v1.5"def main(): if not os.path.exists(INDEX_FILE): print("❌ 没找到知识库!请先运行 build_kb.py") return print("⏳ 正在加载大脑...") index = faiss.read_index(INDEX_FILE) chunks = np.load(CHUNKS_FILE, allow_pickle=True).tolist() embedder = TextEmbedding(model_name=EMBED_MODEL) print("\n" + "="*40) print(f"🤖 本地AI知识库助手 ({OLLAMA_MODEL}) 已启动") print("💡 输入 'exit' 退出") print("="*40) while True: query = input("\n🙋 你的问题: ").strip() if query.lower() in ['exit', 'quit']: break if not query: continue # 1. 检索 print("🔍 正在翻阅资料...", end="\r") query_vec = list(embedder.embed([query]))[0] D, I = index.search(np.array([query_vec], dtype="float32"), k=4) context = [] for idx in I[0]: if idx >= 0: context.append(chunks[idx]) # 2. 生成 Prompt = f""" 基于以下资料回答问题。如果资料里没有提到,就说不知道,不要瞎编。 【资料】: {"\n---".join(context)} 【问题】:{query} """ print("\n🤖 DeepSeek 回答:") try: stream = ollama.chat(model=OLLAMA_MODEL, messages=[{'role': 'user', 'content': prompt}], stream=True) for chunk in stream: print(chunk['message']['content'], end='', flush=True) print("\n") except Exception as e: print(f"❌ 也就是这里出错了: {e}") print("请检查 Ollama 是否已在后台运行!")if __name__ == "__main__": main()复制代码▶️ 第五步:运行起来!
1. 构建知识库
在命令窗口输入:
python build_kb.py复制代码
第一次运行会下载一个约 100MB 的向量模型(已配置国内镜像,很快)。
你会看到进度条在扫描你的文档。
显示 🎉 知识库构建完成! 就成功了。
2. 开始聊天
在命令窗口输入:
python chat_rag.py复制代码
程序启动后,输入你的问题,比如:“总结一下Q4预算表的内容”、“2024年工作汇报里提到了什么”。
你会发现 AI 回答的内容完全是基于你文件夹里的文件!
❓ 常见问题 (FAQ)
Q: 运行 build_kb.py 报错说 SSL 连接错误?
A: 这是网络问题。代码里已经加了 HF_ENDPOINT 镜像,如果还不行,尝试关掉你的科学上网工具,或者切换手机热点试试。
Q: 聊天时电脑非常卡,出字很慢?
A: 你的模型可能太大了。
去 CMD 运行 ollama rm deepseek-r1:14b 删除大模型。
运行 ollama pull deepseek-r1:1.5b (这个超快,渣机也能跑)。
记得修改 chat_rag.py 里的配置代码。
Q: 我往文件夹里加了新文档,AI 怎么不知道?
A: 只要删掉文件夹里的 kb_chunks.npy 和 kb.index 这两个旧文件,重新运行 python build_kb.py 即可重建索引。
教程结束,祝大家搭建愉快!



还没有评论,来说两句吧...