你肯定知道,Agent 的能力在过去两年变得越来越强。但你可能不知道,有一个 Agent 极为依赖的东西,它的能力却几乎没怎么变过:RAG 检索的准确率。
举个例子,在 MuSiQue(一个需要最多 4 跳推理的多跳问答基准测试)上,目前最强的结构化检索方案 HippoRAG 2,它的 Recall@2 只有 49.5%。
这是什么概念呢?你让 Agent 去查一个需要跨文档推理的问题,在它返回的前 2 条结果里,有一半以上的答案根本不在里面。就好比你派了个实习生去档案室查资料,他翻半天弄回来两份文件后你一看,居然全是别的案子……
而 Agent 在发现查不到后,就会多查几轮,然后每一轮的误差就开始不断叠加。当它查到了五轮之后,可能已经偏到十万八千里去了。
检索不准,Agent 再聪明也白搭。

那,怎么办呢?便是今天要介绍的:来自 Zleap AI 团队的 SAG(SQL-Retrieval Augmented Generation)。它把 MuSiQue 上的 Recall@2 从 49.5% 暴力拉升到了 64.1%,Recall@5 则直接干到了 80.04%。
| 平均 Recall@2 |
领先 HippoRAG 2 |
生产数据规模 |
| 79.3% |
+11.1 pp |
5亿+ |
在三个多跳基准测试上的平均 Recall@2 为 79.3%,领先了 HippoRAG 2 11.1 个百分点。
并且,这并不只是停留在论文里的模拟数字,SAG 已经在 5 亿级 数据规模的生产环境中稳定运行。论文、Benchmark 复现代码、在线 Demo 均已公开。
只会看脸
传统向量 RAG 的逻辑简单好理解:把每段文本变成一个向量,当问题来了,就找几段最「像」的文本。它优势是:快、便宜、好部署。在许多简单问答的场景下,确实是够用的。但它有个根本性的短板:向量搜索只知道「像不像」,不知道「谁跟谁有关系」。
举个例子,你问:「A 公司收购了 B 公司,B 公司的 CTO 后来加入了 C 项目,C 项目影响了哪个产品路线?」这个问题答案散落在三篇完全不同的文档里。单独拿出任意一篇,和你的问题都不太「像」。只有连起来,才是完整答案。
向量 RAG 稳定找到这条链的概率,可以说是……相当之低。因为,它只会「看脸」,不会「顺藤摸瓜」。

GraphRAG 看到了这个问题,它的思路是:先从文本里把实体和关系抽出来,建一张知识图谱,沿着图谱做多跳检索。方向应该是对了。但……
图谱太重
GraphRAG 会把文本拆成三元组:「OpenAI → 发布 → GPT-5」「GPT-5 → 属于 → LLM」「发布 → 时间 → 2025年」。它的每一步都要靠 LLM 来抽取实体、归一化名称、合并重复、发现社区、最后生成摘要。跑一遍,又慢又贵。
而麻烦的在后面:这个世界并不是一成不变的。新的实体、新的关系会不断出现,旧关系也可能过时。如何有效更新,也是个问题。
打江山不易,守江山更难……

HippoRAG 2 是目前结构化 RAG 里公认的强基线,它证明了 RAG 必须结合结构化记忆和多跳检索,大方向没错。但 HippoRAG 2 依赖全局 Personalized PageRank 来做图排序,这在 benchmark 规模下还行,一旦数据量上来并且每天增量增长,全局 PageRank 的负担就会相当大。
打个比方,你每次往图书馆加一本新书,就得把整个图书馆的书重新排列一遍。实践中,Agent 的数据底座必须支持持续写入、持续更新。每来一批新数据就要全局重建?这显然也不行。
索引卡片
于是,SAG 换了个思路。不建图谱,不做三元组,不搞全局图。它给每个文本 chunk 加了一张「索引卡」:
一个 chunk 对应一个 event(事项摘要),同时从原始 chunk 里抽取出多个 entity(实体)。实体类型涵盖人物、组织、地点、时间、产品、话题等 11 种标签。

event 保留完整语义,entity 负责索引和连接。

两者通过 SQL 的关联查询建立多对多连接,共同定义了一条潜在的超边。这和三元组路线有着本质区别:
- 三元组:头 → 关系 → 尾,拆碎,质量依赖每条关系
- SAG 超边:event ⟷ entities,完整事项 + 多实体桥接
三元组把一件完整的事拆得支离破碎。拆碎之后,质量高度依赖每条「关系」抽得准不准。同一件事,不同模型可能抽出「使用」「基于」「提出」「支持」四个不同谓词。到了真实数据里,这种差异会被迅速放大。但 SAG 只让 LLM 做两件相对稳定的事:把一个 chunk 总结成一个完整的事项,同时从原始 chunk 里应提尽提地抽取实体。事项保留上下文,实体负责桥接。
在图结构上,这更像超图中的超边:一个 event 同时连接多个 entity。不像两点之间的一条线,更像一件事把所有相关的人、地点、组织、时间全部串在一起。
比三元组更轻,效果反而更好。
原因在于 RAG 到最后还是要回到原文证据。三元组太碎,容易丢上下文。而 SAG 的 event 则保留了上下文,同时提供了可检索、可扩展的结构。我翻了它的代码,发现一个细节:SAG 在抽取 event 时,会强制做代词消歧。子事项必须把所有「他」、「该公司」、「这个产品」替换成完整名称。从而每个 event 就是一段独立可搜的完整描述,不依赖上下文就能被理解。
SAG 给原始数据加了一层更轻、更鲁棒的语义索引。
跟着线索跳
SAG 分两步:离线写入,在线检索。
离线阶段,系统把文档切成 chunk,每个 chunk 提取一个 event 和多个 entity,写进 MySQL,同时写入 Elasticsearch 的向量索引和全文索引。这里有一个细节:每条 event-entity 关系自身也带有一段描述文本,还有自己的 embedding 向量。同一个实体「OpenAI」在不同 event 里的角色描述可能完全不同,「OpenAI,发布 GPT-5 的公司」和「OpenAI,Sam Altman 创立的公司」在向量空间里是不同的点。这也让实体的召回变得更加精准。

在线检索是重点。问题进来后,LLM 先从问题里识别出关键实体。然后走两条路并行:
- 路径 A:结构化召回 — 用识别出的实体去向量索引里找相近的实体,再通过 SQL 的 JOIN 查出这些实体关联了哪些 event,找到对应的 chunk。
- 路径 B:语义召回 — 同时直接用问题向量去做相似度检索,找到语义接近的 event。
- 合并 + 查询时扩展 — 从已找到的 event 出发,通过 SQL 反向查出关联的 entity,再用这些 entity 去找新的 event。每一轮只引入之前没出现过的新内容。
- 映射回原文 — 把筛选出的 event 映射回原始 chunk,回答基于原文证据。

为什么要两条路?路径 A 通过实体关联覆盖结构化的多跳线索,路径 B 通过语义匹配覆盖直接相关的事项。两者在证据召回上高度互补。论文的消融实验印证了这一点:纯语义路径的 Recall@5 只有 56.2%,而加入少量结构化路径的事项候选后,直接飙到了 80.0%。

这就是多跳。实现方式上,用的只是 SQL 里的关系扩展,不需要全局 PageRank,不需要让 LLM 临时推理一张图。就是数据库里的 JOIN,而已。

SAG 提供了两个使用模式:快速模式 省掉 LLM 精排,便于追求速度;高精度模式 加一步 LLM 重排序,更追求准确率。两者都基于 event/entity 索引和多跳检索,核心架构一致。
新 SOTA
那么,SAG 的效果怎么样呢?

在 HotpotQA、2WikiMultiHop、MuSiQue 三个多跳基准测试上,同样的 embedding 模型(BGE-Large-EN-v1.5)和 LLM(Qwen3.6-Flash)配置下:
| 指标 |
SAG |
HippoRAG 2 |
提升幅度 |
| Recall@2 |
79.3% |
68.2% |
+11.1 pp |
| Recall@5 |
88.2% |
83.3% |
+5.9 pp |
| MuSiQue R@2 |
64.1% |
49.5% |
+14.6 pp |
| MuSiQue R@5 |
80.0% |
65.1% |
+14.9 pp |
差距最大在 MuSiQue,Recall@2 领先近 15 个百分点。相当于每 3 次查询,SAG 就能比 HippoRAG 2 多命中 1 次关键证据。

你可能会问:为什么 Recall@2 比 Recall@10 更重要?这很好理解——Agent 显然不希望每次拿回一大堆上下文再自己挑,那 context 几下就干满了。Agent 需要的是在更少的返回结果里更早拿到关键内容,否则 LLM 要读更多内容,成本高、延迟高、干扰也多。
在三个数据集里最难的 MuSiQue,包含最多 4 跳推理,且每条推理链都不可跳过,跳过就会失败。SAG 在这上面的优势最为突出,也得益于 event/entity 索引在复杂关联问题里发挥的作用。
论文里还有一组关键的消融实验:超边 vs 三元组。
| 方案 |
MuSiQue Recall@5 |
| 三元组 |
77.16% |
| SAG 超边 |
80.04% |
更简单的结构,反而效果更好。原因在于三元组只保留了部分语义,向量检索容易匹配到与查询关键词重合但实际上无关的片段。而完整事项将多个实体压缩在一条超边内,多跳扩展时等效连接更密,每一步累积的误差也更小。
还有一组对比:HippoRAG 2 原论文使用更强的 NV-Embed-v2,在 MuSiQue 上 Recall@5 达到 74.6%;但当换成 BGE-Large-EN-v1.5 后,直接掉到了 65.1%,损失近 10 个百分点。而 SAG 在同样的 BGE 下跑出 80.0%,换成 NV-Embed-v2 后升到 81.7%,几乎不受影响。这不难看出:HippoRAG 2 的高分很大程度上依赖更强的嵌入模型,而 SAG 的增益,主要来自算法结构本身。
SAG 对底层模型的选择,要鲁棒得多。
五亿条也能跑
我们知道,学术 benchmark 上好看是一回事,能不能在生产环境里跑起来,又是另一回事了。SAG 有几个天然适合规模化的特点:
- chunk 天然并发:每个 chunk 的 event/entity 提取可以独立运行。写入侧可以大批量并发处理,不需要串行慢慢建图。
- 实体查重靠 SQL:没有复杂的 entity resolution。入库前做简单字符串归一 + SQL 查重,同名同类型的实体直接复用。
- 关系都是局部的:新数据进来,切 chunk,抽 event 和 entity,写入 SQL。不需要重建全局图。
简单到听起来有些草率,但这也正是 SAG 的鲁棒性:即使只靠简单的字符串校验,超边结构也已经能跑出 SOTA 的效果。毕竟 entity 在 SAG 里本质上就是索引点,真正保留语义的是 event。

这更像数据库的增量写入,跟图谱的全局重建完全是两种思路。Zleap AI 团队已经在实际生产中积累了 5 亿级 的数据量,而且还在持续增长。在这个规模下,SAG 仍然稳定运行,在线检索延迟保持在秒级以内。
为了让大家直观体验,团队还做了一个 Wikipedia 的 SAG Demo:https://wiki.zleap.com。把 Wikipedia 的数据放进 SAG,你可以直接测试多跳检索效果。

Demo 支持快速模式和高精度模式,输入一个多跳问题,SAG 会实时构建局部超边图谱,从维基百科中找出跨文档的关联证据。


Agent 最佳底座
可以说,SAG 是面向 Agent(目前)的最佳数据底座。我们知道,Agent 和普通问答系统不同,普通问答系统检索一次答一次,而 Agent 往往要连续查很多次,先查一个线索,再根据线索查下一个,再根据新结果决定下一步。检索准确率在这个场景下,就不只是体验问题,它会直接关系到整条任务链路的稳定性。

如果第一次查错了,后面的推理就建立在错误材料上;而如果第一次没查到,Agent 就可能会换一个错误方向继续查。在复杂任务里,这种错误会不断叠加、放大,然后失败。
更准检索的价值在于:用更少的查询次数找到正确内容,在必须多次查询时降低每一步错误叠加的概率。

同时,Agent 的记忆能力是 SAG 天然适合的另一个场景。Agent 的记忆并不是由孤立文本组成,同一个用户、项目、偏好,可能在不同时间反复出现。且新的记忆可能补充、修正,甚至推翻旧的记忆。纯向量记忆更像是在找相似文本,但 Agent 其实需要知道的是:哪些是历史背景,哪些是当前状态。
SAG 的结构对这个问题同样非常合适:event 保留完整事项,entity 把同一个人、项目、任务连接起来,再在 SQL 里加上时间和关联 id,就能区分出新旧状态。用 SAG 来做记忆,是因为它本身就在给数据建立「事项 + 实体 + 时间 + 关系」的索引。
这才是 Agent 可以长期使用的数据结构。
RAG 要解决的核心问题,在于数据进入 Agent 系统时应该被组织成什么样子。SAG 给出的答案是:用 event/entity 给原始数据加一层轻量索引,用 SQL 做多跳检索,让数据可以增量写入、并发处理、持续增长。
从文本召回,走向结构化数据底座。
如果你对这类技术方案感兴趣,欢迎在 云栈社区 与更多开发者交流。
相关链接
论文:https://arxiv.org/abs/2606.15971
GitHub:https://github.com/Zleap-AI/SAG-Benchmark
在线 Demo:https://wiki.zleap.com