恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索,TaoToken 统一 Key 通道实测

  • 首页
  • 资讯中心
  • /
  • 每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索,TaoToken 统一 Key 通道实测

相关资讯

从一张电子台账看危废库数字化:越华环保集团实践记录 2026/10/11 9:42:34
金融知识图谱构建实战:Neo4j+Python+Cypher完整指南 2026/10/11 9:42:34
impeccable:可验证的技术严谨性标准与工程落地实践 2026/10/11 9:42:33

最新资讯

从GitHub热门榜单到技术风向标:拆解一周开源项目规律
ACM 51个经典算法大全:126页Word实战源码与避坑指南
WebBrowser控件在Windows桌面应用中的工程化实践
科技前沿的EMBA:如何判断是否适配你的职业阶段
Windows Server下UHD630驱动装不上?绕过限制手工安装与QSV硬解指南
SecureCRT 9.5 安装与中文显示配置:从编码到避坑的完整指南

今日推荐

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索,TaoToken 统一 Key 通道实测

发布时间:2026/10/11 9:47:34
每日一个开源项目(第152篇):SAG - 用 SQL JOIN 代替 PageRank 做多跳 RAG 检索,TaoToken 统一 Key 通道实测 1. 多跳 RAG 检索为什么总在长链问题上翻车多跳检索要解决的问题很具体答案不在单个 chunk 里而是散落在两三篇甚至四五篇文档中需要把它们串起来才能回答。比如「A 公司的 CTO 在哪次会议上第一次提到 B 项目这个项目的技术负责人后来去了哪家公司」——这种问题标准向量检索基本没戏。原因在于向量检索的底层逻辑是「语义最相近」。它找到的是和 query 字面或语义最接近的 chunk但「最接近」不等于「能回答需要多步推理的问题」。第一跳的 chunk 可能确实相关但第二跳、第三跳的信息藏在语义距离很远的文档里向量空间里根本排不上号。GraphRAG 和 HippoRAG 这类方案用知识图谱来补这个短板离线把文档抽成节点和边查询时从种子节点出发做图遍历。听起来合理但有两个绕不开的代价。第一离线构建全局图谱成本高文档一更新就得重建或增量维护工程上很重。第二PageRank 类评分在长链条下有衰减——阻尼因子 d 通常取 0.85每经过一跳分数乘以 0.15四跳之后远端节点的得分只剩种子分数的万分之五根本竞争不过近端节点。SAGStructured Agentic Graph换了一条路不提前构建全局图谱查询时用 SQL JOIN 做图结构扩展。每个 chunk 提取一个 event语义摘要和若干 entity实体event 和 entity 之间的关联用关系型数据库的外键表达多跳扩展就是 JOIN 操作。JOIN 不传播分数只传播可达性——实体 X 关联的所有事件JOIN 结果里一视同仁不管它在图谱上离种子多远。这篇就带你从零把 SAG 跑起来用 TaoToken 统一 Key 通道接上模型调用然后实测 SQL JOIN 多跳检索和 PageRank 方案在长链问题上的差异。适合已经了解 RAG 基本概念、想搞清楚多跳检索工程实现的同学。2. TaoToken 统一 Key 通道把 LLM 和 Embedding 调用收口到一处SAG 的离线摄取和在线检索都要调模型摄取阶段每个 chunk 要跑一次 LLM 提取 event entities检索阶段要做 embedding 相似度搜索和 LLM 重排序。如果 LLM 和 Embedding 分别接不同厂商Key 管理、Base URL 配置、模型切换都会变成麻烦事。TaoToken 在这里的角色是统一 Key 通道一个 API Key 同时覆盖对话模型和 embedding 模型Base URL 统一指向https://taotoken.net/apiSAG 的.env里 LLM 和 Embedding 两组配置可以填同一套凭证。这样做的直接好处是——换模型只改LLM_MODEL和EMBEDDING_MODEL两个变量不用动 Key 和地址。先拿 Key。访问 TaoToken API Keys 页面 创建一个 Key复制出来备用。如果你还没注册从 TaoToken 官网 进。拿到 Key 之后SAG 的.env里 LLM 和 Embedding 两组配置这样填# LLMOpenAI 兼容 API统一走 TaoToken LLM_BASE_URLhttps://taotoken.net/api LLM_API_KEYsk-你的TaoTokenKey LLM_MODELqwen3.6-flash # Embedding同样走 TaoToken EMBEDDING_BASE_URLhttps://taotoken.net/api EMBEDDING_API_KEYsk-你的TaoTokenKey EMBEDDING_MODELtext-embedding-3-large # 可选Rerank 模型 RERANK_MODELqwen3-rerank # 搜索模式 DEFAULT_SEARCH_MODEfast INGEST_CONCURRENCY5这里有个容易踩的坑SAG 的.env.example默认填的是 OpenAI 官方地址如果你直接复制不改请求会打到api.openai.com而你的 Key 是 TaoToken 的结果就是 401。所以LLM_BASE_URL和EMBEDDING_BASE_URL两处都要改成https://taotoken.net/api注意末尾不要多加/v1——SAG 内部会自己拼路径多写一层会变成/v1/v1/chat/completions直接 404。模型选择上qwen3.6-flash在摄取阶段性价比不错提取 event entities 这种结构化任务对模型推理能力要求不算极端flash 级别够用。Embedding 用text-embedding-3-large是为了和 SAG 论文里的基准对齐如果你想省成本可以换小模型但召回率会掉一些。INGEST_CONCURRENCY5是并行摄取并发数TaoToken 这边对并发没有硬限制但本地 PostgreSQL 写入和网络往返会成为瓶颈5 是个稳妥的起点文档量大可以往上调到 10。如果你打算长期跑编码类 Agent 工作流把 SAG 当工具端点接进 Claude Code 之类的环境可以考虑 Coding Plan额度模型更适合持续调用。只是验证检索效果的话按量付费的 Key 就够了。3. 可复制配置SAG 本地部署 SQL JOIN 多跳检索参数这一节把从 clone 到跑通检索的完整配置给全。SAG 的技术栈是 TypeScript PostgreSQL pgvector React本地用 Docker 起数据库最省事。先拉代码、装依赖git clone https://github.com/Zleap-AI/SAG.git cd SAG cp .env.example .env # 编辑 .env按上一节的配置填入 TaoToken 的 Base URL 和 Key启动 PostgreSQL带 pgvector 扩展docker compose up -d初始化数据库表结构npm install npm run db:setupdb:setup会建三张核心表events事件表、entities实体表、event_entities关联表。关联表就是 SQL JOIN 多跳扩展的关键——它用外键把 event 和 entity 连起来正向 JOIN 找「包含某实体的所有事件」反向 JOIN 找「某事件关联的所有实体」。启动开发服务器npm run dev # WebUI: http://localhost:5173 # API: http://localhost:4173打开 WebUI 之后先建一个项目然后上传几篇 Markdown 或 TXT 文档触发摄取。摄取阶段每个 chunk 会调一次 LLM 提取 event entities控制台能看到进度。文档不多的话几十秒就跑完。接下来是检索参数。SAG 的检索配置集中在config/search.ts不同版本路径可能略有差异以仓库实际结构为准核心参数如下export const searchConfig { // Step 1: 种子检索 entityVectorThreshold: 0.9, // 实体向量相似度阈值 eventVectorThreshold: 0.4, // 事件向量相似度阈值 // Step 2: 查询时 SQL 多跳扩展 maxHops: 1, // 默认跳数 H1 entityFrontierBudget: 50, // 实体前沿裁剪预算 // Step 3: 最终选择 candidatePoolSize: 100, // 候选事件池大小 structuralTopK: 5, // 结构路径取 top 5 semanticTopK: 5, // 语义路径取 top 5 finalChunkCount: 10, // 合并去重后最终返回 10 个 chunk };几个参数值得展开说。maxHops控制多跳扩展的跳数默认 1 意味着从种子事件出发做一次反向 JOIN 取实体、一次正向 JOIN 找新事件。调到 2 会再扩展一轮召回更多但候选池会膨胀重排序压力变大。entityFrontierBudget是实体前沿的裁剪预算默认 50——这个参数就是 SAG 在 2WikiMultiHop 上略逊于 HippoRAG 2 的原因低频桥接实体可能被裁掉。如果你的场景里桥接实体比较冷门可以把这个值调大代价是 JOIN 结果集变大。entityVectorThreshold设 0.9 比较激进意味着只有高度相似的实体才会被纳入扩展集。这个值调低会引入更多噪声实体JOIN 出来的事件相关性下降。eventVectorThreshold设 0.4 相对宽松因为事件向量是语义摘要相似度天然比实体低。搜索模式在.env里用DEFAULT_SEARCH_MODE控制。fast模式不调 LLM 解析查询直接走 BM25 全文实体匹配 SQL 多跳 重排序延迟低standard模式先用 LLM 从查询里提取实体再做向量 SQL 多跳 LLM 重排序对模糊的自然语言问题更鲁棒。实测下来实体名明确的查询用 fast 就够复杂推理问题切 standard。如果你要把 SAG 暴露成 Agent 可调用的工具MCP 配置这样写{ mcpServers: { sag: { command: npm, args: [run, mcp], env: { SAG_MCP_SOURCE_ID: your_project_id } } } }SAG_MCP_SOURCE_ID填你在 WebUI 里建的项目 ID。配好之后 Agent 就能调sag_search、sag_ingest_document、sag_explain_search、sag_get_event这几个工具。sag_explain_search特别有用它会返回某次检索的完整路径——种子事件是哪些、JOIN 扩展出了哪些事件、最终选了哪些 chunk调参的时候靠它定位问题。4. 验证请求多跳召回实测与 PageRank 对比配置跑通之后关键一步是验证 SQL JOIN 多跳到底有没有把跨文档的信息捞回来。构造一个需要两跳的问题来测。假设你上传了三篇文档文档 A 讲「张三在 2024 年 Q2 的产品评审会上提出了星尘计划」文档 B 讲「星尘计划的技术负责人是李四」文档 C 讲「李四后来加入了某研究院」。问题问「星尘计划的技术负责人现在在哪」。这个问题需要三跳从「星尘计划」找到文档 A 的事件JOIN 到实体「星尘计划」再 JOIN 到文档 B 的事件拿到「李四」再 JOIN 到文档 C。标准向量检索大概率只能召回文档 A 和 B文档 C 因为和 query 语义距离远排不进 top 10。用 SAG 的 API 发一个检索请求curl -X POST http://localhost:4173/api/search \ -H Content-Type: application/json \ -d { sourceId: your_project_id, query: 星尘计划的技术负责人现在在哪, mode: standard, maxHops: 1 }返回结果里重点看两个字段chunks是最终召回的 10 个 chunktrace是检索路径追踪。如果多跳生效trace.entityFrontier里应该能看到「星尘计划」这个实体trace.expandedEvents里应该包含文档 B 和文档 C 对应的事件。我试过用sag_explain_search工具看路径它会把每一步的耗时和中间结果都列出来。种子检索阶段实体引导路径召回的事件和直接事件召回的事件会分别标注SQL 扩展阶段反向 JOIN 取出的实体前沿和正向 JOIN 找到的新事件也会列清楚。如果文档 C 的事件出现在expandedEvents里但没进最终chunks说明多跳召回成功了是重排序环节把它筛掉了这时候要调structuralTopK或检查重排序模型。对比 PageRank 方案的话SAG 仓库里带了基准测试脚本在Zleap-AI/SAG-Benchmark里。论文给的数据是 MuSiQue 上 SAG Recall5 80.0% vs HippoRAG 2 65.1%差 14.9 个百分点。MuSiQue 专门设计 4 步推理链正好打在 PageRank 衰减的痛点上。HotpotQA 上差距缩小到 2.1pp因为 HotpotQA 大多是 2 跳问题PageRank 衰减还不严重。2WikiMultiHop 上 SAG 反而低 2.4pp原因是实体前沿裁剪预算固定 50低频桥接实体被截掉了。消融实验的数据也值得看去掉多跳扩展H0MuSiQue Recall5 从 80.0% 掉到 69.4%说明多跳贡献了约 10.6pp去掉结构路径掉到 56.2%说明实体引导的 SQL JOIN 路径是主力用轻量重排序器替换 LLM 重排序掉到 62.2%说明 LLM 重排序不能省差距 17.8pp。本地复现的时候如果你想对比 PageRank可以在同一批文档上跑 HippoRAG 2 的检索用相同的问题集对比 Recall5。注意嵌入模型要统一SAG 论文用的是 bge-large-en-v1.5换 NV-Embed-v2 之后 MuSiQue Recall5 能到 81.71%说明提升来自结构设计本身不只是嵌入质量。5. 常见报错排查401、local proxy failed、reading choices、OAuth跑 SAG 的过程中模型调用链路上的报错最集中。逐个说。401 Unauthorized。最常见的原因是.env里LLM_BASE_URL或EMBEDDING_BASE_URL没改成 TaoToken 的地址请求打到了默认的 OpenAI 官方端点而 Key 是 TaoToken 的自然 401。检查两处 Base URL 是否都是https://taotoken.net/apiKey 是否完整复制注意别带空格。还有一种情况是 Key 被禁用或额度耗尽去 API Keys 页面 确认状态。local proxy failed。这个报错通常出现在你本地配了 HTTP 代理但代理没启动或者代理地址不通。SAG 的请求走 Node 的 fetch会读HTTP_PROXY/HTTPS_PROXY环境变量。如果你不需要代理把这两个变量清掉如果确实需要确认代理进程在跑。注意别把代理地址填成 TaoToken 的地址那是两回事。reading choices 报错。典型信息是Cannot read properties of undefined (reading choices)意思是 API 返回体里没有choices字段。原因通常是 Base URL 多写了一层/v1请求打到了https://taotoken.net/api/v1/v1/chat/completions返回 404 页面而不是 JSON。检查LLM_BASE_URL末尾不要带/v1。另一种可能是模型名写错了LLM_MODEL填了一个 TaoToken 不支持的模型 ID返回体结构不对。去 模型对话页面 确认可用模型列表。OAuth 相关报错。如果你在配 MCP 的时候看到 OAuth 报错通常是 Claude Code 那边的认证配置和 SAG 的 MCP 服务器没对上。SAG 的 MCP 走 stdio 传输不需要 OAuth报错一般来自 Agent 端。检查 MCP 配置里的command和args路径是否正确SAG_MCP_SOURCE_ID是否填了有效的项目 ID。如果 Agent 端要求 OAuth说明它把 SAG 当成了远程 MCP 服务器改成 stdio 本地启动即可。摄取阶段卡住或超时。INGEST_CONCURRENCY设太高会导致大量请求并发TaoToken 这边虽然不限并发但本地网络和 PostgreSQL 写入会成为瓶颈表现为进度条不动。调低到 3 试试。另外检查文档格式SAG 目前主要支持 Markdown 和 TXTPDF 需要先转文本。SQL JOIN 返回空结果。如果trace.expandedEvents是空的说明实体前沿没匹配上。检查entityVectorThreshold是不是设太高0.9 比较激进调低到 0.8 试试。或者查询里的实体名和文档里的实体名不一致比如查询写「星尘计划」但文档里写「星尘项目」向量相似度不够就匹配不上。这种情况切standard模式让 LLM 提取实体鲁棒性更好。排查的时候善用sag_explain_search它返回的 trace 能定位到具体是哪一步出的问题。接入文档在 TaoToken 文档页Base URL、鉴权方式、模型列表都有说明。6. 把 SAG 接进你的 Agent 工作流SAG 跑通之后最有价值的用法是把它作为 MCP 工具端点接进 Agent。每个 SAG 项目自动暴露一个 MCP 服务器Agent 通过sag_search就能检索你的知识库通过sag_ingest_document能动态追加文档通过sag_explain_search能看检索路径。配置的时候三件套要写全Base URL 指向https://taotoken.net/apiKey 用 TaoToken 的Model ID 填qwen3.6-flash或你选的模型。这三样在.env里对应LLM_BASE_URL、LLM_API_KEY、LLM_MODELMCP 配置里通过环境变量传给 SAG 进程。如果你用 Claude Code 做长期编码把 SAG 的 MCP 配进去之后Agent 在回答涉及你项目文档的问题时就能走多跳检索而不是靠上下文窗口硬塞。Claude Code 的接入方式参考 Claude Code Anthropic 配置页把 Base URL 和 Key 填对就行。长期跑 Agent 工作流的话Coding Plan 的额度模型比按量付费更适合持续调用。只是验证 SAG 检索效果的话按量付费的 Key 完全够用摄取几十篇文档加几百次检索成本很低。最后说一个实测经验SAG 的maxHops默认 1 在大多数场景够用但如果你的问题确实需要 3 跳以上调到 2 之后记得同步调大candidatePoolSize否则候选池不够重排序没得选。另外entityFrontierBudget这个参数在桥接实体冷门的场景要手动调大默认 50 会漏路径——这就是 SAG 在 2WikiMultiHop 上输给 HippoRAG 2 的原因知道短板在哪才能判断它适不适合你的场景。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号