graphify 钩子机制详解:post-commit 自动重建图谱与 CLAUDE.md 原生集成
graphify 提供了两条把知识图谱“常驻化”的集成路径:一是 git post-commit / post-checkout 钩子,让每次提交或切分支后在后台自动重建 graph.json;二是把 ## graphify 规则段写入项目 CLAUDE.md,让 Claude Code 会话在回答代码库问题前自动查图、改完代码后自动重建。本文基于仓库内参考文档 hooks.md 与对应实现源码 hooks.py、install.py,完整讲解这两条路径的安装命令、触发行为、钩子脚本内部机制与配套配置项,帮助你在真实项目中把图谱保鲜机制落地。
1. 两条集成路径的分工
graphify 的“保持图谱新鲜”问题有两个典型场景,对应两种集成方式:
| 场景 | 集成方式 | 命令 | 实现位置 |
|---|---|---|---|
每次 git commit / 切分支后自动重建 |
git hooks(post-commit + post-checkout) | graphify hook install |
graphify/hooks.py |
| Claude Code 会话常驻感知图谱 | 写入本地 CLAUDE.md + PreToolUse 钩子 |
graphify claude install |
graphify/install.py |
CLI 入口在 cli.py:graphify hook [install|uninstall|status] 三个子命令分别转调 graphify.hooks 中的 install / uninstall / status。
2. git post-commit 钩子:提交后自动重建图谱
参考文档给出的基本用法只有三条命令,无后台常驻进程——每次提交触发一次,与任何编辑器兼容:
graphify hook install # 安装
graphify hook uninstall # 移除
graphify hook status # 查看状态
提交发生后,钩子通过 git diff 检测哪些代码文件发生了变化,对这些文件重新执行 AST 抽取,并重建 graph.json 与 GRAPH_REPORT.md。文档/图片的变更会被钩子忽略——这类变更需要手动执行 /graphify --update。
一个容易被忽略但很实用的行为:如果项目里已经存在 post-commit 钩子(比如 Husky 写入的脚本),graphify 会追加(append)而不是覆盖,见 hooks.py 中的 _install_hook。
2.1 实际安装了什么:post-commit + post-checkout + 合并驱动
从 hooks.py 的 install() 看,graphify hook install 一次性完成三件事:
- post-commit 钩子:块首尾带标记
# graphify-hook-start/# graphify-hook-end(常量_HOOK_MARKER),便于重复安装时就地更新、卸载时精确切除,不影响同一文件里其他工具的内容; - post-checkout 钩子:只在分支切换(第三个参数为
1)且graphify-out/已存在时触发全量重建——切分支可能触碰任意文件,增量 diff 不适用,因此走全量路径; - git 合并驱动注册:通过
git config写入merge.graphify.driver = graphify merge-driver %O %A %B,并在.gitattributes追加graphify-out/graph.json merge=graphify,让 graph.json 的冲突以并集方式合并(见_register_merge_driver)。
status 输出会逐项报告三者状态(installed / not installed / 合并驱动 registered 与否),并校验钩子里烤入的可视化节点上限是否与 .graphifyrc 一致,不一致时提示 out of date(status())。
2.2 钩子脚本内部机制(源码级)
生成的钩子脚本模板是 _HOOK_SCRIPT,其运行流程值得逐段了解:
- 确定性聚类:
export PYTHONHASHSEED=0。networkx 的 louvain 社区发现会遍历字符串键的集合,其顺序受进程级哈希种子随机化影响,钉住种子可让graphify-out结果跨次可复现。 - 冲突期跳过:存在
rebase-merge/rebase-apply/MERGE_HEAD/CHERRY_PICK_HEAD时直接exit 0,避免阻断git rebase --continue等流程。 - 手动开关:
GRAPHIFY_SKIP_HOOK=1可临时禁用重建。 - worktree 防护:linked worktree 中
git-dir != git-common-dir,此时跳过重建,防止在错误的检出里写出“野”的增量图谱(_WORKTREE_GUARD)。 - 变更检测与自环防护:
CHANGED=$(git diff --name-only HEAD~1 HEAD ...);若本次提交只改了graphify-out/下的产物(比如把图谱提交进了 git),则跳过,避免“重建→产物变化→再重建”的循环。 - Python 解释器探测(
_PYTHON_DETECT):按“安装时钉死的sys.executable→graphify-out/.graphify_python→ PATH 上 graphify 启动器的 shebang →uv tool环境扫描 →python3/python”的顺序探测,每个候选都用importlib.util.find_spec('graphify')轻量验证而不真正 import 整个包,规避冷启动下数秒级的同步阻塞。 - 跨平台后台启动:重建以完全脱离的 Python 子进程运行(
_LAUNCHER_TEMPLATE),POSIX 用start_new_session=True,Windows 用CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP,git commit 立即返回,不会阻塞 shell;这是为了绕开 Git for Windows 自带 MSYS shell 缺少nohup/setsid的问题。
后台重建本体的核心代码在 _REBUILD_BODY_COMMIT:从环境变量 GRAPHIFY_CHANGED 拿到变更文件列表,调用 graphify.watch 的 _rebuild_code(root, changed_paths=changed, force=...) 做增量重建;若 graphify-out/memory/ 下有保存的 Q&A 记录,还会顺带刷新 reflections/LESSONS.md(尽力而为,失败不影响钩子)。
2.3 可用配置项与环境变量
钩子与重建过程支持以下可调项(均从 hooks.py 源码确认):
| 配置 | 形式 | 作用 |
|---|---|---|
GRAPHIFY_REBUILD_TIMEOUT |
环境变量 | 重建超时(秒),默认 600;到点抛 TimeoutError 退出 |
GRAPHIFY_FORCE |
环境变量 | 置 1/true/yes 时强制全量重建 |
GRAPHIFY_OUT |
环境变量 | 图谱输出目录,默认 graphify-out |
GRAPHIFY_MAX_WORKERS |
环境变量 | 并行工作进程数;Git for Windows/MSYS 下默认自动降为 1 |
GRAPHIFY_SKIP_HOOK |
环境变量 | 置 1 时跳过重建(commit 与 checkout 钩子均生效) |
GRAPHIFY_REBUILD_LOG |
环境变量 | 重建日志路径,默认 ~/.cache/graphify-rebuild.log |
GRAPHIFY_VIZ_NODE_LIMIT |
环境变量 | 可视化节点数上限,可由 .graphifyrc 的项目默认值垫底(每次运行时仍可覆盖) |
.graphifyrc |
仓库根文件 | 目前支持 viz_node_limit=<非负整数> 键值对,见 _load_graphifyrc |
排查重建问题时,直接看 ~/.cache/graphify-rebuild.log 即可——钩子启动时会打印 launching background rebuild (log: ...) 提示日志位置。
3. 原生 CLAUDE.md 集成:让 graphify 在 Claude Code 中常驻
参考文档说明:每个项目运行一次,即可让 graphify 在所有 Claude Code 会话中保持开启:
graphify claude install # 写入规则段
graphify claude uninstall # 移除规则段
这一步之后,未来会话中不再需要手动调用 /graphify——Claude 会在回答代码库问题前先查图,并在代码变更后重建图谱。
3.1 写入内容:## graphify 规则段
实现见 claude_install():以标记 ## graphify(常量 _CLAUDE_MD_MARKER)为边界,对已存在的 CLAUDE.md 执行“替换或追加”(_replace_or_append_section),即重复安装只会原地刷新同一段,不会累积多份。写入的段落全文来自 always_on/claude-md.md,内容为:
## graphify
This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
Rules:
- For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
规则的核心思路是分级降级:优先 graphify query/path/explain 拿作用域子图,宽导航用 wiki/index.md,GRAPH_REPORT.md 只在必要时兜底;改码后用纯 AST 的 graphify update . 保持图谱新鲜(无 API 成本)。
3.2 附带的 PreToolUse 钩子:hook-guard
graphify claude install 除了写 CLAUDE.md,还会向 .claude/settings.json 注册两组 PreToolUse 钩子(_install_claude_hook):
- 匹配
Bash|Grep:执行graphify hook-guard search,在 agent 发起搜索时引导其先查图谱; - 匹配
Read|Glob:执行graphify hook-guard read,可选--strict严格模式。
严格模式下,每个会话第一次直接读文件会被拦截,直到先跑过一次 graphify query(运行时可用 GRAPHIFY_HOOK_STRICT=0 关闭,无需重装)。安装命令支持 graphify claude install --strict。这些引导/拦截行为的实现与验证分别位于 cli.py 的 hook-guard 分支 以及测试 test_hook_guard.py、test_claude_md.py、test_install.py。
3.3 卸载
graphify claude uninstall 会移除 CLAUDE.md 中的 ## graphify 段,并从 .claude/settings.json 与本地私有的 .claude/settings.local.json 中清理 graphify 的 PreToolUse 条目(用户可能把钩子挪到 local 文件里避免提交进共享仓库,见 _uninstall_claude_hook)。
4. 组合使用建议与验证
两条路径互补:git 钩子负责“提交/切分支后图谱自动保鲜”,CLAUDE.md 集成负责“agent 会话内优先查图”。建议的组合是:
- 先在项目根执行一次
/graphify(或graphify extract)生成graphify-out/graph.json与GRAPH_REPORT.md——post-checkout 钩子要求graphify-out/已存在才会工作; graphify hook install,随后graphify hook status确认三项均为 installed/registered;- 提交一次代码,观察 shell 输出
[graphify hook] launching background rebuild,再查~/.cache/graphify-rebuild.log确认增量重建完成; graphify claude install后检查CLAUDE.md与.claude/settings.json,在 Claude Code 中提问验证其是否优先执行graphify query。
需要临时暂停时,GRAPHIFY_SKIP_HOOK=1 git commit 即可跳过钩子重建;文档、图片类变更钩子本就不处理,按参考文档的约定手动执行 /graphify --update。
5. 小结
graphify 的钩子体系把“图谱保鲜”做成了零常驻进程的确定性流程:post-commit/post-checkout 钩子以标记块方式安全地追加进既有 git 钩子链,用跨平台脱离启动保证提交不被阻塞,用 worktree 防护、变更过滤、超时限制与合并驱动覆盖了实际协作中的主要坑位;而 graphify claude install 则以一段可原地刷新的 ## graphify 规则加 PreToolUse hook-guard,把“先查图、再读码”固化为 Claude Code 的默认行为。两者都由仓库内测试(test_hooks.py、test_claude_md.py、test_install.py)持续验证,行为边界清晰、可随时 uninstall 完全回退。
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