Graphify:把你的项目变成一张知识图谱,然后问它你没想到的问题

2026-06-02 2 min read 墨然

我最近一直在用 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、以及一份纯文本审计报告。报告里有几个核心概念值得提前理解。

Graphify 全图概览 交互式 HTML 图的全景。每个圆点一个节点,颜色代表不同社区,节点大小反映连接数。

神节点(God Nodes)

Graphify 会自动计算度数最高的节点,也就是全图连接最多的实体。对于一个代码库,这其实就是工程意义上的"核心抽象"。

神节点不一定是最大的文件或最复杂的类。有时候一个工具类、一个配置中心、一个网关接口,反而会成为整个系统的中枢。这些信息靠直觉很难判断,但图会用数字直接告诉你。

社区结构(Communities)

Graphify 用 Louvain 算法做社区检测,把在图中连接紧密的节点自动聚合成一个个社区。每个社区都有一个自动生成的语义标签。

比较不同社区的 cohesion 值(内聚性)特别有意思。Cohesion 越高,说明这个社区内部的节点连接越紧密。

社区 A:10 个节点,cohesion 0.03  → 节点很多但连接稀疏,可能名不副实
社区 B:5 个节点,cohesion 0.45  → 节点不多但内部连接紧密,是个高内聚模块
社区 C:3 个节点,cohesion 0.60  → 极小但内聚极高,可能是过于孤立的模块

Graphify 社区结构特写 社区结构的局部放大:每个彩色簇代表一个社区,同色节点之间连接紧密,不同色簇之间由跨社区桥梁节点连接。

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 完图就更新好了,不需要手动操作。

图自增长

回答过的查询还会被保存回图中。每次 queryexplain 的结果都会变成一个 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 并不真正理解项目"的问题。