RAG 检索增强生成:让大模型拥有实时知识
大模型虽然强大,但有两个绕不开的硬伤:知识截止日期(训练数据有时效性,不知道最新信息)和幻觉问题(一本正经地编造不存在的内容)。RAG(Retrieval-Augmented Generation,检索增强生成)就是为了解决这两个问题而诞生的技术方案。
简单说,RAG 的思路是:不指望大模型什么都记住,而是在回答问题之前,先从外部知识库中检索相关资料,把这些资料塞给大模型作为参考,再让它生成回答。就像开卷考试一样,模型可以"翻书"查资料。
RAG 的整体架构
图表加载中...
整个流程分两个阶段:
离线索引阶段:提前把知识库中的文档处理好——切分成合适的片段,转化为向量,存入向量数据库。这是一次性的预处理工作。
在线查询阶段:用户提问时,先把问题转化为向量,从向量数据库中检索最相关的文档片段,然后把这些片段和用户的问题一起构造成 Prompt,交给大模型生成最终回答。
文档切分(Chunking)
文档切分是 RAG 管线中最容易被忽视、但对效果影响极大的环节。切分的好坏直接决定了检索的精度。
为什么要切分:大模型的上下文窗口有限(即使是 128K 窗口的模型,也不可能把整个知识库塞进去),向量检索也需要在较短的文本段上才能保证语义匹配的精度。
常见的切分策略:
固定长度切分:按字符数或 token 数切分,简单粗暴。缺点是可能把一个完整的段落或概念从中间切断。
按语义切分:根据段落、章节等自然边界切分,保持语义完整性。比如按 Markdown 的标题层级切分、按段落分隔切分。
重叠切分:相邻的 chunk 之间保留一定的重叠区域(通常 10%-20%),避免关键信息恰好落在切分边界上被丢失。
实践建议:chunk 大小通常在 256-1024 个 token 之间。太小会丢失上下文,太大会引入噪音降低检索精度。
向量化(Embedding)
向量化是把文本转换成高维向量的过程,目的是让语义相似的文本在向量空间中距离更近。
图表加载中...
上图中,"如何部署 Flink 集群"和"Flink 集群搭建步骤"虽然用词不同,但语义相近,所以它们的向量相似度很高(0.96)。而"Spark 的 RDD 原理"是完全不同的话题,相似度就很低(0.31)。
常用的 Embedding 模型:
| 模型 | 维度 | 特点 |
|---|---|---|
| OpenAI text-embedding-3-small | 1536 | 效果好,需要调 API |
| BGE-large-zh | 1024 | 中文效果好,可本地部署 |
| m3e-base | 768 | 轻量级,中文友好 |
| jina-embeddings-v2 | 768 | 支持 8K 长文本 |
向量检索
向量检索的核心是从数据库中找到与用户问题最相似的 Top-K 个文档片段。
相似度计算方式:
余弦相似度:最常用,计算两个向量的夹角余弦值,范围 [-1, 1],值越大越相似。
欧氏距离:计算两个向量之间的直线距离,距离越小越相似。
内积:直接计算向量点积,适用于已归一化的向量。
向量数据库通过构建索引(如 HNSW、IVF 等)来加速检索,避免暴力遍历所有向量。常见的向量数据库有 Milvus、Pinecone、Weaviate、Chroma 等。
重排序(Reranking)
向量检索的结果并不总是完美的。向量检索是用双编码器(Bi-Encoder)独立编码 query 和 document,速度快但精度有限。重排序用交叉编码器(Cross-Encoder)同时编码 query 和 document,能捕捉更细粒度的语义交互。
图表加载中...
典型做法是:先用向量检索快速召回 Top-20 候选片段,再用 Cross-Encoder 对这 20 个片段精排,取最终的 Top-3 或 Top-5 送入大模型。这样兼顾了检索速度和精度。
常用的重排序模型有 Cohere Rerank、BGE-reranker、cross-encoder/ms-marco-MiniLM 等。
Prompt 构造
检索到相关文档后,需要把它们和用户问题组装成一个 Prompt 交给大模型。一个典型的 RAG Prompt 结构如下:
你是一个专业的技术助手。请根据以下参考资料回答用户的问题。
如果参考资料中没有相关信息,请明确告知用户你不知道,不要编造答案。
参考资料:
---
[检索到的文档片段1]
---
[检索到的文档片段2]
---
[检索到的文档片段3]
用户问题:{用户的原始问题}
关键原则是:明确指示模型只根据提供的参考资料回答,减少幻觉;如果资料中没有相关信息,让模型坦诚说不知道,而不是瞎编。
RAG 的评估指标
评估 RAG 系统的效果需要从检索和生成两个维度入手:
| 维度 | 指标 | 含义 |
|---|---|---|
| 检索质量 | 召回率 Recall@K | Top-K 结果中包含正确答案的比例 |
| 检索质量 | MRR | 正确答案在结果列表中的排名倒数的均值 |
| 生成质量 | 忠实度 Faithfulness | 生成的回答是否忠于检索到的参考资料 |
| 生成质量 | 相关性 Relevance | 回答是否切实解决了用户的问题 |
常见优化手段
混合检索:将向量检索和关键词检索(BM25)结合使用。向量检索擅长语义匹配,关键词检索擅长精确匹配。两者结合能覆盖更多场景。
Query 改写:用大模型对用户的原始问题进行改写或扩展,生成多个不同表述的查询,分别检索后合并结果。这能有效提升召回率。
层级检索:先用文档摘要做粗粒度检索,确定相关文档,再在文档内部做细粒度的 chunk 检索。适合知识库规模大、文档多的场景。