graphify 提交钩子与 CLAUDE.md 原生集成:每次 git commit 自动重建知识图谱
graphify 会在项目下生成可查询的知识图谱(graphify-out/graph.json、GRAPH_REPORT.md),但若每次代码变更都要手动触发一次全量重建,图谱会迅速过期、失去价值。本文面向 graphify 的 Pi(以及 Claude Code 等)Agent 使用场景,基于 hooks 参考文档 讲解两种"自动化"方案:post-commit git 钩子(每次 commit 自动增量重建图谱)与 原生 CLAUDE.md 集成(让 Claude Code/Pi 会话天然感知图谱)。读完本文,你将掌握 graphify hook install/uninstall/status 与 graphify claude install/uninstall 的完整用法、底层触发机制,以及全部可用环境变量与调优手段。
一、核心背景:把"手动重建"变成"随提交自动发生"
graphify 的完整流水线(详见 skill 主文档)通常由用户显式触发,产物落在 graphify-out/:graph.json(结构化图谱)、GRAPH_REPORT.md(社区、枢纽节点、惊喜连接等人类可读报告)、graph.html(可视化)。增量更新模式(/graphify --update)只对新增/变更文件重新抽取,比全量重建便宜得多,但依然需要一次人工调用。
两个"接线"方案解决的问题正是这个"最后一次调用":
- git 提交钩子:把增量重建挂到每次
git commit之后,触发一次、无需任何后台进程、与编辑器无关(只要你还在用 git,换任何编辑器都会触发)。 - CLAUDE.md 原生集成:把"先查图谱、改完代码再更新图谱"的规则写进项目本地的
CLAUDE.md,让 Agent 会话从第一天起就把图谱当作默认的代码库知识入口,不再需要每次手动/graphify。
注意:钩子与 CLAUDE.md 集成只针对代码变更做 AST 增量重建(确定性、无 LLM、零 API 成本)。文档、图片等资源的变更不在钩子覆盖范围内,需要手动执行
graphify update .(会话内等价于/graphify --update)刷新。
二、post-commit 钩子:三个命令完成安装与生命周期管理
参考文档给出的核心命令极简:
graphify hook install # 安装
graphify hook uninstall # 移除
graphify hook status # 检查
安装后,每次 git commit 钩子会自动:
- 通过
git diff HEAD~1 HEAD找出本次提交变更的代码文件; - 仅对这些变更文件重新执行 AST 抽取(增量);
- 重建
graphify-out/graph.json与graphify-out/GRAPH_REPORT.md。
文档同时给出了两条重要的行为约定:
- 文档/图片类变更会被钩子忽略——这类资源需要手动跑
/graphify --update; - 若已存在其他 post-commit 钩子,graphify 不会覆盖,而是追加到现有钩子末尾。
从源码看"安装"到底做了什么
打开 hooks.py 可以看到 install()(hooks.py)实际安装的是三类东西,status 也会分别报告每一类的状态:
| 安装产物 | 用途 | 标记(marker) |
|---|---|---|
.git/hooks/post-commit |
commit 后增量重建 | # graphify-hook-start … # graphify-hook-end |
.git/hooks/post-checkout |
切换分支后全量重建 | # graphify-checkout-hook-start … # graphify-checkout-hook-end |
git 合并驱动 merge.graphify |
graph.json 的 union 合并 |
.gitattributes 中 graphify-out/graph.json merge=graphify |
几个实现细节值得注意:
- append 而非覆盖:
_install_hook()(hooks.py)在读入已有钩子后,若内容中已存在 graphify 标记则原位更新这段内容(幂等),否则把 graphify 脚本追加到文件末尾;全新文件则补写#!/bin/sh头并加可执行权限。对应测试见 tests/test_hooks.py。 - 尊重
core.hooksPath/ Husky:hooks 目录通过git rev-parse --git-path hooks解析(hooks.py),而不是手写解析.git/config,因此能正确处理 Husky(core.hooksPath指向.husky/_)、includeIf 与 linked worktree;当目录以_结尾时还会自动回退到用户可编辑的父目录(.husky/),见_user_hooks_dir()(hooks.py)。 - 安装位置:
install()会从当前目录向上查找最近的 git 仓库根(.git目录),找不到会抛出No git repository found。所以命令应在目标仓库根目录执行。
增量重建的跳过逻辑与"防抖"设计
生成的 post-commit 脚本在真正触发重建前会做一系列判断(hooks.py),理解它们有助于排查"为什么提交后没重建":
- rebase / merge / cherry-pick 期间跳过:检测
GIT_DIR/rebase-merge、rebase-apply、MERGE_HEAD、CHERRY_PICK_HEAD存在即退出,避免阻塞--continue时的未暂存变更; GRAPHIFY_SKIP_HOOK=1可显式跳过(post-checkout 同样遵守,保证行为一致);- linked worktree 中跳过:主 checkout 的
graphify-out/才归属权威图谱,从 worktree 重建会产生多余的增量图并与git clean竞争,故比较git rev-parse --git-dir与--git-common-dir来识别并退出(hooks.py); - 仅 graphify-out/ 产物变化时跳过:避免"图谱输出被纳入版本控制"时提交产物→触发重建→再提交产物的死循环;
- 无变更文件(空 diff)直接退出。
此外脚本还会 export PYTHONHASHSEED=0(保证 louvain 社区划分结果在多次运行间可复现),并在 Windows/MSYS 环境默认把 GRAPHIFY_MAX_WORKERS 降为 1(GUI git 客户端传入的管道句柄可能不稳定,串行更安全)。
三、钩子重建是"分离式后台进程":提交绝不阻塞
参考文档强调钩子"不需要后台进程、每次 commit 只触发一次"。实际上重建本身是在分离的子进程中执行的,从而让 git commit 立即返回:
- 旧实现依赖
nohup ... &,而 Git for Windows 自带的 MSYS shell 没有nohup/setsid,导致重建静默失败。现在由外层 Python 启动器负责分离(POSIX 用start_new_session,Windows 用CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP),跨平台行为一致,见_LAUNCHER_TEMPLATE(hooks.py)。 - 子进程的输出写入日志
~/.cache/graphify-rebuild.log(可用GRAPHIFY_REBUILD_LOG覆盖)。提交时终端只打印一行提示,重建过程完全在后台完成。 - 重建核心调用
graphify.watch._rebuild_code(...)(watch.py),并把变更文件清单经GRAPHIFY_CHANGED环境变量传入;post-commit走带changed_paths的增量路径,post-checkout因分支切换可能牵动任意文件而走全量路径。重建前还会调用_apply_resource_limits()(watch.py)做 best-effort 的资源限制。 - 若项目存在"工作记忆"(
graphify-out/memory/*.md),重建后还会 best-effort 刷新反思笔记reflections/LESSONS.md,失败不影响钩子退出码。
找不到解释器怎么办:四级探测链
graphify 可能经 uv tool、pipx、venv 或系统安装,钩子触发时(尤其是 GUI git 客户端/CI,PATH 往往很精简)未必能找到解释器。为此安装时会固定安装时解释器的绝对路径,运行时再按优先级探测(hooks.py):
- 安装时钉住的
sys.executable(过滤掉含 shell 元字符的非法路径,见_pinned_python(),hooks.py); graphify-out/.graphify_python记录的解释器(skill 与 CLI 都会写此文件,内容同样经过字符白名单校验);- 从 PATH 上的
graphify启动器解析 shebang / 推断同目录python(.exe); - 扫描
uv tool环境(~/.local/share/uv/tools、$HOME/AppData/Roaming/uv/tools,尊重UV_TOOL_DIR),最后回退python3/python。
探测使用 importlib.util.find_spec 而非真正导入 graphify,避免每次提交前白白付出数秒的整包导入开销。若全部探测失败,钩子打印提示并安全退出(exit 0),不会阻塞提交。
四、钩子级可调参数与环境变量速查
以下变量均可在源码注释与生成脚本中找到依据,按需设置在 shell 环境或提交命令前:
| 环境变量 | 默认值 | 作用 | 依据 |
|---|---|---|---|
GRAPHIFY_SKIP_HOOK |
0 |
设为 1 时跳过钩子触发的重建(post-commit 与 post-checkout 均生效) |
hooks.py |
GRAPHIFY_REBUILD_TIMEOUT |
600 |
重建超时(秒),超时后钩子进程以非零退出 | hooks.py |
GRAPHIFY_FORCE |
空 | 为 1/true/yes 时强制全量重建,绕过增量 |
hooks.py |
GRAPHIFY_OUT |
graphify-out |
输出目录名;也可由 .graphify_root 侧车文件决定重建根目录 |
hooks.py |
GRAPHIFY_REBUILD_LOG |
~/.cache/graphify-rebuild.log |
后台重建进程的日志路径 | hooks.py |
GRAPHIFY_MAX_WORKERS |
按平台 | Windows/MSYS 默认降为 1,可显式覆盖恢复并行 |
hooks.py |
GRAPHIFY_CHANGED |
— | 内部传递本次变更文件清单(换行分隔) | hooks.py |
PYTHONHASHSEED |
0 |
钩子固定写入,保证社区划分结果可复现 | hooks.py |
另一个项目级配置入口是仓库根目录的 .graphifyrc 文件(key=value 格式,# 开头为注释)。目前支持 viz_node_limit(非负整数,例如 viz_node_limit=0),会在安装钩子时烘焙为 export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-<值>}"(见 _load_graphifyrc() 与 install(),hooks.py)。注意烘焙时使用 :- 默认值形式,因此单次运行的显式环境变量仍可覆盖项目默认值;配置被修改后,graphify hook status 会提示钩子"out of date",需要重跑 install 同步。解析出错时 status 会打印 warning 而不崩溃。
五、graph.json 的合并驱动:多人协作不丢边
代码仓库一般都会被多人提交、切分支、合并。如果 graphify-out/graph.json 被纳入版本控制,常规的文本合并几乎必然冲突。因此 graphify hook install 会顺带注册一个 git 合并驱动:
- git 配置:
merge.graphify.driver(graphify merge-driver),解释器同样以安装时钉住的方式传入,确保合并时即使 PATH 无 graphify 也能运行; .gitattributes:写入graphify-out/graph.json merge=graphify(默认输出目录被绝对路径覆盖时回退为字面graphify-out,见_merge_attr_line(),hooks.py)。
这样合并冲突时 git 调用 graphify merge-driver %O %A %B 对两份 graph.json 做 union 合并。graphify hook status 会分别报告 post-commit、post-checkout、merge driver 三项状态(含 not registered、partially registered、installed/out of date 等细分),uninstall 则把三者全部回滚。
六、原生 CLAUDE.md 集成:让 Agent 会话始终"先查图谱"
git 钩子解决的是"图谱如何保鲜",CLAUDE.md 集成解决的是"Agent 如何用起来"。参考文档指出,只需在项目里执行一次:
graphify claude install
它会向项目本地的 CLAUDE.md 写入一个 ## graphify 小节,内容来自仓库打包的 claude-md.md(该 always-on 块由 tools/skillgen 生成、skillgen --check 防漂移,安装器通过 _replace_or_append_section() 原样注入,见 install.py)。写入的规则本质上是:
- 回答代码库问题前先查图谱:
graphify query "<question>"(存在graphify-out/graph.json时),关系用graphify path "<A>" "<B>",概念聚焦用graphify explain "<concept>"——返回的是裁剪后的子图,通常远小于全文 grep; - 有 wiki 先用 wiki:若
graphify-out/wiki/index.md存在,用它做大范围导航而不是直接翻源码; GRAPH_REPORT.md仅作兜底:只在 query/path/explain 信息不足或需要宏观架构审视时通读;- 改完代码记得更新图谱:
graphify update .(仅 AST、无 API 成本)。
这样后续会话无需再手动 /graphify,Agent 在回答架构、文件关系类问题时会被强制先落入图谱这张"地图"。
不止写文档:还注册 PreToolUse 钩子
graphify claude install 的"原生集成"并不止于一段 markdown。它还会向 .claude/settings.json 写入 PreToolUse 钩子(install.py),匹配 Glob|Grep、Bash|Grep、Read|Glob 等工具,在 Agent 尝试搜索源码前注入提示:
- 搜索提示:图谱存在时,必须先
graphify query "<question>",只有定位之后或需要修改/调试具体行时才允许 grep(消息载荷见 cli.py); - 读取提示:读源码文件前应先 query/explain/path 定向,该规则对子代理同样生效;检测到文件在最近一次构建后发生过变更时,还会提示图谱可能过期并建议
graphify update(见 cli.py); - strict 模式:可选地把首次原始文件读取直接 deny,强制先跑一次
graphify query(可用GRAPHIFY_HOOK_STRICT=0关闭)。
这些钩子的命令经 _resolve_graphify_exe() 解析为绝对路径(项目级安装则使用裸 graphify 命令以便配置随仓库提交),在 sh、cmd.exe、PowerShell 下均可解析。uninstall 会同时清理 CLAUDE.md 小节与 .claude/settings.json/settings.local.json 中的钩子(install.py):
graphify claude uninstall # 移除 graphify section 与 PreToolUse 钩子
配套测试覆盖了 roundtrip、升级、字符串精确匹配等边界,见 test_install_roundtrip.py 与 test_install.py。
七、方案对比与适用建议
| 关注点 | git 提交钩子 | CLAUDE.md 原生集成 |
|---|---|---|
| 触发时机 | 每次 git commit(+ 分支切换) |
每次 Agent 会话开始前加载规则 |
| 解决的问题 | 图谱保鲜(增量重建) | 图谱被优先使用(知识入口) |
| 适用对象 | 代码变更的持续追踪 | Claude Code / Pi 等以 CLAUDE.md 为上下文载体的 Agent |
| 文档/图片变更 | 不覆盖,需手动 graphify update . |
规则文本本身不含此路径 |
| 需要后台进程 | 否(提交触发、分离执行) | 否 |
推荐落地顺序:先在仓库执行 graphify claude install 让 Agent 建立"先查图谱"的习惯,再执行 graphify hook install 让图谱随提交自动保鲜;两者互不冲突,hook status 与 claude uninstall 可随时用于诊断和回滚。若你使用 Codex、Cursor、Gemini 等其他宿主,graphify 提供了对应的平台安装器(agents/codex/gemini 等,见 skill 主文档 的分发结构,各平台参考文件布局在 graphify/skills 下),集成思路与本文一致:一份 always-on 规则 + 一层工具级钩子。
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