首页
/ graphify 的 Kilo Code 技能文件 skill-kilo.md 深度解析:/graphify 命令从语料检测到图查询的完整流水线

graphify 的 Kilo Code 技能文件 skill-kilo.md 深度解析:/graphify 命令从语料检测到图查询的完整流水线

2026-09-06 21:09:04作者:邬祺芯Juliet

graphify/skill-kilo.md 是 graphify 项目为 Kilo Code 这一 AI 编码宿主定制的 Agent Skill 文件,它定义了 /graphify 斜杠命令被触发后的完整行为规范:从语料检测、确定性 AST 结构抽取、并行语义抽取子代理、社区聚类,到 HTML/JSON/报告三件套输出与增量更新的每一步。本文以该技能文件为主体,逐节拆解其流水线设计、Kilo 专属规则与诚实性约束,并结合 skillgen 多平台生成机制与安装器源码说明它是如何被渲染、校验和落盘到用户机器上的。

一、skill-kilo.md 在 graphify 中的定位

graphify 的核心卖点是:把任意文件夹里的代码、文档、论文、图片和视频变成一个可查询的知识图谱,产出交互式 HTML、可直接喂给 GraphRAG 的 JSON 以及一份白话审计报告 GRAPH_REPORT.md。由于不同 AI 编码宿主(Claude Code、Codex、Copilot、Kilo Code 等)的代理派发机制、Shell 环境和技能目录约定各不相同,graphify 为每个宿主维护一份独立的 SKILL.md 文件,skill-kilo.md 就是其中 Kilo Code 变体。

文件开头的 YAML frontmatter 是 Agent Skills 规范的入口元数据:

---
name: graphify
description: "Use for any question about a codebase, its architecture, file relationships, or project content — especially when graphify-out/ exists, where the question should be treated as a graphify query first. ..."
---

从 frontmatter 的 description 可以读出技能被触发的核心判据:只要用户的问题涉及代码库、架构、文件关系或项目内容——尤其是工作目录下已经存在 graphify-out/ 产物时——宿主应当优先把它当作一次 graphify 图查询,而不是去翻原始文件。

该文件不是一个手写的孤立文件。从 tools/skillgen/platforms.toml 中的平台声明可以看到它的生成来源:

[platform.kilo]
bucket = "split"
core = "core"
skill_dst = "graphify/skill-kilo.md"
refs_dst = "graphify/skills/kilo/references"
dispatch = "agent-tool-disk"
extraction = "verbose"
extra_sections = ["kilo-rules"]

含义逐条对应:

  • bucket = "split":采用"精简核心 + 参考侧车(sidecar)"的拆分形态。核心流程写在 skill-kilo.md 里,重内容拆到 graphify/skills/kilo/references/ 下的 8 个参考文档:add-watch.mdexports.mdextraction-spec.mdgithub-and-merge.mdhooks.mdquery.mdtranscribe.mdupdate.md
  • dispatch = "agent-tool-disk":Part B 的语义抽取子代理派发方式采用"Agent 工具 + 磁盘收集结果"模式(每个子代理把 JSON 写到 graphify-out/.graphify_chunk_NN.json,主流程再合并);
  • extraction = "verbose":使用完整版的抽取规范(区别于 kiro/pi/claw 使用的 compact 版);
  • extra_sections = ["kilo-rules"]:在"Honesty Rules(诚实规则)"之前插入一段 Kilo 专属规则,其内容即 tools/skillgen/fragments/extra/kilo-rules.md

测试 tests/test_skillgen.py 固化了这些约束,例如 test_kilo_renders_its_rules_tail_section 断言渲染产物中 ## Kilo-specific rules 必须存在且位于 ## Honesty Rules 之前;另有多处断言保证 kilo 使用 verbose 版 extraction-spec.md、frontmatter 不含 trigger: 字段、hooks 参考文档保留 graphify claude install 措辞。在仓库根目录运行 python -m tools.skillgen 可重新生成,--check 会在产物与期望发生漂移时失败。

二、完整 Usage 命令参考

skill-kilo.md## Usage 小节是全量命令面,读者可以直接把它当作 /graphify 的 CLI 速查表:

/graphify                                             # 对当前目录跑全流水线(生成 HTML;加 --obsidian 输出 Obsidian 库)
/graphify <path>                                      # 对指定路径跑全流水线
/graphify https://github.com/<owner>/<repo>           # 克隆仓库后对其跑全流水线
/graphify https://github.com/<owner>/<repo> --branch <branch>  # 克隆指定分支
/graphify <url1> <url2> ...                           # 克隆多个仓库,各自构建后合并为跨仓库图
/graphify <path> --mode deep                          # 深度抽取,产出更丰富的 INFERRED 边
/graphify <path> --update                             # 增量:仅重新抽取新增/变更的文件
/graphify <path> --directed                            # 构建有向图(保留 source→target 方向)
/graphify <path> --whisper-model medium                # 用更大的 Whisper 模型提升转写精度
/graphify <path> --cluster-only                       # 在现有图上重跑聚类
/graphify <path> --no-viz                             # 跳过可视化,只出报告 + JSON
/graphify <path> --html                               # (HTML 默认生成,此标志为 no-op)
/graphify <path> --svg                                # 额外导出 graph.svg(可嵌入 Notion、GitHub)
/graphify <path> --graphml                             # 导出 graph.graphml(Gephi、yEd)
/graphify <path> --neo4j                              # 生成 graphify-out/cypher.txt 供 Neo4j 使用
/graphify <path> --neo4j-push bolt://localhost:7687   # 直推 Neo4j
/graphify <path> --falkordb                           # 生成 graphify-out/cypher.txt 供 FalkorDB 使用
/graphify <path> --falkordb-push falkordb://localhost:6379   # 直推 FalkorDB
/graphify <path> --mcp                                # 启动 MCP stdio 服务器供 Agent 访问
/graphify <path> --watch                              # 监听目录,代码变更时自动重建(无需 LLM)
/graphify <path> --wiki                               # 构建可被 Agent 爬取的 wiki(index.md + 每社区一篇文章)
/graphify <path> --obsidian --obsidian-dir ~/vaults/my-project  # 把 vault 写到自定义路径
/graphify add <url>                                   # 抓取 URL 存到 ./raw 并更新图
/graphify add <url> --author "Name"                   # 标注作者
/graphify add <url> --contributor "Name"              # 标注加入语料库的贡献者
/graphify query "<question>"                          # BFS 遍历——宽泛上下文
/graphify query "<question>" --dfs                    # DFS——追踪具体路径
/graphify query "<question>" --budget 1500            # 限制回答在 N 个 token 内
/graphify path "AuthModule" "Database"                # 两个概念间的最短路径
/graphify explain "SwinTransformer"                    # 用白话解释某个节点

这些标志在技能正文中被精确调度:默认运行只走"检测 → 抽取 → 建图 → 聚类 → 报告/HTML"主线;--wiki--neo4j*--falkordb*--svg--graphml--mcp 等导出型标志走 Step 6b-8,其细节被外置到 graphify/skills/kilo/references/exports.md,只有对应标志出现时才读取——这正是 "split" 形态控制单次会话上下文膨胀的手段。

三、被调用时的决策规则:快路径、帮助与路径默认值

技能在 ## What You Must Do When Invoked 部分给宿主 Agent 立了三条硬规则,它们决定了命令的行为语义:

  1. 帮助短路:用户只输入 /graphify --help/graphify -h 时,逐字打印 Usage 小节后立即返回——不执行任何命令、不做文件检测、不默认路径为 .
  2. 快路径(Fast path)——已有图直接查询:在做任何事之前先检查 graphify-out/graph.json 是否存在(相对当前工作目录,即项目根)。若它存在,且用户请求是关于代码库的自然语言问题("X 是怎么工作的?"、"谁调用了 Y?"、"追踪 Z 的数据流"),而不是显式重建命令(--update--cluster-only 或隐含重新抽取的裸路径/URL),则完全跳过 Step 1–5,直接跳到 query 流程,立即运行 graphify query "<question>"。不跑 detect、不检查语料规模、不要求用户缩小范围——图已经建好了,用它。
  3. 路径默认值:未给路径时使用 .,不得反问用户;路径以 https://github.com/http://github.com/ 开头时视为 GitHub URL,先执行 Step 0。

Step 0:GitHub 仓库与多路径合并(仅 URL 或多路径时)

只有路径是一个或多个 GitHub URL、或需要合并多个本地子文件夹时才执行本步,克隆、跨仓库合并与 monorepo 流程外置在 graphify/skills/kilo/references/github-and-merge.md。普通本地路径直接跳过。

四、Step 1:解释器解析与安装确认

技能不假设 python3 就是 graphify 的运行环境。Step 1 的 bash 块按三个优先级解析可用的 Python 解释器:

  1. uv tool 安装(现代 Mac/Linux 上最可靠):uv tool run --from graphifyy python -c "import sys; print(sys.executable)" 取 venv 解释器路径;
  2. graphify 可执行文件 shebang(覆盖 pipx 与直接 pip 安装):读取 $(which graphify) 首行 shebang,先做字符白名单校验(含非 [a-zA-Z0-9/_.@-] 字符即放弃),再验证该解释器能 import graphify
  3. 兜底 python3

import graphify 失败,则依次尝试 uv tool install --upgrade graphifyy,或 pip install graphifyy(失败时重试 --break-system-packages)。注意 PyPI 上的发行包名是 graphifyy

解析成功后,两块关键状态被持久化:

mkdir -p graphify-out
"$PYTHON" -c "import sys; open('graphify-out/.graphify_python', 'w', encoding='utf-8').write(sys.executable)"
# 保存扫描根,让无参数的 `graphify update` 下次知道去哪儿找
echo "$(cd INPUT_PATH && pwd)" > graphify-out/.graphify_root

此后每个 bash 块中都必须用 $(cat graphify-out/.graphify_python) 替换 python3,保证后续步骤与安装环境一致。配套地,技能末尾的 "Interpreter guard for subcommands" 一节要求:在运行 --update--cluster-onlyquerypathexplainadd 等任何子命令前,先检查 .graphify_python 是否存在,缺失(例如用户删掉了 graphify-out/)时先重新解析并写回。

五、Step 2:文件检测与语料规模闸门

Step 2 调用 graphify.detect.detect,并刻意用 Python 而非 shell 重定向写出侧车文件(注释说明这是为了避免 PowerShell 宿主上的控制台编码漂移,issue #2528):

from graphify.detect import detect
result = detect(Path('INPUT_PATH'))
Path('graphify-out/.graphify_detect.json').write_text(json.dumps(result, ensure_ascii=False), encoding="utf-8")
print(f'Detected {result["total_files"]} files')

实现见 graphify/detect.pydetect 定义于该模块,另有 detect_incremental 支撑 --update 的增量检测)。检测完成后技能要求宿主不打印原始 JSON,而是呈现一份干净的汇总(0 文件的类别省略):

Corpus: X files · ~Y words
  code:     N files (.py .ts .go ...)
  docs:     N files (.md .txt ...)
  papers:   N files (.pdf ...)
  images:   N files
  video:    N files (.mp4 .mp3 ...)

随后按三条分支行动,这体现了技能的"诚实规则"设计:

  • total_files == 0:直接停止,报告 "No supported files found in [path].";
  • skipped_sensitive 非空:报告被跳过的数量与文件名清单,让被误判的源码/文档可见,可被改名或移出(#2106);
  • total_words > 2,000,000total_files > 500:显示警告,并计算按文件数排序的前 5 个一级子目录(以 detect JSON 中绝对路径 scan_root 为基,排除 graphify-out/ 侧车,直接位于根的文件计为 (root))。若全部文件都在 (root) 无子目录,则不要求缩小范围,而是建议 --no-cluster 跳过昂贵聚类;否则展示 Top 5 并等待用户回答后再继续。其余情况直接进入 Step 2.5(有视频文件时)或 Step 3。

Step 2.5:音视频(仅当检测到视频文件)

detect 返回 0 个 video 文件时整步跳过;有音视频时按 graphify/skills/kilo/references/transcribe.md 先转写成文本,再把转录稿当作文档参与 Step 3。

六、Step 3:双通道抽取(AST 结构抽取 + 语义抽取)

Step 3 是整个流水线的心脏,拆为**结构抽取(deterministic、零 token 成本)语义抽取(LLM、消耗 token)**两条并行通道,最后在 Part C 合并。技能对此有三条强约束:

API key 边界(值得单列):graphify 不需要任何 API key,宿主永远不得向用户索要或因此阻塞。代码纯靠 AST 结构抽取——纯代码语料(最常见的 /graphify .)完全跳过语义抽取。语义抽取仅在 GEMINI_API_KEY/GOOGLE_API_KEY 已设置时使用 Gemini(默认模型 gemini-3-flash-preview,可用 GRAPHIFY_GEMINI_MODEL 或无头 CLI 的 --model 覆盖,此时调用 graphify.llm.extract_corpus_parallel(files, backend="gemini"));未设置时宿主 Agent 本身就是 LLM——正在运行的会话承担语义抽取。graphify 不读取 ANTHROPIC_API_KEYOPENAI_API_KEY 或其他任何提供商的 key;技能明确警告"如果你发现自己在提示用户补 key 或因此停下,那是误读了本技能"。

Part A:代码文件的 AST 结构抽取(与 Part B 并行启动)

from graphify.extract import collect_files, extract
code_files = []
detect = json.loads(Path('graphify-out/.graphify_detect.json').read_text(encoding="utf-8"))
for f in detect.get('files', {}).get('code', []):
    code_files.extend(collect_files(Path(f)) if Path(f).is_dir() else [Path(f)])

if code_files:
    result = extract(code_files, cache_root=Path('INPUT_PATH'))
    Path('graphify-out/.graphify_ast.json').write_text(json.dumps(result, indent=2, ensure_ascii=False), encoding="utf-8")
    print(f'AST: {len(result["nodes"])} nodes, {len(result["edges"])} edges')
else:
    # 写空骨架,保证 Part C 合并有输入
    Path('graphify-out/.graphify_ast.json').write_text(json.dumps({'nodes':[],'edges':[],'input_tokens':0,'output_tokens':0}, ensure_ascii=False), encoding="utf-8")

技能强调 Part A 与 Part B 必须在同一条消息里同时启动:AST 确定性且快,在子代理处理文档/论文的间隙完成;并行化在大语料上可节省 5–15 秒。同时要求把 --mode deep 是否出现记录下来,作为 DEEP_MODE=true 传给每一个 Part B2 子代理,不得丢失。

Part B:语义抽取(并行子代理)

快路径:若检测发现 0 个文档、论文、图片(纯代码语料),Part B 整体跳过——但必须先写一个空的语义文件,否则 Part C 的合并(无条件读 .graphify_semantic.json)会 FileNotFoundError

Path('graphify-out/.graphify_semantic.json').write_text(json.dumps({'nodes':[],'edges':[],'hyperedges':[],'input_tokens':0,'output_tokens':0}), encoding='utf-8')

派发纪律(技能原话 "MANDATORY"):必须使用 Agent 工具派发子代理,逐文件自己读是被禁止的(慢 5–10 倍)。派发前打印耗时预估:代理数 = ceil(未缓存非代码文件数 / 22)(chunk 大小 20–25 个文件),每批约 45 秒并行执行。

Step B0 — 先查抽取缓存:调用 graphify.cache.check_semantic_cache,且 prompt_file 参数必须传 SPEC_PATH——即与本技能并列、Step B2 会原样交给每个子代理的 extraction-spec.md绝对路径。设计意图(#1939):缓存条目归属于产生它的那份抽取提示词;graphify 升级改变了提示词时,旧条目会重新抽取而不是回放。代码片段还体现两处防御:只对 document/paper/image 三类送语义抽取(代码已由 AST 通道覆盖,否则子代理会重读所有源码,#1392);缓存命中就写 .graphify_cached.json未命中就删除该文件,防止 Part C 合并进上一轮残留的陈旧缓存。

Step B1 — 分块:从 .graphify_uncached.txt 读未缓存文件,每 20–25 个一组;每张图单独成 chunk(视觉模型需要独立上下文);同一目录的文件尽量同组,让相关工件落在同一 chunk 里,跨文件关系更容易被抽出来。

Step B2 — 在一条消息里派发全部子代理:对每个 chunk 调用一次 Agent 工具,且所有调用必须在同一响应中发出,这是并行执行唯一的方式;逐个等返回等于串行,违背设计。子代理类型固定 subagent_type="general-purpose",禁用 Explore——后者只读,无法把 chunk 文件写盘,会静默丢失抽取结果。每个子代理接收由 references/extraction-spec.md 原样替换 FILE_LISTCHUNK_NUMTOTAL_CHUNKSDEEP_MODECHUNK_PATH 五个占位符后得到的提示词(其中包含 JSON schema、节点 ID 规则、置信度评级、frontmatter、超边与视觉规则),并把结果写到绝对路径CHUNK_PATH(由当前工作目录——即 Part C 会 glob graphify-out/ 的地方——推导,而不是 .graphify_root 指向的扫描目录,#1392)。

Step B3 — 收集、缓存、合并:逐 chunk 校验磁盘上 .graphify_chunk_NN.json 是否存在——存在且含有效 nodes/edges 才纳入并写缓存;缺失则警告"chunk N 不在磁盘上,子代理可能被以只读(Explore)类型派发了,请用 general-purpose 重跑",不得静默跳过;某子代理失败或 JSON 无效则警告并跳过该 chunk,不中断整个流程。超过半数 chunk 失败或缺失时停止,要求用户确认使用 subagent_type="general-purpose" 后重跑。合并阶段还要求:每次 Agent 调用完成后,从工具结果的 usage 字段读出真实 token 数回写 chunk JSON(chunk 文件里只有占位零值),再把所有 chunk 合并为 .graphify_semantic_new.json;随后 save_semantic_cache与 B0 相同的 SPEC_PATH 盖章缓存(读与写若用不同提示词,条目会落在下次查找的位置之外,#1939);最后把缓存 + 新结果按节点 id 去重合并进 .graphify_semantic.json,并清理临时文件。

Part C:AST 与语义合并为最终抽取

合并规则是"AST 节点优先,语义节点按 id 去重追加;边直接拼接;超边只来自语义侧",输出 .graphify_extract.json 并打印 Merged: N nodes, M edges (X AST + Y semantic)

七、Step 4 至 Step 9:建图、健康检查、标注、可视化与收尾

Step 4:建图、聚类、分析、产出

本步把 directed=IS_DIRECTED 传给 build_from_json()——出现 --directed 时替换为 True(构建保留 source→target 方向的 DiGraph),否则 False(默认无向 Graph),替换纪律与 INPUT_PATH 相同,不得把字面量留在代码里。核心调用链(各模块真实存在于仓库中):

G = build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED)   # graphify/build.py
if G.number_of_nodes() == 0:      # 写入前的空图守卫(#1392)
    print('ERROR: Graph is empty - extraction produced no nodes.')
    raise SystemExit(1)
communities = cluster(G)           # graphify/cluster.py
cohesion = score_all(G, communities)
gods = god_nodes(G)                # graphify/analyze.py
surprises = surprising_connections(G, communities)
questions = suggest_questions(G, communities, labels)   # 占位标签,Step 5 用真标签重算
wrote = to_json(G, communities, 'graphify-out/graph.json')  # graphify/export.py
if not wrote:                      # #479 缩水守卫
    print('ERROR: refused to shrink graphify-out/graph.json (existing graph has more nodes; #479).')
    raise SystemExit(1)
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, 'INPUT_PATH', suggested_questions=questions)  # graphify/report.py

两个守卫值得注意:root= 参数与 --update 手册保持同一基(#1361),保证全量构建与增量更新在重新抽取时节点键不漂移;to_json 在新图小于现存 graph.json 时返回 False 且不写盘(#479 缩水守卫),只有真正写盘后才生成 GRAPH_REPORT.md 与分析侧车 .graphify_analysis.json,使报告永不描述 graph.json 中不存在的图。若打印 ERROR: Graph is empty 必须停止并告知用户,不得继续标注或可视化。

Step 4.5:图健康检查(只读完整性闸门)

在标注之前对抽取结果做非破坏性诊断(实现于 graphify/diagnostics.pydiagnose_extraction / format_diagnostic_report),暴露增量更新与 AST/LLM ID 不匹配这三类"静默损坏模式":边坍缩、悬空/缺失端点、自环。该步骤永不中止流程,但若打印 GRAPH HEALTH WARNING,必须在最终摘要中呈现("图仍可用,但完整性问题必须可见"——诚实规则的要求)。

Step 5:社区标注

宿主读取 .graphify_analysis.json,为每个社区依据其节点标签写一个 2–5 词的白话名字(如 "Attention Mechanism"、"Training Pipeline"),然后把 LABELS_DICT 与真标签代回 Step 5 代码块:重算 suggest_questions(标签影响提问措辞)、重新 generate 报告、写 .graphify_labels.json 供可视化器使用,并用 community_labels=labels 重新导出 graph.json,让节点携带策划过的 community_name(#2490);同一份抽取下 #479 守卫按节点数通过,若仍拒绝则照实呈现守卫信息,不得强行越过。

Step 6:HTML(默认)与 Obsidian(opt-in)

HTML 始终生成(除非 --no-viz):graphify export html,节点超过 5000 时自动聚合到社区视图。Obsidian vault 仅在显式给出 --obsidian生成(它每节点一个文件):graphify export obsidian,可加 --dir 指向已有 vault。Steps 6b–8(--wiki--neo4j/--neo4j-push--falkordb/--falkordb-push--svg--graphml--mcp,以及 total_words 超过 5000 时的 token 缩减 benchmark)只在对应标志存在时执行,默认运行全部跳过;细节外置在 references/exports.md。注意顺序约束:--wiki 导出必须赶在 Step 9 清理之前,以便 .graphify_labels.json 尚存。

Step 9:清单、成本追踪与清理

收尾代码块做三件事(节选语义):

  1. 保存 manifest 供 --update 使用:调用 graphify/detect.pysave_manifestroot= 把清单键相对化到扫描根(跨克隆/机器可移植,后续 --update 匹配缓存而非全部未命中,#1417);只给真正产出了输出的语义文件盖章——chunk 失败或被省略的检测文件必须保持未盖章,否则下次 --update 会把它当成已完成,其内容将永久丢失(#2015);代码文件总是盖章(AST 是确定性的)。派发但未盖章的文件其陈旧 semantic_hash 会被清除,使 detect_incremental 重新排队而不是误读为未变(#1948)。
  2. 累计成本追踪:每次运行的 input/output token 追加进 graphify-out/cost.jsonruns,并累加全时总量。
  3. 清理临时侧车.graphify_detect/extract/ast/semantic/analysis.json、全部 .graphify_chunk_*.json.needs_update)。

完成后向用户报告产物清单(graph.htmlGRAPH_REPORT.mdgraph.json,给了 --obsidian 才多一行 obsidian/),并只粘贴报告中的 God Nodes、Surprising Connections、Suggested Questions 三节(不贴全文),然后从建议问题中挑出跨社区边界最多/桥接节点最意外的那个,以"这个图能回答的最有趣的问题是:[问题]。要我追踪一下吗?"收尾——图是地图,流水线跑完后的角色是向导,每次回答以自然的追问结尾,让会话像导航而非一次性报告。

八、Kilo 专属规则与其余子命令入口

技能末尾的 ## Kilo-specific rules 一节是 skillgen 用 kilo-rules.md 片段注入的宿主差异点,共四条:

  • 使用 Kilo 原生的 Task 工具做语义抽取扇出(对应 dispatch = "agent-tool-disk" 的磁盘收集模式);
  • 所有 chunk 任务在同一条响应中发起以保证并行;
  • 抽取 chunk 一律使用 subagent_type="general"(Kilo 的类型名,对应通用型 Agent);
  • 会话中修改过代码文件后,运行 graphify update .,保持图与代码同步。

其余入口均指向侧车参考文档:

  • 解释器守卫:任何子命令(--update--cluster-onlyquerypathexplainadd)前先检查 .graphify_python,缺失则用 shebang 解析兜底重新写回;
  • --update 与 `--cluster-only:前者只重新抽取新增/变更文件,后者在现有图上重跑聚类,两条流程都外置在 references/update.md
  • query 流程graphify-out/graph.json 已存在且用户提问时,用 graphify query "<question>" 从图回答而非重建;遍历前先用图自身词汇表扩展问题措辞(避免用词错位把答案塌缩成噪声);CLI 不可用时回退到对 graph.json 的内联 NetworkX 遍历;回答只依据图输出内容,引用具体事实时引用 source_location;BFS/DFS 模式、--budget 上限、save-result 反馈以及 /graphify path/graphify explain 流程详见 references/query.md
  • add--watch:都不是默认构建的一部分,详见 references/add-watch.md
  • commit hook 与 CLAUDE.md 集成:安装 post-commit 自动重建钩子或把 graphify 接入项目 CLAUDE.md 时,见 references/hooks.md

最后是五条 Honesty Rules(诚实规则),与项目"每条边都可解释"的定位一脉相承:绝不虚构边(不确定就用 AMIGUOUS);绝不跳过语料规模警告;报告中永远展示 token 成本;绝不把凝聚度分数藏在符号后面(展示原始数值);超过 5000 节点的图绝不未经警告就跑 HTML 可视化。

九、Kilo Code 上的落盘方式:技能、命令与插件三件套

skill-kilo.md 如何到达用户机器,由 graphify/install.py 中的平台表与 Kilo 专属逻辑定义。平台表中 kilo 的条目为:

"kilo": {
    "skill_file": "skill-kilo.md",
    "skill_dst": Path(".config") / "kilo" / "skills" / "graphify" / "SKILL.md",
    "claude_md": False,
    "skill_refs": "kilo",
},

graphify kilo install 会把 graphify/skill-kilo.md 与对应的 skills/kilo/references 侧车安装到 ~/.config/kilo/skills/graphify/SKILL.md(Kilo 的技能目录约定),且 Kilo 不需要 CLAUDE.md 常驻块(claude_md: False)。

Kilo 变体还有两处其他宿主没有的额外产物:

  1. 原生 /graphify 命令文件:安装时把包内的 graphify/command-kilo.md 复制到 ~/.config/kilo/command/graphify.md。该命令是一个极薄的派发存根,其全文要求"立即调用 graphify 技能,把完整的 /graphify 参数字符串原样透传,无参数时目标路径视为 .",并明确不得在交给 graphify 技能之前从原始文件作答——这条与技能 frontmatter 的"图优先"判据形成闭环。
  2. .kilo 插件钩子:安装器写入 .kilo/plugins/graphify.js(一个 tool.execute.before 钩子),并把插件注册进项目根的 .kilo/kilo.json(若项目已有带注释的 kilo.jsonc,自动写入只针对 kilo.json,避免改写用户的 JSONC)。卸载时对应删除插件文件并反注册。

十、小结:一个技能文件如何承载完整方法论

回到 graphify/skill-kilo.md 本身,它的信息架构可以概括为四层:

  • 命令面(Usage + 子命令路由):20 余个标志与 add/query/path/explain 子命令,全部给出确定性行为定义;
  • 流水线(Step 0–9):检测 → 双通道并行抽取(AST + 带缓存/分块/磁盘收集的语义子代理)→ 建图聚类分析(空图守卫 + 缩水守卫)→ 健康检查 → 社区标注 → 可视化 → manifest/成本/清理,每一步都有可复制的 bash 块与 issue 编号标注的失败防护;
  • 宿主差异(Kilo-specific rules):Task 工具扇出、同响应并行、general 子代理类型、改码后 graphify update . 四条;
  • 价值观(Honesty Rules):EXTRACTED/INFERRED/AMBIGUOUS 审计标签、token 成本透明、原始分数展示、规模警告不可跳过。

对读者而言,这份文件既是 Kilo Code 用户的 /graphify 行为说明书,也是理解 graphify "本地确定性 AST 解析、每条边可解释、无向量库" 设计哲学的最佳入口;而 tools/skillgen/tests/test_skillgen.py 则保证了它在 13+ 个宿主变体之间渲染一致、可回归校验。

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