首页
/ Graphify 钩子与 Trae 原生集成实战:post-commit 自动重建知识图谱与 AGENTS.md 常驻规则

Graphify 钩子与 Trae 原生集成实战:post-commit 自动重建知识图谱与 AGENTS.md 常驻规则

2026-09-06 18:06:23作者:管翌锬

导读:本文以 graphify 的 Trae 技能参考文档为主线,讲解两种让"知识图谱保持新鲜"的机制——基于 git 钩子的每次提交自动重建,以及基于 AGENTS.md 的 Trae 会话常驻集成。读完你将掌握 graphify hook install / graphify trae install 的完整用法、其底层触发链路与增量重建原理,以及 Trae 与 Claude Code 在钩子能力上的关键差异及对应的取舍策略。

graphify 的核心产物是一个 graphify-out/ 下的可查询知识图谱(graph.json + GRAPH_REPORT.md),它来自对代码库的确定性 AST 解析,每条边都有解释,且不依赖向量库。但图谱的保质期只有到"下一次代码变更"为止。官方技能文档 graphify/skills/trae/references/hooks.md 定义了两种让图谱自动跟上代码演进的接入方式:git 钩子与 AGENTS.md 常驻指令。本文据此展开,并引入 graphify/hooks.pygraphify/install.py 的源码佐证其内部实现。

一、方案总览:两种"always-on"机制与适用场景

hooks.md 开头的加载条件("Load this when the user asked to install the post-commit hook or wire graphify into a project's AGENTS.md")可以看出,这份参考文档精确覆盖两种需求:

机制 触发时机 适用对象 是否需要后台进程
git 钩子 每次 git commit 之后 任何编辑器/任何工作流 否,每次提交触发一次
AGENTS.md 集成 Trae 会话开启即常驻 Trae / Trae CN 会话 否,规则文件生效

两者的核心差异在于"自动重建"能力的强弱:

  • git 钩子是纯代码仓库层面的自动机:提交后自动重跑 AST 抽取并合并重建图谱,编辑器无关、会话无关;
  • AGENTS.md 集成则是"规则引导"式:让 Trae 在回答代码库问题前先查图谱、在修改代码后主动重建。它做不到工具调用级的自动拦截,因此代码变更后仍需手动触发 /graphify --update

二、git 提交钩子:每次 commit 后自动重建图谱

2.1 三个子命令

在任意 git 仓库根目录执行:

graphify hook install     # 安装:自动重建钩子
graphify hook uninstall   # 卸载:移除钩子
graphify hook status      # 状态:检查是否已安装

命令在 graphify/cli.py 中被分发到 graphify/hooks.pyinstall / uninstall / status 三个函数。注意:从源码看,install 并不止安装单个 post-commit 钩子。查看 hooks.pyinstall() 实现可知,一次 graphify hook install 实际完成三件事,返回结果逐行汇报:

post-commit: installed at .../hooks/post-commit      # 提交后增量重建
post-checkout: installed at .../hooks/post-checkout  # 切换分支后重建
merge driver: registered (graphify-out/graph.json merge=graphify)  # graph.json 的 union 合并驱动

2.2 触发链路:从一次 commit 到 graph.json 更新

graphify hook install 会在最近 git 仓库的 hooks 目录写入脚本(见 hooks.py_HOOK_SCRIPT),其执行链路是:

  1. 提交完成后,git 触发 post-commit 钩子;
  2. 钩子先做一系列短路判断(rebase/merge/cherry-pick 中、worktree 场景、GRAPHIFY_SKIP_HOOK=1、仅 graphify-out/ 产物变更等,见 2.5 节),全部通过才继续;
  3. 通过 git diff --name-only HEAD~1 HEAD 检测本次提交改了哪些文件,把文件清单放入环境变量 GRAPHIFY_CHANGED
  4. 分离式后台进程方式启动 Python 重建(提交命令立即返回,不被阻塞);
  5. 重建主体读取 GRAPHIFY_CHANGED,调用 graphify/watch.py_rebuild_code(root, changed_paths=[...])——只对变更文件重新跑 AST 抽取并增量合并,进而更新 graph.jsongraph.htmlGRAPH_REPORT.md(产物写回逻辑在 watch.py,含"无变化则不动产物"的去抖保护)。

这正是 hooks.md 所述行为的实现细节:"钩子检测哪些代码文件变了(git diff HEAD~1)、仅对这些文件重跑 AST 抽取、重建 graph.jsonGRAPH_REPORT.md"。文档与图片变更会被钩子忽略——处理这类变更请手动执行 /graphify --update

2.3 与已有钩子共存:追加而非覆盖

文档明确承诺:"If a post-commit hook already exists, graphify appends to it rather than replacing it."

源码将其落实为标记区间(marker block)机制hooks.py 定义了成对标记:

_HOOK_MARKER = "# graphify-hook-start"
_HOOK_MARKER_END = "# graphify-hook-end"
_CHECKOUT_MARKER = "# graphify-checkout-hook-start"
_CHECKOUT_MARKER_END = "# graphify-checkout-hook-end"

写入逻辑在 _install_hook()hooks.py):

  • 目标钩子文件不存在 → 新建,内容为 #!/bin/sh + graphify 脚本;
  • 文件存在但不含 graphify 标记 → 把 graphify 段追加到文件末尾,用户原有的钩子逻辑原样保留;
  • 文件已含 graphify 标记 → 原地更新该区间(便于重装升级,且幂等:内容一致时返回 "already installed")。

卸载时 _uninstall_hook()hooks.py)用正则仅删除 # graphify-hook-start ... # graphify-hook-end 区间;若删除后文件只剩 shebang 或为空则整体移除,否则保留"其他钩子内容"。

2.4 为什么钩子不会阻塞你的提交:分离式后台启动

文档强调钩子"无需后台进程,每次提交触发一次"。但全量重建可能耗时较长,若在 post-commit 里同步执行会卡住 shell。从实现看(hooks.py),graphify 采用了跨平台的 Python 分离启动 shim:

  • 外层一次性 Python 进程立即返回,内层 subprocess.Popen(..., start_new_session=True)(POSIX)或 CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP(Windows)把真正的重建子进程完全脱离;
  • 子进程输出写入日志文件 $GRAPHIFY_REBUILD_LOG(默认 ~/.cache/graphify-rebuild.log),供事后排障;
  • 注释中明确提到旧实现依赖 nohup ... &,而 Git for Windows 自带的 MSYS shell 没有 nohup,会导致重建静默失败(issue #1161),因此改为"由 Python 自己完成 detach"。

2.5 智能跳过与防抖:钩子不会无脑触发

文档只描述了最简模型(提交→重建),真实钩子脚本(hooks.py)包含大量保护性短路,从源码可归纳如下:

场景 行为 原因
rebase / merge / cherry-pick 进行中 直接退出 避免阻塞 --continue(工作区尚有未提交变更)
git worktree 链接工作树 直接退出 图谱属于主检出目录,从 worktree 重建会造成脏增量图并与 git clean 竞争(issue #1809/#1806)
变更全部位于 graphify-out/ 直接退出 防止"图谱产物入库 → 触发重建 → 又产生变更"的循环
GRAPHIFY_SKIP_HOOK=1 直接退出 用户显式逃生阀,一次提交内临时禁用
无任何变更(如空提交) 直接退出 无意义触发

此外钩子还会 export PYTHONHASHSEED=0:源码注释说明 networkx louvain 对字符串键集合的迭代顺序受 PYTHONHASHSEED 随机化影响,固定种子可让 graphify-out/ 的社区划分结果逐次可复现。在 Windows/MSYS 环境下,钩子默认把 GRAPHIFY_MAX_WORKERS 限制为 1(GUI 客户端/Agent shell 可能继承脆弱的管道句柄,串行更稳妥;用户显式设置仍可覆盖)。

2.6 Python 解释器探测链与可调环境变量

为了让钩子在 GUI 客户端、CI、uv tool / pipx 等"PATH 不完整"的环境里也能工作,钩子内嵌了一套四级解释器探测逻辑(hooks.py),顺序为:

  1. 安装时钉死的解释器路径(__PINNED_PYTHON__,来自执行 hook install 时的 sys.executable);
  2. graphify-out/.graphify_python 文件(CLI 与技能写入的持久化记录,uv-tool 重装后依然有效);
  3. PATH 上的 graphify launcher(Windows 下探测旁侧 python.exe,POSIX 下解析 shebang);
  4. uv tool 环境目录扫描(~/.local/share/uv/tools~/AppData/Roaming/uv/tools 等),最后回退 python3 / python

探测使用 importlib.util.find_spec 而非整包 import——避免在每次提交前同步执行完整包导入造成秒级停顿。若全部失败,钩子打印提示并以退出码 0 结束,绝不让一次普通 commit 失败。

重建行为可通过以下环境变量调节(均来自 hooks.py 内嵌脚本的读取逻辑):

环境变量 默认值 作用
GRAPHIFY_CHANGED 钩子内部传入的本次变更文件清单(换行分隔),驱动 changed_paths 增量重建
GRAPHIFY_OUT graphify-out 输出目录;若其中存在 .graphify_root,则以该文件记录的真实根目录为准
GRAPHIFY_REBUILD_TIMEOUT 600 重建超时秒数;0 表示不设超时(POSIX 用 SIGALRM,Windows 用守护线程兜底)
GRAPHIFY_FORCE 1/true/yes 时强制执行完整重建
GRAPHIFY_REBUILD_LOG ~/.cache/graphify-rebuild.log 重建日志位置
GRAPHIFY_REBUILD_MEMORY_LIMIT_MB 未设 内存上限(经 watch.py_apply_resource_limits 生效,best-effort)
GRAPHIFY_SKIP_HOOK 0 设为 1 临时跳过本次钩子
GRAPHIFY_VIZ_NODE_LIMIT 来自 .graphifyrc 可视化节点上限,可用 .graphifyrc 中的 viz_node_limit=N 烘焙为项目默认(见 hooks.py 的解析),单次运行的环境变量覆盖仍优先

2.7 附带安装的 merge driver:多人协作不冲突

这是 graphify hook install 顺手完成的第三件事。当 graph.json 入库且多人分支并行修改时,二进制化的 node-link 图谱在 git 三路合并里几乎必然冲突。为此 install 会(hooks.py):

  • 写入 git config:merge.graphify.namemerge.graphify.driver(驱动命令为钉死解释器执行 python -m graphify merge-driver %O %A %B);
  • .gitattributes 追加一行 graphify-out/graph.json merge=graphify(若输出目录被绝对路径覆盖则回退到默认名,见 _merge_attr_line())。

status 会通过 _merge_driver_status() 汇报其注册状态(registered / partially registered / not registered),保证钩子可用性可被诊断。

2.8 检查安装状态

graphify hook status

status() 实现(hooks.py)看,输出逐项汇报三块状态,例如:

post-commit: installed
post-checkout: installed
merge driver: registered

若检测到 graphify-out/ 已存在但内容过期,它会提示手动更新。值得注意:status 是只读诊断,即使 .graphifyrc 格式非法,也只打印 warning 而不会抛 traceback;若钩子里烘焙的 viz_node_limit.graphifyrc 不一致,会提示 "installed (out of date: ...)" 提醒重装。

三、Trae 原生 AGENTS.md 集成:让 graphify 在每个会话常驻

3.1 一条命令完成项目级接入

对 Trae(以及中国大陆版 Trae CN),在项目根目录执行一次:

graphify trae install       # 或:graphify trae-cn install

install.py_PLATFORM_CONFIG 看,Trae 与 Trae CN 共用同一份 skill 本体(skill-trae.md)与同一套渐进式参考文献包 skill_refs: "trae",只是落地目录不同:

平台 Skill 落地位置 AGENTS.md 写入
trae .trae/skills/graphify/SKILL.md 本地 AGENTS.md## graphify
trae-cn .trae-cn/skills/graphify/SKILL.md 本地 AGENTS.md## graphify

安装逻辑在 _project_installinstall.py)中把 trae 归入 _copy_skill_file + _agents_install 的组合流程:既把 /graphify 技能与 references/ 参考文档装进项目,也往 AGENTS.md 写入常驻段落。项目级安装结束后会提示把相关文件 git add 纳入版本控制,这样团队每个人 clone 后自动生效。

3.2 AGENTS.md 里写入了什么

_agents_install()install.py)以 ## graphify 为标记(_AGENTS_MD_MARKER),借助 _replace_or_append_section幂等写入:已存在则整段替换、不存在则追加到文件末尾,文件其余内容一律不动。写入的内容来自打包好的常驻规则块 graphify/always_on/agents-md.md,其要点为:

  • 项目在 graphify-out/ 下有一份带 god nodes、社区结构与跨文件关系的知识图谱;
  • 用户输入 /graphify 时,先使用已安装的 graphify 技能再处理其他事;
  • 回答代码库问题前:若 graphify-out/graph.json 存在,优先执行 graphify query "<question>";关系类问题用 graphify path "<A>" "<B>";聚焦概念用 graphify explain "<concept>"——三者返回的是作用域受限的子图,通常比整份 GRAPH_REPORT.md 或裸 grep 小得多;
  • 钩子或增量更新后 graphify-out/ 出现脏文件属预期行为,不构成跳过 graphify 的理由(除非任务本身与图谱过期/错误相关,或用户明确要求不用);
  • graphify-out/wiki/index.md 存在,用它做整体导航,避免直接浏览原始源码;
  • 只有做架构级评审或 query/path/explain 上下文不足时,才读整份 GRAPH_REPORT.md
  • 修改代码后运行 graphify update . 保持图谱新鲜(纯 AST 更新,不消耗 LLM API)。

3.3 关键差异:Trae 没有 PreToolUse 钩子

文档用 Note 高亮了一个与 Claude Code 的本质区别:

Unlike Claude Code, Trae does NOT support PreToolUse hooks. The AGENTS.md rules are the always-on mechanism — there is no automatic graph rebuild on tool use. Run /graphify --update manually after code changes if the graph needs refreshing.

在 Claude Code 中,graphify 会写入 PreToolUse 钩子(见 install.py_claude_pretooluse_hooks,配合 cli.pyhook-guard,在每次搜索/读取工具调用前拦截并引导到图谱),从而实现工具调用级的自动感知。Trae 不支持这类钩子,因此:

  1. 常驻机制退化为规则## graphify 段落就是 always-on 的全部——它指导 Trae 在回答问题前先查图谱;
  2. 没有自动重建:工具调用时不存在 graphify 的介入机会,代码改动后若需要最新图谱,请手动执行 /graphify --update
  3. 这正是 2.1 节 git 钩子的用武之地:Trae 场景里,"git 钩子负责自动重建 + AGENTS.md 负责会话内引导"可以互补使用——代码提交即自动刷新图谱,Trae 会话里再按规则优先消费图谱。

3.4 卸载与清理

graphify trae uninstall     # 或:graphify trae-cn uninstall    # 移除相应段落与技能

_agents_uninstall()install.py)只会精确删除 AGENTS.md## graphify 的整个段落(含其下规则),文件里的其他团队规范、说明文档原样保留;同时 _project_uninstall 会一并移除 .trae/(或 .trae-cn/)下的 skill 与版本戳文件。若仓库里还有 Claude、Codex 等其他平台的接入,graphify uninstall alluninstall_allinstall.py)可统一清理全部平台。

四、组合建议与常见问题

4.1 推荐落地组合

  1. 首次构建:/graphify .(或 graphify .)生成完整 graphify-out/
  2. 安装 git 钩子:graphify hook install —— 之后每次提交自动做代码变更的增量重建,无 API 成本;
  3. Trae 项目接入:graphify trae install(国内版用 trae-cn),并把 .trae/skills/AGENTS.md 提交进仓库;
  4. 文档/图片类修改,或需要语义层级重建时,手动 /graphify --update(纯增量路径见 graphify/skills/trae/references/update.md 的实现指引)。

4.2 常见问题速查

Q:提交后没有立即看到图谱变化? A:正常。重建在分离进程中执行,日志在 ~/.cache/graphify-rebuild.log;大仓库可能耗时数分钟。可用 graphify hook status 确认钩子确实已安装。

Q:钩子会处理我改的 markdown / 图片吗? A:不会,钩子只针对代码文件做 AST 级增量重建。文档、PDF、图片的语义抽取需要 LLM 参与,请手动跑 /graphify --update

Q:我已经有 post-commit 钩子(如 husky),会被覆盖吗? A:不会。graphify 以 # graphify-hook-start/end 标记区间追加,且对 husky 设置的 core.hooksPath 做了适配(hooks.pygit rev-parse --git-path hooks 解析真实目录,并对 Husky 9 的 .husky/_ 包装目录做父目录回退,见 _user_hooks_dir)。卸载也只会摘除自己的区间。

Q:Trae 里改了代码,Agent 会记得自动重建吗? A:会按 AGENTS.md 规则主动建议/执行 graphify update .,但没有工具调用级的强制拦截;规则被忽略或图表确需即时刷新时,手动执行 /graphify --update 是最终保障。仓库配套测试 tests/test_hooks.pytests/test_install.pytests/test_agents_platform.pytests/test_install_roundtrip.py 覆盖了钩子安装/卸载/状态与各平台 AGENTS.md 写入、幂等与清理等路径,可作为进一步阅读实现细节的入口。

五、小结

graphify hook install 把"图谱保鲜"做成了代码仓库的固有属性:提交即增量重建、无后台进程、与既有钩子和平共存、处处有逃生阀与防抖保护;graphify trae install 则把"优先用图谱、改完代码刷新图谱"的规则固化进项目的 AGENTS.md,让 graphify 在 Trae 的每个会话里常驻生效。理解二者的边界——尤其是 Trae 无 PreToolUse 钩子这一限制——就能组合出"git 钩子自动建 + AGENTS.md 引导查"的高性价比工作流:日常代码演进全自动保鲜,深度语义更新(文档/图片)按需手动触发。

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