首页
/ graphify × Gemini CLI:让 AI 助手优先查询代码知识图谱的 always-on 指令层设计与实践

graphify × Gemini CLI:让 AI 助手优先查询代码知识图谱的 always-on 指令层设计与实践

2026-09-04 11:22:16作者:薛曦旖Francesca

graphify 会把任意代码库连同其文档、SQL schema、配置文件一起解析为本地确定性 AST 知识图谱。本文以 gemini-md.md 这个 Gemini CLI 专用常驻指令块为主体,逐条拆解它写入项目 GEMINI.md 的四条"图谱优先"工作规则,并结合 install.py 的安装器源码与 test_gemini_hook.py 的测试,说明这套指令如何通过 graphify install --platform gemini 落地、又被 BeforeTool hook 如何实时"提醒"AI 走图谱路径,读完后你可以完整复现 Gemini CLI + graphify 的接入与日常使用闭环。

一、它是什么:写在 GEMINI.md 里的常驻规则块

gemini-md.md 只有短短十行,但它是 graphify 为 Gemini CLI 定制的"always-on"指令块——一段会在每次会话中被 Gemini CLI 读取、并长期生效的行为约束。原文完整内容如下:

## 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).

它的定位非常清晰:声明事实 + 四条规则。开头一句向 AI 声明"本项目在 graphify-out/ 目录下已有一份包含 god nodes(枢纽节点)、community structure(社区结构)与跨文件关系的知识图谱";随后四条规则规定了 AI 回答代码库问题时的信息检索次序——先查图谱、再查 wiki 导航、最后才读完整报告,改完代码还要刷新图谱。这四条规则构成了整篇文章的展开主线。

二、四条规则逐条解读

规则 1:代码问题先查图谱——query / path / explain 三级查询

这是四条规则中信息量最大的一条,它给了 Gemini 三个分层工具:

命令 用途 CLI 完整用法(摘自 cli.py 的 Usage 提示)
graphify query "<question>" 面向自然语言问题的范围化子图检索 graphify query "<question>" [--dfs] [--context C] [--budget N] [--graph path]
graphify path "<A>" "<B>" 查询两个节点之间的关系路径 graphify path "<source>" "<target>" [--graph path]
graphify explain "<node>" 聚焦解释某个概念/节点 graphify explain "<node>" [--graph path]

规则原文强调的前提是 graphify-out/graph.json exists——即只有当图谱确实构建过,才走查询路径,避免空图查询。三条命令返回的都是"scoped subgraph"(范围化子图),指令块明确指出其体积"通常远小于 GRAPH_REPORT.md 或裸 grep 的输出"。这正是 graphify 的核心卖点:用一份小得多的上下文回答代码库问题,而不是让模型去读整个报告或大海捞针式地 grep。

从源码结构看,querycli.py 中被实现为基于 graphify.serve._query_graph_text 的图上检索,并保持图无向以支持 BFS/DFS 探索;pathexplain 则强制使用有向视图。三种查询执行后都会调用 querylog.log_query 记录查询日志,并写入查询时间戳,为 hook 的"近期是否查过图"判断提供依据。

规则 2:用 wiki 做宽泛导航

第二条规则要求:如果 graphify-out/wiki/index.md 存在,就用它做宽泛导航,而不是直接翻原始源码。graphify 构建图谱时会同步产出一个 markdown 形式的 wiki 索引(见 wiki.py),相当于给整个代码库生成了一份"目录页"。这条规则的意义在于把"浏览"这一动作从逐文件打开,升级为沿 wiki 层级跳转,既省上下文窗口,也避免模型在目录树里迷路。

规则 3:GRAPH_REPORT.md 只作最后兜底

第三条规则刻意"降权"了 graphify-out/GRAPH_REPORT.md:它只应在两种场景被读取——做全局架构评审时,或者 query / path / explain 三者都没有给出足够上下文时。仓库内 worked/httpx/GRAPH_REPORT.md 这类报告可以看到其形态:整库级的社区划分与枢纽节点综述,信息密度高但体积大,适合作为"地图总览"而非"问题答案"。指令块把阅读次序硬编码为:子图查询 → wiki 导航 → 完整报告,本质是一份针对 AI 的渐进式信息披露(progressive disclosure)策略。

规则 4:改完代码必须 graphify update .

最后一条规则规定了图谱保鲜义务:修改代码之后运行 graphify update .。括号里的 "(AST-only, no API cost)" 点明了它的成本模型——增量更新只走本地确定性 AST 解析,不产生任何 LLM API 费用。这与 graphify"本地解析、每条边可解释、不依赖向量库"的整体设计一致:图谱可以低成本地随代码演进,而不需要重新花钱全量重建。

三、指令块如何进入 GEMINI.md:installer 源码级走读

gemini-md.md 只是"包内的源文件",真正把它变成项目规则的是 install.py 中的 gemini_install(第 707 行起)。执行 graphify install --platform gemini 时会发生三件事:

  1. 拷贝技能文件:_copy_skill_file("gemini", ...) 把包内 skill.md 原样拷入 ~/.gemini/skills/graphify/SKILL.md(项目级安装则是 .gemini/skills/graphify/SKILL.md),并附带 references/ 渐进式文档与 .graphify_version 版本戳;
  2. 写入 GEMINI.md 规则段:以 ## graphify 作为 section 标记,通过 _replace_or_append_sectiongemini-md.md 的内容幂等地写入或替换到项目根目录的 GEMINI.md(见 install.py)。"替换"是关键:旧版本安装留下的过时措辞会在升级时被整段覆盖,用户无需卸载重装;
  3. 注册 BeforeTool hook:向 .gemini/settings.jsonhooks.BeforeTool 数组追加一条钩子(见 install.py)。

其中 section 替换函数 _replace_or_append_section 有一个值得注意的健壮性设计:它只在某一行精确等于 ## graphify(去除首尾空白后)时才算命中,绝不做子串匹配;section 范围延伸到下一个 H2 标题之前。注释里说明这是为了避免历史上"子串误匹配删掉用户手写内容"的缺陷——对用户自维护的 GEMINI.md 来说,精确边界是安全底线。卸载时 gemini_uninstall 用同样精确匹配的 _remove_marker_section 反向清理,若清完后文件为空则直接删除 GEMINI.md

四、BeforeTool hook:规则 1 的运行时"第二保险"

GEMINI.md 里的规则是"软约束"(依赖模型自觉遵守),graphify 还配了一条"硬提醒"。_gemini_hook(install.py)生成的钩子形如:

{
  "matcher": "read_file|list_directory",
  "hooks": [{ "type": "command", "command": "<graphify 可执行路径> hook-guard gemini" }]
}

即:每当 Gemini CLI 调用 read_filelist_directory 工具前,都会先执行 graphify hook-guard gemini。它的行为由 tests/test_gemini_hook.py 完整固化:

  • 永不拦截:无论图谱是否存在,返回的 JSON 恒为 {"decision": "allow"},工具调用不会被 hook 阻断;
  • 有图谱就提醒:当前目录存在 graphify-out/graph.json 时,在 additionalContext 中追加"先用 graphify query"的引导文本(测试 test_allows_and_nudges_with_graph 断言该文本包含 graphify query);
  • 无图谱则静默:没有图谱时不附加任何上下文,避免噪音;
  • 尊重输出目录覆盖:GRAPHIFY_OUT 环境变量生效(测试 test_honors_graphify_out_override)。

这个设计与 paths.py 相呼应:输出目录名默认是 graphify-out,但可通过 GRAPHIFY_OUT 环境变量改为任意相对名或绝对路径(适用于 worktree 或共享输出场景),hook 与 CLI 读取的是同一个单一事实来源。项目级安装时,由于 .gemini/settings.json 会被提交进版本库,钩子命令刻意使用裸 graphify 命令而非某台机器的绝对路径,保证换机器后依然可用。

五、这个文件从何而来:skillgen 单一事实源与防漂移

gemini-md.md 并不是手写的散落副本,而是由 tools/skillgen 从人类维护的单一 fragment tools/skillgen/fragments/always-on/gemini-md.md 生成的六个 always-on 块之一(同族还有 claude-mdagents-mdantigravity-ruleskiro-steeringvscode-instructions)。install.py_always_on 函数文档字符串写得很直白:安装包内的六个块必须与 fragment 逐字节一致,由 skillgen --check 的 roundtrip 校验守护漂移。这也解释了为什么 graphify install 能"幂等升级"——只要 fragment 更新,一次重新安装即可让所有项目的 GEMINI.md 段同步到最新措辞。

六、落地清单与自定义

在任意项目根目录,完整接入流程为:

  1. 安装 Gemini 平台技能(用户级,技能落在 ~/.gemini/skills/graphify/):graphify install --platform gemini;
  2. 使用项目级安装(规则、.gemini/settings.json 钩子与 .gemini/skills/graphify/SKILL.md 全部落在项目内并可提交版本库):graphify install --project --platform gemini,安装器会自动提示 git add 对应路径;
  3. 首次构建图谱后,项目内即出现 graphify-out/graph.jsonGRAPH_REPORT.mdwiki/ 索引,此后 Gemini CLI 按本文规则 1–3 的次序检索;
  4. 每次改动代码后运行 graphify update . 增量刷新;
  5. 需要换输出目录时,在进程启动前设置 GRAPHIFY_OUT 环境变量(例如 worktree 隔离或团队共享输出)。

若需调整规则措辞,正确做法是修改 tools/skillgen/fragments/always-on/gemini-md.md 后由 skillgen 重新生成,而不是手改各项目里的 GEMINI.md 段落——否则下次 graphify install 的精确 section 替换会用包内版本覆盖你的手工修改。

小结

gemini-md.md 用十行文字把"图谱优先"的检索次序钉死在 Gemini CLI 的会话规则里:query/path/explain 三级子图查询是默认入口,wiki 索引承担宽泛导航,GRAPH_REPORT.md 退居全局评审兜底,graphify update . 保证图谱零 API 成本地保鲜。配合 install.py 的幂等 section 注入与 hook-guard gemini 的每次读取前提醒,这套机制让 AI 助手在回答代码库问题时,先看到的永远是"小得多、且每条边都有解释"的范围化子图,而不是整个报告或 grep 的洪流。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
docsdocs
暂无描述
Markdown
889
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341