RAG 技术地图:从向量检索到 GraphRAG、LightRAG 与 Agentic RAG
RAG 早已不只是“切块、向量检索、拼进 Prompt”。本文从失败模式出发,梳理混合检索、GraphRAG、LightRAG、Self-RAG、Corrective RAG 与 Agentic RAG 的关系,并给出可落地的选型与评测方法。
很多 RAG 教程停在同一个流程:文档切块,生成向量,查询时取回 Top K,再把结果塞进 Prompt。这个流程足以做出 Demo,也很容易让人产生一种错觉:只要换一个更好的 Embedding 模型、把 K 调大一点,回答质量就会稳定上升。
真正上线后,更常见的情况是系统找回了一些相关片段,却不足以回答问题。用户问某项设计为什么调整,系统找回了新方案,却漏掉旧方案的约束;用户要比较三个产品,检索结果集中在其中一个;用户问整个知识库里反复出现的主题,向量检索给出几段局部描述,却无法完成全局归纳。
这些失败不属于同一层。切块破坏上下文是知识组织问题,查询与文档措辞不一致是检索问题,多步问题只搜一次是流程控制问题,拿到错误证据仍然强答则是验证问题。GraphRAG、LightRAG、Self-RAG、Corrective RAG 和 Agentic RAG 之所以同时出现,是因为它们在修补不同环节。
这篇文章不按“第一代、第二代、第三代”给 RAG 排序。我更愿意把它们放到同一张技术地图里,先看系统在哪一层出错,再决定要加哪一种机制。
一、先把 RAG 看成一条知识流水线
RAG 的全称是 Retrieval-Augmented Generation,即检索增强生成。最初的 RAG 工作把参数化知识和外部非参数记忆结合起来:模型负责理解与生成,外部索引负责保存可以更新、可以追溯的知识。这个定义比“向量库问答”宽得多。
一个能长期维护的 RAG 系统至少包含下面几层:
- 数据层:原始文档、网页、代码、图片、表格、数据库和 API。
- 解析与索引层:清洗、切块、元数据、Embedding、关键词索引、图谱或结构化索引。
- 查询层:意图识别、查询改写、过滤、召回、融合和重排。
- 上下文层:去重、压缩、证据编排、冲突处理和 Token 预算。
- 生成层:根据证据回答、引用来源、表达不确定性或拒绝回答。
- 评测与反馈层:记录检索轨迹,区分召回失败和生成失败,并用线上反馈更新测试集。
这几层共同决定效果。换一个向量数据库只改变其中一部分;给流程套上 Agent,也不会自动修好过期文档和错误权限。
更实用的排障方式是把一次失败沿链路反推:
回答错了
├─ 证据其实是对的:检查 Prompt、引用约束和生成模型
├─ 证据不完整:检查查询拆解、召回、重排和上下文预算
├─ 证据本身错误:检查来源、版本、权限和索引更新
└─ 问题超出知识库:检查拒答、外部搜索和任务路由
只有知道故障在哪一层,技术选型才不会变成追逐名词。
RAG 和微调解决的是两类问题
RAG 与微调经常一起出现在方案讨论里,但它们的落点不同。RAG 把请求和外部知识连接起来,适合更新事实、补充私有资料和提供引用;微调改变模型的行为分布,更适合稳定输出格式、语气、任务习惯或某一类能力。
| 问题 | 更适合优先考虑 | 原因 |
|---|---|---|
| 规则每周变化,需要显示出处 | RAG | 知识可以独立更新,回答能回到来源 |
| 希望模型稳定输出特定 JSON | 微调或约束解码 | 这是行为与格式问题 |
| 让模型熟悉私有文档中的最新事实 | RAG | 不必把易变事实写入参数 |
| 让模型学会一种固定分类任务 | 微调 | 目标是改变任务行为 |
| 既要内部知识,又要固定表达方式 | RAG + 微调 | 两条链路各自负责知识与行为 |
微调也能让模型记住部分训练材料,但这种记忆不容易精确更新、删除和引用。把它当成知识库,会很快遇到版本和可追溯性问题。反过来,RAG 也不能替代能力训练:给模型检索到再多代码规范,也不保证它会稳定地产出符合规范的代码。
二、基础 RAG:简单,但不是随便切块就够了
基础 RAG 的典型链路是:
离线:文档 → 解析 → 切块 → Embedding → 向量索引
在线:问题 → Embedding → 相似度召回 → Top K → LLM → 回答
它适合答案集中在少量局部文本里的问题,例如产品规则查询、API 说明、术语解释和客服 FAQ。知识规模不大、文档结构规整时,基础方案的性价比很高。
基础不等于粗糙。至少有五件事值得在引入复杂框架前做好。
1. 切块要保留结构
固定字符数切块容易把标题、定义、条件和例外拆开。更稳妥的做法是先按 Markdown 标题、HTML DOM、代码符号或 PDF 版面切分,再在过长章节内部递归分块。每个块应携带标题路径、文档版本、来源和权限等元数据。
父子块检索也很实用:用较小的子块做精确匹配,命中后把较完整的父块交给模型。这样既保留召回精度,又不会让一句话脱离所在章节。
常见切块方法可以按语料特点选择:
| 方法 | 适合什么内容 | 容易出现的问题 |
|---|---|---|
| 固定长度 | 结构弱、需要快速建立基线的纯文本 | 句子、表格和条件可能被拦腰截断 |
| 递归切分 | Markdown、普通文档 | 分隔符规则写得不好时仍会丢层级 |
| 结构感知 | HTML、代码、带标题的技术文档 | 依赖解析器质量,复杂 PDF 需要版面识别 |
| 语义切分 | 主题边界明显的长文本 | 计算更贵,阈值变化会让块不稳定 |
| 父子块 | 既要精确命中,又要保留完整上下文 | 需要维护块之间的映射和额外读取 |
PDF 尤其容易踩坑。按页提取看起来省事,但一页可能同时包含上个章节的结尾、下个章节的开头和跨页表格。更可靠的方式是先恢复标题、段落、表格和阅读顺序,再决定切块边界。解析结果应该抽样检查,不能因为文本成功写入向量库就默认它是正确的。
2. Embedding 和向量索引各自负责什么
Embedding 模型把文本和查询映射到向量空间,向量索引负责从大量向量中快速找到近邻。前者决定“什么内容被认为相似”,后者决定“怎样在可接受的延迟里找到这些相似项”。向量数据库不是 Embedding 模型,也不会自动修复表示质量。
相似度可以使用余弦、点积或欧氏距离,具体选择要与模型的训练方式和索引配置一致。向量是否归一化也会影响结果。工程上常见的近似最近邻索引包括 HNSW,以及 IVF、PQ 等压缩或分桶方案:HNSW 通常以更多内存换取较好的召回和查询速度;IVF/PQ 更利于压缩大规模向量,但需要在召回率、训练与查询参数之间取舍。
模型选择不要只看公开榜单。中文比例、专业术语、文本长度和查询类型都会改变效果。最小可行评测集应该来自自己的语料,并至少比较 Recall@K、查询延迟、索引体积和更新速度。
3. 不要只依赖稠密向量
向量擅长语义近似,对订单号、错误码、类名、缩写和罕见专有名词未必稳定。BM25 一类关键词检索正好擅长精确词项。线上常用的混合检索会并行运行两路召回,再通过 Reciprocal Rank Fusion 或学习排序融合结果。
async def hybrid_retrieve(query, filters):
dense, lexical = await asyncio.gather(
vector_store.search(query, filters=filters, top_k=30),
bm25.search(query, filters=filters, top_k=30),
)
fused = reciprocal_rank_fusion(dense, lexical)
return reranker.rank(query, fused)[:8]
这里的 top_k=30 只是候选池,不应直接把 60 个片段交给生成模型。召回负责尽量不漏,重排负责把真正能回答问题的证据放到前面。
4. 召回和重排是两项不同工作
向量召回通常使用 Bi-Encoder:查询和文档分别编码,文档向量可以提前计算,因此适合在大规模索引里快速找候选。它的限制也来自这种分离计算——查询与候选之间没有在编码阶段进行逐词交互,一些细微条件很难辨别。
Cross-Encoder 会把查询和候选一起输入模型,直接预测相关性。它能看到二者的完整交互,排序通常更精细,但无法经济地逐条扫描整个知识库。因此,常见做法是先用向量、BM25 等方法召回几十条候选,再用 Cross-Encoder 重排,最后给生成模型留下少量证据。
图里的 30–100 条候选和 5–10 条最终证据只是调试起点。长文档、复杂比较问题可能需要更多证据,短事实问题则可以更少。参数应该由自己的 Recall@K、上下文精度、延迟和回答评测决定。
5. 元数据过滤发生在语义相似之前
时间范围、租户、产品线、语言、权限和文档状态都不适合交给 Embedding 猜测。用户问“当前规则”,旧版本即使语义更接近,也不应排在现行版本前面。
过滤条件最好来自结构化意图,而不是在向量结果返回后用字符串排除:
{
"intent": "查询当前退款规则",
"filters": {
"status": "active",
"effective_at": "2026-09-30",
"product": "consumer"
},
"must_have_evidence": ["适用条件", "例外", "生效时间"]
}
6. 引用必须映射回原文
RAG 在给模型补知识的同时,还要让回答可以核验。索引阶段需要保留从块到原始文档、页码、标题和版本的映射。经过摘要或压缩的内容也必须保留来源集合,否则最后显示的“引用”可能只是相关页面,并没有支撑具体结论。
7. 给“不知道”留出口
低相关度结果不等于证据。系统需要明确的证据阈值和拒答策略。如果关键条件缺失,可以要求用户补充范围,也可以说明知识库中没有足够材料。强迫模型在每次请求中产出完整答案,会把召回不足伪装成流畅的幻觉。
三、查询改写:同一件事可能有很多说法
用户表达和文档表达不一致,是 RAG 中最常见的召回损失。用户说“登录一直转圈”,文档可能写“认证回调超时”;用户问“为什么这个任务没跑”,运维手册记录的是“调度实例未进入就绪队列”。
查询改写主要有几种做法:
- 规范化:补全缩写、统一实体名称、修正错别字。
- 多查询扩展:从不同表述生成多个检索查询,再合并结果。
- 假设文档生成:先生成一段可能的答案或文档,再用它做向量检索,这类方法常被称为 HyDE。
- 问题分解:把比较、归因或多跳问题拆成可独立检索的子问题。
- 反向退一步:先寻找上位概念或通用规则,再回到具体问题。
扩展不是越多越好。每增加一路查询,召回可能提高,噪声、延迟和费用也会增加。一个简单事实问题被拆成十个子问题,通常说明控制策略过度设计。
我倾向于让规划模型输出可审计的结构,而不是要求它暴露一大段自由形式的“思维过程”:
{
"complexity": "multi_hop",
"subqueries": [
"方案 A 的适用条件与限制",
"方案 B 的适用条件与限制",
"A 与 B 在更新成本上的差异"
],
"sources": ["docs", "code"],
"stop_when": "每个比较项至少有一个有效来源"
}
它既方便执行,也方便回放。出现问题时,我们能看到是规划漏了一个比较维度,还是检索没有找回对应证据。
四、模块化 RAG:把固定直线拆成可替换部件
基础 RAG 通常是一条固定直线。生产系统会把这条直线拆成模块:查询经过路由器后进入不同数据源,召回结果经过过滤、融合和重排,必要时重新查询,最后才交给生成模型。
┌→ 关键词索引 ─┐
用户问题 → 查询路由器 ├→ 向量索引 ├→ 融合 → 重排 → 证据包
├→ 图索引 ┤
└→ SQL / API ─┘
这种设计有两个直接好处。
一是每个模块可以独立评测。召回率低时不用先怀疑生成模型;重排器更换后也能比较相同候选集上的变化。
二是不同问题可以走不同路径。查询订单状态应该调用业务 API,而不是在文档向量库里寻找一段描述;询问跨文档主题时,可以进入图检索或全局摘要;查错误码时,关键词检索往往比复杂 Agent 更可靠。
模块化 RAG 是后面各种高级路线的共同基础。GraphRAG 改变知识组织与检索方式,Corrective RAG 加入检索质量判断,Agentic RAG 则让路由和循环变得动态。
五、GraphRAG:当问题关心关系和全局结构
向量检索的基本单位是片段。它能判断哪些片段与查询相似,却不会天然建立“人物属于组织”“服务依赖数据库”“政策由哪些历史决策演变而来”这样的显式关系。
GraphRAG 把文档转换为实体和关系图,再在图上构建社区及社区报告。以微软开源实现的标准索引流程为例,它会从文本单元中抽取实体、关系和可选的声明,运行社区检测,并为不同层级的社区生成摘要。查询时主要有两种思路:
- Local Search 从某个实体出发,组合相邻实体、关系、原始文本和其他上下文,适合“某个对象与谁相关”“一次变更影响哪些组件”。
- Global Search 读取社区报告,以 map-reduce 方式汇总多个社区的局部回答,适合“整个语料中有哪些主要主题”“各类观点怎样分布”。
这解决了普通 Top K 检索很难处理的全局问题。一个主题可能分散在数十份文档中,没有任何单块文本与问题高度相似;社区摘要却能先在离线阶段把分散信息组织起来。
GraphRAG 的代价同样明确:
- 实体与关系抽取需要额外模型调用,索引成本明显增加。
- 实体消歧会影响整张图。“RAG”“检索增强生成”和某个内部简称可能被错误地当成三个实体。
- 图中的关系来自文本抽取,不等于经过验证的业务事实。
- 社区结构和报告需要维护,文档变化不再只是向量索引追加。
- 全局查询读取大量社区报告,延迟和 Token 消耗可能高于普通检索。
早期介绍经常把 GraphRAG 写成“完全不能增量更新”。这个说法已经不准确。当前官方 CLI 提供 update 命令和 update 类索引方法。不过,有更新入口不代表维护成本等同于向量库追加一个块。新增实体可能改变社区归属,下游摘要和报告也可能需要重新计算。工程上应该评估实际更新范围、删除一致性与报告刷新延迟。
所以,GraphRAG 适合关系密集、跨文档和全局归纳问题较多的知识库。FAQ、产品手册或答案集中在单个段落里的场景,先做好混合检索和重排往往更划算。
六、LightRAG:用双层检索连接局部实体与全局主题
LightRAG 也使用图结构,但它不是简单把 GraphRAG 的某些步骤删掉。它重新设计了索引和查询方式,希望同时保留细粒度实体关系与较高层主题语义,并降低更新成本。
在索引阶段,文档被切成块,模型从中抽取实体及关系,相关描述被合并。系统同时保存图结构和可用于检索的键值信息。新文档可以独立抽取后再与已有节点和边合并,不必每次从头重建完整索引。
查询时,LightRAG 从问题中提取两类关键词:
- 低层关键词 更接近具体实体、属性与关系,适合局部事实查询。
- 高层关键词 表达主题和概念,适合较抽象的整体问题。
检索模式可以只关注局部、只关注全局,也可以组合两者。相关实体、关系和原始文本共同组成生成上下文。它与纯向量检索最大的区别,是检索对象不再只有“相似片段”,还包括由实体关系连接起来的知识结构。
LightRAG 的优势也不能只看论文名称里的 “Light”。实际系统仍然需要处理实体抽取质量、同名实体合并、图存储、向量存储、文档删除和模型版本迁移。它的增量机制减少了全量重建压力,但错误实体也可能随着增量合并进入图中。
如果知识持续更新,又确实存在大量实体关系和多跳问题,LightRAG 值得验证。验证的重点不应只是最终答案,还要单独观察实体召回、关系路径、索引更新时间和删除后残留。
LightRAG 的公开实现提供四种常见查询模式:
| 模式 | 主要检索对象 | 适用问题 |
|---|---|---|
naive |
文本块 | 用作普通向量检索基线 |
local |
低层关键词对应的实体与关系 | 某个对象的属性、关联和局部事实 |
global |
高层关键词对应的关系与主题 | 较宽泛的主题和整体问题 |
hybrid |
低层与高层信息组合 | 同时需要具体实体和整体背景的问题 |
这些名称不能直接套用成 GraphRAG 的同名机制。GraphRAG 的 Global Search 建立在社区报告及其 map-reduce 汇总上;LightRAG 的 global 模式来自它自己的高层关键词和图检索设计。比较方案时,要看实际索引产物和查询路径,不能只对照模式名称。
增量更新还有一个容易被忽略的时序问题。假设旧文档写“服务使用方案 A”,新文档改成“服务已迁移到方案 B”。如果系统只把新实体和关系并入图,A 与 B 可能同时存在。查询时出现的不是简单重复,而是互相冲突的事实。生产系统至少要保存来源版本、valid_from / valid_to、删除记录和抽取模型版本,并在上下文编排阶段明确处理冲突。能追加数据,不等于已经解决知识更新。
七、Self-RAG 与 Corrective RAG:检索之后还要判断证据
固定 RAG 有两个隐含假设:每个问题都需要检索;检索回来的内容都值得使用。这两个假设都不成立。
Self-RAG:按需检索并反思输出
Self-RAG 的论文提出让模型通过特殊的反思标记学习何时检索,并对检索片段的相关性、回答的支撑程度和输出质量做判断。它关注的是模型如何在生成过程中自适应地使用检索,而不是简单固定取回若干段落。
严格来说,论文里的 Self-RAG 包含专门训练,不等于在 Prompt 末尾加一句“请反思”。工程实践中可以借鉴它的控制思想,但不要把普通的二次提示包装成同一种方法。
Corrective RAG:检索质量差时走修正分支
Corrective RAG(CRAG)在检索结果和生成之间加入评估器。评估器判断当前证据可信、模糊还是不可靠,再触发不同动作:直接使用,进一步精炼,或者转向外部搜索。原论文还使用分解再重组的方式,从文档中保留有用内容并过滤干扰信息。
一个简化的工程版本可以写成:
evidence = retrieve(query)
grade = retrieval_grader(query, evidence)
if grade == "sufficient":
context = compress(evidence)
elif grade == "ambiguous":
context = retrieve(rewrite(query))
else:
context = trusted_web_search(query)
return answer_with_citations(query, context)
真正难的部分是 retrieval_grader。如果它与生成模型有相同偏见,就可能给相关但无答案的片段打高分。生产环境需要用人工标注的失败样本校准阈值,并保留“证据仍不足”的终止状态。
Self-RAG 与 CRAG 都在处理一件常被忽略的事:检索是一种有风险的输入。错误资料放进上下文后,模型往往会因为它“看起来像证据”而更加确信。
八、Agentic RAG:让检索成为一个有状态的决策过程
Agentic RAG 没有唯一固定实现。它通常指让 Agent 的规划、工具调用、反思和状态管理进入 RAG 流程,使系统可以根据中间结果决定下一步,而不是从查询到回答只执行一次固定管线。
一个典型过程是:
理解任务
↓
判断是否需要外部知识
↓
拆分子问题并选择数据源
↓
执行检索 / SQL / API / 网页搜索
↓
检查证据覆盖与冲突
├─ 不足:改写查询、换工具或继续检索
└─ 足够:组织证据并生成回答
↓
验证引用与终止
它适合下面几类请求:
- 需要多跳证据,后一步查询依赖前一步结果;
- 数据分布在文档、数据库、代码仓库和外部网页中;
- 用户任务不只问答,还包括比较、调查、生成报告或执行操作;
- 系统需要根据证据质量动态重试或切换数据源;
- 不同子问题需要不同权限和工具。
例如用户问“为什么昨晚的任务失败,这个问题是否影响今天的数据”。系统要先查任务状态,再根据错误码检索手册,随后查询上游数据状态,最后判断影响范围。一次向量 Top K 很难覆盖这条链路,Agent 的工具路由和状态机更合适。
不过,Agentic RAG 的灵活性来自更多运行时决策,也意味着更多不确定性:
- 查询可能越拆越多,形成没有收益的检索循环;
- Agent 可能选错工具,或对一次失败不断重试;
- 多轮结果持续进入上下文,早期噪声会影响后续判断;
- 延迟与费用从固定值变成分布,尾延迟更难控制;
- 权限边界从“能读哪个索引”扩展为“能调用哪些工具并携带哪些数据”。
因此,Agentic RAG 不能只靠一个无限循环。至少需要显式状态和预算:
class RetrievalState(TypedDict):
question: str
plan: list[dict]
evidence: list[dict]
unresolved: list[str]
attempts: int
token_budget: int
tool_budget: int
def should_stop(state):
return (
evidence_complete(state)
or state["attempts"] >= 4
or state["tool_budget"] <= 0
)
停止条件、工具白名单、每个数据源的超时、证据去重和最大预算,都是 Agentic RAG 的核心能力。没有这些约束,它只是一个可以反复检索的 Prompt。
九、这些 RAG 不是一条升级路线
把常见方案放在一起比较,会发现它们优化的是不同维度。
| 路线 | 主要改变 | 更擅长的问题 | 主要代价 |
|---|---|---|---|
| 基础 RAG | 向量召回文本块 | 局部事实、单文档问答 | 措辞敏感,跨块能力弱 |
| 混合 RAG | 关键词、向量、过滤与重排 | 专有名词、错误码、通用知识问答 | 调参与融合更复杂 |
| 模块化 RAG | 可组合的路由与处理模块 | 多数据源、不同查询类型 | 需要明确接口和可观测性 |
| GraphRAG | 实体关系、社区及社区报告 | 全局主题、关系密集、跨文档归纳 | 索引和维护成本高 |
| LightRAG | 图与向量结合的双层检索 | 局部实体与全局主题、多跳问题 | 抽取和图一致性仍需治理 |
| Self-RAG | 按需检索与生成反思 | 需要自适应检索的生成任务 | 原方法涉及训练与反思控制 |
| Corrective RAG | 检索质量评估与修正分支 | 召回质量波动、需要外部补充 | 评估器本身可能误判 |
| Agentic RAG | 动态规划、工具路由和循环 | 多步骤、多工具、调查型任务 | 延迟、成本和行为更难预测 |
一个系统完全可以同时使用多种机制:Agent 负责把复杂问题拆开;明确事实走混合检索;跨文档关系走 LightRAG;全局归纳走 GraphRAG;检索后再由评估器检查证据是否足够。组合的前提是每个模块都有清晰收益,而不是把所有新名词装进一条链路。
十、一套更现实的生产架构
如果从零建设,我会优先采用“共享证据协议 + 多种检索器 + 受控编排”的结构。
1. 统一证据格式
无论结果来自向量库、图、SQL 还是 API,都转换为统一证据对象:
{
"content": "用于回答的内容",
"source_id": "doc-173",
"source_type": "document",
"uri": "/docs/refund-policy",
"version": "2026-09-18",
"retrieval_mode": "hybrid",
"score": 0.86,
"permissions": ["employee"],
"supports": ["退款时限", "例外条件"]
}
统一协议让融合、去重、引用和评测不再绑定某个数据库。图检索可以额外记录关系路径,SQL 可以记录查询与结果版本,但都必须回答“这条证据来自哪里”。
2. 用路由器选择最低成本的有效路径
路由不必一开始就由大模型完成。错误码、订单号和明确的数据查询可以用规则识别;只有复杂语义问题才调用规划模型。
明确事实 / 专有名词 → 混合检索
实体关系 / 多跳 → 图检索或 LightRAG
语料级主题 / 全局归纳 → GraphRAG Global Search
实时状态 / 精确数值 → SQL 或业务 API
开放世界且内部证据不足 → 可信网页搜索
复合调查任务 → Agentic 编排以上工具
“先用最便宜的方法”不是单纯节省费用。固定管线通常更容易测试,也更容易给出稳定延迟。只有问题确实需要动态规划时,才进入 Agent 循环。
3. 把证据覆盖写进终止条件
不要只用“模型觉得可以回答了”作为结束判断。规划阶段可以声明必需证据,运行时逐项填充:
{
"required_evidence": [
{"name": "当前规则", "status": "found"},
{"name": "历史变更原因", "status": "found"},
{"name": "影响范围", "status": "missing"}
]
}
预算耗尽但仍有关键项缺失时,系统应该输出部分结论和缺口,而不是把“未找到”自动补成一个听起来合理的答案。
4. 让权限跟随检索和生成
权限过滤应在召回阶段生效,不能先取回全部内容,再要求模型“不要泄露”。Agent 调用多个工具时,还要限制结果能否流入其他工具、日志和长期记忆。最终引用也要经过权限校验,避免正文可以显示,点击来源却越权,或反过来暴露隐藏文档标题。
5. 记录完整检索轨迹
线上日志至少要包含:原始问题、路由结果、改写查询、过滤条件、各路候选、重排结果、最终证据、工具耗时、模型版本、回答引用和终止原因。敏感内容需要脱敏或只保留标识,但不能只记录最后答案。
没有轨迹,用户点一个“踩”之后,团队仍然不知道是索引没更新、路由选错、重排漏掉证据,还是模型没有遵守证据。
十一、评测要把检索和生成拆开
RAG 最容易出现的评测误区,是只让另一个大模型给最终回答打一个总分。总分下降时无法定位问题,分数上升也可能只是回答更流畅。
检索评测
测试集应该标注回答需要哪些证据,而不仅是参考答案。常见指标包括:
- Recall@K:必要证据是否出现在前 K 个结果中;
- MRR / nDCG:有效证据是否排在更靠前的位置;
- Context Precision:提供给模型的上下文中有多少真正相关;
- 证据覆盖率:复合问题的各个子结论是否都有材料;
- 版本与权限正确率:是否命中有效且允许访问的来源。
图检索还要评估实体识别、关系路径和社区摘要是否丢失关键限定。Agentic RAG 则需要观察工具选择正确率、平均循环次数、无效调用率和预算耗尽率。
生成评测
生成阶段更关心:
- 结论是否正确;
- 每个事实是否得到证据支持;
- 引用是否真的支撑相邻结论;
- 是否遗漏关键条件和反例;
- 证据不足时能否正确拒答;
- 多个来源冲突时是否说明冲突,而不是静默选边。
LLM Judge 可以扩大评测规模,但不应独立决定质量。评审模型可能偏爱更长、更自信或措辞更接近参考答案的回答。需要用人工标注集校准,并定期抽查高分样本中的引用。
测试集要按失败模式组织
一套只包含“能在文档里直接找到答案”的测试集,无法评价高级 RAG。至少要覆盖:
- 单段事实问题;
- 专有名词和精确标识查询;
- 跨文档多跳问题;
- 时间、版本和权限约束;
- 全局主题与归纳问题;
- 多来源冲突;
- 知识库不存在答案;
- 需要 SQL、API 或外部搜索的任务。
每次线上失败都应该归类后进入回归集。评测集因此会逐渐贴近真实业务,而不是长期停留在上线前准备的几十道理想问题上。
十二、怎样选择:从失败样本开始,而不是从框架开始
如果当前系统还是一个基础向量检索,我会按下面的顺序推进。
第一步:把朴素 RAG 做扎实
整理文档版本与权限,改进结构化切块,加入关键词和向量混合召回,再用重排器控制最终上下文。建立带证据标注的测试集,同时记录线上检索轨迹。
很多“需要 GraphRAG”的问题,到这里已经能解决一大半。原因并不神秘:原系统可能连精确词项、有效版本和标题层级都没有正确使用。
第二步:针对明确故障增加模块
- 查询表述不稳定:增加改写、多查询或 HyDE。
- 长文上下文破碎:使用父子块、章节摘要或层次检索。
- 检索结果质量波动:加入证据评分和 Corrective 分支。
- 多数据源问题:增加查询路由和统一证据协议。
- 多跳问题:先尝试问题分解,再评估图结构是否带来稳定收益。
第三步:小范围验证图检索
选一个关系密集、答案确实跨文档的子语料,对比混合 RAG、GraphRAG 和 LightRAG。除了答案质量,还要记录索引费用、更新时间、删除一致性、查询延迟和人工维护量。
图检索如果只在演示问题上更好,却让日常文档更新变成昂贵批任务,它就还没有成为生产方案。
第四步:只给复杂任务启用 Agentic RAG
先定义工具边界、状态、预算和停止条件,再让 Agent 动态规划。简单问答继续走固定管线。复杂任务可以逐步开放更多工具,并通过回放确认 Agent 为什么选择某条路径。
Agentic RAG 的成熟度不体现在循环次数,而体现在它能否用有限步骤拿到足够证据,并在无法完成时清楚地停下来。
十三、我对这套体系的理解
RAG 为一次回答提供可获取、可验证、可更新的依据,重点已经从模型的参数记忆转向外部证据。不同技术路线可以归到三个问题:
- 知识怎样被保存:文本块、关键词索引、向量、实体关系、社区摘要或结构化表。
- 证据怎样被找到:相似度、关键词、过滤、重排、图遍历、全局归纳或工具调用。
- 流程怎样被控制:固定管线、质量修正、自反思,或带预算和状态的 Agent。
GraphRAG 和 LightRAG 主要改变前两个问题,Agentic RAG 主要改变第三个问题。它们可以组合,却不互相替代。图里没有正确的数据,Agent 再聪明也只能规划出一条通向错误证据的路线;检索已经稳定的问题,增加自主循环反而会扩大成本和方差。
最值得优先建设的能力仍然很朴素:可信的数据、清晰的版本、可追溯的证据、分层的评测和能够复盘的运行轨迹。有了这些底座,新的检索方法可以被准确比较;没有这些底座,系统只能靠几个成功案例判断“好像变聪明了”。
参考资料
- Lewis 等,Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Edge 等,From Local to Global: A Graph RAG Approach to Query-Focused Summarization
- Microsoft,GraphRAG 官方文档
- Guo 等,LightRAG: Simple and Fast Retrieval-Augmented Generation
- Asai 等,Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection
- Yan 等,Corrective Retrieval Augmented Generation
- Singh 等,Agentic Retrieval-Augmented Generation: A Survey on Agentic RAG
- 小林面试笔记,RAG 原理、切块、Embedding、向量数据库与重排
- 小林面试笔记,GraphRAG 与 LightRAG 原理及区别
如果这篇文章对你有帮助