首页
/ Graphify 知识图谱自动增量重建:Git post-commit 钩子与 CLAUDE.md 原生集成实战

Graphify 知识图谱自动增量重建:Git post-commit 钩子与 CLAUDE.md 原生集成实战

2026-09-07 18:24:37作者:董宙帆

导读

graphify 把代码库(连同文档、SQL schema、配置、PDF)解析成位于 graphify-out/ 下的可查询知识图谱(graph.jsonGRAPH_REPORT.md),但要让它始终反映最新的代码,就必须在代码变更后重新构建图谱。本指南讲解 graphify 提供的两条"自动维护"路径:Git post-commit 钩子(每次 git commit 后自动增量重建,无需常驻后台进程、与任何编辑器/IDE 解耦)与 CLAUDE.md 原生集成(把 graphify 的规则写入项目 CLAUDE.md,让 Claude Code 会话中图谱"常开")。读完你就能在自己的仓库上安装、检查、卸载这两种集成,并理解它们在 graphify/hooks.pygraphify/install.pygraphify/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 钩子,完整链路为:

  1. 钩子先用 git diff --name-only HEAD~1 HEAD 找出本次提交改动的文件(首个提交等没有 HEAD~1 时回退为 git diff HEAD,见 graphify/hooks.py);
  2. 过滤掉仅 graphify-out/ 产物自身的变化(避免"图谱输出被 git 跟踪 → 钩子又触发重建"的死循环,见 graphify/hooks.py);
  3. 把待处理文件列表通过环境变量交给一个分离的后台 Python 进程
  4. 该进程调用 graphify/watch.py_rebuild_code(root, changed_paths=changed)只对改动的代码文件重新执行 AST 提取,未变化的文件节点从既有 graph.json 中保留(删除的文件则从保留集中剔除);
  5. 重建产物 graph.jsonGRAPH_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 可以看到它一次完成三件事:

  1. post-commit 钩子:每次提交后增量重建;
  2. post-checkout 钩子:每次 git checkout 切换分支时做一次全量代码重建(分支切换可能改动任意文件,所以不走增量、以完整重建路径处理,见 graphify/hooks.py);
  3. 注册 graph.json 的 union merge driver:向 git config 写入 merge.graphify.driver,并在 .gitattributes 增加一行 graphify-out/graph.json merge=graphifygraphify/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-mergerebase-applyMERGE_HEADCHERRY_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):

  1. 向项目根目录的 CLAUDE.md 写入一个 ## graphify 小节(若文件不存在则新建,若已存在同名节则更新);
  2. .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):

  1. 新增/改动了文档、图片、PDF——钩子只处理代码的 AST 重建,语义抽取类内容必须手动跑增量管道;
  2. 需要立即在本次会话内让图谱反映刚写的代码,等不及下一个 commit 触发;
  3. 在非 git 目录、或未安装钩子的机器上工作;
  4. 希望强制执行一次全量一致性检查(graphify update . --force 类选项可绕过收缩保护)。

graphify update 走的是与钩子完全相同的 _rebuild_code 路径(只是阻塞等待锁),所以产物与提交触发的重建保持一致。


六、相关源码与测试参考

想深入验证本文所述行为,可从仓库内以下路径继续跟进:

仓库的测试目录(tests/)为这些机制提供了回归覆盖,例如钩子逻辑相关测试 tests/test_hooks.py、安装/卸载相关 tests/test_install.pytests/test_install_roundtrip.pytests/test_install_references.py,以及 CLAUDE.md 集成相关 tests/test_claude_md.py 等。


结语

一条原则贯穿全文:钩子管代码,Agent 规则管会话,LLM 工作留给手动 updategraphify hook install 用一次安装换来"每次提交自动增量重建、不阻塞、不依赖编辑器、不消耗 API"的图维护机制;graphify claude install 则把"先查图谱、改后重建"固化进每个 Claude Code 会话。两条路径配合 graphify/hooks.py 中沉淀的工程细节(分离进程、解释器钉死、并发排队、rebase/worktree 跳过、merge driver),让知识图谱在真实的多人协作节奏中始终保持新鲜。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388