大语言模型(LLM)能流畅地写文章、回答问题、编写代码,但它有一个根本性的局限:它的知识被冻结在训练数据截止的那一刻。问它昨天发生了什么新闻?不知道。问它你公司内部的技术文档?更不知道。

更棘手的是,LLM有时候会"一本正经地胡说八道"——这就是所谓的**幻觉(Hallucination)**问题。模型会自信满满地编造一个不存在的论文引用、一个错误的API参数、甚至一个虚构的历史事件。

**RAG(Retrieval-Augmented Generation,检索增强生成)**正是为解决这些问题而生。它的核心思想简单而有效:在让LLM回答之前,先从外部知识库中检索相关信息,把这些信息塞到提示词(Prompt)里,让LLM基于真实资料来回答。

一、RAG的核心思想

1.1 一个直觉的类比

想象你是一个闭卷考试的学生(这就是纯LLM)——只能靠记忆作答,记不清的地方就只能猜。

现在允许你带一本参考书(这就是RAG)——遇到不确定的问题,先翻书找到相关段落,然后基于书中的内容来组织答案。

显然,开卷考试的准确率会高得多。

1.2 RAG的核心价值

LLM的局限RAG的解决方案
知识过期,无法获取训练截止后的信息随时更新知识库,实时生效
幻觉问题,生成不存在的信息基于真实文档生成,可追溯来源
垂直领域知识不足接入专业知识库,提供领域专业回答
更新成本高,Fine-tuning代价大只需更新知识库,成本低且灵活

1.3 RAG的基本流程

graph LR
    Q["用户提问"] --> R["检索器
Retriever"] KB["知识库"] --> R R --> C["相关文档片段"] C --> P["构造Prompt
问题 + 相关文档"] P --> LLM["大语言模型"] LLM --> A["生成回答"]

三个核心步骤:

  1. 检索(Retrieve):根据用户的问题,从知识库中找到最相关的文档片段
  2. 增强(Augment):将检索到的信息与原始问题一起构造成Prompt
  3. 生成(Generate):LLM基于增强后的Prompt生成回答

二、从关键词到语义:检索方式的演进

2.1 传统关键词搜索的局限

最简单的检索方式是关键词匹配。比如用户问"如何购买商品?",搜索引擎会提取关键词"购买"、“商品”,然后去匹配包含这些词的文档。

问题很明显:

  • 文档中写的是"下单流程说明"——语义完全一致,但没有任何关键词重合
  • 无法理解同义词:“购买"vs"下单"vs"采购"vs"买”
  • 必须精确匹配关键词,用词不同就检索不到

我们需要一种理解语义的检索方式。

2.2 文本嵌入(Text Embedding)

文本嵌入模型(如OpenAI的text-embedding-3-small、BGE等)将文本转换为高维向量(通常512/768/1024/1536维),使得语义相近的文本在向量空间中距离相近:

"如何购买商品?"      → [0.23, -0.15, 0.82, ...]  (768维向量)
"下单流程说明"        → [0.21, -0.12, 0.79, ...]  ← 向量很近,语义匹配!
"今天天气真好"        → [-0.65, 0.43, -0.21, ...] ← 向量很远

在高维向量空间中,每个维度代表不同的语义特征(如情感倾向、主题领域、动作类型等)。语义相似的文本会在空间中聚集在一起——“购买”、“下单”、“采购"形成一个语义簇,而"天气预报"则远离这个簇。

与Transformer中Embedding的对比

Transformer架构中也有Embedding层,两者的目的和特性有显著区别:

维度Transformer词嵌入RAG文本嵌入
嵌入粒度Token级别:每个token一个向量文本级别:整段文本压缩成一个向量
核心目的作为模型的输入表示,供后续Attention层处理直接用于语义检索,衡量文本间的相似度
训练目标预测下一个token(自监督),嵌入在训练中自然学到专门为语义相似度优化(对比学习),使相似文本距离近
输出维度较大(如GPT-3为12288维),因为要承载丰富的语义信息供后续层使用较小(如text-embedding-3-small为1536维),因为要高效存储和检索
位置信息需要叠加位置编码,模型需要知道token的顺序不需要位置编码,最终输出是位置无关的整体语义表示
使用方式中间表示,输入到Attention和FFN层做进一步计算最终产物,直接用于向量相似度计算

直觉理解:

Transformer Embedding:            RAG Embedding:
"如何购买商品"                     "如何购买商品"
↓ Token化                         ↓ 整句编码
["如何", "购买", "商品"]           整个句子一个向量
↓ 每个Token一个向量                [0.23, -0.45, ..., 0.12]
[v1, v2, v3]                      (直接用于检索匹配)
↓ 送入Attention层继续处理

Transformer的Embedding是模型内部的"起点”,token级别的向量还要经过几十层注意力和前馈网络才发挥作用;而RAG的文本嵌入是一个独立的"终点",整段文本被压缩成一个向量,直接用来做检索匹配。

实际上,许多文本嵌入模型(如BGE、E5)本身就是基于Transformer架构构建的——它们使用Transformer的Encoder来处理输入文本,然后对最后一层所有token的输出做池化(如取[CLS]向量或平均池化),得到一个代表整段文本的单一向量。

2.3 向量相似度度量

有了向量表示后,如何量化两个向量之间的"距离"?主流有两种方式:

余弦相似度(Cosine Similarity)

$$\text{cos\_sim}(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{||\mathbf{a}|| \cdot ||\mathbf{b}||}$$
  • 计算两个向量的夹角
  • 值域为 $[-1, 1]$,越接近1表示越相似
  • 只关注方向,不考虑向量长度——适合文本检索,因为我们关心的是语义方向而非文本长度

欧氏距离(Euclidean Distance)

$$d(\mathbf{a}, \mathbf{b}) = \sqrt{\sum_{i}(a_i - b_i)^2}$$
  • 计算两个向量在空间中的直线距离
  • 值域为 $[0, +\infty)$,距离越小越相似(注意方向与余弦相似度相反)
  • 同时考虑方向和长度

实践中,余弦相似度更常用于文本检索,因为它更关注语义方向而非文本长度差异。一篇很长的文档和一个简短的问题,只要语义方向一致,余弦相似度就会很高。

2.4 向量数据库

当知识库包含数百万个文档片段时,不可能逐一比较。向量数据库通过近似最近邻(ANN)算法实现高效检索。

传统数据库 vs 向量数据库

对比维度传统数据库向量数据库
查询方式精确匹配(WHERE id=123)相似度搜索(找最近的K个向量)
索引结构B-Tree、HashHNSW、IVF
典型场景结构化数据查询语义检索、推荐系统

存储结构

向量数据库中的每条记录通常包含向量、原始文本和元数据:

{
  "id": "doc_001",
  "vector": [0.23, -0.45, 0.67, ..., 0.12],
  "text": "购买商品的步骤是...",
  "metadata": {
    "source": "用户手册",
    "category": "购物",
    "timestamp": "2024-01-01"
  }
}

元数据在后续的过滤和追溯中非常有用。

主流向量数据库

向量数据库特点
FAISSMeta开源,高性能,支持GPU加速
Pinecone全托管云服务,开箱即用
Weaviate开源,支持混合搜索
Chroma轻量级,适合原型开发
Milvus开源,面向大规模场景
Qdrant开源,Rust实现,高性能

ANN索引算法

核心挑战是在百万级向量中实现毫秒级检索。常用算法:

  • HNSW(Hierarchical Navigable Small World):构建多层跳表式的图结构,从顶层粗粒度搜索逐渐下沉到底层精细搜索。召回率可达95%以上
  • IVF(Inverted File Index):先将向量空间聚类,查询时只在最近的几个聚类中搜索,内存友好
  • PQ(Product Quantization):将高维向量压缩为短码,大幅减少内存占用

这些算法以亚线性的复杂度完成检索——百万级向量的查询延迟通常在10ms以内。

三、RAG的完整Pipeline

RAG的流程分为两个阶段:离线阶段(向量化)在线阶段(检索生成)

graph LR
    subgraph 离线阶段 ["离线阶段:知识库构建"]
        DOC["原始文档"] --> CHUNK["文档分块"]
        CHUNK --> EMB1["向量化"]
        EMB1 --> VDB["存入向量数据库"]
    end
    
    subgraph 在线阶段 ["在线阶段:检索与生成"]
        Q["用户提问"] --> EMB2["Query向量化"]
        EMB2 --> SEARCH["相似度检索"]
        VDB --> SEARCH
        SEARCH --> TOP["Top-K文档"]
        TOP --> PROMPT["构造Prompt"]
        Q --> PROMPT
        PROMPT --> LLM["LLM生成回答"]
    end

3.1 离线阶段:知识库构建

3.1.1 文档加载

将各种格式的文档转换为纯文本:PDF、Word、HTML、Markdown、数据库记录等。针对不同格式需要专门的解析策略——PDF需要提取表格结构,代码文件按函数分块,Markdown按标题层级切分,以保留格式语义。

3.1.2 文档切分(Chunking)

这是RAG中最关键且最容易被低估的环节。为什么要切分?

  • LLM的上下文窗口有限(4K/8K/32K/128K),不能把整篇文档都塞进去
  • 嵌入模型对长文本的语义表示质量下降
  • 精确检索需要更细粒度的文本单元

常用的切分策略:

策略方式优点缺点
固定长度切分每N个字符切一刀简单,大小均匀可能切断语义
按段落/句子切分以自然段落或句子为边界保持语义完整长度不均匀
递归切分先按大块切,大块太长则递归细分灵活平衡实现稍复杂
语义切分用嵌入模型判断语义边界语义最完整计算成本高
滑动窗口切分相邻chunk之间保留Overlap重叠避免边界信息丢失冗余增加
结构化切分按标题层级、标签切分(Markdown/HTML)保留文档结构,语义边界清晰依赖文档格式规范

重叠(Overlap) 是一个重要的技巧:相邻的chunk之间保留一部分重叠文本,避免关键信息恰好被切断在边界上。

原文:  [        Chunk 1        ]
                     [        Chunk 2        ]
                                  [        Chunk 3        ]
       ←──────→ ←──→ ←──────→ ←──→ ←──────→
        独有部分  重叠   独有部分  重叠   独有部分

3.1.3 嵌入与存储

对每个chunk调用嵌入模型生成向量,连同原始文本和元数据一起存入向量数据库。

3.2 在线阶段:检索与生成

graph LR
    Q["用户问题"] --> QE["嵌入模型"]
    QE --> QV["问题向量"]
    QV --> SEARCH["向量检索"]
    DB["向量数据库"] --> SEARCH
    SEARCH --> DOCS["相关文档"]
    DOCS --> PROMPT["构造Prompt"]
    Q --> PROMPT
    PROMPT --> LLM["LLM"]
    LLM --> ANS["回答"]

关键约束:Query向量化必须使用与文档向量化相同的Embedding模型,否则它们处于不同的向量空间,无法进行有意义的相似度比较。

3.2.1 召回策略

从向量数据库中选择文档有两种主要策略:

Top-K 召回:返回相似度排名前K的文档。

K = 5,返回相似度最高的5个文档:
[Doc1: 0.92, Doc2: 0.87, Doc3: 0.81, Doc4: 0.76, Doc5: 0.45]
  • 优点:固定数量,结果可控
  • 缺点:可能包含不相关的低分文档(如Doc5只有0.45)

相似度阈值:只返回相似度超过阈值的文档。

阈值 = 0.7,只返回相似度 > 0.7 的文档:
[Doc1: 0.92, Doc2: 0.87, Doc3: 0.81, Doc4: 0.76]
// Doc5: 0.45 被过滤
  • 优点:保证质量,过滤不相关文档
  • 缺点:结果数量不固定,可能为空

实践中通常结合使用:先Top-K召回,再用阈值过滤掉低分文档。

3.2.2 构造Prompt

将检索到的文档与问题组合成Prompt:

请根据以下参考资料回答用户的问题。如果参考资料中没有相关信息,请说明你不确定。

参考资料:
[文档片段1]
[文档片段2]
[文档片段3]

用户问题:如何在iOS中实现启动优化?

3.2.3 生成

LLM基于带有上下文的Prompt生成回答。因为有真实文档作为依据,幻觉率大幅降低。

四、高级RAG技术

基础RAG虽然有效,但在实际应用中会遇到各种挑战。以下是一系列优化技术。

4.1 查询优化

用户的原始问题不一定适合直接用于检索。

查询重写(Query Rewriting)

让LLM先改写用户的问题,使其更适合检索:

原始问题: "为什么我的App启动这么慢?"
重写后:   "iOS应用冷启动优化方法 启动耗时分析 dyld加载优化"

查询分解(Query Decomposition)

将复杂问题拆解为多个子问题,分别检索后综合:

原始问题: "对比MVVM和MVC架构在iOS中的优缺点"
子问题1: "iOS中MVVM架构的优点和缺点"
子问题2: "iOS中MVC架构的优点和缺点"
子问题3: "MVVM和MVC的对比分析"

HyDE(Hypothetical Document Embeddings)

先让LLM生成一个"假设的答案文档",用这个假设文档(而不是问题本身)去做检索。因为假设文档与真实文档在语义空间中更近:

graph LR
    Q["用户问题"] --> LLM["LLM生成
假设答案"] LLM --> HYP["假设文档"] HYP --> EMB["嵌入"] EMB --> SEARCH["向量检索"] SEARCH --> REAL["真实文档"]

自查询(Self-Query)

让LLM从自然语言问题中自动提取元数据过滤条件,缩小检索范围:

用户问题: "最近3个月关于Python的技术文档"
↓ LLM提取
语义查询: "Python技术文档"
过滤条件: category="技术文档", date > 2024-08, language="Python"

4.2 检索优化

BM25关键词检索

BM25(Best Matching 25) 是经典的关键词检索算法,基于TF-IDF的改进版本。它的核心思想是:

$$\text{BM25} = \text{词频(TF)} \times \text{稀有度(IDF)} \times \text{长度归一化}$$
  • 词频:关键词在文档中出现越多,得分越高(但有饱和效应,避免长文档刷分)
  • 稀有度:越罕见的词权重越高(“的"出现在几乎所有文档中,权重很低;“dyld"只出现在特定文档中,权重很高)
  • 长度归一化:避免长文档天然占优

BM25的优势在于对精确匹配的能力——专有名词、代码片段、ID编号等不需要语义理解的检索场景。

结合稀疏检索(BM25关键词)和稠密检索(向量语义),取两者之长:

graph LR
    Q["用户Query"] --> S["BM25
关键词检索
Top-50"] Q --> D["向量检索
语义相似度
Top-50"] S --> F["融合排序
RRF/加权"] D --> F F --> R["最终Top-10"]
检索方式优势劣势
BM25关键词检索精确匹配能力强(专有名词、代码、ID)无法理解同义词和语义
向量语义检索语义理解能力强(同义词、改写)对精确匹配不如关键词
混合检索兼顾精确匹配和语义理解实现和调参更复杂

**RRF(Reciprocal Rank Fusion)**是常用的融合方法:

$$\text{RRF}(d) = \sum_{r \in R} \frac{1}{k + \text{rank}_r(d)}$$

对于每个检索器 $r$,文档 $d$ 的排名越靠前,得分越高。$k$ 是平滑常数(通常取60)。

实践表明,混合检索通常比单一检索方式提升15-20%的效果

重排序(Re-ranking)

初始检索(召回阶段)追求速度,需要处理百万级文档,用的是较轻量的模型。召回后,用一个更精确(但更慢)的模型对Top-K结果重新排序:

向量检索 Top-50 → Rerank精排模型 → 最终 Top-5

为什么需要Rerank? 向量检索使用的是Bi-Encoder(双塔模型),Query和Document独立编码,无法捕捉它们之间的交互关系。Rerank使用Cross-Encoder(交叉编码器),将Query和Document拼接后联合编码,精度更高。

graph TD
    subgraph 召回阶段 ["召回:Bi-Encoder(双塔模型)"]
        Q1["Query"] --> ENC1["Encoder"]
        ENC1 --> V1["向量"]
        D1["Document"] --> ENC2["Encoder"]
        ENC2 --> V2["向量"]
        V1 --> SIM["余弦相似度"]
        V2 --> SIM
    end
    
    subgraph 精排阶段 ["精排:Cross-Encoder(交叉编码器)"]
        QD["[Query, Document] 拼接"] --> BERT["Transformer"]
        BERT --> ATT["Attention交互层"]
        ATT --> SCORE["相关性分数"]
    end
对比维度Bi-Encoder(召回)Cross-Encoder(精排)
编码方式Query和Document独立编码Query和Document联合编码
交互程度只在最后做向量相似度计算每个token在Attention层中互相关注
速度快,文档向量可预先计算,复杂度O(1)慢,每对(Query, Document)都要重新计算
精度较低,无法捕捉细粒度交互较高,能理解Query和Document的深层关系
适用规模百万级检索百级精排

实际案例:

Query: "Python异步编程用什么库?"

召回Top1: "Python异步编程是一种并发编程范式"        (0.88)  ← 语义相近但没回答问题
召回Top2: "asyncio是Python标准库的异步IO框架"      (0.85)

Rerank后: "asyncio是Python标准库的异步IO框架"      (0.95) ← 精排后排到第一

多路召回融合(Multi-Recall Fusion)

同时使用多个Embedding模型召回,用RRF等算法融合结果。不同模型对不同类型的文本有各自的优势,融合后效果更好。

元数据过滤(Metadata Filtering)

结合结构化过滤条件缩小检索范围,减少噪声:

检索条件 = 语义相似度Top-10 + category="技术文档" + date > "2024-01-01"

4.3 索引优化

父子分块(Parent-Child Chunking)

核心思想:小块检索,大块使用——用小粒度提高召回精准度,用大粒度保证上下文完整性。

graph TD
    DOC["原始文档"] --> PARENT["切分为父块
(如1000字)"] PARENT --> CHILD["每个父块再切分为子块
(如200字)"] CHILD --> INDEX["向量化并索引子块"] INDEX --> SEARCH["用户Query检索子块"] SEARCH --> RETURN["召回子块后
返回对应的父块内容给LLM"]
  • 优势:子块语义更聚焦、检索更准确;返回父块避免信息碎片化,LLM获得更充分的背景信息
  • 挑战:需要同时存储父块和子块,维护父子关系的索引;返回父块会增加Token消耗

层级索引(Hierarchical Index)

对文档建立多层索引:先检索摘要找到相关文档,再检索具体段落:

第一层: 文档摘要索引 → 找到相关文档
第二层: 段落级索引   → 在相关文档中找到具体段落

知识图谱增强

将文档中的实体和关系提取为知识图谱,检索时不仅用向量相似度,还利用图结构进行多跳推理:

问题: "张三的导师发表过哪些关于Transformer的论文?"

知识图谱:
  张三 --导师--> 李四
  李四 --发表--> "Attention Is All You Need"
  李四 --发表--> "BERT: Pre-training..."

4.4 生成优化

上下文压缩(Context Compression)

召回的文档中可能包含大量与问题无关的内容。上下文压缩用LLM提取与问题最相关的片段,去除冗余信息:

  • 减少Token消耗
  • 提高LLM对关键信息的关注度
  • 避免无关信息干扰回答质量

引用标注

让LLM在回答中标注信息来源,便于用户验证:

根据公司技术文档[1]iOS应用的冷启动优化主要从以下方面入手
1. 减少动态库数量[1]
2. 优化+load方法[2]
3. 延迟非必要的初始化[2]

[1] 《启动优化指南》第3
[2] 《性能优化实践》第5.2

自我反思(Self-Reflection)

让LLM检查自己的回答是否完全基于检索到的文档,如果发现自己在"编造”,则修正:

graph TD
    A["生成初始回答"] --> B["自我检查
回答是否有依据?"] B -->|是| C["输出回答"] B -->|否| D["标注不确定部分
或重新检索"] D --> A

4.5 其他优化手段

优化手段思路适用场景
Embedding模型微调使用领域数据对Embedding模型进行微调垂直领域,专业术语多
文档格式针对性优化针对PDF/Markdown/表格/代码采用专门的解析和分块策略多格式文档混合的知识库
多路召回融合同时使用多个Embedding模型召回,融合结果对召回率要求高的场景
元数据过滤结合结构化过滤条件缩小检索范围知识库有明确分类的场景
上下文压缩召回后用LLM提取与问题最相关的片段Token消耗敏感的场景
自查询让LLM从自然语言中提取过滤条件用户查询包含时间/分类等结构化信息

五、RAG vs. 微调

维度RAG微调(Fine-tuning)
知识更新更新知识库即可,实时生效需要重新训练,成本高
幻觉控制有明确的来源,可追溯仍可能产生幻觉
成本推理时增加检索和上下文成本训练成本高,推理成本不变
适用场景需要实时/专有知识、需要引用来源需要改变模型的行为模式或风格
知识深度受限于知识库质量和检索质量知识内化到模型参数中

在实践中,两者常常结合使用:先用RAG提供领域知识,再用微调让模型更好地利用检索到的信息。

六、RAG的评估

6.1 检索质量评估

指标定义说明
Hit Rate(命中率)Top-K结果中至少包含一个正确答案的比例命中次数 / 总查询次数
MRR(Mean Reciprocal Rank)首个正确答案排名的倒数平均值正确答案在第2位,MRR = 1/2 = 0.5
NDCG(归一化折损累计增益)综合考虑相关性和位置的排序质量位置越靠前的文档权重越高
召回率(Recall)相关文档中被检索到的比例衡量"有没有漏掉”
精确率(Precision)检索到的文档中相关文档的比例衡量"有没有噪声"

6.2 生成质量评估

指标定义说明
Faithfulness(忠实度)生成答案是否基于检索到的文档避免幻觉,确保可追溯性
Answer Relevance(答案相关性)答案是否直接回答了用户的问题通常用LLM-as-Judge评估
Context Relevance(上下文相关性)检索到的文档与问题的相关程度减少无关信息对生成的干扰
完整性回答是否覆盖了问题的各个方面避免遗漏关键信息

LLM-as-Judge 是目前评估生成质量的主流方法:用一个LLM来判断另一个LLM的输出质量,相比人工评估更高效,相比规则匹配更灵活。

6.3 系统整体评估

graph TD
    E["RAG系统评估"] --> R["检索质量"]
    E --> G["生成质量"]
    E --> S["系统指标"]
    
    R --> R1["Hit Rate / MRR / NDCG"]
    R --> R2["召回率 / 精确率"]
    
    G --> G1["Faithfulness / Answer Relevance"]
    G --> G2["Context Relevance / 完整性"]
    
    S --> S1["端到端正确率"]
    S --> S2["延迟"]
    S --> S3["成本(Token消耗)"]

6.4 常用评估框架

框架特点
RAGAS端到端RAG自动化评估框架,计算忠实度、答案相关性、上下文精确率等
TruLensLLM应用可观测性平台,提供多维度评估仪表盘
LlamaIndex EvalLlamaIndex内置的评估模块
LangSmithLangChain的评估和监控平台

七、RAG的工程实践

7.1 主流RAG框架

框架特点
LangChain最流行的LLM应用框架,组件丰富
LlamaIndex专注于RAG和数据索引
Haystack端到端NLP框架,支持复杂Pipeline
Semantic Kernel微软出品,企业级

7.2 一个典型RAG系统的架构

graph TB
    subgraph 数据层 ["数据层"]
        DOC["文档源
Confluence/Notion/Git/..."] PIPE["数据Pipeline
加载→切分→嵌入"] VDB["向量数据库"] DOC --> PIPE --> VDB end subgraph 检索层 ["检索层"] QP["查询处理
重写/分解/HyDE/自查询"] HR["混合检索
向量+BM25+元数据过滤"] RR["重排序
Cross-Encoder"] QP --> HR --> RR end subgraph 生成层 ["生成层"] CC["上下文压缩"] PC["Prompt构造"] LLM["LLM"] PP["后处理
引用标注/自我反思"] CC --> PC --> LLM --> PP end VDB --> HR RR --> CC USER["用户"] --> QP PP --> USER

7.3 常见的坑与应对

问题原因解决方案
检索不到相关文档chunk太大/太小、嵌入模型不适配调整chunk大小、尝试不同嵌入模型、混合检索
检索到了但答案不对LLM未能利用上下文优化Prompt模板、增加few-shot示例、上下文压缩
回答包含幻觉检索结果不够相关加强重排序、添加自我反思环节
延迟太高检索+生成双重延迟缓存热点查询、流式输出、预检索
答案信息过时知识库未及时更新建立增量更新Pipeline
专有名词检索不到向量检索对精确匹配弱混合检索(BM25 + 向量)

八、RAG的挑战与演进方向

8.1 RAG面临的核心挑战

挑战描述
检索召回失败Query改写不当、分块策略不合理导致相关文档未被召回
上下文窗口限制召回文档过多无法全部放入,需平衡检索精度与上下文长度
多跳推理能力弱单次检索难以解决需要多步推理和信息综合的复杂问题

将RAG与Agent结合,让模型自主决定何时检索、检索什么、如何利用检索结果:

graph TD
    Q["用户问题"] --> AGENT["Agent
规划与推理"] AGENT -->|"需要检索"| SEARCH["检索知识库"] AGENT -->|"需要计算"| CALC["调用计算工具"] AGENT -->|"需要外部数据"| API["调用外部API"] AGENT -->|"信息足够"| GEN["综合生成回答"] SEARCH --> AGENT CALC --> AGENT API --> AGENT AGENT -->|"需要更多信息"| SEARCH
维度传统RAGAgentic Search
模式单次检索 → 生成答案规划 → 多次检索 → 推理 → 综合答案
优势响应快速、架构简单、成本可控自主规划、多跳推理、工具调用
劣势无法动态调整检索策略,缺乏推理规划能力延迟高、成本高、复杂度高、可控性弱
适用场景简单问答、知识查询、文档问答复杂分析、多源信息整合、需要实时数据

技术路线选择

  • 简单场景:传统RAG即可满足
  • 中等复杂度:RAG + Rerank + 混合检索
  • 高复杂度:Agentic Search(需权衡成本和延迟)

8.3 Graph RAG

微软提出的Graph RAG将知识图谱与RAG深度结合:

  1. 从文档中提取实体和关系,构建知识图谱
  2. 对知识图谱做社区检测,生成不同粒度的摘要
  3. 查询时利用图结构进行推理

特别适合需要全局理解(如"总结所有安全事件的共同模式")的场景。

8.4 多模态RAG

不局限于文本,支持图片、表格、代码等多种模态的检索和理解:

  • 图片:用多模态嵌入模型(如CLIP)将图片和文本映射到同一向量空间
  • 表格:专门的表格理解模型提取结构化信息
  • 代码:代码嵌入模型(如CodeBERT)理解代码语义

九、总结

RAG是连接LLM与现实世界知识的桥梁。它的核心价值在于:

  1. 知识实时性:无需重新训练模型即可更新知识
  2. 减少幻觉:基于真实文档回答,可追溯来源
  3. 数据隐私:私有数据不需要传给模型提供商训练
  4. 成本效率:比微调大模型便宜得多

RAG不是一个单一的技术,而是一个系统工程。从文档切分、嵌入选择、检索策略到Prompt设计,每个环节都会影响最终效果。理解这些环节的原理和权衡,才能构建出真正好用的RAG系统。