graphify 实战与源码解析:用 /graphify 把代码库变成可查询的知识图谱
graphify 是一个面向 AI 编程助手的知识图谱工具:在 Claude Code、Codex、Cursor、Gemini CLI 等助手里输入 /graphify,它会把代码、文档、SQL、图片乃至音视频解析成一张本地知识图谱,让你"查询"代码库而不是"翻找"代码库。本文以 graphify 仓库中的挪威语 README(docs/translations/README.no-NO.md)所描述的完整功能为主线,结合 pyproject.toml、graphify/cache.py、docs/how-it-works.md 等仓库文件,讲清楚它的三段式抽取管线、置信度标签体系、安装配置方式,以及 SHA256 增量缓存等底层实现机制。
定位:写给 AI 助手的 /graphify 技能
挪威语 README 对 graphify 的概括是:在 Claude Code、Codex、OpenCode、Cursor、Gemini CLI、GitHub Copilot CLI、VS Code Copilot Chat、Aider、OpenClaw、Factory Droid、Trae、Hermes、Kiro 或 Google Antigravity 中写 /graphify,它会读取你的文件、构建知识图谱,并返回你原本不知道存在的结构。它完全多模态:代码、PDF、markdown、截图、图表、白板照片、其他语言图片、音视频都可以进图——概念和关系被从所有媒介中抽出并连到同一张图上;视频则用 Whisper 在本地转写;代码侧通过 tree-sitter AST 支持 25 种编程语言。
这个定位有一个很具体的动机:README 提到 Andrej Karpathy 维护一个 /raw 文件夹,往里堆文章、推文、截图和笔记;graphify 给出的答案是每次查询比直接读原始文件少 71.5 倍的 token,且图谱在会话之间持久存在。这条基准数据在仓库 docs/how-it-works.md 中有更完整的说明:
| 语料 | 文件数 | 缩减倍数 |
|---|---|---|
| Karpathy 仓库 + 论文 + 图片 | 52 | 71.5x |
| graphify 源码 + Transformer 论文 | 4 | 5.4x |
| httpx(合成 Python 库) | 6 | 约 1x |
缩减比例随语料规模增长:6 个文件本身就能装进上下文窗口,图谱的价值在那里是结构清晰度而非压缩;到 52 个文件时节省才开始显著复利。仓库 worked/ 目录下保留了真实语料和实际输出(如 worked/karpathy-repos/graph.json 和 worked/karpathy-repos/GRAPH_REPORT.md),可以自行复跑验证。
工作原理:三段式管线(Three Passes)
挪威语 README 的 "Hvordan det fungerer" 一节概括了 graphify 的三遍处理流程:先做确定性 AST 遍历,用 LLM 之外的方式从代码文件里抽取结构;再用 faster-whisper 在本地转写音视频;最后让 Claude 子代理并行处理文档、文章、图片和转写文本。结果合并进一张 NetworkX 图,用 Leiden 算法做社区检测,再导出为交互式 HTML、可查询 JSON 和审阅报告。结合 docs/how-it-works.md 的细节,三遍管线可以更精确地描述:
Pass 1 — 代码结构(免费、零 API 调用) tree-sitter 解析代码文件,抽出类、函数、import、调用图和行内注释,全程本地、无 LLM,支持 25 种语言。SQL 文件有专门处理:表、视图、外键和 JOIN 关系也是确定性抽取。一个容易忽略的关键设计是:代码文件在常规管线中不送入 LLM 语义抽取器——如果语料全是代码,Pass 3 直接跳过,语义抽取只留给文档、论文、图片和转写文本。这也解释了为什么纯代码语料不需要任何 API key 就能完整建图。
Pass 2 — 视频与音频(本地、零 API 调用) faster-whisper 本地转写。为了让转写文本聚焦你的领域,转写 prompt 会用你代码图中当前的"god nodes"(连接度最高的概念)做种子。转写文本带缓存,重复运行跳过已处理文件。
Pass 3 — 文档、论文、图片(Claude 子代理、消耗 token)
Claude 并行处理 markdown、PDF、图片和转写文本。每个子代理读取一批文件并输出 JSON 片段(节点、边、组关系),片段最终合并为单图。进入 Pass 3 之前,可选的转换器会把 Office 文件(.docx/.xlsx,需 [office] extra)等格式转成 graphify-out/converted/ 下的 Markdown 边车文件再抽取。
代码并行抽取在 docs/how-it-works.md 中有量化说明:代码文件用 ProcessPoolExecutor 并行抽取,绕开 Python GIL 实现真正的多进程;84 个代码文件的语料上,并行 AST 抽取比串行快约 1.66 倍。
社区检测:Leiden 算法,不需要向量
社区发现使用 Leiden 算法——按边密度聚类的图聚类方法,连接密集的节点落入同一社区。值得注意的是 docs/how-it-works.md 的说明:"不需要嵌入"。Claude 抽出的语义相似边(semantically_similar_to)本身就在图里,直接影响社区形状——图结构本身就是相似性信号,没有独立的嵌入步骤,也没有向量数据库。这是 graphify 与 GraphRAG/向量检索路线的核心差异。Leiden 依赖 graspologic,在 pyproject.toml 中声明为可选 extra leiden,且限定 Python < 3.13。
置信度标签:EXTRACTED / INFERRED / AMBIGUOUS
挪威语 README 明确写到:每条关系都会被标记为 EXTRACTED、INFERRED(带置信度分数)或 AMBIGUOUS 之一。完整定义见 docs/how-it-works.md:
| 标签 | 含义 |
|---|---|
EXTRACTED |
直接来自源码(如函数调用、import) |
INFERRED |
Claude 做出的合理推断,附 confidence_score(0.0–1.0) |
AMBIGUOUS |
不确定——在报告中标出供人工审阅 |
EXTRACTED 边的置信度恒为 1.0;INFERRED 边使用离散评分档:
- 0.95 — 近乎确定(显式跨文件引用,唯一合理目标)
- 0.85 — 强证据(命名 + 上下文都吻合)
- 0.75 — 合理(上下文支持但非显式)
- 0.65 — 弱(仅命名相似)
- 0.55 — 推测性
这套离散档(而非连续打分)的好处是可审计:报告里每条 INFERRED 边都能对照标准判断可信程度,仓库中 tests/test_inferred_confidence_rubric.py 专门验证该评分规则。
安装:Python 3.10+ 与 PyPI 包 graphifyy
挪威语 README 给出的安装要求与命令:
- 要求:Python 3.10+,以及 Claude Code、Codex、OpenCode、Cursor 等任一 AI 助手;
- 官方包:PyPI 包名为
graphifyy(双 y),CLI 命令仍是graphify。
uv tool install graphifyy && graphify install
# 或 pipx
pipx install graphifyy && graphify install
# 或 pip
pip install graphifyy && graphify install
这些要求在 pyproject.toml 中一一对应:name = "graphifyy"、requires-python = ">=3.10"。两条 CLI 入口在 pyproject.toml 定义:
[project.scripts]
graphify = "graphify.__main__:main"
graphify-mcp = "graphify.serve:_main"
其中 graphify-mcp 对应 graphify/serve.py 提供的 MCP stdio/HTTP 服务器,把图谱暴露为 query_graph、get_node、get_neighbors、shortest_path 等工具。
依赖方面,核心包只声明了 networkx、numpy、rapidfuzz 和一组 tree-sitter 语法(pyproject.toml),Python、JavaScript、TypeScript、Go、Rust、Java、C/C++、C#、Ruby、Kotlin、Swift、Zig、Fortran、Bash 等语法默认随包安装;而 SQL、Pascal、OCaml、Common Lisp、Terraform/HCL、BYOND DreamMaker 等小众语法,以及 PDF、Office、视频转写、Neo4j/FalkorDB 推送、Ollama 等能力都以可选 extra 提供(pyproject.toml),例如 uv tool install "graphifyy[video]" 装 faster-whisper + yt-dlp,"graphifyy[sql]" 装 tree-sitter-sql。按需安装是刻意设计:[dm] extra 只有 Windows wheel,其余平台需要 C 工具链编译,保持可选可避免拖累所有人的默认安装。
输出产物:graphify-out/ 的四个部分
运行 /graphify . 之后,挪威语 README 展示的产物结构:
graphify-out/
├── graph.html 交互式图谱 —— 任意浏览器打开
├── GRAPH_REPORT.md god nodes、惊人连接、建议问题
├── graph.json 持久化图谱 —— 数周后仍可查询
└── cache/ SHA256 缓存 —— 重复运行只处理变更文件
各文件的作用与实现依据:
- graph.json — NetworkX 的 node-link 格式。每个节点含
id(稳定标识)、label(可读名)、file_type(code/document/paper/image/rationale)、source_file;每条边含source、target、relation(动词短语如calls、imports、implements、semantically_similar_to)、confidence(三档标签之一)、confidence_score(仅 INFERRED)、source_file。3 个以上节点的组关系存为超边,位于G.graph["hyperedges"]。完整格式定义见 docs/how-it-works.md。 - GRAPH_REPORT.md — 报告生成逻辑在 graphify/report.py,包含 "Surprising Connections" 等固定栏目;"why" 节点(
# NOTE:/# WHY:注释、docstring 中的设计理由)作为独立节点链接到被解释的代码,正是 README 所说"Hvorfor"栏目的来源。 - cache/ — 详见下一节的源码级解析。
- graph.html — 导出器实现在 graphify/exporters/html.py。
常用命令
挪威语 README 的 "Bruk"(使用)一节列出五个典型操作:
/graphify .
/graphify ./raw --update
/graphify query "hva kobler Attention til optimizeren?"
/graphify path "DigestAuth" "Response"
graphify hook install
graphify update ./src
逐条解读:
/graphify .— 对当前目录建图,产出上述四个产物;/graphify ./raw --update— 增量重抽取,只处理有变更的文件(依赖下文的 SHA256 内容指纹);/graphify query "..."— 对自然语言问题返回有范围的子图。query的实现入口在 graphify/analyze.py 一侧的查询打分逻辑,终端等价命令为graphify query "<question>";/graphify path "A" "B"— 追踪两个实体之间的最短路径,例如FastAPI --uses--> DefaultPlaceholder <--references-- get_request_handler() --references--> ModelField这类 3 跳结果;graphify hook install— 安装 git post-commit/post-checkout 钩子,提交和切分支时自动重建图谱(仅 AST 部分,零 API 成本),并注册 merge driver 使graph.json永远不会出现冲突标记;钩子安装逻辑见 graphify/hooks.py,graphify update ./src则用于git pull之后手动同步。
报告里能拿到什么
挪威语 README "Hva du får"(你得到什么)一节列出五样东西:
- God nodes(神节点) — 连接度最高的概念,一切流量都经过它们;
- Overraskende forbindelser(惊人连接) — 按"意外程度"排序的跨模块连接;
- Foreslåtte spørsmål(建议问题) — 图谱恰好有能力回答的问题;
- "Hvorfor"(为什么) — docstring 与设计理由被抽成独立节点,解释背后的架构决策;
- Token 基准 — 混合语料上 71.5x 的 token 缩减。
这五样在 docs/how-it-works.md 与 graphify/report.py 中都有对应实现;worked/ 目录里每个案例都带一份诚实的 review.md,记录图谱"对在哪里、错在哪里",例如 worked/httpx/GRAPH_REPORT.md 可以对照原始语料 worked/httpx/raw/ 逐条验证。
源码纵深:SHA256 缓存为什么能安全增量
挪威语 README 只说了一句"cache/ 是 SHA256 缓存,重复运行只处理变更文件",docs/how-it-works.md 补充了"每个文件按内容哈希指纹、重跑跳过未变更文件"。而 graphify/cache.py 的实现远比这句话复杂,值得展开:
文件指纹:缓存 key 是文件内容加相对路径的 SHA256(graphify/cache.py)。加入路径意味着"内容相同但位置不同"的文件不会互相污染缓存;首次命中后回退到完整 SHA256,避免小文件的前缀碰撞问题。
AST 缓存按版本命名空间:graphify/cache.py 有一段关键注释——AST 缓存条目是 graphify 自家抽取器代码的产物,只对该版本有效。如果 key 只按文件内容,那么新版本里修复了抽取 bug 后,旧缓存会把 bug 前的结果继续服务下去。因此 AST 缓存放在 cache/ast/v{version}-s{schema}/ 下,按包版本和缓存 schema 双命名空间,并在首次使用时清扫其他版本的残留目录(_cleanup_stale_ast_entries)。
语义缓存按 prompt 指纹:语义缓存条目是 LLM 的产物,只按内容 key 会在 prompt 变更后的新版本里继续回放旧 prompt 的条目,把不同"年代"的抽取结果混进一张图;但按包版本 key 又会让每个 patch release 都为未变更文件重新付费。最终方案是对抽取 prompt 本身做指纹(graphify/cache.py):条目存放在 cache/semantic/p{fingerprint}/ 下,prompt 没变的版本之间条目继续有效,prompt 真的变了才失效。
这个设计解释了 --update 为什么既快又安全:代码文件走版本化 AST 缓存,文档文件走 prompt 指纹语义缓存,两类缓存各自独立失效。相关行为有测试覆盖,如 tests/test_cache.py、tests/test_incremental.py。
隐私与本地优先
挪威语 README "Personvern"(隐私)一节的三句话承诺,与仓库实现一致:
- 代码文件通过 tree-sitter 本地处理,无 LLM 参与——纯代码语料的
graphify extract完全离线、无需 API key; - 视频用 faster-whisper 本地转写,不出机器;
- 无遥测、无用量追踪、无分析。
只有文档/PDF/图片的语义抽取会调用模型:在 IDE 内通过 /graphify 技能走当前会话的模型;无头 CI 场景(graphify extract)则按 docs/how-it-works.md 和 README 主文档说明的优先级自动检测后端(Gemini → Kimi → Claude → OpenAI → DeepSeek → Azure → Bedrock → Ollama),或直接 --backend ollama 走完全本地推理。语义后端的实现集中在 graphify/llm.py,其中 token 预算、分块、截断重试(GRAPHIFY_MAX_RETRY_DEPTH 控制二分深度)等机制都有对应的环境变量。
小结与延伸阅读
graphify 的核心思路可以压缩为三句话:代码结构靠确定性 AST 白拿,语义关系靠 LLM 子代理并行补齐,两者合并进一张带置信度标签的 NetworkX 图;增量靠内容指纹 + 版本化/prompt 指纹的双缓存体系;查询靠对 graph.json 的子图检索和最短路径追踪,而不是重新读文件。
想继续深入当前仓库,推荐按这条路线:
- docs/how-it-works.md — 管线、Leiden、置信度评分、token 基准的完整说明;
- ARCHITECTURE.md — 模块职责划分与添加新语言抽取器的方法;
- pyproject.toml — 包名、版本、语言语法依赖与全部可选 extra 的权威清单;
- worked/ — 真实语料的输入/输出/review 三元组,可复跑验证;
- tests/ — 覆盖语言、增量、缓存、置信度评分等行为的完整测试集,如 tests/test_languages.py、tests/test_minhash.py。
适用前提提醒:本文所有结论基于当前仓库快照(pyproject.toml 中版本 0.9.52,Python 3.10+);挪威语 README 属于较早的翻译快照(v4 时代措辞,如"25 种语言"),仓库主 README 与文档中已演进到更多语言与平台,具体数值以 docs/how-it-works.md 和源码为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
