news 2026/7/7 2:09:15

每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索

引言

“图谱 RAG 的标准做法是离线构建全局图谱,然后用 PageRank 做查询时的评分扩展——但 PageRank 有衰减,链条越长分数越低。SAG 转而用 SQL JOIN 在查询时动态扩展,没有衰减,也不需要提前构建全局图谱。”

这是"每日一个开源项目"系列的第152篇文章。今天的主角是SAG(Structured Agentic Graph)——Zleap-AI 开源的新一代多跳 RAG 框架,有 arXiv 论文(2606.15971)背书。

多跳检索的核心难题:问题的答案需要把来自多个不同文档段落的信息串联起来。标准向量检索找到语义最相近的 chunk,但"语义最相近"不等于"能回答需要多步推理的问题"。GraphRAG 和 HippoRAG 用知识图谱解决这个问题,但有两个代价:离线构建全局图谱成本高,PageRank 评分在长链条下存在衰减。

SAG 换了一条路:不提前构建全局图谱,在查询时用 SQL JOIN 做图结构扩展。每个 chunk 提取一个"事件"(语义摘要)和若干实体,事件和实体之间的关联关系通过关系型数据库的外键表达,多跳扩展就是 JOIN 操作,确定性强,没有衰减。

你将学到什么

  • SAG 的核心数据模型:chunk → event + entities 的设计逻辑
  • 查询时三步流程:种子检索 → SQL 扩展 → 双路径最终选择
  • 为什么 SQL JOIN 比 PageRank 在长链多跳上表现更好
  • 与 HippoRAG 2、GraphRAG 的对比:优势在哪里,短板在哪里
  • MCP 集成:把 SAG 项目暴露为 Agent 可调用的工具
  • 全栈实现:TypeScript + PostgreSQL + pgvector + React

前置知识

  • 了解 RAG 和多跳检索的基本概念
  • 了解知识图谱(节点、边、多跳推理)的基本概念
  • 了解 SQL JOIN 的概念

项目背景

项目简介

SAG(Structured Agentic Graph)是一个文档检索系统,用事件-实体图结构做知识组织,通过 SQL JOIN 实现多跳检索,专为 Agent 工作流设计。

"Structured"指的是把非结构化文档转化成事件+实体的结构化表示;"Agentic"指的是每个 SAG 项目都内置 MCP 服务器,可以作为 Agent 的工具端点使用;"Graph"指的是通过 SQL JOIN 实现的查询时图遍历。

作者/团队介绍

  • 团队: Zleap-AI
  • 官网: zleap.com
  • arXiv: 2606.15971
  • License: MIT
  • 基准测试仓库: Zleap-AI/SAG-Benchmark

项目数据

  • ⭐ GitHub Stars:1,900+
  • 🍴 Forks: 87+
  • 📄 License: MIT

核心设计:chunk → event + entities

SAG 的基础数据模型只有三种元素:

一个文档 chunk ↓ 一个 Event(语义事件) ↑↕↓ 多个 Entities(实体)

Event(事件):对这个 chunk 的语义摘要。每个 chunk 对应恰好一个 event,event 保留了完整的语义。

Entity(实体):从 chunk 里提取的命名实体,作为图遍历的锚点。11 种类型:时间、地点、人物、组织、群体、话题、作品、产品、动作、度量指标、标签。实体本身不携带独立语义,只是"连接不同事件的索引和扩展点"。

隐式超边:一个 event 加上它所有的 entities,构成一条隐式超边。这与 HyperGraphRAG 的思路类似,但 SAG 不显式构建超图,而是通过关系型数据库的外键关联来实现等效效果。

为什么不用三元组(Triple)而用 Event? 三元组方式: chunk → (Alice, works_at, Google) (Alice, attended, Meeting_001) (Bob, attended, Meeting_001) 关系被分解,重建完整上下文需要多跳 Event 方式: chunk → Event: "Alice 和 Bob 在 Meeting_001 上讨论了产品路线图" Entity: Alice, Bob, Meeting_001 完整语义保留在 event,entity 作为连接点

论文的消融实验证实:在 MuSiQue 上,超边(event)方案 Recall@5 = 80.0%,三元组方案 = 77.1%。


两阶段架构

离线阶段(文档摄取)

文档 (Markdown / TXT) ↓ 文本分块(chunking) ↓ LLM 提取(并行,可配置并发数): 每个 chunk → 1 个 event + N 个 entities ↓ 写入两个后端(同步): PostgreSQL → 结构化存储(事件表、实体表、关联表) pgvector → 向量索引(事件向量、实体向量) 全文搜索索引 → BM25 实体匹配

关键特性:只有追加写入,没有全局图谱的重建。新文档的摄取不影响已有数据,不需要重新跑 PageRank 或重建图结构。

在线阶段(三步检索)

Step 1:种子检索(双路径并行)

Path A:实体引导的结构化召回 1. LLM 从查询里提取实体 → 种子实体集 U_q 2. 向量相似度搜索实体索引(阈值 0.9)→ 扩展实体集 Û_q 3. SQL JOIN:找到所有包含这些实体的事件 ℰR_entity = {e | ∃u ∈ Û_q : SQL-Join(e, u)} Path B:直接事件召回 查询向量 → 事件向量相似度搜索(阈值 0.4) 合并:ℰR = ℰR_entity ∪ ℰR_direct

Step 2:查询时扩展(SQL 多跳)

这是 SAG 的核心机制:

从种子事件集 ℰR 出发: ↓ 反向 JOIN:取出种子事件关联的所有实体(实体前沿) ↓ 正向 JOIN:找到所有包含这些实体的新事件(跨文档扩展) ↓ 重复 H 跳(默认 H=1) 结果:ℰ_cand = ℰR ∪ ℰE

这就是"多跳"的实现方式。如果文档 A 提到了实体 X,文档 B 也提到了实体 X,那么从文档 A 的事件出发,一次 JOIN 就能找到文档 B 里的相关事件——即使这两个文档在向量空间里相距很远。

Step 3:最终选择(双路径融合)

候选集 ℰ_cand(100 个候选事件) ↓ 结构路径:LLM 对候选链条重排序 → 取 top 5 事件 → 映射到 chunks 语义路径:查询向量直接检索 chunk → 取 top 5 ↓ 合并去重 → 最终 10 个 chunks

SQL JOIN vs. PageRank:为什么 SAG 在长链多跳上更好

HippoRAG 2 的做法:离线构建全局知识图谱,查询时用 Personalized PageRank(PPR)从种子节点出发,分数沿图边传播。

问题出在 PPR 的阻尼因子(damping factor):每经过一跳,分数乘以(1-d)(d 通常是 0.85),也就是保留 15% 的概率。经过 2 跳,节点得分乘以 0.15²=0.0225;3 跳后几乎清零。

HippoRAG 2 长链多跳的问题: 答案需要路径:A → B → C → D → E(4跳) 经过 PPR:E 的得分 ≈ seed分数 × 0.15⁴ ≈ 0.0005 × seed分数 远端节点分数太低,竞争不过直接相关的近端节点

SAG 的 SQL JOIN 不传播分数,只传播可达性:实体 X 关联的所有事件,JOIN 结果里一视同仁,不论它们在图谱上距离种子有多远。

MuSiQue 是这个差异的集中体现:MuSiQue 专门设计了需要 4 步推理链的多跳问题,HippoRAG 2 在这个数据集上明显弱于 SAG(65.1% vs 80.0%)。

SAG 的短板在 2WikiMultiHop:SAG 有一个固定的实体前沿裁剪预算(50 个),低频的桥接实体在裁剪时可能被截掉,导致它在 2WikiMultiHop 上略低于 HippoRAG 2(88.0% vs 90.4%)。


基准测试结果

使用bge-large-en-v1.5嵌入模型,qwen3.6-flash作为 LLM:

Recall@5 对比

数据集SAGHippoRAG 2差距
MuSiQue80.0%65.1%+14.9pp
HotpotQA96.5%94.4%+2.1pp
2WikiMultiHop88.0%90.4%-2.4pp
平均 Recall@279.30%68.14%+11.16pp

换用更强的NV-Embed-v2嵌入,MuSiQue Recall@5 达到81.71%,说明提升来自结构设计本身,不只是嵌入质量。

消融实验

配置MuSiQue R@5
完整 SAG80.0%
去掉多跳扩展(H=0)69.4%
去掉结构路径56.2%
用轻量重排序器替换 LLM 重排序62.2%

结论:多跳扩展贡献了约 10.6pp 的提升,LLM 重排序不可跳过(差距 17.8pp)。


快速开始

gitclone https://github.com/Zleap-AI/SAG.gitcdSAG# 配置环境变量cp.env.example .env# 编辑 .env:填入 LLM API Key、Embedding API Key# 启动 PostgreSQL(带 pgvector)dockercompose up-d# 安装和初始化npminstallnpmrun db:setup# 启动开发服务器npmrun dev# WebUI: http://localhost:5173# API: http://localhost:4173

.env 关键配置

# LLM(OpenAI 兼容 API) LLM_BASE_URL=https://api.openai.com/v1 LLM_API_KEY=your_key LLM_MODEL=qwen3.6-flash # 或 gpt-4o-mini # Embedding EMBEDDING_BASE_URL=https://api.openai.com/v1 EMBEDDING_API_KEY=your_key EMBEDDING_MODEL=text-embedding-3-large # 可选:Rerank 模型 RERANK_MODEL=qwen3-rerank # 搜索模式 DEFAULT_SEARCH_MODE=fast # fast / standard INGEST_CONCURRENCY=5 # 并行摄取并发数

两种搜索模式

Fast 模式(不调用 LLM 解析查询):

查询 → BM25 全文实体匹配 → SQL 多跳扩展 → 重排序 优点:延迟低,无 LLM 查询解析成本 适合:实体名明确的查询

Standard 模式(LLM 提取查询实体):

查询 → LLM 提取实体 → 向量+SQL 多跳扩展 → LLM 重排序 优点:对模糊和自然语言问题更鲁棒 适合:需要复杂推理的查询

MCP 集成

每个 SAG 项目自动暴露一个 MCP 服务器端点,可以直接给 Claude Code 等 Agent 用:

{"mcpServers":{"sag":{"command":"npm","args":["run","mcp"],"env":{"SAG_MCP_SOURCE_ID":"your_project_id"}}}}

可用 MCP 工具

工具功能
sag_search搜索项目知识库
sag_ingest_document上传新文档
sag_explain_search解释特定问题的检索路径
sag_get_event获取特定事件的详细信息

Web UI 功能

  • 知识图谱浏览器:可视化事件-实体节点,支持拖拽、缩放、展开
  • 搜索链路追踪:实时显示每次检索的内部步骤和各阶段延迟
  • 原始模型日志:查看完整的 LLM / Embedding / Rerank 请求和响应
  • 项目隔离:每个项目有独立的文档库、对话历史、图谱和 MCP 配置

项目地址与资源

  • 🌟GitHub: Zleap-AI/SAG
  • 📄arXiv: 2606.15971
  • 🔬基准测试: Zleap-AI/SAG-Benchmark
  • 🌐官网: zleap.com

总结

SAG 的核心贡献在于找到了一种轻量的多跳检索实现:不构建全局知识图谱,不依赖 PageRank 评分,用关系型数据库的 JOIN 操作在查询时动态扩展图结构。这个选择有两个连带优势:文档更新是追加写入不需要重建,SQL JOIN 的可达性不受跳数影响不存在衰减。

"事件"作为语义单元(而非三元组)的设计也是值得关注的:每个 chunk 的完整语义被保留在一个 event 节点里,实体只作为连接点使用。这比三元组方案在 MuSiQue 上高出近 3 个百分点,验证了这个设计决策。

短板是透明的:固定裁剪预算在 2WikiMultiHop 上略逊于 HippoRAG 2,在需要探索低频桥接实体的场景会漏掉一些关键路径。知道短板在哪里,才能判断它是否适合你的场景。


探索 PrimeSkills —— 精选 AI Agent 与技能的市场,每一个都经过真实企业工作流验证,去掉浮夸,留下真正有用的。

欢迎访问我的个人主页,发现更多有价值的见解和有趣的产品。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 2:08:34

5分钟搞定VLC播放器终极美化:VeLoCity皮肤完整指南

5分钟搞定VLC播放器终极美化:VeLoCity皮肤完整指南 【免费下载链接】VeLoCity-Skin-for-VLC Castom skin for VLC Player 项目地址: https://gitcode.com/gh_mirrors/ve/VeLoCity-Skin-for-VLC 厌倦了VLC播放器千篇一律的默认界面?想要一个既美观…

作者头像 李华
网站建设 2026/7/7 2:07:28

BPF工具实战:中断、SMP调用与缓存性能

1. 中断时间分析:softirqs 和 hardirqs CPU在执行任务时,会花费一部分时间处理中断。传统工具如 mpstat 可以显示 CPU 在硬中断(%irq)和软中断(%soft)上的时间,但无法分解到具体的中断类型。BPF…

作者头像 李华
网站建设 2026/7/7 2:06:32

[特殊字符]遗忘之海PC公测|UU远程云电脑免费体验

终于等到遗忘之海PC公测上线✨!整理了玩法亮点、开服福利和超好用的远程游玩技巧,新手开荒直接抄作业!本次公测仅开放PC端口,很多宝子出门在外没法守着电脑,特别容易错过绝版福利和开荒进度😭!还…

作者头像 李华
网站建设 2026/7/7 2:05:00

面包板 300mil 间距转接方案:3种 DIY 方法实测与成品对比

面包板 300mil 间距转接方案:3种 DIY 方法实测与成品对比在电子原型开发中,面包板因其免焊接、可重复使用的特性成为硬件调试的必备工具。但当我们面对双列直插(DIP)封装的模块时,标准面包板300mil(7.62mm&…

作者头像 李华
网站建设 2026/7/7 2:04:48

鸿蒙 PC 底层开发技术详解(七):二进制自签名算法的实现

提示:本文创作过程中大量使用 AI 辅助研究,作者已验证代码结果的正确性,但无法保证所有结论一定严谨,切勿将文中结论用于严谨学术用途。 1 前言 本文是《鸿蒙 PC 底层开发技术详解(四):代码签名…

作者头像 李华
网站建设 2026/7/7 2:04:50

SIEMENS 07562981 印刷电路板

SIEMENS 07562981 印刷电路板是西门子医疗设备专用的控制板组件,其核心特点如下。中间15条:SIEMENS 07562981 专为西门子MRI系统配套设计。承担服务控制与信号管理功能。采用西门子医疗设备制造标准。适用于西门子07564060等型号设备。采用工业级元器件&…

作者头像 李华