Graphify:把你的项目变成一张知识图谱,然后问它你没想到的问题
我最近一直在用 Codex CLI 做各种项目,时间长了慢慢发现一个问题。
不是模型不够聪明。模型越来越强,写代码、改 bug、补测试、重构,都越来越稳。真正的问题在另一个维度:AI 助手很难真正"理解"一个项目。
让它改一个文件的时候,它能看上下文,能调用相关函数,能跑测试来验证。但如果我问它"这个系统到底是怎么组织的?核心模块有哪些?哪里是真正的瓶颈?"——它往往给不出扎实的回答。不是它不想,而是它没有那个视角。它只能看到当前对话里喂给它的文件,看不到整个项目的结构图谱。
于是我开始找有没有工具能补这个缺口。结果找到了 Graphify。
这不是一个典型的开发工具。它不抢着帮你写代码,不做编译检查,不跑测试。它只做一件事:把你的整个项目变成一张知识图谱,然后告诉你这张图上有什么是你不知道的。
核心概念:不是搜索引擎,是关联发现
Graphify 做的事情,如果简化到一句话就是:
任何文件夹里的任何文件 → 可导航的知识图谱 → 社区检测 → 报告 + HTML + JSON
它能吃进去的文件类型很广:代码(.py、.ts、.go、.java、.rs 等等)、Markdown 文档、PDF 论文、截图、白板照片、甚至 Twitter 推文和音频转写。不挑语言,不挑格式。全都能解析,然后提取出节点(类、函数、概念、术语、论文作者)和边(调用关系、引用、实现、依赖、语义相似性)。
这听起来有点像代码搜索引擎。但 Graphify 和搜索最大的区别是:搜索告诉你"有没有",Graphify 告诉你"和什么连着"。
你在 IDE 里搜索某个核心 Service 的实现类,会找到它的定义位置。但 Graphify 会告诉你:这个节点有几十条边,连接了认证模块、订单流程、通知系统、外部 API 等多个子系统——它是整个系统的中枢。搜索告诉你的是一维的结果,图谱告诉你的是一张关系网。
然后在此基础上,它还会做社区检测。这个很关键。不是简单地把同一个文件夹的文件归为一组,而是根据真实的连接关系,把在图中联系紧密的节点聚合成社区。结果往往和你预期的目录结构不完全一致——这正是最有价值的地方。
图能告诉你什么
Graphify 跑完之后会输出三样东西:交互式 HTML 图、原始图 JSON、以及一份纯文本审计报告。报告里有几个核心概念值得提前理解。
交互式 HTML 图的全景。每个圆点一个节点,颜色代表不同社区,节点大小反映连接数。
神节点(God Nodes)
Graphify 会自动计算度数最高的节点,也就是全图连接最多的实体。对于一个代码库,这其实就是工程意义上的"核心抽象"。
神节点不一定是最大的文件或最复杂的类。有时候一个工具类、一个配置中心、一个网关接口,反而会成为整个系统的中枢。这些信息靠直觉很难判断,但图会用数字直接告诉你。
社区结构(Communities)
Graphify 用 Louvain 算法做社区检测,把在图中连接紧密的节点自动聚合成一个个社区。每个社区都有一个自动生成的语义标签。
比较不同社区的 cohesion 值(内聚性)特别有意思。Cohesion 越高,说明这个社区内部的节点连接越紧密。
社区 A:10 个节点,cohesion 0.03 → 节点很多但连接稀疏,可能名不副实
社区 B:5 个节点,cohesion 0.45 → 节点不多但内部连接紧密,是个高内聚模块
社区 C:3 个节点,cohesion 0.60 → 极小但内聚极高,可能是过于孤立的模块
社区结构的局部放大:每个彩色簇代表一个社区,同色节点之间连接紧密,不同色簇之间由跨社区桥梁节点连接。
cohesion 低于 0.05 的社区,Graphify 会在报告里建议考虑合并或重构。这个判断不是拍脑袋,而是基于真实连接密度的计算。
跨社区桥梁
Graphify 的报告中有一个叫 Suggested Questions 的章节,其中最值得关注的就是跨社区桥梁。
它用 betweenness centrality(中介中心性)这个图论指标,衡量一个节点在最短路径中作为中介的频率。简单说:如果整个系统的信息流通要频繁经过某个节点,它的 betweenness 就高。
当一个工具类、一个查询构造器、或者一个通用服务的 betweenness 异常高时,意味着:
- 整个系统大量依赖这个组件
- 它没有通过一层抽象来隔离,直接散落在各处
- 如果未来要改动这个组件,辐射面会非常广
在这之前,你可能从没想过某个基础设施类会成为技术债务的信号。但 Graphify 用图结构告诉你。
知识盲区(Isolated Nodes)
报告还会标记出孤立节点——那些只连接了很少其他节点的实体。这些节点的存在可能有几种原因:
- 确实是被遗忘的废弃代码
- 可能是工具类,虽然被用到但 AST 抓不到动态调用
- 可能是新加的模块,还没和其他部分建立足够连接
无论哪种情况,这些都是值得人工审视的信号。
建立一张图,而不是从头再来
Graphify 不是每次都要全量重建。
增量更新 --update
只重新提取新增和变更的文件。如果只改了代码文件(没有改文档),连 LLM 都不需要——只跑 AST 提取 + 重新聚类即可。在正常的开发节奏里,图更新几乎零 token 成本。
看门狗模式 --watch
监听文件夹变动,代码改了自动重建,文档改了打个标记等人来触发 --update。像后台守护进程一样默默运行,状态总是最新的。
Git 钩子
graphify hook install 安装 post-commit 钩子。每次 commit 后自动重建图的代码部分(AST 部分),commit 完图就更新好了,不需要手动操作。
图自增长
回答过的查询还会被保存回图中。每次 query 或 explain 的结果都会变成一个 Q&A 节点写入图文件。下次增量更新时,这些问答就会成为图的一部分。图随着使用自我增长。
Graphify 的架构逻辑
整条流水线分为三条并行的路径:
输入文件
│
├── 代码文件 (.py .ts .go .java …)
│ └── AST 提取(确定性,免费)
│ 提取:类、方法、调用、import、泛型
│
├── 文档/论文 (.md .pdf .txt …)
│ └── 语义提取(LLM 子 agent,并行)
│ 提取:概念、术语、引用、决策理由
│
├── 图片/截图 (.png .jpg …)
│ └── Vision 提取(LLM 子 agent)
│ 提取:UI 布局、图表趋势、思维导图
│
└── 视频/音频 (.mp4 .mp3 …)
└── Whisper 转写 → 当作文档处理
三条路径并行跑完后,结果合并到同一张图中,然后跑 Louvain 社区检测,输出 HTML + JSON + 报告。
关键设计决策:代码文件走 AST 提取,不需要 LLM,所以 token 成本为零。 如果一个项目只有代码没有文档,语义提取阶段根本不跑 LLM,全部由 AST 搞定。
只有 Markdown 文档、PDF 论文、图片才需要 LLM 做语义提取。这些文件的处理通过并行子 agent 来加速——每 20-25 个文件一个 agent,所有 agent 同步跑。
诚实审计:什么能信,什么不能信
Graphify 有一条很硬的设计原则:每条边都必须标记来源。
它把边分成三类:
| 类型 | 意义 | 来源 |
|---|---|---|
| EXTRACTED | 源文件中明确存在的关系 | import、call、implements、citation |
| INFERRED | 合理推断 | 共享数据结构、隐含依赖 |
| AMBIGUOUS | 不确定,需要人判断 | 弱信号、跨语言引用 |
每条边还有 confidence_score。EXTRACTED 固定是 1.0,INFERRED 则根据证据强度在 0.4-0.9 之间浮动。没有默认值——Graphify 强制要求每个 INFERRED 边都单独给出置信度。
这个设计很重要。很多工具会给出一张看起来很确定的图,但你不知道哪些是它读到的、哪些是它猜的。Graphify 告诉你每一项的来源。你永远知道什么是发现的,什么是发明的。
三种查询模式
图建好以后,最常见的交互方式是三种查询:
BFS(广度优先) — “X 连接到了什么?” 适合问一个模块的完整上下文。返回它的所有邻居节点,快速理解一个模块在整个系统中的位置。
DFS(深度优先) — “X 怎么到达 Y?” 适合追踪一条调用链。比如"这个请求从 Controller 到数据库经过了哪些层?"
最短路径 — “X 和 Y 之间有什么连接?” 适合发现两个看似无关的模块之间有哪些中间节点,往往能揭示你没想到的间接依赖。
这三种模式不是互相替代,而是互补。BFS 给全貌,DFS 给深度,最短路径做连接诊断。
局限性:它不是万能的
我不会把 Graphify 神化。它有几个明显的边界。
第一,它对大型代码库的社区命名有噪音。
当项目规模更大时,社区命名和合并的质量会变得关键。Graphify 现在靠节点的语义标签来做社区命名,不一定能反映架构师的意图。有时会出现碎片化的微社区。
第二,语义提取的质量取决于使用的模型。
对于标准技术栈(Java Spring Boot、Python Django、TypeScript React),它的表现非常好。但对于冷门领域,INFERRED 边的质量可能会下降。
第三,纯代码项目,语义提取贡献有限。
对于业务代码为主的项目(大多数后端项目都是),Graphify 的"AI 智慧"部分没有完全发挥。AST 提取覆盖了 import、call、implements 等结构关系,但它抓不到"为什么"——架构决策、设计意图、业务逻辑的分层动机。这些东西存在文档里,如果项目没有补充性文档,图就停留在结构层面。
第四,对于"架构决策"类问题,它不能直接回答。
“为什么不直接用 RPC 而要用消息队列?"——这种问题的答案存在于 Slack 讨论、设计文档、代码注释里。如果这些信息没有被喂给 Graphify,图不会知道。
什么场景值得用
根据我的试用体验,我觉得 Graphify 在下面几种场景下价值最大:
- 新接手一个项目 — 不需要读完所有代码,跑一次 Graphify 看神节点和社区结构,快速找到核心入口和最模块化最松散的地方
- 重构前的审计 — 想知道"哪些类实际是核心”、“哪些模块边界已经模糊”、“有哪些跨社区桥梁需要关注”,图比直觉可靠
- 检验模块划分是否合理 — 如果 MVC 分层在图上完全不出现,说明目前的目录结构可能和实际调用关系脱节
- 长期知识管理 — Graphify 的持久化和增量更新机制,让它适合作为项目知识图谱长期维护,每次问问题时不重新读全部代码
反过来,如果项目很小(几十个文件),或者你已经是项目的唯一开发者且对结构了然于胸,那 Graphify 的增量价值不大。
生态系统
Graphify 原生支持多种导出机制:
--svg→ 导出 graph.svg,嵌入 Notion/GitHub--graphml→ 导出 graph.graphml,导入 Gephi、yEd 做更精细的可视化--neo4j/--neo4j-push→ 导出 cypher 脚本或直接推入 Neo4j 数据库graphify claude install→ 写入CLAUDE.md,让 Claude Code 每次回答代码问题前自动查图
我的真实评价
Graphify 不是一个让你"哇"一声的工具。
它没有 AI 生成的代码片段,没有漂亮的交互演示,不会帮你修 bug,也不会加速你的 CI。它输出的是一张图、一份报告、和一堆关系数据。
但它在做一件很难的事情:让隐性结构显性化。
每个项目都有两张图:一张是你以为的结构(目录树、包名、模块文件夹),一张是运行时真正存在的连接。这两张图很少有完全一致的时候。时间越长,偏离越大。
Graphify 的价值不在那张漂亮的 HTML 动态图里——我看了几次就不怎么打开了——而在那份纯文本的 GRAPH_REPORT.md 里。它用数字和关系告诉你:神节点是这些,社区边界在这里,有一堆节点被低估或高估了,有些类型参数被到处传递却没人意识到它成了系统关键路径。
这些信息,靠人读代码很难发现。不是读不懂,而是读代码的视角是沿着一条路径走的,不会站在全局图的角度看所有连接。人类开发者擅长的是线性推理,图工具擅长的是网状关系发现。
这也是为什么我觉得 Graphify 和 AI Coding 是互补的。AI Coding 擅长执行——改文件、跑测试、修 bug。Graphify 擅长理解——告诉你项目到底长什么样,核心是什么,哪里的结构和预期不一样。
这两个能力放在一起,才会真正解决"AI 并不真正理解项目"的问题。
