graphify 自动知识图谱钩子指南:git post-commit 增量重建与 Claude Code 原生 CLAUDE.md 集成
graphify 把任意代码库连同文档、SQL 模式、配置与 PDF 一起转化为可查询的知识图谱(graph.json + GRAPH_REPORT.md),而本文讲解的正是让这份图谱"永不掉队"的两条自动化通路:为 git 仓库安装 post-commit / post-checkout 钩子实现每次提交后的图谱自动重建,以及通过 graphify claude install 把原生 CLAUDE.md 集成写进项目,让 Claude Code 会话长期保持"先查图谱、改码即更新"的工作习惯。读完本文,你将掌握钩子的安装/卸载/状态检查命令、其增量重建的完整机制与全部可用环境变量,以及 CLAUDE.md 集成后实际注入的指令内容与底层的 PreToolUse 钩子实现。
本主题的权威依据是随 skill 打包分发的引用文档 hooks.md(同一内容也以生成产物形式存在于 skillgen 期望目录),核心实现集中在 git 钩子模块 与 安装/卸载子系统。
何时加载本参考:两类接线场景
该引用文档的开头明确了它的触发语义——当用户在会话中要求"安装 post-commit 钩子"或"把 graphify 接入某个项目的 CLAUDE.md"时加载本文件。也就是说,本内容属于 graphify skill 的渐进式引用包(progressive references):copilot 平台的 skill 主体是精简入口,按需点开对应的 references/*.md,而不是把全部长文档塞进主 skill。仓库中 copilot 平台配置 声明了 skill_refs: "copilot",skillgen 工具据此渲染出每份引用文档的期望快照用于回归校验。
两类接线场景分别对应仓库中的两套实现子系统:
| 场景 | 命令 | 核心实现文件 |
|---|---|---|
| 每次 git commit 后自动重建图谱 | graphify hook install |
graphify/hooks.py |
| 让 Claude Code 会话始终感知并维护图谱 | graphify claude install |
graphify/install.py、always-on 指令块 |
场景一:git post-commit 钩子 —— 提交即重建
引用文档给出的安装方式是三条命令,一次安装、永久生效,全程无需常驻后台进程——钩子由 git 在每次提交时触发一次,与编辑器/终端无关:
graphify hook install # 安装
graphify hook uninstall # 移除
graphify hook status # 检查安装状态
从源码看,install() 实际做的不止"写一个 post-commit 脚本",而是三项工作(见 hooks.py):
- 安装 post-commit 钩子——提交后增量重建;
- 安装 post-checkout 钩子——切换分支后重建(引用文档未展开,但
status输出会同时报告两者); - 注册
graph.json的 union merge driver——通过git config写入merge.graphify.driver,并在 .gitattributes 中追加一行graphify-out/graph.json merge=graphify,使多人协作时图谱文件的合并走专用 driver,避免冲突时二进制级覆盖。
钩子触发后发生了什么
引用文档描述了核心工作流:每次 git commit 之后,钩子通过 git diff HEAD~1 检测本次改动了哪些代码文件,仅对这些文件重新执行 AST 提取并增量重建,最终产出最新的 graph.json 与 GRAPH_REPORT.md;文档/图片等非代码改动会被钩子忽略,这类变更需要手动执行 /graphify --update(即 CLI 的 graphify update .,纯 AST、无 API 成本)来更新图谱。
源码层面的实际脚本(hooks.py)把这个描述落实为一条有多个保护闸门的 shell 流水线,值得关注的关键点:
- 变更集计算:
git diff --name-only HEAD~1 HEAD(首提交回退到git diff --name-only HEAD);为空则直接退出。 - 防自激循环:当变更仅涉及
graphify-out/自身产物时跳过重建——这保证了把图谱产物纳入版本控制的仓库不会"改了图→触发重建→又改图"地死循环(见 hooks.py)。 - 确定性输出:脚本固定
export PYTHONHASHSEED=0。原因在注释中讲得很清楚——networkx 的 louvain 社区发现对字符串键集合的遍历顺序受PYTHONHASHSEED随机化影响,固定种子才能让graphify-out逐次可复现(见 hooks.py)。 - 不阻塞提交:重建体通过 Python 的
subprocess.Popen以**脱离会话(detached)**方式启动,git commit 立即返回。历史上曾用nohup ... &,但 Git for Windows 的 MSYS shell 没有 nohup/setsid,导致重建静默失败、图谱悄悄过期(issue #1161);现改为跨平台 Python 启动器,POSIX 走start_new_session,Windows 走CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP(见 hooks.py)。 - rebase/merge/cherry-pick 期间跳过:检查
$GIT_DIR下的rebase-merge、rebase-apply、MERGE_HEAD、CHERRY_PICK_HEAD标记,避免在--continue尚未暂存改动时重建(见 hooks.py)。 - 链接工作树跳过:通过比较
git rev-parse --git-dir与--git-common-dir判断是否位于 linked worktree,是则退出——主检出目录的graphify-out/才拥有权威图谱(见 hooks.py)。 - 增量重建入口:钩子把变更文件列表经环境变量传入 Python 侧,调用 graphify.watch 的
_rebuild_code(_root, changed_paths=changed)做受限增量提取(见 hooks.py)。
与已有钩子共存:追加而非覆盖
引用文档特别强调:如果仓库里已存在 post-commit 钩子,graphify 会追加到其后而非替换它。实现上这正是 _install_hook 的核心逻辑(hooks.py):若文件尚不存在则以 #!/bin/sh 头创建;若存在但无 # graphify-hook-start 标记则追加;若已有 graphify 区块则用起止标记原地更新(幂等,重复安装不会产生重复区块,test_install_idempotent 验证了标记只出现一次)。卸载时同样用标记精确剥离 graphify 段落,其他钩子内容原样保留;如果剥离后只剩 shebang 才会删除整个文件(见 hooks.py)。
这套行为由 tests/test_hooks.py 全面覆盖:test_install_creates_hook 验证安装后标记存在、test_install_appends_to_existing_hook 验证已有钩子内容被保留、test_install_creates_post_checkout_hook 验证 post-checkout 一并生成、test_uninstall_removes_hook 验证整体移除、test_install_registers_merge_driver 与 test_uninstall_removes_merge_driver_keeps_other_attrs 验证 merge driver 的注册与干净回退。你可以用 graphify hook status 随时核对三块状态(post-commit / post-checkout / merge driver)。
钩子运行时可调的环境变量
引用文档没有罗列,但这些开关全部存在于 hooks.py 的钩子脚本与重建体中,是排查"为什么提交后图没更新"时的关键排查手段:
| 环境变量 | 作用 | 源码出处 |
|---|---|---|
GRAPHIFY_SKIP_HOOK=1 |
临时跳过本次钩子触发的重建(post-commit 与 post-checkout 都识别) | hooks.py |
GRAPHIFY_FORCE=1 |
强制全量重建而非增量 | hooks.py |
GRAPHIFY_REBUILD_TIMEOUT |
重建超时秒数,默认 600;POSIX 用 SIGALRM,无 alarm 平台用看门狗线程强制退出 |
hooks.py |
GRAPHIFY_OUT |
图谱输出目录,默认 graphify-out;同时读取 graphify-out/.graphify_root 确认仓库根 |
hooks.py |
GRAPHIFY_REBUILD_LOG |
重建日志路径,默认 ~/.cache/graphify-rebuild.log |
hooks.py |
GRAPHIFY_MAX_WORKERS |
Git for Windows/MSYS 下默认强制为 1(串行重建),显式设置则优先 | hooks.py |
此外钩子内置了一套解释器探测链(hooks.py):安装时把 sys.executable 固定(pin)进脚本,运行时依次探测固定解释器 → graphify-out/.graphify_python → PATH 上的 graphify 启动器 → uv tool 环境目录 → python3/python。探测用 importlib.util.find_spec 而非直接 import,避免每次提交触发 10 秒级冷加载。这套机制解决了 GUI git 客户端与 CI 的极简 PATH 拿不到 graphify 的问题,也让 uv tool install(README 推荐方式)的隔离 venv 可被定位。项目级配置 .graphifyrc 中的 viz_node_limit 会被烘焙进钩子(如 export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-100}"),同时保留单次命令覆盖能力(见 hooks.py)。
值得留意的一个使用前提:钩子目标是最近的 git 仓库根(向上查找 .git),找不到会直接报 No git repository found;钩子目录通过 git rev-parse --git-path hooks 解析,因而兼容 core.hooksPath(如 Husky)自定义的钩子目录,也正确处理 linked worktree(hooks.py)。
场景二:原生 CLAUDE.md 集成 —— 让 Claude Code 始终感知图谱
引用文档给出的核心命令只需对每个项目执行一次:
graphify claude install
其效果是:向项目本地的 CLAUDE.md 写入一个 ## graphify 段落,指示 Claude 在回答代码库问题前先查图谱、在代码变更后重建图谱;之后的会话无需再手动 /graphify。卸载命令同样一行:
graphify claude uninstall # 移除该段落
实际写入 CLAUDE.md 的指令内容
真正注入的段落来自打包的 always-on 指令块(由 tools/skillgen 从单一人工维护片段生成,并有 skillgen --check 防漂移守护)。安装时通过 _replace_or_append_section 以精确标题匹配方式幂等插入或原地更新,不会把 ### graphify 这类子串误判为段落边界而误删用户手写内容(见 install.py)。其内容相当于给 Claude 立下四条使用规则:
- 仓库的知识图谱位于
graphify-out/,包含 god 节点、社区结构与跨文件关系; - 回答代码库问题前,若
graphify-out/graph.json存在则先运行graphify query "<question>";需要关系路径用graphify path "<A>" "<B>",聚焦概念用graphify explain "<concept>"——这些命令返回的是裁剪过的子图,通常远小于整份报告或 grep 输出; - 若存在
graphify-out/wiki/index.md,宽泛导航应优先使用 wiki 而非直接翻源码; - 仅在做全局架构审查、或 query/path/explain 上下文不足时才读
graphify-out/GRAPH_REPORT.md;代码改动后用graphify update .保持图谱新鲜(纯 AST,无 API 成本)。
安装背后:不只是写 CLAUDE.md
claude_install()(install.py)实际做两件事:一是上面的 CLAUDE.md 段落写入,二是把一组 PreToolUse 钩子注册进 .claude/settings.json(_install_claude_hook,见 install.py)。钩子经解析后形如:
{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash|Grep", "hooks": [{ "type": "command", "command": "<graphify-exe> hook-guard search" }] },
{ "matcher": "Read|Glob", "hooks": [{ "type": "command", "command": "<graphify-exe> hook-guard read" }] }
]
}
}
"Grep" 被纳入搜索匹配器,是因为当前 Claude Code 的内容搜索走专用 Grep 工具而非 Bash,只匹配 Bash 会让守卫在智能体的主搜索路径上从不触发(见 install.py)。另外命令以 hook-guard 子命令形式调用(对应 main.py 的 _run_hook_guard),替代早期直接在 settings 里写 bash 脚本的做法——后者在 Windows 的 cmd/PowerShell 下无法解析。
严格模式与运行时开关
graphify claude install --strict(配合 --project)会为 read 钩子加上 --strict,使会话中第一次裸读文件被拦截,直到至少执行过一次 graphify query;运行时可用 GRAPHIFY_HOOK_STRICT 环境变量在不重装的前提下开关这一行为(见 install.py)。相关的完整 CLI 帮助文本可在 main.py 的 claude install / claude uninstall 条目中核对。
卸载的"打扫"范围
claude_uninstall()(install.py)不仅移除主 CLAUDE.md 中的段落,还清理 Claude Code 支持的本地变体 CLAUDE.local.md、.claude/CLAUDE.local.md,并同时清理 .claude/settings.json 与 .claude/settings.local.json 两处可能存放钩子的位置——用户可能把钩子挪进 local 文件以免提交进共享仓库。段落剥离同样按精确标题边界执行,删除后文件若为空则整体删除;skill 树(SKILL.md + references/ + 版本戳)也一并移除,避免渐进式分发留下的孤儿目录。卸载会输出逐步信息,可据此确认各文件均被正确处理。
两条自动化的取舍与适用边界
综合引用文档与源码,两种方式面向不同的使用节奏,可总结为:
- git 钩子(
graphify hook install):以"提交事件"为触发点、覆盖所有编辑器的仓库级方案。它的重建只针对代码文件变更,因此适合"代码演进为主、文档零散更新"的仓库;若提交历史里文档/图片改动频繁,需要配合手动graphify update .(等价于引用文档所述/graphify --update)。它的设计刻意避开常驻进程,全部开销发生在每次提交的瞬时触发上。 - CLAUDE.md 集成(
graphify claude install):以"会话上下文"为作用点的 Claude Code 专属方案。它不产生后台任务,而是把## graphify段落写入项目(本地文件,随仓库分发或仅存于本机均可),使 Agent 每次回答问题前天然先查图谱、改码后自觉graphify update .,同时以 PreToolUse 钩子兜底"先查询再读文件"的顺序。 - 两者的共同价值:都服务于同一核心闭环——让
graphify-out/graph.json、GRAPH_REPORT.md与代码始终同步,从而保证graphify query/path/explain的检索与引用永远落在新鲜图谱上。引用文档末尾针对文档/图片变更明确指出的"手动运行/graphify --update",正是对这一闭环的兜底语义。
参考资料
- 引用文档(本文章依据):copilot skill 的 hooks 引用、skillgen 期望产物
- 核心实现:git 钩子模块 hooks.py、安装/卸载子系统 install.py、注入 CLAUDE.md 的指令块
- CLI 分发:main.py 中的 hook / claude 子命令帮助
- 测试佐证:tests/test_hooks.py(安装幂等性、追加共存、post-checkout、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 StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00