【一天一个知识点】RAG系统构建第二步:构建检索器模块(Retriever)
🎯 一、目的与重要性
在RAG系统中,生成模型(如ChatGPT)要想准确作答,必须依赖高质量、相关性强的外部知识。Retriever模块就是实现这个目标的关键:
-
它承担着“为大模型提供上下文”的角色
-
能够在千百万条知识中精准提取与问题相关的信息片段
-
直接决定了整个RAG系统的响应质量与准确率
🧩 二、核心构建流程
我们将 Retriever 的构建过程分为 5 个子任务,如图所示:
🖼️ 总体流程图
flowchart TDA[1️⃣ 文本切分与清洗] --> B[2️⃣ 向量化编码]B --> C[3️⃣ 构建向量数据库]C --> D[4️⃣ 查询接口实现]D --> E[5️⃣ 可选精排器]
1️⃣ 文本切分与预处理
为了提高检索效果,必须将知识库中的文档进行“语义单元”的切分。
-
切分策略:
-
固定长度切分(如每段500字)
-
智能分句(按语义分段)
-
使用工具:LangChain TextSplitter、Haystack PreProcessor
-
-
预处理工作:
-
去除HTML标记、冗余空格
-
统一格式:简繁转换、英文大小写统一
-
添加 metadata(来源、标题、段落号等)
-
2️⃣ 嵌入编码(Embedding)
将每段文本转为向量,使其可以用于语义检索。
-
常用模型(按开放性/性能选择):
模型名称 | 提供方 | 特点 |
---|---|---|
text-embedding-ada-002 | OpenAI | 性能优秀,付费API |
bge-base-zh / bge-m3 | 百度+智源 | 中文效果佳,开源 |
E5-small / E5-large | Huggingface | 多语言支持好 |
text2vec | 中文专用 | 可本地部署 |
-
编码示例(Python):
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('BAAI/bge-base-zh')
embedding = model.encode("什么是RAG检索机制?")
-
注意事项:
-
编码模型与查询必须统一
-
可将结果缓存至磁盘,避免重复计算
-
3️⃣ 构建向量数据库
将所有知识段的向量存入数据库中,支持快速近似最近邻(ANN)搜索。
-
主流工具对比:
工具 | 开源 | 特点 | 推荐场景 |
---|---|---|---|
FAISS | ✅ | 高性能、轻量、单机 | 本地开发/原型 |
Milvus | ✅ | 分布式、强扩展 | 企业部署 |
Weaviate | ✅ | REST接口、支持分类/过滤 | 数据检索API |
Qdrant | ✅ | Rust性能、安全好 | 本地 + 云部署 |
Pinecone | ❌ | 云服务、免维护 | 快速部署 |
-
示意图:嵌入+入库过程
graph TDA[切分后段落] --> B[编码为向量]B --> C[存入向量数据库]C -->|支持相似度检索| D[返回 Top-K 文段]
4️⃣ 构建查询接口(Query API)
用户发起提问后,系统将其转换为向量并检索最相关的知识段落。
-
接口工作流程:
sequenceDiagramparticipant 用户 as Userparticipant RAG系统 as RAGparticipant 向量模型 as Embedderparticipant 向量库 as DB用户->>RAG系统: 输入问题(自然语言)RAG系统->>向量模型: 编码Query向量模型-->>RAG系统: 返回Query向量RAG系统->>向量库: 相似度检索Top-K向量库-->>RAG系统: 返回相关段落RAG系统-->>用户: 提供答案上下文
-
关键参数:
-
Top_k
: 一次取出多少段(常为3-10) -
score_threshold
: 相似度阈值控制准确度 -
filter
: 按文档来源/时间过滤内容(可选)
-
5️⃣ 可选:重排序模块(Reranker)
对 Top-K 检索结果进一步排序,提升最终质量。
-
使用如
bge-reranker
、ColBERT
等模型,进行 Pair-wise 打分 -
LangChain、Haystack 等框架都支持 plug-in 式调用
🎓 示例:代码演示(基于FAISS + BGE)
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddingsembeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-base-zh")
db = FAISS.load_local("faiss_index", embeddings)
docs = db.similarity_search("什么是RAG检索器?", k=5)
for doc in docs:print(doc.page_content)
📌 三、最终效果
完成 Retriever 模块后,我们将具备如下能力:
能力 | 描述 |
---|---|
精准匹配 | 支持中文/多语言语义相似度检索 |
高效 | 基于向量搜索,响应快,支持百万级规模 |
可扩展 | 支持增量添加知识,动态更新 |
灵活 | 可结合过滤器、权重、标签等定制策略 |
✅ 四、进阶建议
-
结合元数据(metadata)进行多维度检索
-
搭配缓存机制,加速高频query响应
-
引入“检索失败兜底策略”提升健壮性
-
评估指标:Hit@K、MRR、Recall、Latency
📦 输出成果整理
项目 | 内容 |
---|---|
向量数据库 | 已建立,存储结构清晰 |
检索接口 | 支持输入query返回Top-K文段 |
可视化/调试工具 | 可展示向量间相似度 |
模块文档 | 编码+检索流程文档、示例代码 |