为什么需要 RAG?

大语言模型很聪明,但它有个硬伤:它的知识停在了训练的那一天。

GPT-4 的知识截止于 2023 年底,问它"昨天发生了什么",它只能编。更致命的是,它不知道你的私人文档、你的数据库、你的公司内部 wiki。你让它回答"我们公司的报销流程是什么",它会一本正经地胡说八道——这就是幻觉(Hallucination)

核心矛盾:LLM 的知识是静态的、通用的,但用户的问题往往是动态的、私有的。要么让模型重新训练(贵得要死),要么给模型现场查资料——后者就是 RAG 的思路。

2020 年,Lewis 等人发表了 Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,正式提出了 RAG 框架。思路简单到令人发指:别让模型硬背答案,让它先翻书。

你问模型一个问题,模型不直接回答。它先去知识库里检索相关文档,把检索到的内容拼到提示词里,然后基于这些上下文来生成回答。相当于从"闭卷考试"变成了开卷考试

RAG 的核心流程

一个标准的 RAG 系统分两大部分:索引(Indexing)检索生成(Retrieval + Generation)。索引是离线提前做好的,检索生成是用户提问时实时发生的。

索引阶段:先把书拆好、编好号

想象你要建一个图书馆。你不能把整本书直接扔进去——得拆成章节、编上索引、贴上标签。RAG 的索引阶段做的是同样的事:

1. 加载(Load):把原始文档读进来。可能是一堆 PDF、一个网页、一个数据库导出。源文件什么样不重要,重要的是变成统一的 Document 对象。

2. 分割(Split):把大文档切成小片段。为什么?因为 LLM 的上下文窗口有限,而且一整本书的向量表示太粗糙,没法精确匹配你的问题。常见的做法是按段落或固定字符数切分,chunk 之间留一点重叠防止信息断裂。

3. 嵌入(Embed):每个小片段过一个 Embedding 模型,变成一个向量(一串浮点数)。这个向量的神奇之处在于:语义相近的文本,它们的向量在空间里也靠得近。"苹果很好吃"和"苹果营养丰富"的向量距离就比"苹果很好吃"和"汽车保养指南"近得多。

4. 存储(Store):把向量和原始文本一起存进向量数据库(VectorStore),比如 Chroma、FAISS、Pinecone、Qdrant。数据库专门为向量相似度搜索做了优化,能在海量向量里毫秒级找到最相似的 Top-K 个。

原始文档 → 分割成块 → 向量化 → 存入向量库
                              ↑
                         Embedding 模型

这四步做好之后,你的"图书馆"就建成了。接下来用户来问问题的时候:

检索生成阶段:翻书 + 答题

1. 检索(Retrieve):用户的提问同样经过 Embedding 模型变成向量,然后去向量库里做相似度搜索(通常是余弦相似度或内积),找出最相关的 K 个文档片段。

2. 增强(Augment):把这 K 个片段和用户的问题拼成一个 Prompt。结构大概是:

请基于以下上下文回答问题:

上下文 1:...
上下文 2:...
上下文 3:...

问题:...
回答:

3. 生成(Generate):把拼好的 Prompt 送给 LLM,让它生成最终回答。因为上下文里已经包含了相关知识,模型不需要"回忆"——它只需要"理解 + 组织语言"。

关键洞察:RAG 把"模型知道什么"和"模型能查到什么"分开了。模型不需要记住你的私有数据,它只需要会用检索工具。这意味着你换数据不用重新训练模型,换模型也不用重新索引数据——解耦带来自由。

索引阶段的工程细节

索引听起来简单,但魔鬼全在细节里。每个选择都会影响最终效果。

Chunk 大小:切太碎 vs 切太大

Chunk 大小是 RAG 里最经典的调参游戏。切太小(比如 100 字符),一个完整的意思被切碎了,检索到的片段缺上下文。切太大(比如 2000 字符),向量表示的语义不够聚焦,检索精度下降。

常见的做法是 500-1000 字符,加上 10-20% 的重叠。但这取决于你的文档类型:代码适合小 chunk,长篇叙事适合大 chunk。最佳实践通常是先测再定

更高级的做法是父子切分(Parent-Child Chunking):检索时用小 chunk 提高精度,生成时用对应的父 chunk(更大的上下文块)提供完整信息。既保证了命中率,又保证了回答质量。

Embedding 模型怎么选?

Embedding 模型是 RAG 的翻译官——它决定了"相似"是什么含义。不同模型对语义的理解不一样:

模型 维度 特点
text-embedding-3-large 3072 OpenAI 旗舰,英文强,可降维
bge-m3 1024 BAAI 出品,多语言强,支持稠密+稀疏
gte-Qwen2 1536 阿里出品,中文优秀
voyage-3 1024 综合能力强,检索任务持久霸榜
jina-embeddings-v3 1024 支持多任务专用向量

中文场景建议优先测试 bge-m3 或 gte-Qwen2。但最终选择还是以你的数据在评测集上的表现说了算。

向量数据库怎么选?

小项目用 FAISS(本地、快、够用),中等项目用 Chroma(简单、Python 原生),大规模生产用 Pinecone / Qdrant / Milvus。如果你已经在用 PostgreSQL,pgvector 是最省事的——不用额外维护一个数据库。

选型的关键维度:数据量级、是否需要分布式、运维成本、预算。对于大多数个人项目和中型团队,Chroma 或 PGVector 是安全的起手式。

检索:让搜索更聪明

单纯的向量相似度搜索看起来很美,但实际场景里经常翻车。原因很简单:用户的提问和知识库文档的措辞往往不一样。

你问"糖尿病人能吃什么",知识库里的文档标题是"糖尿病饮食指南",向量相似度可能匹配不上。于是各种进阶检索策略登场了:

混合检索(Hybrid Search)

向量检索擅长语义匹配,但有时关键词匹配才是王道。"Python 不是蛇"——向量可能觉得 Python(编程语言)和 Python(蟒蛇)挺像,但关键词检索一眼就知道不是一回事。

混合检索的做法是把向量相似度关键词匹配(BM25)的得分加权融合。BM25 是传统信息检索的经典算法,它计算的是词频和逆文档频率——简单说,如果一个词在你的文档里出现频率比在其他文档里高得多,那这个词对这篇文章很重要。

混合检索的公式大致是:

$$\text{score} = \alpha \cdot \text{sim}\_{\text{vector}} + (1-\alpha) \cdot \text{score}\_{\text{BM25}}$$

$\alpha$ 是超参数,你可以在验证集上调。$\alpha=0.7$ 表示七分靠语义、三分靠关键词。实际项目中混合检索通常比纯向量检索高出 5-15% 的 Recall。

查询重写(Query Rewriting)

用户的原始问题往往不是最佳的检索查询词。查询重写的思路是:先让 LLM 把用户的问题改写成更适合检索的形式,然后再用改写后的查询去搜。

比如用户问"它跟 RNN 比怎么样?",改写后变成"Transformer 架构与 RNN 架构的对比分析"——这显然更容易命中知识库里相关的内容。

Query Expansion 是另一种思路:不重写,而是扩展。把一个问题变成多个相关的查询,分别检索后合并结果。比如"Transformer 的缺点"可以扩展为"Transformer 局限性"+"Transformer vs CNN"+"Transformer 计算复杂度"。多路检索通常能提高召回率,但也可能引入噪音。

重排序(Re-ranking)

向量检索的第一轮可能返回了 20 个结果,但真正相关的只有前 3 个,而且这 3 个可能不在最前面。重排序就是再加一个更精确的模型,对初筛结果重新打分。

常用的重排序模型是 cross-encoder——它不像向量检索那样把问题和文档分别编码再比距离,而是把"问题 + 文档"拼接在一起,用同一个 Transformer 判断相关性。精度更高,但速度慢(因为每对都要过一遍模型)。所以典型流程是:向量检索粗筛 Top-50 → 重排序精选 Top-5。

著名的 Reranker 包括 Cohere Rerank、BAAI Reranker 系列。在中文场景下,BAAI 的 bge-reranker-v2-m3 是个不错的起点。

HYDE(假设性文档嵌入)

HYDE 的思路很巧妙:用户提问之后,先让 LLM 根据问题凭空生成一个"假设的完美答案",然后用这个假设答案去检索。原理是:一个问题跟知识库文档可能不在同一个语义空间,但一个答案跟知识库文档却在。

举个栗子:用户问"法国首都是哪?",先用 LLM 生成一段关于巴黎的文字,再拿这段文字去检索。这比直接用问题检索往往能命中更多相关内容。HYDE 的效果取决于 LLM 生成答案的质量——如果 LLM 胡编,你就把检索带偏了。

生成:别让检索白干了

检索做得再好,如果生成阶段没用好检索结果,那也是白费力气。以下是生成阶段的几个关键点:

Prompt 设计

最基础的 RAG Prompt 是"基于以下上下文回答问题"。但实际场景里你需要考虑更多:

  • 上下文不可用时怎么办? 告诉模型"如果检索内容与问题无关,就说不知道",而不是硬编答案。
  • 多个上下文冲突时怎么办? 明确优先级规则,比如"较新的文档优先级较高"。
  • 需要引用来源吗? 在 Prompt 里要求模型回答时标记来源编号,方便用户核实。

上下文窗口管理

你检索了 Top-10 个片段,但模型上下文窗口只有 8K tokens,放不下。怎么办?

  • 滑动窗口:只保留相关性得分最高的几个片段。
  • MMR(最大边际相关性):在相关性和多样性之间平衡,避免 10 个结果说的都是同一件事。
  • 压缩:用 LLM 或专门的压缩模型对检索结果做摘要,只保留关键信息。

引用溯源

RAG 的一大优势是可解释性。如果回答里能标注"以上信息来自文档第 3 章第 2 节",用户信任度会大幅提升。实现方式是在检索时保留 chunk 的元数据(来源文档、页码、章节标题),生成时让模型在对应句尾标注引用。

一个常见的坑:模型有时会忽略检索到的上下文,凭自己的知识回答问题。这被称为"上下文忽视"。解决方法是在 Prompt 里加强约束,或者用更小的、更"听话"的模型做生成。

进阶 RAG 架构

基础的"检索→阅读"流程只是 RAG 的入门版。工业界的 RAG 系统通常远不止这些:

Agentic RAG

把检索工具化,让 AI Agent 自己决定什么时候检索、怎么检索。Agent 可以:先检索引言了解背景 → 发现需要更多细节 → 再检索引言中的具体概念 → 不够?换个查询词再搜。

这种多轮检索的灵活性远高于单次检索。代价是延迟更高、Token 消耗更大。但用户提问越复杂,Agentic RAG 的优势就越明显。

GraphRAG

微软开源的 GraphRAG 把知识图谱融入 RAG。它先从文档中提取实体和关系,构建知识图谱。检索时不只是找相似的文本片段,还能沿着图结构发现实体之间的隐式关联。

比如你问"A 公司和 B 公司有什么关系",纯文本检索可能找不到直接答案。但如果在知识图谱里,A 是 C 的子公司,B 和 C 有合作——GraphRAG 就能推理出"A 和 B 有间接合作关系"。特别适合需要跨文档推理的场景。

RAPTOR

RAPTOR 的核心思路是层次化索引:文档切成小块后,不是平铺直叙地存起来,而是递归地聚类、摘要、再聚类、再摘要,构建一棵"文档树"。

检索时,先在大范围粗搜,再到具体节点细搜。比如用户问"Transformer 的总体架构是什么?",RAPTOR 可以直接返回顶层的摘要节点;问"位置编码的公式是什么?",它定位到最底层的具体片段。层级结构天然适配不同粒度的查询。

多模态 RAG

现代 RAG 不只是搜文字了。你可以搜图片、搜表格、搜视频片段。多模态 Embedding 模型(如 CLIP)把不同模态的数据映射到同一个向量空间——文字搜图、图文联合检索成为可能。

比如你问"2023 年公司的营收趋势",系统可以同时检索到相关文字描述和对应的趋势图表。这对于企业知识库、产品手册、医学影像等场景意义重大。

不同 RAG 架构的取舍:

方案 优势 劣势 适用场景
Naive RAG 简单、易实现 一次检索,不够灵活 简单 QA,文档量小
Agentic RAG 灵活,多轮推理 高延迟,高成本 复杂查询,研究分析
GraphRAG 关联推理,洞察深刻 构建成本高 多实体关联分析
RAPTOR 多层次,粗细粒度兼顾 索引复杂 大型文档库

RAG vs 微调:不是二选一

很多人把 RAG 和微调(Fine-tuning)对立起来,好像两者只能选一个。实际上它们解决的是不同的问题:

RAG 解决的是"模型不知道这些信息":模型训练完了,但你的数据是新的、私有的、动态更新的。RAG 让模型能在推理时"现场查资料"。

微调解决的是"模型做不好这件事":模型的格式、风格、行为模式不对。比如你想让模型用特定语气写合同、按照固定格式输出 JSON、做特定领域的分类任务。

一个很好的经验法则是:先 RAG,再微调。 RAG 成本低、见效快、容易迭代。RAG 解决了就用 RAG,RAG 解决不了的(比如输出格式、任务能力)才考虑微调。两者也可以组合:用 RAG 提供事实知识,用微调优化输出质量。

直觉判断:如果问题属于"查资料就能回答",用 RAG。如果问题属于"需要改变模型的做事方式",用微调。如果两者兼有,两个都要。

面试常考:几个关键判断

Q: RAG 和传统搜索引擎有什么区别?
搜索引擎返回的是文档链接,用户自己判断哪个相关。RAG 把检索结果作为上下文送给 LLM,由 LLM 综合理解后生成一段回答——相当于搜索引擎+阅读理解二合一。RAG 的答案更直接,但也更容易产生幻觉。

Q: Embedding 模型越大越好吗?
不一定。大模型维度更高、精度更好,但检索速度更慢、存储成本更高。找到适合你数据分布的模型比一味追求大模型更重要。很多场景下 768 维的模型已经够用。

Q: RAG 的检索准确率怎么评估?
常用指标包括 Hit Rate(相关文档是否在 Top-K 里)、MRR(第一个正确答案的排名)、NDCG(排名顺序加权)。最终还是要看端到端的回答质量——检索准但回答差,说明问题是生成环节。

Q: RAG 能完全消除幻觉吗?
不能。RAG 降低了幻觉的概率,但不能保证消除。模型仍然可能忽略检索结果、错误理解上下文、或过度推断。RAG 是减少幻觉的有效手段,但不是银弹。

Q: 中文 RAG 有什么特别要注意的?
中文的分词比英文复杂,chunk 策略需要调整(按句子而不是按 token)。中文 Embedding 模型的选择也比英文少,需要专门测试。此外,中文文档的格式多样化(PDF 扫描件、政府公文、表格等)对解析能力要求更高。

一句话总结:
RAG 用检索为 LLM 提供实时、私有的外部知识,用生成综合理解并组织答案,将模型的推理能力与知识库的广度深度相结合——开卷考试,永远比闭卷聪明。

彩蛋

RAG 这个概念最早可以追溯到 2020 年的论文《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》,但它在 2023-2024 年才真正火起来。原因很现实:模型越来越强,幻觉问题也越来越明显。

早期的 RAG 实现非常"直男":检索一条,拼一条,问一次。现在的 RAG 已经发展出查询改写、多轮检索、重排序、自省修正等一整套工业级技巧。有人说 RAG 是"给大模型开了个外挂",但更准确的说法是:RAG 让大模型学会了"在回答之前先查一下"这件事。

有意思的是,你现在看到这篇知识库文章本身就被 ChefRAG——也就是你在这个网站上正在构建的 RAG 系统——索引着。写文章教 RAG,而文章本身又被 RAG 用着。这大概就是程序员式的自指幽默。

← 返回知识库 返回主页