RAG 这个领域过去两年的主流方向是”补结构”。GraphRAG、HyperGraphRAG 都在解决一个问题——纯向量检索没法处理多跳推理,得给文档之间补上关系图。代价是要预先把整张知识图谱建好,存进图数据库,增量更新麻烦,运维成本不低。
最近一个叫 SAG 的项目想换条路:不预建图,查询的时候用 SQL join 现凑。代码是 TypeScript 全栈,数据层就一个 PostgreSQL,连图数据库都不要。论文 arXiv:2606.15971 是五天前刚挂出的预印本,GitHub 仓库 Zleap-AI/SAG 这个时间点 1273 颗星。
我把论文、主仓库、benchmark 仓库都读了一遍,再去对了一下相关 prior art。结论是这个项目的工程取舍很有 taste,但论文层面的”打破不可能三角”是营销话术。要拿去用,得先把几个细账算清楚。
SAG 的数据模型:一个 Event,N 个 Entity
SAG 把每个文档 chunk 拆成两份并行的结构化输出:
- 1 个 Event:这段文字描述的”事情”,保留完整语义
- N 个 Entity:这段文字里出现的实体,分 11 个固定类型——
time / location / person / organization / group / topic / work / product / action / metric / label
注意是”并行”,不是”先抽 Event 再抽 Entity”的流水线。一次 LLM 调用同时吐出两份结构化产物,分别写进 SQL 关系表、pgvector 向量索引、PG 原生 tsvector 全文索引。
11 类 entity 是 close set。GraphRAG 那一派的常见做法是让 LLM 自由抽实体,结果 entity 表里充满”the company””this approach””a new method”这种垃圾。SAG 强制必须归到 11 类之一,否则丢弃。Ontology 上的克制比”开放”有 taste 得多——尤其在 RAG 这种场景,召回准比召回多重要。
数据层是单个 PostgreSQL 16,跑在 pgvector/pgvector:pg16 镜像里。我先确认一下,因为社区里有传言说 SAG 要 MySQL + Elasticsearch——查源码不是这样。docker-compose.yml 里只有一个 sag_lite_postgres 容器,migration 文件 005_enforce_embedding_dimensions.sql 管 pgvector 维度约束,006_entities_text_search.sql 管 tsvector 全文索引。一个库三个引擎,部署成本就一个 docker compose up。
检索流程:反向 SQL join + 1 跳
查询时分两步。
Seed 召回。LLM 从 query 抽实体作种子,同时向量召回 events(相似度阈值 τ=0.4)。这两路结果合并成 seed event 集合。
反向 join 扩展。从 seed events 出发,join 到关联 entities 拿到”实体前沿”,再从前沿实体反查到新的 events。默认多跳深度 H=1,扩展一次就停。
论文用自然语言描述这个过程,没贴 SQL 模板。按我对它 schema 的还原,核心扩展 SQL 大概长这样:
-- 从 seed events 出发,找共享至少一个 entity 的 events
SELECT DISTINCT e.event_id
FROM events e
JOIN event_entity ee ON e.event_id = ee.event_id
WHERE ee.entity_id IN (
SELECT entity_id FROM event_entity
WHERE event_id = ANY($seed_event_ids)
)
AND e.event_id != ALL($seed_event_ids);
这就是论文里说的”动态局部超边”——一个 entity 联通的所有 events 就是一条 hyperedge,但它不预先存在表里,是查询时 join 出来的。
H=1 是个很务实的选择。多跳推理理论上能无限扩,但每多一跳,召回 entity 集合就爆炸式增长,长尾高频实体(比如”中国””Apple”)会牵出大量无关 events。Paper 没明说为什么默认 1 跳,我猜是实测下来 H=2 的召回提升不抵延迟和噪声的恶化。
自报 benchmark:数字漂亮,但要看怎么读
SAG 在论文 Table 2 里贴了一组 Recall@K 对比,对手是 HippoRAG 2。Recall@K 指的是”检索回来的前 K 个 chunk 里包含 ground-truth 支撑文档的比例”——多跳 QA 评测的标准指标,越高越好,60% 算能用,80% 算很强。
| 数据集 | 指标 | HippoRAG 2 | SAG | Δ |
|---|---|---|---|---|
| HotpotQA | R@2 | 78.35% | 91.55% | +13.20 |
| MuSiQue | R@2 | 49.5% | 64.1% | +14.6 |
| MuSiQue | R@5 | 65.13% | 80.04% | +14.91 |
| 2WikiMultiHop | R@5 | 90.4% | 88.0% | -2.4 |
| 9 项平均 | R@2 | 68.14% | 79.30% | +11.16 |
测试 setup 是 bge-large-en-v1.5 做 embedding,Qwen3.6-Flash 做 LLM。
数字本身不难看。MuSiQue 上 +14.6pp 意味着原本 100 个 query 召不回的有 50 个,现在只有 36 个——对下游 QA 准确率的传导效应是真实的。问题是几个细节得知道:
数字全是 SAG 作者自报,paper 5 天前刚挂出,没有第三方复现。
Qwen3.6-Flash 是 2026-04-27 才发布的新模型,社区里根本没有同 config 的 baseline,没法横向对照。换个 LLM 跑出来可能完全是另一个结果。
“9 项里 8 项最优”听起来很猛,但 2WikiMultiHop Recall@5 实际是输的——88.0 vs 90.4。营销话术把这个数据点抹了。
平均涨 11.16pp 主要靠 MuSiQue 一个数据集贡献(+14.6pp),剔除掉看,2Wiki 上的优势很薄。
读 retrieval 指标要警惕的是它和下游 QA 准确率不是 1:1 传导——召回多了,进 LLM context 的噪声也多了。SAG 没有给 QA EM/F1 的对比,只给了 retrieval recall。
真问题:这套思路不新
SAG 论文的核心 positioning 是”无需预建全局图谱,查询时动态构建结构”。这句话单独看没问题。问题是别人比它早 6 到 12 个月提了一样的东西。
| 工作 | arXiv | 提交时间 | 与 SAG 的重叠 |
|---|---|---|---|
| E²RAG | 2506.05939 | 2025-06 | Entity-Event 双子图,Alibaba + NUS |
| DyG-RAG | 2507.13396 | 2025-07 | 事件中心的查询时动态图,Beihang + Philip S. Yu,有代码 |
| LogicRAG | 2508.06105 | 2025-08(AAAI’26) | 论文标题直接叫 You Don’t Need Pre-built Graphs for RAG |
| SAG | 2606.15971 | 2026-06 | 查询时 SQL join 反向扩展 |
LogicRAG 的标题我特地贴原文,因为它一句话占了”不需要预建图”这条 positioning。SAG 比它晚十个月。
SAG 真正的工程增量收窄到三件事:用 SQL 当底座(不是图数据库)、11 类固定 entity 的 ontology、H=1 的默认上限。这都是好工程,但不是新范式。
时间线有点意思
我顺手查了三个东西的创建时间。
主仓库 Zleap-AI/SAG:2025-11-07 创建,第一次 commit 2025-11-17(v0.1.0)。
benchmark 仓库 Zleap-AI/SAG-Benchmark:2026-05-28 创建。
paper arXiv:2606.15971:2026-06-14 提交。
主仓库比 paper 早七个月,benchmark 仓库比 paper 早 17 天。这是典型的”产品先行,论文后补”节奏——东西已经上线、有用户、有 star,paper 是为产品背书用的,不是反过来。这本身不算原罪,但读 paper 的时候得知道这个语境,别把它当成科学突破。
补一句,arXiv 编号 2606.15971 是合法格式(YYMM.NNNNN,2026 年 6 月 = 2606),不是伪造。但只有 v1,没同行评审,DOI 标 “pending registration”。
没被写进 paper 的索引成本
SAG 的索引阶段每个 chunk 调一次 LLM,吐 Event + 11 类 Entity 的合并 JSON。查询阶段每个 query 再调一次 LLM 抽实体。HippoRAG 2 走的是纯向量召回,索引时只要 embedding,没有 LLM 调用。
Paper 没有给索引成本对比,也没有 cost / latency benchmark。”亿级数据秒级检索”是 README 上的话,正文里没有支撑数据。
按 Qwen3.6-Flash 当前价格粗算,一亿 chunk 的索引 LLM 调用成本和纯向量索引能差一到两个数量级。这不是说 SAG 错了,是说要拿它做生产决策,得自己跑一遍小规模成本测试,别只看 Recall 数字做决定。
工程上做对的几件事
批判完了,得说说 SAG 真的值得参考的地方。
单库三合一。关系表、向量索引、全文索引都进同一个 PostgreSQL 16。对小团队来说这一点比 Recall 高几个点重要得多——不用学 Milvus,不用维护 Elasticsearch,不用部署 Neo4j。生产环境少一个组件,意味着少一组监控、少一份 backup 策略、少一次跨服务故障排查。
SQL join 当 hyperedge expansion。图数据库的优势在多跳遍历,但代价是另一套数据栈。SAG 用 entity 作 bridge,反向 join 一次就能拿到”和 seed event 共享至少一个 entity 的所有 events”——这就是个超边,只是不存在表里。一跳够用的话,PG 完全扛得住。
Close-set ontology。前面提过一次值得再强调。11 类 entity 是个可被复用的资产——你完全可以拿 SAG 的 schema 去配自己的 RAG 系统,哪怕不用它的代码。比从零设计 ontology 省一周的来回。
什么时候用 SAG,什么时候别用
适合:
– 团队规模小,不想维护图数据库
– 文档量在百万到千万 chunk 级别,需要多跳但不深
– 已经在用 PostgreSQL,想复用现有运维能力
– 业务实体能落到 11 类里(新闻、金融报告、企业知识库这类公司/产品/事件/人物为主的领域)
别用:
– 文档量上亿,每个 chunk 一次 LLM 调用的索引成本扛不住
– 需要深度多跳(3 跳以上),SQL join 在长尾高频 entity 上会爆炸
– entity 类型超出 11 类太多(医疗、法律、化学这类专业领域,强行套会丢信息)
– 对召回延迟敏感(query 时还要等一次 LLM 抽实体)
我会怎么做
如果团队里有人问”要不要上 SAG”,我会建议先做两件事。
把自己最难的 50 条多跳 query 拿出来,分别跑 HippoRAG 2 和 SAG,自己测 Recall 和下游 QA 准确率。别信 paper 上的数字,那是别人在别人的数据上跑出来的。Retrieval recall 高不等于业务效果好。
估算索引成本。总 chunk 数 × Qwen3.6-Flash 单次调用价格 × 1.2(query 时的实体抽取),看预算扛不扛得住。再算一遍如果未来文档量翻 10 倍,这个数字会变成什么样。
paper 自己说不能信、benchmark 自己跑、成本自己算。这套流程跑完发现 SAG 真合适,那它就是合适的。论文是不是新范式不重要,工具能不能解决你的问题才重要。
参考资料:
- Paper:arXiv:2606.15971
- 主仓库:github.com/Zleap-AI/SAG
- Benchmark 仓库:github.com/Zleap-AI/SAG-Benchmark
- Prior art:DyG-RAG / LogicRAG / E²RAG
作者:toy










AI周刊:大模型、智能体与产业动态追踪
程序员数学扫盲课
冲浪推荐:AI工具与技术精选导航