RAG 不是“把文档放进向量数据库”这么简单。它更像一套让模型使用外部知识的系统方法:先找到证据,再组织上下文,最后要求模型基于证据生成答案。
理解这套技术可以沿着一条逐步增加检索能力的主线展开:
1 | 关键词检索 |
这是一条便于理解的技术路线,不是严格的年代顺序或替代关系。关键词检索至今仍不可缺少;GraphRAG 与 SAG 也不是简单的新旧版本,而是面向结构化约束、多跳关系和跨文档证据的不同设计。
2026 年出现的 SAG(SQL-Retrieval Augmented Generation)提供了一条新的结构化路线:不预先维护全局知识图谱,而是把文本组织成事件与实体,查询时用 SQL Join 临时连接相关事件。本文从关键词检索开始,逐步解释 Naive RAG、Hybrid RAG、GraphRAG 与 SAG 的边界和联系。
一、RAG 解决什么问题
大模型的参数可以记住训练时见过的模式和知识,但存在三个天然限制:
- 知识有截止时间,无法及时反映业务数据变化;
- 参数中的事实难以直接修改、删除和授权;
- 回答来源不透明,出现错误时不容易追溯。
RAG 为模型增加一份可检索的外部记忆。经典 RAG 由参数化的生成模型和非参数化的文档索引组成,最初论文使用稠密向量索引检索 Wikipedia 段落,再让生成模型同时参考问题和检索结果。RAG 原始论文
一个现代 RAG 系统通常包含两条链路:
flowchart LR
subgraph Offline[离线入库]
Source[文档 / 数据源] --> Parse[解析与清洗]
Parse --> Chunk[结构化分块]
Chunk --> Metadata[元数据与权限]
Metadata --> Index[全文 / 向量 / 图索引]
end
subgraph Online[在线问答]
Query[用户问题] --> Rewrite[理解与改写]
Rewrite --> Retrieve[多路召回]
Retrieve --> Fuse[融合与精排]
Fuse --> Context[上下文组装]
Context --> LLM[模型生成]
LLM --> Answer[答案与引用]
end
Index --> Retrieve
RAG 可以缓解幻觉,却不能保证消灭幻觉。如果召回不到正确证据、召回了冲突版本,或者模型忽略了证据,最终答案仍可能出错。因此生产系统要分别评测“检索是否正确”和“生成是否忠于证据”。
二、关键词检索:寻找相同的词
关键词检索本身早于 RAG,也不包含生成阶段,因此严格来说它不是一种 RAG。这里把它放在 Naive RAG 之前,是因为 BM25 等词法检索既是现代 RAG 的重要基础,也是评估向量与结构化检索是否真正带来收益的必要基线。
2.1 倒排索引
关键词检索通常使用倒排索引。正向关系是“文档包含哪些词”,倒排关系则是“某个词出现在哪些文档中”:
1 | redis → 文档 2、文档 8 |
查询时不需要扫描全部文档,只需读取查询词对应的文档列表,再计算相关性分数。
中文检索还涉及分词、同义词、停用词、大小写、简繁体和领域词典。错误码、型号和专有名词不应被通用分词器拆坏。
2.2 TF-IDF 与 BM25
TF-IDF 的直觉是:某个词在当前文档中频繁出现,但在整个语料中很少出现,那么它更能代表该文档。
BM25 在此基础上加入词频饱和与文档长度归一化:
1 | score(D, Q) = Σ IDF(qᵢ) × |
不必死记公式,理解三个性质即可:
- 稀有查询词比常见词贡献更大;
- 一个词重复出现很多次后,收益逐渐饱和;
- 长文不会仅因包含更多词而天然占优。
2.3 优点与盲区
关键词检索特别适合:
- 错误码、订单号、API 名称和产品型号;
- 法条原文、专有名词和精确短语;
- 用户已经知道目标词汇的站内搜索;
- 需要低成本、低延迟和容易解释的场景。
它的主要问题是“词不一样就可能找不到”。例如查询“服务为什么没有响应”,文档写的是“请求超时”,二者含义接近但词面重合很少。查询改写、同义词词典和学习型稀疏检索可以改善这个问题,但会增加复杂度。
三、Naive RAG 与向量检索:寻找相近的含义
3.1 为什么称为 Naive RAG
今天工程语境中的 Naive RAG,通常指最基础的“分块、向量化、Top-K 召回、拼接上下文、生成回答”流程:
1 | 文档 → Chunk → Embedding → 向量索引 |
“Naive”不代表它没有价值,而是说明其检索单元通常彼此独立,缺少查询改写、多路召回、精排、父子 Chunk、关系扩展和迭代检索等增强机制。对于单跳事实和语义问答,它仍然是必须建立的基线。
3.2 Embedding 与相似度
Embedding 模型把问题和文本映射为高维向量:
1 | q = Encoder(query) |
再用余弦相似度、点积或欧氏距离寻找最接近的问题片段。语义相似的句子即使没有共享关键词,也可能落在相近的向量区域。
1 | “接口一直没返回” |
向量数据库不是理解知识的模型。它主要负责保存向量、元数据和原文引用,并高效完成近邻搜索。真正决定语义空间的是 Embedding 模型。
3.3 ANN 索引
对所有向量做精确比较的成本会随数据量增长。生产系统常使用近似最近邻搜索(ANN),用少量精度交换显著的速度和内存收益:
| 索引 | 核心思路 | 特点 |
|---|---|---|
| HNSW | 构造多层近邻图并逐层搜索 | 召回率高、查询快,内存占用较大 |
| IVF | 先聚类,再搜索少量候选分区 | 适合大规模数据,需要训练与调参 |
| PQ | 将向量分段量化压缩 | 大幅节省内存,但会损失精度 |
| Flat | 与全部向量精确计算 | 结果精确,适合小数据或作为评测基线 |
ANN 参数调优必须同时观察 Recall、P95/P99 延迟、内存和并发吞吐,不能只比较单次查询速度。
3.4 Naive RAG 的常见失败
- 精确标识符不稳定:Embedding 未必能可靠区分
ERR_4012与ERR_4021; - 相似不等于相关:主题相似的片段不一定包含回答所需事实;
- 分块破坏语义:表头、上下文或限定条件被切到另一个 Chunk;
- 长尾领域漂移:通用模型不理解内部缩写和特殊术语;
- 时间与权限缺失:只按相似度搜索,可能召回过期版本或无权访问的数据;
- 多跳能力有限:独立排序 Chunk 不会主动连接散落在不同文档中的证据。
所以向量搜索前应先应用租户、ACL、时间、语言和文档状态等硬过滤;无法用于过滤的权限信息不能只写进正文。
四、Hybrid RAG:让精确匹配与语义召回互补
关键词和向量检索不是替代关系。常见做法是两路并行召回:
flowchart LR
Q[查询] --> BM25[BM25 关键词召回]
Q --> Dense[稠密向量召回]
BM25 --> Fusion[RRF / 加权融合]
Dense --> Fusion
Fusion --> Rerank[Cross-Encoder / LLM 精排]
Rerank --> TopK[Top-K 证据]
4.1 为什么不能直接相加分数
BM25 分数和向量相似度的量纲、范围与分布不同,直接相加往往没有稳定含义。常见融合方法包括:
- 归一化加权:分别归一化后设置业务权重;
- RRF:只利用每路结果的名次,降低分数标定差异;
- 学习排序:使用点击、标注或问答反馈训练融合模型;
- 查询路由:错误码问题提高关键词权重,概念问题提高向量权重。
RRF 的简化形式为:
1 | RRF(d) = Σ 1 / (k + rankᵣ(d)) |
它易实现、无需训练,是混合检索的可靠起点。
4.2 召回与精排分工
第一阶段需要从大规模语料中快速“多找一些”,强调 Recall;第二阶段让更昂贵的 Cross-Encoder 或 LLM 同时阅读查询与候选片段,强调排序精度。
1 | 百万级 Chunk |
Top-K 并非越大越好。无关内容会增加 Token 成本、稀释关键证据,甚至让模型受到错误片段干扰。
五、知识图谱与 GraphRAG:寻找相互连接的事实
5.1 从文本到图
知识图谱通常将知识表示为实体、关系和属性:
1 | (Alice) -[任职于]-> (Company A) |
它擅长回答关系型问题:
- 某人与哪些项目有关?
- 两家公司通过什么事件连接?
- 某故障影响了哪些服务和客户?
- 一个结论依赖哪几条跨文档证据?
典型 GraphRAG 会从文本中抽取实体、关系与事实,构建图并进行社区发现,再结合原始文本生成社区摘要。查询时可以从实体向邻居扩展,也可以用社区摘要回答“整个语料的主要主题是什么”一类全局问题。Microsoft GraphRAG 明确区分 Local、Global、DRIFT 和基础向量搜索模式。Microsoft GraphRAG 论文 · GraphRAG 查询文档
5.2 图检索带来的能力
- 显式保留跨文档关系,支持多跳搜索;
- 可从实体、关系、时间或类型施加结构化约束;
- 路径比纯向量距离更容易解释和审计;
- 社区和层级摘要有利于回答全局性问题;
- 可以将检索结果扩展到直接语义不相似但存在关系的证据。
5.3 工程代价
图不是免费的“高级向量库”。它引入了新的质量和运维问题:
- 实体抽取错误会制造不存在的节点;
- 同名消歧、别名合并和实体规范化很难;
- 二元三元组可能拆散一个完整事件的时间、地点和参与者;
- 文档更新后要同步修改节点、边、社区和摘要;
- 索引阶段需要大量模型调用,Microsoft 也提醒标准 GraphRAG 索引可能消耗大量 LLM 资源;
- 图路径存在不代表它与当前问题相关,仍需要文本证据和精排。
因此 GraphRAG 更适合关系密集、多跳和全局归纳问题。FAQ、错误码手册或简单事实查询,混合检索通常更直接。
六、SAG:查询时才激活关系
6.1 SAG 是什么
本文的 SAG 指 SQL-Retrieval Augmented Generation,不是泛指 Search-Augmented Generation。它由 2026 年的论文提出,目标是补足向量 RAG 的多跳能力,同时减少全局知识图谱的构建和维护成本。SAG 论文 · SAG Benchmark
SAG 的关键变化是知识表示方式:
- 每个 Chunk 被整理为一个语义完整的事件;
- 一个事件关联多个带类型的实体;
- 事件与实体保存为普通表和索引;
- 查询时以共享实体作为 Join Key,连接相关事件;
- 连接只服务于当前查询,不持久化为全局图;
- 最终证据仍映射回原始 Chunk,便于引用。
假设两段文档分别表达:
1 | 事件 E1:Alice 在 2025 年加入 Company A,负责 Project X。 |
查询“Alice 负责的项目为什么发生故障”时,查询本身与 E2 的词面和向量语义未必足够接近。SAG 可以先命中 E1,再通过共享实体 Project X Join 到 E2,组成当前查询所需的两跳证据链。
6.2 为什么称为动态超边
普通知识图谱常把关系拆为二元三元组。一个“甲公司于某日在某地收购乙公司”的事件,可能被拆成多条边,事件边界和限定条件容易丢失。
SAG 将一个完整事件以及参与该事件的多个实体视为一条潜在超边:
1 | event ↔ {entity₁, entity₂, ..., entityₙ} |
它在存储中只是事件表、实体表和关联表;当查询沿“事件 → 实体 → 其他事件”扩展时,相关超边才被激活。论文将其称为 query-time dynamic hyperedges。
6.3 索引与查询流程
flowchart TB
subgraph Indexing[离线索引]
Chunk[原始 Chunk] --> Extract[LLM 提取完整事件与类型化实体]
Extract --> EventTable[(Event 表)]
Extract --> EntityTable[(Entity 表)]
Extract --> Incidence[(Event-Entity 关联表)]
Chunk --> Vector[(向量索引)]
end
subgraph Querying[在线查询]
Query[问题] --> Seeds[向量检索 + 查询实体识别]
Seeds --> Join[SQL 按共享实体扩展]
Join --> Candidates[压缩候选事件集]
Candidates --> Select[LLM 最终选择]
Select --> Source[映射回原始 Chunk]
Source --> Generate[回答与引用]
end
Vector --> Seeds
EventTable --> Join
EntityTable --> Join
Incidence --> Join
这里的 SQL 不负责理解自然语言。它负责确定性地执行实体过滤、关联和有界扩展;Embedding 负责找到没有精确词面重合的种子,LLM 负责事件实体抽取、查询理解和最终候选选择。三者各自解决不同问题。
6.4 SAG、Naive/Hybrid RAG 与 GraphRAG 对比
| 维度 | 向量 / 混合 RAG | GraphRAG | SAG |
|---|---|---|---|
| 核心检索单元 | 独立 Chunk | 实体、关系、社区与文本 | 完整事件、实体与原始 Chunk |
| 跨文档关联 | 弱,依赖迭代检索或模型推理 | 预先构建的全局图 | 查询时按共享实体 Join |
| 多元关系 | 隐含在文本中 | 常被拆成二元边 | 一个事件对应多实体超边 |
| 增量写入 | 简单 | 可能需要实体合并和图维护 | 以追加事件和关联记录为主 |
| 全局主题归纳 | 较弱 | 社区摘要较强 | 论文重点不在全局摘要 |
| 精确约束 | 依赖元数据过滤 | 图查询 | SQL 过滤与 Join |
| 索引成本 | Embedding 为主 | 实体关系抽取、聚类与摘要 | 每个 Chunk 做事件实体抽取 |
| 典型优势 | 单跳语义与精确查询 | 关系、路径和全局问题 | 动态增长语料中的多跳证据 |
SAG 不是“只用 SQL 替代向量检索”,也不是简单地把 RAG 与 GraphRAG 并排运行。它仍使用向量召回种子,但把跨 Chunk 的关联组织为关系表,并在查询时激活。
6.5 如何看待实验结果
论文在 HotpotQA、2WikiMultiHopQA 和 MuSiQue 三个多跳问答数据集上比较 BM25、向量检索和多种结构化 RAG。其报告称,在统一使用 BGE-Large-EN-v1.5 Retriever 与 Qwen3.6-Flash Reader 时,SAG 的平均 Recall@5 和问答 F1 分别为 90.07% 与 72.96%;在多跳要求更高的 MuSiQue 上,Recall@5 为 80.36%。论文实验与完整结果
这些数字值得关注,但暂时不能直接推出“SAG 已在所有企业知识库场景优于其他方案”:
- 论文仍是较新的预印本,结论主要来自作者团队;
- 三个主要数据集都是英文百科式多跳问答;
- 实验语料规模为数千到一万余 Passage,不等于真实超大企业语料;
- 产品文档、代码、表格、对话和中文实体的表现尚需单独评测;
- 指标对模型、分块、候选预算和评测脚本非常敏感;
- LLM 抽取和最终选择是系统效果的重要组成部分,不是纯 SQL 带来的收益。
更稳妥的判断是:SAG 展示了“用关系数据库保存轻量事件结构、在查询时动态恢复多跳关系”的可行性,而不是宣告向量检索和知识图谱已经过时。
6.6 潜在局限
- 抽取成本:论文的离线阶段对每个 Chunk 进行一次结构化 LLM 调用,成本仍高于纯向量入库。
- 实体一致性:别名、同名实体和错误类型会直接影响 Join 的准确率。
- 热门实体爆炸:沿“公司”“中国”等高频实体扩展可能产生大量候选,需要类型、度数和预算限制。
- 事件粒度依赖分块:一个 Chunk 同时描述多个事件,或一个事件跨越多个 Chunk 时,“一块一事件”的假设会受到挑战。
- 关系语义较轻:共享实体能说明事件相连,但不自动说明连接与问题相关。
- 全局分析不是强项:语料主题、趋势与社区概览仍可能更适合 GraphRAG 的层级社区摘要。
- 权限传播:跨 Chunk Join 前必须执行文档级 ACL 过滤,不能让无权访问的事件成为桥接节点。
- 模型稳定性:托管模型升级和非确定性会让抽取、选取与论文复现实验出现差异。
七、如何选择检索方案
不要从“哪种技术最先进”开始,而应先分析问题类型:
| 问题或数据特征 | 建议起点 |
|---|---|
| 错误码、SKU、合同编号、API 名称 | BM25 / 全文检索 |
| 自然语言问答、同义表达、概念解释 | 向量检索 |
| 同时存在专有词和自然语言 | BM25 + 向量混合检索 + Rerank |
| 已有高质量结构化数据库 | SQL / API 工具调用,不必强行转成 Chunk |
| 稳定本体、复杂路径、合规推理 | 知识图谱 + 原文证据 |
| 面向整个语料的主题归纳 | GraphRAG 社区与层级摘要 |
| 动态增长语料中的事件关联、多跳问答 | 可试验 SAG |
| 多种问题混合存在 | 查询分类与多路检索路由 |
一个务实的演进顺序是:
1 | BM25 基线 |
先建立简单基线很重要。没有 BM25 和纯向量结果,就无法判断复杂结构到底解决了什么问题,也无法证明额外成本值得。
八、评测比选型更重要
8.1 建立问题集
从真实业务中收集并标注:
- 精确词查询;
- 同义表达查询;
- 时间、部门、版本等过滤查询;
- 需要两到四条证据的多跳查询;
- 无答案问题;
- 权限隔离问题;
- 冲突与过期知识问题。
每个问题至少记录参考答案、必要证据 Chunk、允许的数据范围和问题类型。
8.2 分层指标
| 层级 | 推荐指标 | 关注点 |
|---|---|---|
| 检索 | Recall@K、MRR、nDCG | 正确证据是否被找到及排序 |
| 多跳检索 | Evidence Recall、链路完整率 | 所有必要证据是否同时出现 |
| 生成 | 正确性、Faithfulness、引用准确率 | 回答是否受证据支持 |
| 系统 | P50/P95/P99、吞吐、Token 与模型成本 | 是否可用于生产 |
| 安全 | 越权召回率、敏感信息泄露率 | ACL 是否在每条路径生效 |
只测最终答案会掩盖问题:有时模型凭参数记忆答对,但检索完全错误;有时检索正确,模型却忽略证据。二者必须拆开定位。
8.3 SAG 的试验方法
如果要验证 SAG,不建议立刻替换现有检索栈。可以选择一组明确的多跳问题做影子实验:
- 固定同一份语料、分块和生成模型;
- 建立 BM25、纯向量、混合检索与现有 GraphRAG 基线;
- 为 SAG 记录实体抽取准确率、候选扩展量和 Join 深度;
- 比较相同 Top-K 预算下的证据链完整率;
- 单独统计入库成本、在线延迟和增量更新成本;
- 人工检查失败案例是种子未命中、实体未统一、扩展过宽还是最终选错;
- 在进入生成模型前执行相同 ACL 过滤并做越权测试。
只有当多跳召回提升在自己的数据上稳定复现,且额外成本和风险可以接受,才值得进入生产架构。
九、总结
理解 RAG 的关键不是记住产品名,而是理解不同检索信号:
- 关键词检索寻找相同的词,精确、便宜、可解释;
- Naive RAG 以独立 Chunk 的稠密向量 Top-K 召回为核心,是语义问答基线;
- Hybrid RAG 同时利用词面、语义和精排,通常是通用 RAG 的生产起点;
- GraphRAG 寻找显式连接,擅长路径、关系和全局结构,但索引与维护成本高;
- SAG 将 Chunk 表示为完整事件,以实体为 Join Key,在查询时动态连接证据,为多跳检索提供了轻量结构化新路线。
不存在一种索引能够独自解决所有问题。成熟的知识系统会把全文、向量、元数据、关系和原始证据视为不同层次,并通过真实问题集决定是否需要更复杂的结构。
参考资料
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Dense Passage Retrieval for Open-Domain Question Answering
- From Local to Global: A Graph RAG Approach to Query-Focused Summarization
- Microsoft GraphRAG
- SAG: SQL-Retrieval Augmented Generation with Query-Time Dynamic Hyperedges
- SAG Benchmark 复现仓库
- SAG 开源项目