RAG(Retrieval-Augmented Generation)学习笔记
一、什么是 RAG
RAG(检索增强生成) 是一种将信息检索与大语言模型生成相结合的技术范式。核心思路很简单:在让 LLM 回答问题之前,先从外部知识库中检索相关内容,把检索到的内容作为上下文喂给模型,再让模型基于这些真实数据生成回答。
1.1 为什么需要 RAG
LLM 存在几个固有缺陷:
| 问题 | 说明 |
|---|---|
| 知识截止 | 训练数据有时效性,无法回答最新信息 |
| 幻觉 | 模型会”编造”看似合理但错误的内容 |
| 私有数据缺失 | 企业内部文档、专有知识模型完全不知道 |
| 可溯源性差 | 无法告诉用户回答来自哪里 |
RAG 通过外部检索来弥补这些问题,让 LLM 的回答有据可查、实时更新。
1.2 RAG vs Fine-tuning vs Prompt Engineering
| 维度 | RAG | Fine-tuning | Prompt Engineering |
|---|---|---|---|
| 知识更新 | 实时更新知识库即可 | 需要重新训练 | 依赖上下文窗口 |
| 成本 | 中等(检索系统+推理) | 高(训练算力) | 低 |
| 适用场景 | 知识密集型问答 | 风格/格式适配 | 简单任务引导 |
| 可解释性 | 高(可追溯来源) | 低 | 中 |
| 数据隐私 | 私有数据不出库 | 数据进入模型权重 | 取决于实现 |
实际项目中,这三者经常组合使用。
二、RAG 基本架构
2.1 标准流程
1 | 用户提问 |
2.2 两大阶段
离线阶段(Indexing)
把原始数据变成可检索的知识库:
1 | 原始文档 → 文档切分(Chunking) → 向量化(Embedding) → 存入向量数据库 |
在线阶段(Querying)
用户提问时的实时流程:
1 | 用户问题 → 问题向量化 → 向量相似度检索 → 上下文拼装 → LLM 生成 |
三、核心组件详解
3.1 文档切分(Chunking)
切分策略直接影响检索质量。
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 固定长度切分 | 按字符/token数切割,带重叠 | 通用场景 |
| 按段落/章节切分 | 利用文档结构(标题、换行) | 结构化文档 |
| 语义切分 | 根据语义相似度动态决定切分点 | 长文本、混合内容 |
| 递归切分 | 按分隔符层级递归切分 | 通用,LangChain 默认策略 |
关键参数:
- chunk_size:每个片段的大小,通常 256~1024 tokens
- chunk_overlap:相邻片段重叠区域,通常为 chunk_size 的 10%~20%
1 | # LangChain 递归字符切分示例 |
经验法则:chunk 太大→检索不精准,带入太多噪声;chunk 太小→丢失上下文,回答不完整。需要根据实际数据调优。
3.2 向量化(Embedding)
将文本转为固定维度的稠密向量,用于相似度计算。
常见 Embedding 模型:
| 模型 | 提供方 | 维度 | 特点 |
|---|---|---|---|
| text-embedding-3-small/large | OpenAI | 1536/3072 | 通用性强 |
| bge-large-zh | BAAI | 1024 | 中文表现优秀 |
| GTE (General Text Embedding) | Alibaba | 768/1024 | 多语言 |
| E5-mistral-7b | Microsoft | 4096 | 高质量,推理成本高 |
| Cohere Embed v3 | Cohere | 1024 | 多语言,支持压缩 |
1 | # OpenAI Embedding 示例 |
3.3 向量数据库
存储和检索向量的专用数据库。
| 数据库 | 类型 | 特点 |
|---|---|---|
| Chroma | 嵌入式 | 轻量,适合原型开发 |
| FAISS | 库(Meta) | 高性能,纯内存,适合中小规模 |
| Milvus | 分布式 | 生产级,支持亿级向量 |
| Pinecone | 云服务 | 全托管,零运维 |
| Weaviate | 独立服务 | 支持混合搜索(向量+关键词) |
| Qdrant | 独立服务 | Rust 实现,高性能 |
| pgvector | PG 扩展 | 复用 PostgreSQL 生态 |
相似度度量方法:
- 余弦相似度(Cosine Similarity):最常用,衡量方向相似性
- 欧氏距离(L2):衡量绝对距离
- 内积(Inner Product):与余弦类似,向量需归一化
3.4 检索策略
基础检索
向量检索(Dense Retrieval):将 query 向量化,在向量数据库中找最近邻。
1 | # 伪代码:基础向量检索 |
进阶检索
混合检索(Hybrid Search):结合向量检索和关键词检索(BM25),取长补短。
1 | Query ──→ 向量检索 → 结果A |
多路召回 + 重排序(Retrieve & Re-rank):
1 | Query → 多种检索策略 → 粗排候选集 → Cross-Encoder重排序 → 精排结果 |
重排序模型(如 bge-reranker、Cohere Rerank)对 query-document 对进行深度相关性打分,显著提升精度。
3.5 上下文组装与生成
将检索到的内容组装进 Prompt,交给 LLM 生成。
常见 Prompt 模板:
1 | 你是一个知识问答助手。请根据以下参考资料回答用户的问题。 |
关键点:
- 明确告知模型”基于参考资料回答”,减少幻觉
- 添加”不知道就说不知道”的指令
- 控制注入上下文的总量,避免超过模型窗口限制
四、RAG 进阶技术
4.1 Query 改写与扩展
用户原始提问往往不是最优的检索 query。
| 技术 | 说明 |
|---|---|
| Query Rewriting | 让 LLM 重写问题,使其更适合检索 |
| HyDE(Hypothetical Document Embedding) | 让 LLM 先生成假设性回答,用回答的向量去检索 |
| Multi-Query | 将一个问题拆解为多个子问题,分别检索后合并 |
| Step-back Prompting | 让模型先提出一个更宏观的问题,获取背景知识 |
1 | # HyDE 示例 |
4.2 图谱 RAG(GraphRAG)
微软提出的 GraphRAG 方法,用知识图谱增强检索。
流程:
- 从文档中抽取实体和关系,构建知识图谱
- 对图谱进行社区检测,生成不同层级的摘要
- 查询时同时利用向量检索和图谱结构进行推理
优势:擅长回答需要跨文档推理的全局性问题(如”总结所有文档的主要观点”)。
4.3 自适应 RAG(Adaptive / Self-RAG)
让模型自主判断是否需要检索:
1 | 用户问题 → LLM 判断是否需要检索 |
Self-RAG 论文引入了反思令牌(Reflection Tokens),让模型在生成过程中自评检索质量和回答可靠性。
4.4 嵌套/多跳 RAG(Multi-hop RAG)
处理需要多步推理的复杂问题:
1 | 问题:"A公司的创始人还在B公司任职吗?" |
4.5 Agentic RAG
将 RAG 作为 Agent 的工具之一,由 Agent 自主规划检索策略。
1 | 用户问题 → Agent 思考 |
工具定义示例:
1 | tools = [ |
五、评估体系
5.1 检索质量评估
| 指标 | 说明 |
|---|---|
| Precision@K | 前 K 个结果中相关的比例 |
| Recall@K | 相关文档被召回的比例 |
| MRR | 第一个相关结果的排名倒数 |
| nDCG | 考虑排序位置的增益指标 |
5.2 生成质量评估
RAGAS 框架是 RAG 评估的主流方案:
| 指标 | 评估维度 | 说明 |
|---|---|---|
| Faithfulness | 忠实度 | 回答是否与检索内容一致(不幻觉) |
| Answer Relevance | 答案相关性 | 回答是否切题 |
| Context Precision | 上下文精确率 | 检索内容中有用信息的比例 |
| Context Recall | 上下文召回率 | 回答所需信息是否都被检索到了 |
1 | # RAGAS 评估示例 |
5.3 端到端评估
最终的评估还是要回归业务场景:
- 人工评估:抽样打分,准确率、完整性、流畅度
- LLM-as-Judge:用强模型评估弱模型的输出
- A/B 测试:线上对比不同 RAG 方案的用户满意度
六、工程实践要点
6.1 数据处理
- 数据清洗:去除乱码、重复内容、格式噪声
- 元数据标注:为每个 chunk 添加来源、时间、分类等元数据,支持过滤检索
- 多格式解析:PDF、Word、HTML、Markdown、表格、图片(OCR)各有解析方案
6.2 性能优化
| 优化方向 | 方法 |
|---|---|
| 检索延迟 | 向量索引优化(HNSW、IVF)、缓存热门 query |
| 召回率 | 多路召回、query 扩展、调大 top_k |
| 精度 | 重排序、增加元数据过滤 |
| 上下文利用 | 压缩无关内容、只注入关键段落 |
| 成本 | Embedding 缓存、小模型粗排 + 大模型精排 |
6.3 常见问题与对策
| 问题 | 原因 | 对策 |
|---|---|---|
| 检索不到相关内容 | 切分太碎 / embedding 不准 | 调整 chunk 策略、换 embedding 模型 |
| 检索到了但回答不对 | 上下文太多噪声 | 减少注入量、加重排序 |
| 回答幻觉 | 模型无视上下文自行编造 | 强化 Prompt 指令、降低 temperature |
| 回答不完整 | 信息分散在多个 chunk | 多跳检索、增大 chunk_size |
| 延迟高 | 检索 + LLM 双重耗时 | 异步检索、流式输出、缓存 |
6.4 技术选型参考
原型验证(快速起步):
- Embedding: OpenAI text-embedding-3-small
- 向量库: Chroma / FAISS
- 框架: LangChain / LlamaIndex
生产部署:
- Embedding: BGE / GTE(可自部署,数据不出域)
- 向量库: Milvus / Weaviate / pgvector
- 框架: LlamaIndex(更灵活)或自建 Pipeline
- 重排序: bge-reranker-v2-m3 / Cohere Rerank
七、主流框架对比
| 框架 | 语言 | 特点 | 适用场景 |
|---|---|---|---|
| LangChain | Python/JS | 生态最全,模块丰富,上手快 | 快速原型、通用 RAG |
| LlamaIndex | Python | 专注于 RAG,数据连接器丰富 | 数据密集型应用 |
| Haystack | Python | 生产导向,Pipeline 设计清晰 | 企业级搜索问答 |
| Semantic Kernel | C#/Python/Java | 微软出品,与 Azure 生态集成 | .NET 技术栈项目 |
| DSPy | Python | 编程式 Prompt 优化,自动调参 | 学术研究、Prompt 工程 |
八、学习资源
论文
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(RAG 原始论文,Facebook AI,2020)
- Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection
- GraphRAG: Unlocking LLM Discovery on Complex Data(Microsoft,2024)
实践项目
- LangChain RAG 模板:官方提供了多种 RAG 架构的参考实现
- LlamaIndex 官方示例:覆盖从基础到进阶的各类 RAG 模式
- RAGAS:RAG 评估框架,附带完整评估示例
这篇笔记梳理了 RAG 从基础概念到进阶实践的知识体系。RAG 的本质就是”让 LLM 先查资料再回答”,看似简单,但每个环节(切分、向量化、检索、生成、评估)都有大量工程细节。建议从最简单的向量检索 RAG 起步,遇到具体问题再逐步引入进阶技术——不要一上来就搞 GraphRAG + Agent + Multi-hop,过度的复杂度往往是 RAG 项目失败的原因。