RAG 检索增强生成
RAG (Retrieval-Augmented Generation) 是解决 LLM 知识时效性和幻觉问题的核心技术范式。本文从原理到实践,系统梳理 RAG 的实现要点。
项目实践: RAG 技术贯穿多个项目——云智汇的课程知识库(Pinecone)、RagOfficePro的企业知识问答、MiroFish的向量记忆召回(Chroma)。
为什么需要 RAG?
LLM 存在两个固有缺陷:
- 知识截止:训练数据有时间截止点,无法获知最新信息
- 幻觉问题:在知识盲区会"自信地编造"答案
RAG 通过在推理阶段引入外部知识检索,让 LLM 基于真实文档生成回答,从根本上解决了这两个问题。
RAG 核心流程
文档 → 分块(Chunking) → 向量化(Embedding) → 存入向量数据库
↓
用户提问 → Query 向量化 → 相似度检索 → 取回 TopK 相关文档块
↓
将检索到的上下文注入 Prompt → LLM 生成回答1. 文档分块 (Chunking)
将长文档切分为语义完整的文本块,常见策略:
- 固定长度分块:按 Token 数切分,简单但可能截断语义
- 递归分块:按段落 → 句子 → 字符逐级切分,保持语义完整
- 结构化分块:利用文档结构(标题、章节)进行分块
实践经验: 在云智汇项目中,课件采用结构化分块策略——按章节标题划分,每个块控制在 500-800 Token,块间保留 50 Token 的重叠区域以避免边界信息丢失。
2. 向量化 (Embedding)
将文本块转换为高维向量表示:
- 模型选择:OpenAI
text-embedding-3-small、text-embedding-ada-002,或开源的bge-large-zh - 维度:通常 768-1536 维
- 关键指标:语义相似的文本应产生距离相近的向量
3. 向量数据库
存储和检索向量的核心组件:
| 数据库 | 特点 |
|---|---|
| Chroma | 轻量级,适合原型开发,Python/Java SDK 完善 |
| Pinecone | 全托管云服务,适合生产环境 |
| Milvus | 开源,支持大规模分布式部署 |
| Qdrant | 高性能,支持过滤和聚合 |
ANN 检索算法: 向量数据库使用近似最近邻 (ANN) 算法实现高效检索,常见方案包括 HNSW(分层可导航小世界图)和 IVF(倒排文件索引)。
4. 检索策略
基本检索: 将用户问题向量化后,计算与所有文档块的余弦相似度,取 TopK 个最相关的块。
进阶策略:
- Hybrid Search:结合向量检索和关键词检索 (BM25),兼顾语义理解和精确匹配
- Re-ranking:用交叉编码器对初筛结果重排序,提升精度
- Query Rewriting:改写用户问题,使其更匹配文档措辞
- Multi-query:将一个问题拆分为多个子问题分别检索,合并去重
5. Prompt 注入
将检索到的文档块拼接为上下文,注入到 System Prompt 或 User Prompt 中:
请基于以下参考资料回答用户问题。如果资料中没有相关信息,请说明。
参考资料:
---
[检索到的文档块1]
---
[检索到的文档块2]
---
用户问题:{question}关键参数调优
相似度阈值
不是所有检索结果都相关。设置相似度阈值过滤低质量结果:
- 阈值过高:可能遗漏相关信息(召回率低)
- 阈值过低:引入噪声干扰生成(精确率低)
- 经验值: 0.6-0.7 是比较平衡的起点
TopK 选择
取多少个文档块注入 Prompt:
- TopK 过小:上下文不充分
- TopK 过大:超出上下文窗口,且引入噪声
- 经验值: 3-8 个块通常足够
MiroFish 中的 RAG 实践
MiroFish 使用了双层检索架构:
- Chroma 向量检索:对新闻内容进行语义相似度匹配
- Zep GraphRAG 图谱检索:基于实体关系的图遍历检索
两者结合的优势:
- 向量检索擅长找"含义相近"的内容
- 图谱检索擅长找"关联关系"(A事件涉及B人物,B人物又与C组织有关)
- 混合检索覆盖了"相似"和"相关"两个维度