【AI技术教程】5分钟用Python+FAISS搭建本地RAG知识库,无需云服务

📅 2026/7/9 1:24:13 👁️ 阅读次数 📝 编程学习
【AI技术教程】5分钟用Python+FAISS搭建本地RAG知识库,无需云服务

前言

你是不是也遇到过这样的场景:手里有一堆技术文档、API手册、会议纪要,每次查东西全靠 Ctrl+F 盲搜,效率极低?

RAG(Retrieval-Augmented Generation,检索增强生成)就是为了解决这个问题而生的。它的核心思想很简单:先把知识"存起来",需要时"先检索再回答",而不是让大模型全靠记忆硬编。

今天这篇博客不整虚的,直接带你用纯 Python + FAISS(Facebook 开源的向量检索库)搭建一个本地 RAG 知识库,完全离线、零成本、不依赖任何云 API。文末附完整可运行代码。


一、RAG 到底是什么?大白话解释

RAG 流程可以分为三个核心步骤:

步骤英文名称做了什么类比
1. 向量化Embedding把文字变成"数字指纹"给每本书编一个唯一编号
2. 存储检索Vector Search在海量向量中快速找到相似的图书馆的索引目录
3. 生成回答LLM Generation带着检索结果让大模型回答把相关书页递给老师看

核心优势:

  • ✅ 知识可更新:文档改了,重新向量化就行,不用重新训练模型

  • ✅ 答案有出处:每次回答都基于真实检索到的内容

  • ✅ 本地可控:敏感数据不出门,隐私有保障


二、环境准备

整个项目只需要两个核心依赖:

  • sentence-transformers:将文本转为向量(Embedding)

  • faiss-cpu:Facebook 开源的高效向量检索库

安装命令:

pipinstallsentence-transformers faiss-cpu

💡 如果你的机器有 NVIDIA 显卡,可以把faiss-cpu换成faiss-gpu,检索速度会快几十倍。本文以 CPU 版本演示,开箱即用。


三、实操步骤:从零到一搭建知识库

步骤 1:准备文档数据

假设我们有以下技术文档片段(实际使用时可以是 PDF、Markdown 文件的切分内容):

documents=["Docker 容器是一种轻量级的虚拟化技术,它将应用及其依赖打包在一个隔离环境中运行。","Kubernetes 是一个容器编排平台,用于自动化部署、扩展和管理容器化应用。","Python 的 requests 库是一个简单易用的 HTTP 客户端库,支持 GET、POST 等常用方法。","Git 是一个分布式版本控制系统,支持分支管理、合并和提交历史记录。","Docker Compose 允许通过 YAML 文件定义和运行多容器 Docker 应用。",]

步骤 2:文本向量化

使用sentence-transformers的预训练模型将每段文字转换为 768 维向量:

fromsentence_transformersimportSentenceTransformerimportfaissimportnumpyasnp# 加载预训练 embedding 模型(首次运行会自动下载,约 420MB)model=SentenceTransformer('all-MiniLM-L6-v2')# 对文档进行向量化embeddings=model.encode(documents,show_progress_bar=True)print(f"向量维度:{embeddings.shape}")# 输出: (5, 768)

📌 模型说明:all-MiniLM-L6-v2是一个轻量级中文/英文通用模型,体积小、速度快,适合入门。如果需要更高精度,可以换用all-mpnet-base-v2

步骤 3:构建 FAISS 索引

将向量存储到 FAISS 索引中,实现毫秒级相似度检索:

dimension=embeddings.shape[1]# 768# 使用 L2 距离(欧几里得距离)构建索引index=faiss.IndexFlatL2(dimension)# FAISS 要求 float32 格式embeddings_32=embeddings.astype('float32')index.add(embeddings_32)# 向索引中写入向量print(f"已存储{index.ntotal}条向量")

步骤 4:实现检索功能

defsearch(query:str,top_k:int=3)->list:"""根据问题检索最相关的文档"""query_embedding=model.encode([query])query_32=query_embedding.astype('float32')# FAISS 检索:返回距离最近的前 top_k 个distances,indices=index.search(query_32,top_k)results=[]fori,(dist,idx)inenumerate(zip(distances[0],indices[0])):results.append({"rank":i+1,"distance":round(float(dist),4),"content":documents[idx]})returnresults# 测试检索query="如何管理容器化应用?"results=search(query,top_k=2)forrinresults:print(f"[{r['rank']}] 相似度分数:{r['distance']}")print(f" 内容:{r['content']}\n")

步骤 5:连接大模型生成答案

检索到相关文档后,交给大模型生成最终回答。这里以本地 Ollama 为例:

importrequestsdefgenerate_answer(query:str,retrieved_docs:list)->str:"""基于检索结果生成回答"""context="\n".join([d['content']fordinretrieved_docs])prompt=f"""你是一个专业的技术助手。请基于以下参考资料回答问题。 如果资料中没有答案,请明确说"参考资料中未提及"。 参考资料:{context}问题:{query}"""# 调用 Ollama(需先安装并启动 ollama serve)response=requests.post("http://localhost:11434/api/generate",json={"model":"qwen2.5:7b","prompt":prompt,"stream":False})returnresponse.json().get("response","")# 完整 RAG 流程query="Docker 和 Kubernetes 有什么关系?"docs=search(query,top_k=3)answer=generate_answer(query,docs)print(answer)

四、进阶优化技巧

优化方向具体做法效果
文档切分使用 LangChain 的 RecursiveCharacterTextSplitter 按段落/字符数切分检索精度提升 30%+
混合检索结合关键词检索(BM25)+ 向量检索解决向量检索"语义模糊"问题
重排序(Rerank)用 Cross-Encoder 模型对 top-20 结果重新打分取 top-5 精度显著提升
索引压缩使用 FAISS 的 IVF + PQ 量化,在精度损失<5%时压缩 8 倍千万级向量也可内存加载

五、常见问题解答

Q1:检索出来的内容不够准确怎么办?

优先检查文档切分策略。一段文字太长的话,嵌入向量会"信息稀释"。建议单段控制在 200-500 字。

Q2:中文效果不好?

可以尝试专为中文优化的 embedding 模型,如BAAI/bge-base-zh-v1.5(BGE 模型族),中文语义检索能力更强。

Q3:数据量大了怎么办?

FAISS 单机可处理千万级向量。如果数据量超 500 万条,建议升级到faiss-gpu或考虑 Milvus、Qdrant 等专用向量数据库。


总结

今天我们用不到 50 行 Python 代码,搭建了一个完整的本地 RAG 知识库。核心要点回顾:

  1. Embedding 是基石:把文字变成向量,相似度才能计算

  2. FAISS 是引擎:高效的向量检索,毫秒级返回

  3. 大模型是出口:带着检索结果生成有依据的答案

完整代码可以直接复制运行,无需任何配置。你可以把公司内部文档、学习笔记导入这个知识库,打造一个专属的 AI 问答助手。

下一步推荐:试试把检索结果接入 Claude API 或本地 Ollama,看看实际效果。动手试试吧!