graphify 实测:14 万 star 的代码知识图谱,我把 Flask 和自己三年的工作区拆成了可查询的图

用 AI 编程助手读大仓库,最疼的不是不会读,是读不起:每开一个新会话,它都得把文件翻一遍,token 像流水一样走。向量检索(RAG)是主流答案,但它本质是「找几块长得像的文本碰运气」,返回的是相似度排名,不是代码的真实关系。

上周刷 GitHub 撞见了另一个思路:graphify,把代码库拆成一张图——类、函数、导入、调用都是节点和边,回答问题时沿真实的边遍历,每条边带 文件:行号 引用。GitHub API 实查 144,006 star(2026-11-08),Apache-2.0,我写稿这天凌晨它还在推送提交。我拿它把 Flask 和自己堆了三年的工作区各拆了一遍,这篇文章是全部实测结果。

先说清楚它是什么

graphify 的本体是一个 Python CLI(PyPI 包名是 graphifyy,五个 y,官方说正名在回收中)加一个 AI 助手技能。装好后你在 Claude Code、Codex、OpenCode 这些助手里输入 /graphify .,它就接管整个流程,产出四样东西:可交互的 graph.html、可持久查询的 graph.json、一份人话审计报告 GRAPH_REPORT.md,还有 SHA256 缓存目录。

架构上是两段式:代码文件走 tree-sitter 确定性 AST 抽取,完全不调模型、不要 API key;文档、PDF、图片才走模型语义抽取,而且后端可以指到本地 Ollama。官方反复强调「无 embedding、无向量库」,社区检测用 Leiden 算法按边的密度聚类,不靠相似度。

我的实测环境:macOS 26.5.2,M4 / 16GB,Python 3.13.12,opencode v2.1.4 配免费模型 nemotron-3.5-lightning:free(opencode 官方免费额度当天已耗尽,这也是个坑,后面细说)。

十分钟跑通全流程

安装两步,先装 CLI 再把技能注册进你的助手:

Bash
# 环境:macOS + Python 3.13,Windows/Linux 同理
pip install graphifyy          # 注意是五个 y
graphify install               # 默认注册到 Claude Code
graphify install --platform opencode   # 我用的 opencode,也支持 codex/cursor/gemini 等 17 个平台

然后找一个仓库试。我选了 Flask(读者都能复现):

Bash
graphify clone https://github.com/pallets/flask
cd ~/.graphify/repos/pallets/flask
opencode run -m openrouter/nvidia/nemotron-3.5-lightning:free "/graphify ."

第一次直接跑会报错——flask 有 115 个文档文件和 8 张图片需要语义抽取,没有 API key 就走不下去。报错信息本身很友好,给了两条出路:设一个 key,或者加 --code-only 只索引代码。opencode 里的免费模型自己读懂了报错,主动切到 --code-only 把流程跑完了。

最终数字:100 个代码文件,产出 2325 个节点、3745 条边、213 个社区,整个 agent 会话 35 秒,token 花费 0。我后来用 Python 统计了 graph.json 里的边长这样:

边类型 数量 说明
contains 1316 文件包含符号
references 632 引用
calls 373 显式调用
method 313 方法边
rationale_for 304 注释里的设计理由挂到代码上
imports / imports_from 269 / 253 导入关系
indirect_call 126 间接调用
inherits 41 继承

最关键的一列其实不在表里,是置信度:3454 条 EXTRACTED(92.2%)对 291 条 INFERRED(7.8%),每条边都标了是「源码里直接找到的」还是「模型推测的」。这个设计我给好评——后面有个环节全靠它救场。

查询三件套:query、path、explain

图建好了,查询是纯本地 CLI,不用模型:

Bash
graphify query "AppContext 在哪定义、被哪些模块使用" --budget 1000
graphify path "Flask" "RequestContext" --undirected
graphify explain "Scaffold" --all

query 走 BFS 二度遍历。我问 AppContext,它找到 181 个关联节点,然后诚实地告诉我:预算 1000 token 只够显示 40 个,砍了 141 个,想全看就把预算提到 4852。截断不装死,明示你怎么拿全量,这种交互比很多工具的静默截断强太多。

path 给了我一个重要教训。我在自己工作区的图上查 GGUFWriter(llama.cpp 的 Python 写出器)到 ggml_add(C 层张量加法)的路径:有向图查无路径,加 --undirected 后给了 4 跳结果——中间经过了 math 这个节点,因为 gguf_writer.py 导入了 math,ggml.c 也导入了 math。两个共享一个标准库模块的文件,图上就是连通的。图的边是「语法事实」不是「业务调用链」,跨大社区的路径查询要自己长个心眼,别把连通当因果。

explain 我拿 451 度的 GGUFWriter 试的:5 秒出结果,451 条连接全部带方向(--> 出边 / <-- 入边)、类型、置信度和 文件:行号。

增量更新:改一行,1.9 秒

官方说改代码只重解析改动文件。我在 flask 的教程示例里加了个探针函数,然后:

Bash
graphify update .

总耗时 1.9 秒,节点 2325 变成 2327,探针函数在 graph.json 里查得到了。缓存机制是 SHA256 对文件哈希,没改的文件直接跳过 AST。日常开发挂个 git hook,图就永远跟代码同步。

这里有个我踩的坑:一开始我随手敲了 graphify update examples/tutorial,它给我在子目录下新建了一张独立的 93 节点小图,而不是更新根图。update 的路径参数就是图的根,传子目录就建子图——想清楚再敲。

顺手做的压力测试:103,106 个节点

写这篇的时候出了个事故,反而成了全文最有说服力的数据:agent 在错误的工作目录执行了 /graphify .,把我的整个工作区——三年攒下的文章产出、脚本、克隆的 llama.cpp 源码——全扫了。5381 个代码文件,产出 103,106 节点、254,080 条边、2271 个社区,3 分 28 秒,0 token。我的 M4 风扇都没转起来。

两个意外收获:

  1. 敏感文件自动规避。它检测出 9 个「潜在敏感文件」并跳过——包括我目录里的 .npmrc 和几个 .pem 密钥文件;flask 仓库里则跳过了 .env。跑在本地不外传是一回事,工具主动不碰密钥文件是另一回事,后者更难得。
  2. 混语料会失真。我的工作区里 Python 脚本、C 源码、Svelte 组件、中文 markdown 混在一起,query 的 BFS 起点混进了旧文章标题和中文注释片段,社区标签也出现 torch、os 这种泛化巨社区。图工具假设语料是一个有机项目,喂它一锅粥,它就只能给你一锅粥状的图。建议给每个项目单独建图,配 .graphifyignore(语法同 .gitignore)排掉杂物。

我核验了它的两个声称,一个属实一个注水

循环导入检测:属实,而且解释了 Flask 源码的一个为什么。 报告声称 __init__.py → app.py → ctx.py 存在导入环。我回源码核验:__init__.py 第 5-8 行确实从 .ctx 导入,app.py 第 32 行导入 .ctx;更有意思的是 app.py 第 124 行有个躲在函数体内的 from flask import Flask——这正是为了绕开包级循环才用的延迟导入。图检测到的环路方向是对的,具体逐跳路径带了推断成分(INFERRED 标签没有骗人),但「这里存在循环依赖」这个结论经得起查。

「71.5× fewer tokens」:实测没有这么神。 官网引用的用户证词说比读原文件省 71.5 倍 token。我做了个对照:grep -rn "AppContext" src/ 全量命中 4788 字节裸文本;graphify query --budget 1000 输出 3512 字节结构化结果。单次查询的字节数差距连一倍都不到。graphify 真正省 token 的场景是多轮、跨会话的架构级问题——图是持久化的,第 N 次提问不用再碰源文件;而且它给的是「谁调用谁、属于哪个社区」的关系数据,不是「恰好包含关键词的行」。单看一次 grep 式查询你甚至不需要它,skill 文档自己也承认:一次性单问题,直接 grep 更快。

踩坑清单

  • PyPI 包名是 graphifyy(五个 y),CLI 才叫 graphify。装错了会摸半天。
  • opencode 免费额度是账号级日限额,换模型没用,官方几个免费模型撞的是同一堵墙——我在用免费模型跑安全审计技能那次也撞过。绕法是走 openrouter 的免费模型:nemotron-3.5-lightning:free 顶着 799 行的 skill 文档完成了全部编排,没掉链子——这已经是本站免费模型跑第三方技能系列的第三单,前两单是改 AI 味界面和上面的安全审计。
  • 语义抽取必须有 key。没有 API key 时文档、PDF、图片完全不进图,--code-only 是唯一出路。想让文档也进图,可以把后端指到本地 Ollama,做到全离线;本地大模型的内存账可以参考我之前测的不装内存改「摆放」的推理方案。
  • 社区命名会悄悄回退。没 key 时它先试 claude -p,我机器上没登录,三个批次全失败,最后用 Community N 占位——好在警告打得明明白白,没装没问题。
  • tree-sitter_sql 是可选依赖。flask 仓库里 2 个 SQL 文件没进图,警告提示 pip install "graphifyy[sql]"。要索引带 SQL schema 的项目记得装 extras。

什么时候不建议用

  • 一次性单问题:想知道「X 在哪定义」,grep 一下就完事,建图纯属杀鸡用牛刀(skill 自己都这么劝)。
  • 想拿它当事实核查器:92% 的边是源码抽取的,剩下 8% INFERRED 是模型推测——上文的环路核验就是例子,方向对、细节可能是拼出来的。别把 INFERRED 边直接当架构文档抄。
  • 混杂语料一锅建图:多项目目录、笔记、代码混在一起,社区检测会失真,查询结果噪声大。
  • 代码之外的重语义场景无 key 硬跑:PDF、图片、音视频进图全依赖模型后端,没 key 就是空转。

写在最后

graphify 解决的是一个很具体的问题:让 AI 助手「记住」你的代码结构,并且每次回答都给出可验证的出处。它没有把 RAG 打死——单次查询省不了多少 token——但它把「第二问开始」的成本压到了接近零,同时用 EXTRACTED/INFERRED 标签守住了诚实的底线。

对每天在大仓库里跟 AI 结对的人,值得一装。花 35 秒建一张图,之后每次会话都少烧一截 token,这买卖在我这里是划算的。

推荐阅读

  • rea-video 实测:逐镜拆出视频是实拍、AI 还是代码渲染,我埋了带答案的靶子,也用一行 ffmpeg 伪造了 AIGC 标识

    rea-video 是一个逐镜头拆解视频制作方式的开源工具,能判断每镜是实拍、AI 生成、3D 还是代码渲染,并给出字幕时间轴、音效卡点与复刻方案。我用切点精确到帧的答案卡视频和 AI 生成的真值素材…

  • Cloudflare 安全审计技能实测:222 行的靶子埋 6 个洞,单次通读全抓到,六阶段先撞了额度墙

    Cloudflare 开源的 security-audit 技能把代码审计拆成六个阶段,核心是让发现者与验证者必须是两个不同的 Agent。我造了 222 行、埋 6 个真漏洞和 5 个诱饵的靶子实测…

  • VoiceStudio 实测:10 万星的本地语音克隆,我在 16GB M4 上从源码跑通了引擎,也踩了三个坑

    VoiceStudio 是 10 万星的本地语音克隆工具,我用默认的 OmniVoice 引擎在 16GB M4 上从源码编译跑通:945MB 权重、Metal 加速,加载 1.6 秒、RTF 约 0…

  • floci 实测:LocalStack 停摆后的免费 AWS 模拟器,我无 Docker 从源码跑通了 Agent 本地云链路

    LocalStack 社区版强制登录后,MIT 开源的 AWS 模拟器 floci 成了热门替代品。我在 16GB MacBook 上从源码编译 2.4.0 实测:无 Docker 跑通 S3、Dyn…