Graphify 知识图谱自动增量重建:Git post-commit 钩子与 CLAUDE.md 原生集成实战
导读
graphify 把代码库(连同文档、SQL schema、配置、PDF)解析成位于 graphify-out/ 下的可查询知识图谱(graph.json、GRAPH_REPORT.md),但要让它始终反映最新的代码,就必须在代码变更后重新构建图谱。本指南讲解 graphify 提供的两条"自动维护"路径:Git post-commit 钩子(每次 git commit 后自动增量重建,无需常驻后台进程、与任何编辑器/IDE 解耦)与 CLAUDE.md 原生集成(把 graphify 的规则写入项目 CLAUDE.md,让 Claude Code 会话中图谱"常开")。读完你就能在自己的仓库上安装、检查、卸载这两种集成,并理解它们在 graphify/hooks.py、graphify/install.py、graphify/watch.py 中的底层实现。
本文面向的内容是仓库中随 skill 分发的钩子与集成参考文档 graphify/skills/opencode/references/hooks.md(同名文档也存在于 tools/skillgen/expected/ 下的生成产物中,二者内容一致)。
一、两种"常开"集成:适用场景与分工
默认的 /graphify <path> 构建是一次性全量管道(见 graphify/skill-opencode.md),生成的图谱不会自己跟上代码演化。于是 graphify 提供了两种互补的自动更新手段:
| 集成方式 | 触发机制 | 谁来执行 | 典型场景 |
|---|---|---|---|
graphify hook install |
git 层 post-commit(每个 commit 触发一次) |
机器上的 git | 任何编辑器/CLI/CI 环境,只要走 git commit 就能自动重建 |
graphify claude install |
Agent 会话内的 CLAUDE.md 规则 |
Claude Code 会话 | 让 Agent 在回答代码问题时"先查图谱、改完代码后重建图谱" |
前者解决"物理层"的同步:每次提交后代码变了,图谱跟着变;后者解决"会话层"的同步:让 Agent 的每次问答都建立在最新图谱上,不再需要人工敲 /graphify。两者可以同时启用,职责不冲突。
注意:本文引用的是随 opencode skill 分发的 hooks 参考文档,其中的命令(
graphify hook …、graphify claude …)是 graphify CLI 的全局子命令,不依赖特定 Agent 平台。
二、Git post-commit 钩子:安装、卸载与状态检查
安装钩子只需在目标 git 仓库根目录下执行三条命令(原文命令,完整继承):
graphify hook install # install
graphify hook uninstall # remove
graphify hook status # check
install:在最近的 git 仓库中安装 post-commit 与 post-checkout 两个钩子,并注册 graph.json 的 union merge driver;uninstall:只移除 graphify 写入的部分,保留钩子文件里其他人/工具已有的内容;status:只读诊断,报告 post-commit、post-checkout、merge driver 三项的安装状态,若钩子内容与当前配置已不一致还会提示 "out of date"。
graphify hook status 典型输出形如:
post-commit: installed
post-checkout: installed
merge driver: registered
viz node limit: 0 # 仅当 .graphifyrc 配置了该选项时显示
CLI 侧的命令分发位于 graphify/cli.py,三个子命令分别映射到 graphify/hooks.py 中的 install() / uninstall() / status() 三个函数。
2.1 触发时机与工作方式
安装成功后,每次 git commit 都会触发一次 post-commit 钩子,完整链路为:
- 钩子先用
git diff --name-only HEAD~1 HEAD找出本次提交改动的文件(首个提交等没有 HEAD~1 时回退为git diff HEAD,见 graphify/hooks.py); - 过滤掉仅
graphify-out/产物自身的变化(避免"图谱输出被 git 跟踪 → 钩子又触发重建"的死循环,见 graphify/hooks.py); - 把待处理文件列表通过环境变量交给一个分离的后台 Python 进程;
- 该进程调用 graphify/watch.py 的
_rebuild_code(root, changed_paths=changed),只对改动的代码文件重新执行 AST 提取,未变化的文件节点从既有graph.json中保留(删除的文件则从保留集中剔除); - 重建产物
graph.json与GRAPH_REPORT.md(见 graphify/watch.py)。
不需要任何常驻后台进程或 watcher 守护——每次 commit 触发一次,恢复期间零开销;因为是纯 git 层的 post-commit 机制,所以与编辑器无关(VS Code、JetBrains、Vim、命令行都适用),也不需要 agent 会话在线。
代码重建全程为确定性 AST 解析,不依赖 LLM、不消耗 API token,这从源码注释 "Auto-rebuilds the knowledge graph after each commit (code files only, no LLM needed)" 可以直接印证(graphify/hooks.py)。
2.2 文档与图片变化会被忽略
钩子只负责代码的 AST 增量重建:文档(.md 等)与图片的改动会被钩子忽略——因为语义抽取需要 LLM/视觉模型,而钩子刻意不进入 LLM 流程。遇到这类变更,原文文档给出的做法是手动执行:
/graphify --update # 在 Agent 会话中
# 或等价的 CLI 形式
graphify update .
这里值得注意:graphify/install.py 的 always-on 集成块(见 graphify/always_on/claude-md.md)同样要求 Agent "After modifying code, run graphify update .",与钩子的"代码只归 git 管、文档/图片手动更新"策略完全自洽。
2.3 与既有钩子共存:追加而非覆盖
如果仓库里已经存在其他工具(如 lint 检查、提交信息规范、CI 通知)写入的 post-commit 钩子,graphify 不会清空或覆盖它,而是把自己的代码块追加到文件末尾;卸载时也只删除由 marker 包裹的 graphify 段落,保留其余内容。
实现上每个钩子文件用成对的 marker 界定归属:
- post-commit:
# graphify-hook-start…# graphify-hook-end - post-checkout:
# graphify-checkout-hook-start…# graphify-checkout-hook-end
对应常量与"追加/就地更新"逻辑见 graphify/hooks.py 与 _install_hook() / _uninstall_hook()(graphify/hooks.py)。_install_hook 是幂等的:若 marker 已存在且内容一致,返回 "already installed",不会重复追加;若内容过期则就地替换 graphify 段落(这对升级后钩子脚本更新很有用)。
2.4 install 还顺带做了什么
graphify hook install 不止装 post-commit。从 graphify/hooks.py 可以看到它一次完成三件事:
- post-commit 钩子:每次提交后增量重建;
- post-checkout 钩子:每次
git checkout切换分支时做一次全量代码重建(分支切换可能改动任意文件,所以不走增量、以完整重建路径处理,见 graphify/hooks.py); - 注册 graph.json 的 union merge driver:向 git config 写入
merge.graphify.driver,并在.gitattributes增加一行graphify-out/graph.json merge=graphify(graphify/hooks.py),多人协作合并且图谱输出被 git 跟踪时,用 graphify 自身的合并驱动避免冲突。
另外安装器会**把安装时运行的 Python 解释器绝对路径"钉死"**进钩子脚本(__PINNED_PYTHON__ 占位符,见 graphify/hooks.py)。这样即使用 GUI 客户端或 CI 等 PATH 极简的环境触发钩子,也能找到正确的解释器,而不会因 ~/.local/bin 不在 PATH 上而静默失败。
钩子目录的解析尊重 core.hooksPath(例如 Husky 场景),通过 git rev-parse --git-path hooks 交给 git 自己解析,而不是手写解析 .git/config——相关兼容处理与注释见 graphify/hooks.py。
三、重建细节深挖:跳过高开销步骤的工程化设计
参考文档对钩子只给了"一句话"级描述,但 graphify/hooks.py 的生成脚本里隐藏了大量工程细节,值得展开说明。
3.1 重建是"分离进程"执行的,commit 不被阻塞
钩子触发后 git commit 立即返回,重建在一个完全分离的后台进程里进行。这点非常关键:全仓库重建可能耗时很长,若同步跑在 post-commit 里会阻塞 shell。
跨平台分离的实现值得一提:它没有用传统的 nohup … &(Git for Windows 自带的 MSYS shell 没有 nohup/setsid,会导致重建静默从未运行),而是让 Python 自己做 detach——外层小进程 spawn 真正的重建进程后立即返回;POSIX 用 start_new_session(等价 setsid),Windows 用 CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP(并尽可能 CREATE_BREAKAWAY_FROM_JOB),避免每次 commit 弹出一个空白的控制台窗口。相关设计讨论完整记录在 graphify/hooks.py。
后台进程的输出统一写入 ~/.cache/graphify-rebuild.log(可用环境变量 GRAPHIFY_REBUILD_LOG 覆盖),钩子返回前会打印一行提示,例如:
[graphify hook] launching background rebuild (log: /home/you/.cache/graphify-rebuild.log)
重建若超时或失败,会以非零状态退出并在日志中留下 [graphify hook] Rebuild failed: … 之类的明确信息(graphify/hooks.py)——即使后台失败也不会把失败传染给已成功的 git commit 本身。
3.2 并发保护与排队
多人/多工具频繁提交时,多个 post-commit 可能几乎同时触发。_rebuild_code 用每仓库一把非阻塞 flock 防止重建堆积(graphify/watch.py):
- 增量重建(带
changed_paths)抢锁失败时,会把本次改动写入待处理队列,由正在持锁的重建完成后统一 drain、合并成一次重建,避免改动集丢失; - 全量重建(无
changed_paths)直接吞并队列——它本就覆盖所有文件; - 提交/切分支连环触发时,锁保证不会互相踩踏。
3.3 钩子的"自动跳过"场景
为了不干扰用户工作流,钩子内置了多道退出闸门,全部满足时才会真正启动重建:
- 处于 rebase / merge / cherry-pick 中间状态(存在
rebase-merge、rebase-apply、MERGE_HEAD、CHERRY_PICK_HEAD时跳过,避免阻塞--continue); - 设置了
GRAPHIFY_SKIP_HOOK=1(显式退出开关,post-commit 与 post-checkout 都认); - 在 linked worktree 中提交(
git worktree add场景下主 checkout 才拥有规范产物,从 worktree 重建会写出无人需要的增量图,还会与 CI 的git clean竞态); - 改动只涉及
graphify-out/产物本身; - post-checkout 额外要求:必须是分支切换(第三个参数为 1)、新旧 HEAD 不同、且
graphify-out/已存在(图从未建过则不建)。
对应逻辑可见 graphify/hooks.py。从源码结构还可推断,重建进程内设置了 PYTHONHASHSEED=0 固定 Python 字符串哈希随机化——因为 louvain 社区检测会遍历字符串 key 的集合,哈希种子不定会让社区划分在每次运行时抖动,钉死后 graphify-out 的产出才是可复现的(graphify/hooks.py)。
3.4 可调环境变量与 .graphifyrc
钩子生成的脚本预留了若干可用环境变量(均在 graphify/hooks.py 中可见),整理如下:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
GRAPHIFY_SKIP_HOOK |
未设置 | 设为 1 时本次跳过重建(两个钩子都生效) |
GRAPHIFY_REBUILD_TIMEOUT |
600 |
重建超时上限(秒);设为 0 表示不限时。POSIX 用 SIGALRM,Windows 用 watchdog 线程兜底 |
GRAPHIFY_REBUILD_LOG |
~/.cache/graphify-rebuild.log |
后台重建输出日志路径 |
GRAPHIFY_FORCE |
未设置 | 1/true/yes 时绕过 to_json 的节点数收缩保护,允许重建后图谱节点变少(重构删代码时用) |
GRAPHIFY_OUT |
graphify-out |
输出目录名;钩子也会读取其中的 .graphify_root 以定位真正的仓库根 |
GRAPHIFY_MAX_WORKERS |
自动 | Git for Windows/MSYS 环境默认限为 1(串行),避免继承 GUI 客户端脆弱的管道句柄 |
GRAPHIFY_VIZ_NODE_LIMIT |
来自 .graphifyrc |
可视化节点上限,可单次覆盖仓库默认 |
其中 GRAPHIFY_VIZ_NODE_LIMIT 的项目级默认值来自仓库根目录的 .graphifyrc 文件(key=value 格式,支持 # 注释),目前唯一支持的键是 viz_node_limit,如:
# graphify-out 可视化上限
viz_node_limit=0
install 时会把它烘焙进钩子脚本(形式为 ${GRAPHIFY_VIZ_NODE_LIMIT:-<n>},保证一次性的命令行覆盖仍然生效),status 校验钩子里的值与 .graphifyrc 是否一致。配置解析器见 graphify/hooks.py。
四、CLAUDE.md 原生集成:让图谱在 Claude Code 会话中"常开"
第二部分是每项目运行一次的 Agent 集成。在项目根目录执行:
graphify claude install
这会做两件事(实现见 graphify/install.py):
- 向项目根目录的
CLAUDE.md写入一个## graphify小节(若文件不存在则新建,若已存在同名节则更新); - 向
.claude/settings.json注册 graphify 的 PreToolUse 钩子,让 Claude Code 在调用搜索/读取类工具前先考虑走图谱查询。
此后不再需要手动 /graphify——新会话加载 CLAUDE.md 时就会看到这些规则,自动遵守。集成块内容由仓库内的 always-on 模板 graphify/always_on/claude-md.md 注入(由 graphify/install.py 读取、_replace_or_append_section 落盘)。
写入的 ## graphify 小节核心规则如下(模板原文):
- 先查图谱:涉及代码库的问题,若
graphify-out/graph.json存在,先运行graphify query "<question>";查询关系用graphify path "<A>" "<B>",聚焦概念用graphify explain "<concept>"。这三者返回的是作用域子图,通常远小于整份报告或原始 grep 输出; - 优先 wiki 导航:若
graphify-out/wiki/index.md存在,用它做广度导航,而非直接翻源码; - 大报告最后兜底:
graphify-out/GRAPH_REPORT.md只用于整体架构审阅,或在 query/path/explain 信息不足时再读; - 改码即更新:修改代码后运行
graphify update .让图谱跟上(仅 AST、无 API 成本)。
配套的 CLI 子命令:
graphify claude install # 写入 ## graphify 小节并注册 PreToolUse 钩子
graphify claude uninstall # 移除该小节及相关钩子
卸载是双向清理(graphify/install.py):除了项目根 CLAUDE.md,还会检查 CLAUDE.local.md、.claude/CLAUDE.local.md(用户可能把规则挪到这些本地文件以避免入库)以及 .claude/settings.json / .claude/settings.local.json 中的 graphify PreToolUse 钩子;若某文件因移除小节而变空,则直接删除该文件。安装与卸载均保持幂等(重复执行 "already configured / no change")。
关于 strict 模式:
claude_install支持可选 strict 参数,开启后会话中第一次裸文件读取会被拦截,直到先跑过一次graphify query(详见 graphify/install.py),适合希望强制"图谱优先"的团队,属于参考文档之外的进阶选项。
五、何时需要手动 update
即便装好了钩子与 CLAUDE.md 集成,以下场景仍应手动执行 graphify update(Agent 会话内对应 /graphify --update):
- 新增/改动了文档、图片、PDF——钩子只处理代码的 AST 重建,语义抽取类内容必须手动跑增量管道;
- 需要立即在本次会话内让图谱反映刚写的代码,等不及下一个 commit 触发;
- 在非 git 目录、或未安装钩子的机器上工作;
- 希望强制执行一次全量一致性检查(
graphify update . --force类选项可绕过收缩保护)。
graphify update 走的是与钩子完全相同的 _rebuild_code 路径(只是阻塞等待锁),所以产物与提交触发的重建保持一致。
六、相关源码与测试参考
想深入验证本文所述行为,可从仓库内以下路径继续跟进:
- 钩子脚本生成、安装/卸载/状态、解释器探测、merge driver: graphify/hooks.py
- 增量重建核心
_rebuild_code与并发锁: graphify/watch.py - CLI 子命令分发(
hook、claude、install等): graphify/cli.py - 各平台集成安装/卸载器(
claude_install/claude_uninstall等): graphify/install.py - CLAUDE.md 注入模板(
## graphify小节原文): graphify/always_on/claude-md.md - skill 主文件中指向本文参考文档的入口: graphify/skill-opencode.md
- 参考文档的本体: graphify/skills/opencode/references/hooks.md
仓库的测试目录(tests/)为这些机制提供了回归覆盖,例如钩子逻辑相关测试 tests/test_hooks.py、安装/卸载相关 tests/test_install.py、tests/test_install_roundtrip.py、tests/test_install_references.py,以及 CLAUDE.md 集成相关 tests/test_claude_md.py 等。
结语
一条原则贯穿全文:钩子管代码,Agent 规则管会话,LLM 工作留给手动 update。graphify hook install 用一次安装换来"每次提交自动增量重建、不阻塞、不依赖编辑器、不消耗 API"的图维护机制;graphify claude install 则把"先查图谱、改后重建"固化进每个 Claude Code 会话。两条路径配合 graphify/hooks.py 中沉淀的工程细节(分离进程、解释器钉死、并发排队、rebase/worktree 跳过、merge driver),让知识图谱在真实的多人协作节奏中始终保持新鲜。
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 StartedRust0627
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