Skip to content

RAG 检索增强生成

本页介绍 LLM 应用生态中最核心的落地技术——检索增强生成(Retrieval-Augmented Generation, RAG):在让 LLM 回答问题前,先从外部知识库检索相关文档,拼入 Prompt 再生成答案。它是 LLM 应用生态概览中的”记忆”层,底层依赖向量数据库。

RAG = 开卷考试。

LLM 默认是”闭卷考试”——只能靠训练时记住的知识答题,容易过时、容易编。RAG 让它变成”开卷考试”:

  1. 先翻书(检索):从知识库里找到和问题最相关的几段文字。
  2. 再答题(生成):把找到的文字连同问题一起给 LLM,让它基于这些内容作答。

好处:知识可以随时更新(改文档就行,不用重新训练);回答可以标注来源(可溯源);私有数据不出本地(安全)。

LLM 的知识来源于训练数据,存在三个根本性限制:

  • 知识截止(Knowledge Cutoff):模型训练完成后,无法获取新知识。GPT-4 的训练数据截止到某个日期,之后发生的事它不知道。
  • 参数化记忆的模糊性:LLM 把知识”压缩”进了神经网络参数(权重)中——这是一种有损压缩。常见知识记得清楚,长尾知识容易模糊或混淆,导致幻觉(Hallucination)——模型一本正经地编造看似合理但实际错误的内容。
  • 无法访问私有数据:企业内部文档、个人笔记等从未进入训练数据,LLM 对此一无所知。

RAG 的解决方案是将知识存储在外部(不放进模型参数),推理时按需检索。这把 LLM 从”知识容器”变成了”推理引擎”——它不需要”记住”知识,只需要理解检索到的上下文并据此作答。

建库阶段离线做一次(文档变了重新跑);检索生成阶段每次查询实时执行。Top-K 通常取 3-5 个片段,太多会撑满上下文窗口,太少可能漏掉答案。

分块(Chunking) 是 RAG 中影响检索质量的首要因素。切得太大会引入噪声(不相关内容稀释相关性信号),切得太小会丢失上下文(检索到的片段语义不完整)。

方法原理适用场景
固定长度分块按固定 Token 数(如 512)滑动窗口切割简单文档,快速上手
递归字符分块按分隔符优先级(段落 → 句号 → 空格)递归切分通用场景,LangChain 默认策略
语义分块用 Embedding 相邻句子的语义相似度,在语义突变处切分长文档、叙事性文本
文档结构感知分块按 Markdown 标题、HTML 标签、代码函数边界切分结构化文档(技术文档、代码)
后期分块(Late Chunking)先对整个文档做 Embedding 再分块,保留全局上下文2024 年新方法,显著提升长文档检索

后期分块(Late Chunking) 是 2024 年由 Jina AI 提出的改进方案。传统方法先分块再嵌入,每个块丢失了文档全局上下文。后期分块先用长上下文嵌入模型(如支持 8K+ Token 的模型)处理整篇文档,再在嵌入空间中切分——每个块的向量都”记得”自己来自文档的哪个位置,检索时语义匹配更精准。

实践中常用的经验值:块大小 256-1024 Token,相邻块之间保留 10%-20% 的重叠(Overlap),防止在块边界处切断关键信息(例如一个句子被切成两半)。最佳参数需要针对具体文档和评估集调优。

向量检索(Dense Retrieval) 通过 Embedding 计算语义相似度,能理解同义词和语义关联(“怎么退货” 能匹配到 “退款政策”)。但在精确匹配专有名词、产品型号、代码标识符时表现较弱。

关键词检索(Sparse Retrieval / BM25) 基于词频-逆文档频率(TF-IDF) 的改进算法——BM25 是搜索引擎(如 Elasticsearch)的标准排名函数。它擅长精确匹配稀有术语,但不懂语义。

BM25(Best Matching 25):给定一个查询,BM25 对每篇文档打分:如果文档包含查询中的词,且这些词在整个语料库中比较稀有(IDF 高)、在该文档中出现频率适中(TF),则得分高。它是传统信息检索的基石。

2024-2025 年的工业最佳实践是混合检索:同时跑向量检索和 BM25 关键词检索,然后用倒数排名融合(Reciprocal Rank Fusion, RRF) 将两路结果合并。公式简单但有效:

RRF_score(doc)=∑i1k+ranki(doc)\text{RRF\_score}(doc) = \sum_i \frac{1}{k + \text{rank}_i(doc)}

其中 ranki(doc)\text{rank}_i(doc) 是文档在第 ii 路检索中的排名,kk 通常取 60。排名越靠前贡献越大,两路都靠前的文档得分最高。

初筛(向量检索或混合检索)速度快但精度有限——它用的是双塔模型(Bi-Encoder):问题和文档分别编码为向量,通过点积计算相似度。这种方法的优点是可以预先计算文档向量并建立索引,检索速度快;缺点是问题和文档的交互不够深入。

重排序使用交叉编码器(Cross-Encoder):将问题和每个候选文档拼接在一起送入模型,模型能逐词关注问题和文档的交互关系,精度远高于双塔模型。缺点是必须对每个候选逐一计算,速度慢——因此只在 Top-K(如 20-50 个)初筛结果上做重排序。

用户的原始问题往往不是最佳检索查询。常见改写策略:

  • 查询扩展(Query Expansion):用 LLM 将问题改写为多个语义等价的变体,分别检索后合并结果。例如 “如何提高模型准确率” 扩展为 “提升 ML 模型精度技巧”、“模型调参最佳实践” 等。
  • 查询分解(Query Decomposition):将复杂问题拆解为子问题。例如 “比较 GPT-4o 和 Claude 3.5 的优缺点” 拆解为 “GPT-4o 的优点”、“GPT-4o 的缺点”、“Claude 3.5 的优点”、“Claude 3.5 的缺点” 四个子查询。
  • HyDE(假设文档嵌入):先让 LLM 生成一个假设性答案(可能完全错误),然后用这个”假答案”的向量去检索——原理是假答案的措辞往往比原始问题更接近真实文档的表述。
  • 步骤回溯(Step-Back Prompting):让 LLM 先提取问题背后的通用概念,检索通用规则后再回答具体问题。
import numpy as np
from openai import OpenAI
client = OpenAI()
# 1. 知识库(5 段文档)
docs = [
"RAG 是检索增强生成,让 LLM 先检索再回答。",
"向量数据库存储文本的嵌入向量,支持语义检索。",
"LoRA 是一种参数高效微调方法,只调少量参数。",
"Transformer 是基于自注意力的序列模型。",
"RLHF 用人类反馈强化学习来对齐 LLM 行为。",
]
# 2. 嵌入并存储
emb = client.embeddings.create(model="text-embedding-3-small", input=docs)
matrix = np.array([d.embedding for d in emb.data])
# 3. 检索 + 生成
question = "什么是 RAG?"
q_emb = client.embeddings.create(model="text-embedding-3-small", input=question).data[0].embedding
# 余弦相似度找最相关的段落
# 注意:归一化后的向量点积 = 余弦相似度
scores = matrix @ np.array(q_emb)
top_idx = np.argmax(scores)
context = docs[top_idx]
# 拼入上下文让 LLM 回答
reply = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"根据以下资料回答问题。\n资料:{context}\n问题:{question}"}],
)
print(reply.choices[0].message.content)

生产级 RAG:使用 LlamaIndex 实现混合检索 + 重排序

Section titled “生产级 RAG:使用 LlamaIndex 实现混合检索 + 重排序”
from llama_index.core import VectorStoreIndex, Settings, Document
from llama_index.core.schema import NodeWithScore
from llamaindex.retrievers.bm25 import BM25Retriever
from llama_index.core.retrievers import QueryFusionRetriever
from llama_index.postprocessor.cohere_rerank import CohereRerank
# 1. 构建索引
documents = [Document(text="...你的文档内容...")]
index = VectorStoreIndex.from_documents(documents)
# 2. 创建两个检索器:向量检索 + BM25 关键词检索
vector_retriever = index.as_retriever(similarity_top_k=20)
bm25_retriever = BM25Retriever.from_defaults(docstore=index.docstore, similarity_top_k=20)
# 3. 融合检索:RRF 合并两路结果
hybrid_retriever = QueryFusionRetriever(
retrievers=[vector_retriever, bm25_retriever],
num_queries=1, # 不做查询扩展
use_async=True,
similarity_top_k=20,
)
# 4. 重排序:用 Cohere Cross-Encoder 精排 Top-5
reranker = CohereRerank(top_n=5)
# 5. 组装 RAG Pipeline
nodes = hybrid_retriever.retrieve("如何部署 RAG 系统?")
reranked_nodes = reranker.postprocess_nodes(nodes, query_str="如何部署 RAG 系统?")
# 拼接重排序后的 Top-5 片段作为上下文
context = "\n\n".join([n.node.text for n in reranked_nodes])

Contextual Retrieval(上下文化检索)

Section titled “Contextual Retrieval(上下文化检索)”

2024 年 Anthropic 提出上下文化检索(Contextual Retrieval):在分块时,用 LLM 为每个块生成一句”这个块属于哪个文档的哪个部分”的上下文说明,拼在块前面再做嵌入。这个简单的改进将检索失败率降低了 49%(结合 BM25 + Reranker 后降低 67%)。

# 传统分块:每个块是孤立的
chunks = split_into_chunks(document)
# chunks[0] = "第三季度收入增长 15%..."(脱离文档标题,检索时不知道是哪家公司)
# Contextual Retrieval:给每个块加上下文
for chunk in chunks:
context = llm.generate(
f"以下是一份文档的一个片段。请用一句话说明它来自什么文档、什么章节。\n"
f"文档标题:{document.title}\n片段内容:{chunk.text}"
)
chunk.text = f"{context}\n\n{chunk.text}"
# chunk.text 变为:"本片段来自 Apple 2024 Q3 财报,营收分析章节。\n\n第三季度收入增长 15%..."

Naive RAG → Advanced RAG → Modular RAG

Section titled “Naive RAG → Advanced RAG → Modular RAG”

RAG 技术经历了三代演进:

模型在生成过程中自主决定是否需要检索、检索到的内容是否相关、自己生成的回答是否被检索内容支持。通过训练特殊的”反思标记(Reflection Tokens)“实现:

  • Retrieve:当前步骤是否需要检索?
  • Relevant:检索到的片段和问题相关吗?
  • Supported:生成的回答有检索内容支撑吗?

这避免了”每次都检索”的浪费,也防止了”检索到不相关内容反而误导模型”的问题。

轻量级方案:用一个评估器判断检索到的内容质量——如果检索结果可靠,直接用;如果不可靠,用网络搜索补充;如果完全不相关,抛弃检索结果,纯靠模型自身知识回答。

2025 年的趋势:把 RAG 从固定管线升级为智能体(Agent)。LLM 作为编排者自主决定:

  • 是否需要检索?(简单问题直接回答)
  • 检索哪个数据源?(知识库 vs 网络搜索 vs 数据库)
  • 检索结果够不够?(不够就换个查询再检索)
  • 是否需要多轮检索?(先查概念,再查具体参数)

Microsoft 于 2024 年开源的方案。传统 RAG 只能做局部检索(找到和问题相关的段落),但在回答”这篇文档的主要主题是什么""各概念之间有什么关联”等全局性问题时力不从心。

GraphRAG 在建库阶段额外构建一张知识图谱(Knowledge Graph):

  1. 用 LLM 从文档中抽取实体(人名、组织、概念)和关系(A 是 B 的创始人)。
  2. 用社区发现算法(Community Detection) 将图谱聚类成主题社区。
  3. 为每个社区生成摘要。

检索时,根据问题类型选择策略:具体问题走传统向量检索,全局问题走图谱社区摘要,获得”上帝视角”的理解。

没有评估就没有优化。RAG 系统需要独立评估检索和生成两个环节:

评估维度指标含义
检索质量召回率(Recall)答案所需的信息是否被检索到了?
检索质量精确率(Precision)检索到的内容有多少是相关的?
检索质量MRR(平均倒数排名)第一个相关结果的排名倒数,越接近 1 越好
生成质量忠实度(Faithfulness)回答是否基于检索到的内容,没有幻觉?
生成质量答案相关性(Answer Relevance)回答是否切题?
生成质量上下文利用率(Context Utilization)检索到的信息是否被充分利用?

RAGAS(RAG Assessment) 是最流行的 RAG 评估框架:给定问题、检索到的上下文、模型回答和(可选的)参考答案,用另一个 LLM 自动评估上述指标。无需人工标注,适合持续迭代。

  • Perplexity 搜索:AI 搜索引擎,每次查询实时检索网页 → LLM 总结 → 附引用链接,把 RAG 做成了消费者产品。2024-2025 年估值超 90 亿美元,证明了 RAG 在消费者市场的商业价值。
  • 企业知识库问答:将公司文档(Wiki、PDF、合同)建成向量库,员工用自然语言提问即可获得带出处引用的答案——Slack/钉钉里的 AI 助手大多基于此。
  • 法律 / 医疗文档辅助:律师查法条与判例、医生查诊疗指南,RAG 确保回答基于权威文献而非 LLM 的”记忆幻觉”。
  • 代码库问答:把代码仓库嵌入向量库,开发者问”这个函数在哪定义""如何使用这个 API”,RAG 直接从代码中找答案——Cursor、GitHub Copilot Chat 的底层能力。
  • 多模态 RAG:不仅检索文本,还检索图片、表格、PDF 中的图表。2025 年多模态嵌入模型(如 OpenAI text-embedding-3、Cohere Embed v3)已支持跨模态检索——用文字描述就能搜到相关图片。
  • Agentic RAG 成为主流:RAG 从”固定检索管线”进化为”LLM 自主编排检索策略”,能根据问题难度自适应选择检索路径、数据源和迭代次数。
  • 原生长上下文与 RAG 的融合:2024-2025 年 LLM 上下文窗口从 128K 扩展到 1M-2M(Gemini 2M Token),“把所有文档塞进上下文”似乎可以取代 RAG。但实践表明:大海捞针(Needle-in-a-Haystack) 问题在中段位置仍有信息丢失,且超长上下文成本高、延迟大——RAG 仍是精确知识检索的最佳方案,长上下文是补充而非替代。
  • 上下文化检索(Contextual Retrieval)普及:Anthropic 2024 年的方法——为每个文档块添加 LLM 生成的上下文摘要——正成为分块的标准步骤。
  • 结构化 RAG:Text-to-SQL、Text-to-Cypher(图数据库查询语言)与向量检索融合,LLM 根据问题类型自动选择查结构化数据还是非结构化文本。
  • 多模态 RAG 成熟:表格、图表、PDF 扫描件的检索不再是难题,专门的文档解析模型(如 ColPali)能直接对视觉化的文档做检索。
类库语言说明
LangChainPython / TSRAG 全流程编排,从文档加载到检索生成一站式
LlamaIndexPython专注 RAG 的数据框架,索引与检索策略丰富
ChromaDBPython轻量开源向量数据库,本地开发首选
PineconeSaaS托管型向量数据库,生产级规模与延迟
WeaviateGo / Python开源向量搜索引擎,内置混合检索(关键词 + 向量)
FAISSPython / C++Meta 开源的高效向量检索库,单机性能标杆
RAGASPythonRAG 评估框架,自动量化检索和生成质量
LightRAGPython轻量级 GraphRAG 实现,比 Microsoft GraphRAG 更快更省
ColBERTPython后期交互式检索模型,精度介于 Bi-Encoder 和 Cross-Encoder 之间
术语英文解释
嵌入Embedding把文本/图像转换为固定长度的数值向量,语义相近的内容向量也相近
分块Chunking将长文档切成小段落,便于检索时精准匹配
后期分块Late Chunking先对整篇文档做嵌入再分块,保留全局上下文信息
向量检索Vector Search / Dense Retrieval通过计算向量间的距离/相似度来查找语义相关内容
BM25Best Matching 25基于词频和逆文档频率的经典关键词检索排名函数
混合检索Hybrid Search同时使用向量检索和关键词检索,合并结果以兼顾语义和精确匹配
倒数排名融合Reciprocal Rank Fusion (RRF)将多路检索结果按排名倒数加权融合的方法
Top-KTop-K检索时返回相似度最高的 K 个结果,通常 K = 3-5
重排序Reranking用更精细的 Cross-Encoder 模型对 Top-K 初筛结果重新打分排序
双塔模型Bi-Encoder问题和文档分别独立编码为向量再计算相似度,速度快适合初筛
交叉编码器Cross-Encoder问题和文档拼接后联合编码,精度高但速度慢,适合重排序
幻觉HallucinationLLM 编造看似合理但实际不正确的内容,RAG 的主要缓解对象
HyDEHypothetical Document Embedding先让 LLM 生成假设性答案再用其向量检索,提升召回
上下文检索Contextual Retrieval为每个文档块添加 LLM 生成的上下文说明,提升检索精度
GraphRAGGraph RAG结合知识图谱的 RAG 变体,捕捉实体间的结构化关系
Agentic RAGAgentic RAGLLM 作为智能体自主编排检索策略的 RAG 范式
Self-RAGSelf-RAG模型自主判断是否需要检索、检索质量、回答忠实度的 RAG 方案
RAGASRAG Assessment用 LLM 自动评估 RAG 系统检索和生成质量的框架
  • RAG 原始论文:Lewis et al., “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”(2020),Facebook AI 提出 RAG 框架,将检索器与生成器联合训练——RAG 的开山之作。
  • HyDE:Gao et al., “Precise Zero-Shot Dense Retrieval without Relevance Labels”(2022),用 LLM 生成假设答案提升检索质量。
  • GraphRAG:Edge et al., “From Local to Global: A Graph RAG Approach to Query-Focused Summarization”(Microsoft Research, 2024),将知识图谱引入 RAG,解决全局性问题的检索缺陷。
  • Self-RAG:Asai et al., “Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection”(2023),模型自主决定检索时机的方案。
  • CRAG:Yan et al., “Corrective Retrieval Augmented Generation”(2024),检索质量评估与纠正机制。
  • Contextual Retrieval:Anthropic, “Introducing Contextual Retrieval”(2024),用 LLM 为文档块添加上下文,将检索失败率降低 49%。
  • RAG 综述:Gao et al., “Retrieval-Augmented Generation for Large Language Models: A Survey”(2023),系统梳理 Naive/Advanced/Modular RAG 三代技术演进。