RAG 知识库核心模块全解(产品视角 + 技术细节)
“关于知识库这块,你有什么能讲的吗?”我一脸懵逼,数据咋清洗,数据格式咋定的不是刚说完吗??🤔复盘了一下,感觉应该是想问下面这些
🧱 1. 文档切分策略(切得好,才能召回准)
🌟 目标:
把长文档切成合适的语义段,既能保证上下文连贯,又不超出 token 限制。
📌 常见策略:
策略 | 描述 | 优点 | 缺点 |
---|---|---|---|
固定窗口 + 重叠 | 每 N 词/句切一段,前后有部分重叠 | 实现简单、信息不漏 | 语义断裂、冗余多 |
基于分隔符 | 以段落、标题、换行等结构切 | 保留结构,适合规整文档 | 不适合没有格式的内容 |
智能语义切分 | 利用句向量计算相似度判断切点 | 保证每段语义完整 | 计算开销大、依赖模型 |
百炼等 SaaS 的“智能切分” | 大模型判断分段位置 | 效果通常不错 | 不透明、不稳定可控性 |
🧰 推荐做法:
用 langchain.text_splitter
中的 RecursiveCharacterTextSplitter
(递归+分隔符):
from langchain.text_splitter import RecursiveCharacterTextSplittersplitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100,separators=["\n\n", "\n", ".", " ", ""]
)
chunks = splitter.split_text(your_text)
💡 坑点:
- chunk 太短 → 表达不完整
- chunk 太长 → embedding稀释,token溢出
- overlap 必须控制好,100左右比较稳
🧬 2. 向量生成(embedding)
🌟 目标:
把文本片段转化为模型能理解的向量(embedding),进入语义空间。
📌 常见 embedding 模型:
模型名 | 维度 | 语言 | 优势 |
---|---|---|---|
text-embedding-ada-002 (OpenAI) | 1536 | 英文/中英混合 | 商用稳定 |
bge-base-zh / bge-large-zh | 768/1024 | 中文优化 | 免费、本地跑 |
text2vec 系列(阿里) | 768 | 中文为主 | 多任务优化好 |
e5-mistral (英文/多语) | 1024 | 多语 | 零样本搜索好用 |
🛠️ 示例代码:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("bge-base-zh")emb = model.encode("鼠标断连怎么解决")
🔥 记得用 BGE 模型要加 prompt:“为这个句子生成表示以用于检索相关文档:xxxx”
🔍 3. 向量库选择(存储+召回)
🌟 目标:
将 embedding 存入可快速近似搜索的数据库中,用于后续查询。
📌 常见库:
库名 | 特点 | 本地部署 | 检索速度 |
---|---|---|---|
FAISS | 最轻量,Python快 | ✅ | 快速 |
Milvus | 企业级,高并发 | ✅ | 分布式好 |
Chroma | Langchain生态 | ✅ | 简单 |
Weaviate / Qdrant | 支持更多索引类型 | ✅ | 更复杂可扩展 |
🛠️ 示例:FAISS 本地构建
import faiss
import numpy as npindex = faiss.IndexFlatIP(768) # 余弦相似度
index.add(np.array([vec1, vec2, vec3])) # vec 是 np.array 的向量D, I = index.search(np.array([query_vec]), top_k)
🎯 4. 检索策略:向量、关键词、混合召回
🌟 目标:
提高召回的准度和覆盖率。
📌 召回方式对比:
策略 | 原理 | 优点 | 风险 |
---|---|---|---|
Dense 向量检索 | 用embedding比对相似度 | 抗表达差异 | 易召回无关内容 |
Keyword(BM25) | 用关键词精准召回 | 准确度高 | 不支持变形表达 |
Hybrid(混合检索) | 两者并用 + 融合评分 | 稳准平衡 | 实现复杂 |
📌 混合召回核心是:关键词召回召不准 → 靠语义补;语义召回太泛 → 靠关键词兜底
🧠 常用组合:
关键词召回 top30 + 向量召回 top30 → 合并 → rerank top10
🧠 5. Rerank 排序(二次排序)
🌟 目标:
提高最终召回片段的相关性排序,降低误召回风险。
📌 推荐模型:
名称 | 原理 | 优势 |
---|---|---|
bge-reranker-base | 双句相似度评分 | 中文好,性能稳定 |
Cohere Rerank | 商用API | 效果强 |
cross-encoder/ms-marco | 多语言 | 开源 |
🛠️ 示例伪代码:
score = reranker(query, [chunk1, chunk2, chunk3])
ranked = sorted(zip(score, chunks), reverse=True)
🧩 6. Prompt 拼接策略(上下文注入)
🌟 目标:
将检索到的内容+用户问题组织成 Prompt 喂给 LLM。
📌 模板示例:
你是某品牌客服助手,以下是产品说明文档内容:【知识片段】
1. 鼠标若断连,请检查电量或更换接收器
2. 鼠标灯不亮通常为电池电量低用户提问:
鼠标今天怎么又断连了?请基于上方知识内容回答。
🧠 控制点:
- 控制 token 长度:太多片段 LLM 会截断
- 用
CONTEXT_WINDOW = 3500
控制拼接字数 - 多段知识片段要用编号或分隔符
---
,降低混淆
❌ 7. 检索失败处理机制(没命中咋办)
🌟 目标:
保证系统在没有命中知识时,不答错,不胡说。
📌 建议处理方式:
情况 | 策略 |
---|---|
没有任何召回 | 给 LLM 明确提示:“未检索到相关知识,直接回答‘暂未收录该问题’” |
命中不确定内容 | 添加置信度判断逻辑(低于阈值不展示) |
用户可能问了不支持的功能 | 在知识库中加入“该设备不支持XX”明确表述,防止误空 |