欢迎光临
我们一直在努力

【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 开源的高效向量检索库

安装命令:

pip install sentence-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 维向量:

from sentence_transformers import SentenceTransformer
import faiss
import numpy as np

# 加载预训练 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:实现检索功能

def search(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 = []
for i, (dist, idx) in enumerate(zip(distances[0], indices[0])):
results.append({
"rank": i + 1,
"distance": round(float(dist), 4),
"content": documents[idx]
})
return results

# 测试检索
query = "如何管理容器化应用?"
results = search(query, top_k=2)

for r in results:
print(f"[{r['rank']}] 相似度分数: {r['distance']}")
print(f" 内容: {r['content']}\\n")

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

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

import requests

def generate_answer(query: str, retrieved_docs: list) > str:
"""基于检索结果生成回答"""
context = "\\n".join([d['content'] for d in retrieved_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}
)
return response.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 知识库。核心要点回顾:

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

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

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

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

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

    赞(0)
    未经允许不得转载:171主机测评 » 【AI技术教程】5分钟用Python+FAISS搭建本地RAG知识库,无需云服务
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址