01.1 - 什么是 RAG?
定位: 整个 RAG 知识库的起点——理解 RAG 的本质:它是什么、为什么需要、如何工作 面试高频度: ⭐⭐⭐⭐⭐ 考查方式: 概念理解、场景分析、RAG vs 其他方案对比
一、这是什么?为什么需要它?
是什么
RAG (Retrieval-Augmented Generation) 是一种将 信息检索 与 大语言模型生成 相结合的架构范式。它的核心思想是:
模型在生成回答之前,先从外部知识库中检索相关文档,然后基于检索到的内容生成答案。
传统 LLM 生成:
用户输入 → LLM → 基于训练固化知识生成 → 输出
RAG 生成:
用户输入 → 检索外部知识库 → 注入检索结果作为上下文 → LLM 基于上下文生成 → 输出为什么需要 RAG?
要理解 RAG 的价值,先理解大语言模型(LLM)的本质缺陷:
| 缺陷 | 表现 | 根本原因 |
|---|---|---|
| 知识截止 | 模型不知道训练之后发生的事件 | 模型训练是一次性的,知识固化在权重中 |
| 幻觉 | 模型编造看似合理但错误的事实 | 模型本质是"下一个词预测",没有事实校验机制 |
| 无法访问私有知识 | 模型不知道企业内部数据 | 训练数据是公开的 |
| 知识更新成本高 | 更新知识需要重新训练 | 改变模型行为需要 Fine-tuning |
| 无来源引用 | 输出缺乏可验证性 | 知识内化在参数中,不可追溯来源 |
RAG 的解法是"不改变模型,而是改变模型能看到什么"——将推理与知识存储解耦:
模型负责:推理、理解、生成(模型能力)
知识库负责:存储、检索、提供事实(知识能力)这种解耦带来了四个关键收益:
| 收益 | 解释 | 实际效果 |
|---|---|---|
| 知识实时更新 | 修改知识库即可,不涉及模型训练 | 分钟级更新,零训练成本 |
| 事实可追溯 | 每个回答都关联来源文档 | 用户可验证,信任度提升 |
| 幻觉显著降低 | 模型基于事实性上下文生成 | 减少 30-70% 的事实错误 |
| 领域适配灵活 | 换知识库即换领域 | 一个模型服务多种场景 |
二、原理拆解
2.1 RAG 的三段式架构
RAG 的核心流程分为三个阶段,形成一条完整的 Pipeline:
┌─────────────────────────────────────────────────────────────┐
│ RAG 三段式 Pipeline │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 检索 │ │ 增强 │ │ 生成 │ │
│ │ Retrieve │───→│ Augment │───→│ Generate │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ ┌───┴───┐ ┌────┴───┐ ┌───┴────┐ │
│ │用户查询│ │知识库中│ │生成模型│ │
│ │向量化 │ │相关片段│ │组装回答│ │
│ │×向量检索│ │拼接 │ │+来源引用│ │
│ └───────┘ └────────┘ └────────┘ │
└─────────────────────────────────────────────────────────────┘阶段 1:检索 (Retrieve)
将用户查询转化为检索请求,从知识库中找到最相关的文档片段。
查询 → (可选:查询转换/扩展) → 向量化 → ANN 搜索 → 返回 Top-K 相关块- 输入:用户自然语言查询
- 输出:K 个最相关的文档块(chunks)
- 关键变量:K 值、检索策略(向量/关键词/混合)
阶段 2:增强 (Augment)
将检索到的文档块与用户查询组合成增强的 Prompt。
系统:你是基于以下文档回答问题的助手。如果你不知道答案,请告知用户。
文档1:[检索到的第一个文档块]
文档2:[检索到的第二个文档块]
...
文档K:[检索到的第K个文档块]
---
用户问题:[原始查询]
请基于上述文档回答问题:- 输入:检索结果 + 用户查询
- 输出:增强后的 Prompt
- 关键变量:Prompt 模板设计、上下文窗口管理
阶段 3:生成 (Generate)
增强后的 Prompt 送入 LLM,生成最终回答。
增强 Prompt → LLM 推理 → 基于上下文的回答 + 来源引用- 输入:增强 Prompt
- 输出:最终回答
- 关键变量:模型能力、温度等生成参数
2.2 RAG 的索引阶段(离线)
在检索之前的离线阶段同样关键——知识库的构建质量直接影响检索质量:
原始文档 → 文档加载 → 文本分块 → Embedding → 向量存储
(加载器) (策略) (模型) (数据库)| 步骤 | 作用 | 常见工具 |
|---|---|---|
| 文档加载 | 从各种来源读取文档 | LangChain Loaders, Unstructured |
| 文本分块 | 将长文档切成可检索的块 | RecursiveCharacterTextSplitter |
| Embedding | 将文本转为向量 | OpenAI Embedding, BGE, E5 |
| 向量存储 | 存储向量并建索引 | FAISS, Chroma, Pinecone |
2.3 RAG 的三代演进
RAG 不是静止的技术,它经历了三代演进:
┌──────────────────────────────────────────────────────────┐
│ RAG 三代架构演进 │
│ │
│ Naive RAG (v1) │
│ ┌──────┐ ┌──────────┐ ┌──────┐ │
│ │Query │──→│ Vector DB │──→│ Gen │ │
│ └──────┘ └──────────┘ └──────┘ │
│ 单次检索 + 直接生成 │
│ │
│ Advanced RAG (v2) │
│ ┌──────┐ ┌──────────┐ ┌──────────┐ ┌──────┐ │
│ │Query │──→│ Pre- │──→│ Retrieve │──→│ Gen │ │
│ └──────┘ │ Retrieval│ └──────────┘ └──────┘ │
│ │(HyDE/ │ │ │
│ │ MultiQ) │ ┌──────────┐ │
│ └──────────┘ │ Post- │ │
│ │ Retrieval│ │
│ │(Rerank) │ │
│ └──────────┘ │
│ 检索前后增加优化环节 │
│ │
│ Modular RAG (v3) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Agent │──→│ Router │──→│ 融合模块 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ ┌───┴───┐ ┌────┴────┐ ┌────┴────┐ │
│ │工具调用│ │多路检索 │ │多轮对话 │ │
│ │路由决定│ │图检索 │ │记忆管理 │ │
│ └───────┘ └─────────┘ └─────────┘ │
│ 模块化组合 + 灵活编排 │
└──────────────────────────────────────────────────────────┘| 代际 | 特点 | 代表技术 | 适用场景 |
|---|---|---|---|
| Naive RAG | 检索→生成,简单直接 | Vector DB + LLM | 简单问答 |
| Advanced RAG | 检索前后增加优化 | HyDE、Reranker、Hybrid Search | 生产级应用 |
| Modular RAG | 组件化、可编排 | Agent、Router、多模块组合 | 复杂场景 |
三、图解全景
RAG 的完整生命周期
┌─────────────┐
│ 原始文档 │
│ PDF/Web/DB │
└──────┬──────┘
│ 加载
▼
┌─────────────────────┐
│ 文本分块 (Chunk) │
│ 每个块 256-1024 tokens│
└──────────┬──────────┘
│ Embedding
▼
┌─────────────────────────────────┐
│ 向量数据库 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Chunk1│ │Chunk2│ │Chunk3│ ... │
│ │Vec 1 │ │Vec 2 │ │Vec 3 │ │
│ └─────┘ └─────┘ └─────┘ │
└────────────────┬────────────────┘
│ 检索
┌────────────────┴────────────────┐
│ 用户查询 │
│ "公司的年假政策是什么?" │
└────────────────┬────────────────┘
│ 查询向量化
▼
┌─────────────────────────────────┐
│ ANN 搜索 (Top-K 最相似) │
│ 返回 3-5 个相关文档块 │
└────────────────┬────────────────┘
│ 增强
▼
┌─────────────────────────────────┐
│ Prompt 组装 │
│ 系统指令 + 检索结果 + 用户问题 │
└────────────────┬────────────────┘
│ 生成
▼
┌─────────────────────────────────┐
│ LLM 生成回答 │
│ "根据公司制度第3章第2条,年假..."│
│ [引用:员工手册.pdf 第5页] │
└─────────────────────────────────┘图中关键权衡标注:
- ← Chunk 大小权衡:大块→信息完整但噪声多;小块→精准但上下文可能不足
- ← K 值权衡:K 太少→可能遗漏信息;K 太多→超出上下文窗口或引入噪声
- ← 模型选择权衡:强模型→高质量但慢/贵;小模型→快/便宜但能力有限
四、实战验证
4.1 最简单的 RAG Demo(Python + LangChain)
python
# 安装:pip install langchain langchain-community chromadb
# 需要设置 OPENAI_API_KEY 或替换为本地 Embedding 模型
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.chains import RetrievalQA
# 1. 加载文档
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
# 2. 文本分块
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100
)
chunks = text_splitter.split_documents(documents)
# 3. 向量化并存储
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=OpenAIEmbeddings()
)
# 4. 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 5. 创建 RAG Chain
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o-mini"),
retriever=retriever,
return_source_documents=True
)
# 6. 执行查询
response = qa_chain.invoke({"query": "什么是公司的年假政策?"})
print(f"回答:{response['result']}")
print(f"来源:{response['source_documents']}")4.2 命令行验证 RAG 效果
bash
# 使用 Ollama 本地运行 RAG(需要安装 Ollama + 下载模型)
# 安装:ollama pull nomic-embed-text # Embedding 模型
# 安装:ollama pull llama3.2 # 生成模型
# 使用 LangChain CLI 快速体验
pip install "langchain-cli[all]"
langchain app new rag-demo --package rag-chroma
cd rag-demo
# 编辑 chains.py 配置本地模型
langchain serve4.3 关键实验:有 RAG vs 无 RAG 对比
python
# 对比实验:同一问题在有/无 RAG 下的表现
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
# 无 RAG:直接问
without_rag = llm.invoke("2025年诺贝尔物理学奖得主是谁?")
# 可能回复:"我的知识截止于...,无法回答最新信息"
# 有 RAG:先检索知识库再问
# (假设知识库已包含 2025 年诺贝尔奖信息)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever # 上面创建的检索器
)
with_rag = qa_chain.invoke({"query": "2025年诺贝尔物理学奖得主是谁?"})
# 回复:基于知识库中的信息准确回答 + 来源引用五、面试视角
| 问题 | 答案要点 |
|---|---|
| 什么是 RAG?用一句话概括 | RAG 是一种在生成回答前先从外部知识库检索相关文档来增强上下文的技术范式,解决 LLM 知识固化、幻觉和私有数据访问问题 |
| RAG 解决了 LLM 的哪些核心缺陷? | 1) 知识截止:无需重训练即可更新;2) 幻觉:提供事实上下文减少编造;3) 私有数据:可接入企业内部知识;4) 可追溯性:回答可引用来源 |
| RAG 的三阶段是什么?各阶段的关键变量? | Retrieve(K值、检索策略)→ Augment(Prompt模板、上下文管理)→ Generate(模型选择、生成参数) |
| Naive RAG vs Advanced RAG 的核心区别? | Naive 是直通式检索+生成;Advanced 在检索前后增加了 Pre-Retrieval(查询优化/HyDE)和 Post-Retrieval(Reranking/Hybrid Search)环节 |
| RAG 的局限性有哪些? | 1) 检索质量决定天花板;2) 端到端延迟增加(检索+生成);3) 上下文窗口限制;4) 对长尾/复杂查询效果下降;5) 知识库维护成本 |
| RAG 适合什么场景?不适合什么场景? | 适合:FAQ/客服、知识库问答、文档分析、报告生成。不适合:开放域创意写作(不依赖外部知识)、实时对话(延迟敏感)、数学推理(需模型内在能力) |
| RAG 和 Fine-tuning 是什么关系? | 互补关系。RAG 负责知识注入(改知识库即可),Fine-tuning 负责行为/风格适配(需训练)。两者可组合:RAG + Fine-tuning = 强知识 + 好风格 |
| RAG 幻觉是如何产生的? | 1) 检索到不相关文档→模型被误导;2) 模型过度依赖自身知识忽略上下文;3) 检索结果冲突→模型自行"调和"产生错误 |
📚 相关链接
- **RAG系统架构总览** — 深入理解 RAG 的三代架构演进
- **RAGvs微调-技术选型对比** — RAG 与 Fine-tuning 的详细对比
- **检索系统索引** — 检索系统的完整链路
- **生成融合索引** — 生成端的设计策略
- <- 返回 **RAG基础索引**