news 2026/9/7 5:28:59

graphify 接入 Pi 编码智能体:skill-pi.md 的 /graphify 完整运行手册

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
graphify 接入 Pi 编码智能体:skill-pi.md 的 /graphify 完整运行手册

graphify 接入 Pi 编码智能体:skill-pi.md 的 /graphify 完整运行手册

【免费下载链接】graphifyTurn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.项目地址: https://gitcode.com/GitHub_Trending/graph/graphify

graphify/skill-pi.md是 graphify 为 Pi coding agent 平台定制的 SKILL 文件:当用户在 Pi 会话中输入/graphify时,Pi 会按这份 700 余行的“运行手册(runbook)”把任意代码、文档、论文、图片与视频目录转成可查询的知识图谱,并给出query/path/explain三种图查询入口。读完本文,你既能完整复现该手册规定的九步构建流水线与全部命令行参数,也能理解其中每个步骤背后 graphify 仓库源码(graphify/build.py、graphify/cache.py、graphify/diagnostics.py 等)承担的具体职责。

skill-pi.md 在仓库中的定位

skill-pi.md与 Claude Code 平台的主技能文件 graphify/skill.md 内容逐字节一致(当前仓库版本中两者diff为空),它属于 graphify 的“split 桶”平台之一:一个技能主体加上一组按需加载的references/参考文档。可以从三处源码确认这一结构:

  1. 安装配置:graphify/install.py 中"pi"平台条目声明了"skill_file": "skill-pi.md"、安装目标~/.pi/agent/skills/graphify/SKILL.md以及"skill_refs": "pi"(参考文档目录);
  2. 技能生成:tools/skillgen/platforms.toml 中[platform.pi]声明skill_dst = "graphify/skill-pi.md"refs_dst = "graphify/skills/pi/references",即 skill-pi.md 是由 skillgen 工具从tools/skillgen/fragments/下的片段渲染生成、并以 tests/test_skillgen.py 做回归校验的产物;
  3. 打包分发:pyproject.toml 的 package-data 中同时打包了skill-pi.mdskills/*/references/*.md,保证pip install后 Pi 仍能拿到完整技能包。

随技能主体一同分发的 Pi 参考文档位于 graphify/skills/pi/references/,按主题拆分,正文中只在对应步骤才要求加载:

参考文档加载时机
extraction-spec.md语义抽取子代理的提示词与 JSON Schema
query.mdquery/path/explain遍历流程
update.md--update增量重建与--cluster-only
exports.md--wiki--neo4j--falkordb--svg--graphml--mcp等导出
add-watch.mdadd <url>语料抓取与--watch自动重建
github-and-merge.mdURL 克隆与多仓库合并
transcribe.md音视频转写(Whisper)
hooks.mdpost-commit 钩子与 CLAUDE.md 集成

安装方式在 README.md 的平台表中给出:graphify install --platform pi或等价的graphify pi install。安装后,Pi 会话中所有/graphify ...请求都交由skill-pi.md正文驱动,用户无需记忆 graphify CLI 的细节。

命令参考:/graphify 的完整用法

文档开头的 Usage 块是/graphify的完整命令面,Pi 在执行任何操作前必须严格遵守它的语义:

/graphify # 对当前目录跑完整流水线(HTML 可视化;加 --obsidian 生成 vault) /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 server 供其他 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" # 用通俗语言解释某个节点

文档同时明确了三条调用语义:/graphify --help(或-h,且无其他参数)时原样打印 Usage 块并停止,不执行任何命令;未给路径时默认使用.(当前目录),不得反问用户;路径以https://github.com/http://github.com/开头时,先执行 Step 0(克隆)再继续。

快速路径:已有图时直接走查询

手册在“被调用时必须做的事”一节规定了最高优先级规则:先检查graphify-out/graph.json是否存在(相对当前工作目录)。若它存在,且用户的请求是自然语言问题(“X 怎么工作?”“谁调用了 Y?”)而非显式重建命令(--update--cluster-only或暗示重新抽取的裸路径/URL),则完全跳过 Step 1–5,直接进入 query 流程——不运行 detect、不检查语料规模、不要求用户缩小范围。这条“快速路径”体现了 graphify 的设计前提:图是持久化资产,提问时应当“查图而不是重建图”,后文 query 小节会展开。

Step 0–1:解析 Python 解释器并保证安装

Pi 这类宿主不保证python3就是装有 graphify 的解释器(可能装在 uv tool、pipx 或 venv 里),因此 Step 1 的核心是一段解释器探测脚本,探测成功后把解释器路径落盘到graphify-out/.graphify_python后续所有 bash 块都必须用$(cat graphify-out/.graphify_python)替代字面量python3

# Detect the correct Python interpreter (handles uv tool, pipx, venv, system installs) PYTHON="" GRAPHIFY_BIN=$(which graphify 2>/dev/null) # 1. uv tool installs — most reliable on modern Mac/Linux if [ -z "$PYTHON" ] && command -v uv >/dev/null 2>&1; then _UV_PY=$(uv tool run --from graphifyy python -c "import sys; print(sys.executable)" 2>/dev/null) if [ -n "$_UV_PY" ]; then PYTHON="$_UV_PY"; fi fi # 2. Read shebang from graphify binary (pipx and direct pip installs) if [ -z "$PYTHON" ] && [ -n "$GRAPHIFY_BIN" ]; then _SHEBANG=$(head -1 "$GRAPHIFY_BIN" | tr -d '#!') case "$_SHEBANG" in *[!a-zA-Z0-9/_.@-]*) ;; *) "$_SHEBANG" -c "import graphify" 2>/dev/null && PYTHON="$_SHEBANG" ;; esac fi # 3. Fall back to python3 if [ -z "$PYTHON" ]; then PYTHON="python3"; fi if ! "$PYTHON" -c "import graphify" 2>/dev/null; then if command -v uv >/dev/null 2>&1; then uv tool install --upgrade graphifyy -q 2>&1 | tail -3 _UV_PY=$(uv tool run --from graphifyy python -c "import sys; print(sys.executable)" 2>/dev/null) if [ -n "$_UV_PY" ]; then PYTHON="$_UV_PY"; fi else "$PYTHON" -m pip install graphifyy -q 2>/dev/null \ || "$PYTHON" -m pip install graphifyy -q --break-system-packages 2>&1 | tail -3 fi fi # Write interpreter path for all subsequent steps (persists across invocations) mkdir -p graphify-out "$PYTHON" -c "import sys; open('graphify-out/.graphify_python', 'w', encoding='utf-8').write(sys.executable)" # Save scan root so `graphify update` (no args) knows where to look next time echo "$(cd INPUT_PATH && pwd)" > graphify-out/.graphify_root

三个探测顺序对应 README 中反复强调的安装建议:uv tool install/pipx install的隔离环境最可靠,裸pip install因环境漂移最容易产生ModuleNotFoundError——这段脚本实际上是把 README 的运维建议固化成了可执行逻辑。若 import 成功则静默进入 Step 2;graphify-out/.graphify_root则记录扫描根目录,供无参graphify update使用。

Step 2:文件探测与语料体检

Step 2 调用 graphify/detect.py 中的detect()扫描目标路径,把分类结果写入graphify-out/.graphify_detect.json(注意:手册特别要求用 Python 写 sidecar 而不是 shell 重定向,避免 PowerShell 宿主上的控制台编码漂移):

$(cat graphify-out/.graphify_python) -c " import json from graphify.detect import detect from pathlib import Path 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') "

输出不是原始 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非空:报告数量并列出被跳过的文件名,让被误判的源文件可见、可改名或移动;
  • total_words> 2,000,000 或total_files> 500:必须展示警告,并计算按文件数排序的 top 5 一级子目录(从 detect JSON 读取绝对路径scan_root,合并code/document/paper/image/video全部文件列表,过滤scan_root + "/graphify-out/"前缀的中间产物,取scan_root之后的第一个路径段,根目录直属文件记为(root))。若全部文件都在(root),则不问用户、改为建议--no-cluster跳过昂贵的聚类;否则展示 top 5 并等待用户选择子目录后再继续。

Step 3:双通道抽取——AST 结构通道与 LLM 语义通道

手册对 Step 3 的关键定性是:结构抽取是确定性的、免费的,语义抽取才花 token。并且给出了一条强约束——“graphify 不需要 API key,永远不要向用户索要,也不要因为缺 key 而阻塞”:

  • 代码文件走 AST,完全不需要 LLM 和 key;纯代码语料(最常见的/graphify .)直接跳过语义抽取;
  • 语义抽取(仅针对文档、论文、图片)只有在GEMINI_API_KEY/GOOGLE_API_KEY已设置时才使用 Gemini(pip install 'graphifyy[gemini]',默认模型gemini-3-flash-preview,可用GRAPHIFY_GEMINI_MODEL--model覆盖);
  • 若两个 key 都未设置,向用户打印一次提示后继续——此时“宿主 agent 本身就是 LLM”,即由 Pi 会话自己承担语义抽取,graphify 明确不读ANTHROPIC_API_KEYOPENAI_API_KEY或其他厂商的 key。

Part A(AST)与 Part B(语义)要求在同一轮消息中并行启动:AST 启动的同时派发全部语义子代理,大语料上可省 5–15 秒。

Part A——对代码文件跑 AST 抽取,输入来自 detect JSON 的files.code,结果落盘为.graphify_ast.json

$(cat graphify-out/.graphify_python) -c " import sys, json from graphify.extract import collect_files, extract from pathlib import Path 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: Path('graphify-out/.graphify_ast.json').write_text(json.dumps({'nodes':[],'edges':[],'input_tokens':0,'output_tokens':0}, ensure_ascii=False), encoding=\"utf-8\") print('No code files - skipping AST extraction') "

这里调用的graphify.extract.extract即 graphify/extract.py 中的统一抽取入口,其下游按语言分派到 graphify/extractors/ 下的 tree-sitter 解析器(Python、Go、Rust、C#、Swift、SQL、Terraform 等),与 tests/test_extract.py 覆盖的行为一致。

Part B——语义抽取(并行子代理)。先是一条“快速路径”:纯代码语料跳过 Part B,但必须先写出空的.graphify_semantic.json{'nodes':[],'edges':[],'hyperedges':[],'input_tokens':0,'output_tokens':0}),否则 Part C 的合并会因FileNotFoundError失败——因为 Part C 无条件读取该文件。

对确实含文档/论文/图片的语料,手册把流程拆成 B0–B3 四步,并强制要求使用 Pi 的 Agent 工具(“逐个自己读文件慢 5–10 倍”):

  • B0 查缓存:调用 graphify/cache.py 的check_semantic_cache(all_files, root=..., prompt_file=SPEC_PATH),只把document/paper/image三类送检(代码已被 AST 覆盖;视频在 Step 2.5 先转写为文档)。SPEC_PATH是随技能分发的 extraction-spec.md 的绝对路径——缓存条目以提示词文件归属,graphify 升级改变了抽取提示词后,旧条目会被重新抽取而不是直接回放;命中写入.graphify_cached.json,未命中列表写入.graphify_uncached.txt
  • B1 分块:每块 20–25 个文件,图片独占一块(视觉需要独立上下文),同一目录的文件尽量同块,便于抽取跨文件关系;
  • B2 派发:所有子代理调用必须在同一条消息里发出才能真正并行;必须用可写盘的通用型 agent(Pi 中即具备文件写入权限的子代理类型),只读代理会把结果悄悄丢掉。派发给每个子代理的提示词逐字取自 extraction-spec.md,替换FILE_LISTCHUNK_NUMTOTAL_CHUNKSDEEP_MODECHUNK_PATH(绝对路径)五个占位符;
  • B3 收集与合并:以.graphify_chunk_NN.json落盘为成功信号;缺失或 JSON 无效只警告不中止,超过一半分块失败才停止并要求检查代理类型。合并前要把每个 Agent 调用结果usage字段里的真实 token 数写回 chunk JSON(chunk 文件里只有占位 0),再把所有 chunk 合并为.graphify_semantic_new.json,随后用save_semantic_cache(...)把新结果写回缓存(传入与 B0 相同的SPEC_PATH),最后把“缓存 + 新增”合并、按节点 id 去重,写入.graphify_semantic.json,并清理临时文件。

extraction-spec 中规定的抽取规则值得单独强调,因为它们直接决定图的质量边界:每条边必须带confidence_scoreEXTRACTED恒为 1.0;INFERRED只能取 0.95/0.85/0.75/0.65/0.55 之一,禁止 0.5 默认值;AMBIGUOUS为 0.1–0.3);节点 id 必须是小写[a-z0-9_]{stem}_{entity}确定性格式(src/auth/session.py+ValidateTokensrc_auth_session_validatetoken),且必须与 AST 抽取器的 id 规则一致——这是 Part C 能按 id 去重、--update能按source_file精确替换而不产生重复节点的前提。

Part C——AST 与语义合并:AST 节点优先,语义节点按 id 去重后追加,边直接拼接,hyperedges 只来自语义侧,最终写入.graphify_extract.json并打印Merged: N nodes, E edges (x AST + y semantic)

Step 4–4.5:建图、聚类、分析与完整性体检

Step 4 是流水线的核心,一次调用链跑完“建图 → 社区检测 → 分析 → 导出”四件事,对应仓库中四个模块:graphify/build.py 的build_from_json、graphify/cluster.py 的cluster/score_all、graphify/analyze.py 的god_nodes/surprising_connections/suggest_questions、graphify/report.py 的generate

mkdir -p graphify-out $(cat graphify-out/.graphify_python) -c " import sys, json from graphify.build import build_from_json from graphify.cluster import cluster, score_all from graphify.analyze import god_nodes, surprising_connections, suggest_questions from graphify.report import generate from graphify.export import to_json from pathlib import Path extraction = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding=\"utf-8\")) detection = json.loads(Path('graphify-out/.graphify_detect.json').read_text(encoding=\"utf-8\")) G = build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED) # Guard BEFORE any write: an empty extraction must not clobber a good graph.json if G.number_of_nodes() == 0: print('ERROR: Graph is empty - extraction produced no nodes.') raise SystemExit(1) communities = cluster(G) cohesion = score_all(G, communities) tokens = {'input': extraction.get('input_tokens', 0), 'output': extraction.get('output_tokens', 0)} gods = god_nodes(G) surprises = surprising_connections(G, communities) labels = {cid: 'Community ' + str(cid) for cid in communities} questions = suggest_questions(G, communities, labels) wrote = to_json(G, communities, 'graphify-out/graph.json') if not wrote: 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) Path('graphify-out/GRAPH_REPORT.md').write_text(report, encoding=\"utf-8\") analysis = { 'communities': {str(k): v for k, v in communities.items()}, 'cohesion': {str(k): v for k, v in cohesion.items()}, 'gods': gods, 'surprises': surprises, 'questions': questions, } Path('graphify-out/.graphify_analysis.json').write_text(json.dumps(analysis, indent=2, ensure_ascii=False), encoding=\"utf-8\") print(f'Graph: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges, {len(communities)} communities') "

三个占位符约定:IS_DIRECTED在给出--directed时替换为True(NetworkX 的DiGraph,保留 source→target 方向),否则False(默认无向Graph);INPUT_PATH替换为实际路径——root=参数让source_file相对化到同一基准,保证全量构建与--update增量重抽在节点键上完全一致(tests/test_build.py 对build_from_json的合并行为有回归覆盖)。

这段代码里有两道“写前守卫”,是手册的诚实性约束落到代码层的体现:

  1. 空图守卫build_from_json后节点数为 0 立即SystemExit(1),绝不用空抽取覆盖已有的graph.jsonGRAPH_REPORT.md
  2. 收缩守卫(#479 shrink-guard):graphify/export.py 的to_json在新图比现有graph.json更小时返回False且不写盘;只有图确实被写出,才允许写报告与分析 sidecar,确保报告永远不描述一个graph.json里不存在的图。若收缩确属故意(删除了文件),需用--force的全量重建。

Step 4.5 是一道只读完整性体检,调用 graphify/diagnostics.py 的diagnose_extraction,专门暴露增量更新与 AST/LLM id 不匹配时的四种静默损坏模式:悬空端点边、缺失端点边、自环、同端点坍缩边(有向/无向分别计数):

$(cat graphify-out/.graphify_python) -c " import json from pathlib import Path from graphify.diagnostics import diagnose_extraction, format_diagnostic_report extraction = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding=\"utf-8\")) summary = diagnose_extraction(extraction, directed=IS_DIRECTED, root='INPUT_PATH') print(format_diagnostic_report(summary)) flags = [f'{summary[k]} {label}' for k, label in ( ('dangling_endpoint_edges', 'dangling-endpoint edges'), ('missing_endpoint_edges', 'missing-endpoint edges'), ('self_loop_edges', 'self-loop edges'), ('directed_same_endpoint_collapsed_edges', 'collapsed (directed) edges'), ('undirected_same_endpoint_collapsed_edges', 'collapsed (undirected) edges'), ) if summary.get(k, 0)] print('GRAPH HEALTH WARNING: ' + '; '.join(flags) + ' - graph may be incomplete/corrupt.' if flags else 'Graph health: OK (no dangling/missing/collapsed edges).') "

该步骤永不中止流程,但若打印了GRAPH HEALTH WARNING,最终摘要中必须把它显式呈现出来(见文末 Honesty Rules)。

Step 5–6:社区打标与可视化输出

Step 5 是流水线中唯一要求 agent 发挥语言能力的环节:读.graphify_analysis.json,为每个社区依据其节点标签起一个 2–5 词的通俗名(如 “Attention Mechanism”“Training Pipeline”),然后把LABELS_DICT(形如{0: "Attention Mechanism", 1: "Training Pipeline"})代回第二段脚本重生成GRAPH_REPORT.md、保存graphify-out/.graphify_labels.json,并带community_labels=labels重新to_json一次,让graph.json的节点携带 curated 的community_name。由于用的是同一份 extraction,节点数不变,收缩守卫自然通过;若仍被拒,只呈现守卫信息,不得强推。

Step 6 的输出规则很明确:

  • HTML 总是生成(除非--no-viz):graphify export html,节点超过 5000 时自动聚合到社区视图;
  • Obsidian vault 仅在显式给出--obsidian时生成(每节点一个文件,成本高):graphify export obsidian,自定义目录用--dir,默认graphify-out/obsidian
  • --wiki--neo4j/--neo4j-push--falkordb/--falkordb-push--svg--graphml--mcp等导出只在对应标志出现时执行,各自细节见 references/exports.md;--wiki必须在 Step 9 清理前跑完,因为它还要读.graphify_labels.json

Step 9:manifest 落盘、成本记账与收尾

Step 9 是增量能力的记账环节,也是最容易写错的一环,手册中每条注释都对应一个具体故障模式:

$(cat graphify-out/.graphify_python) -c " import json from pathlib import Path from datetime import datetime, timezone from graphify.detect import save_manifest detect = json.loads(Path('graphify-out/.graphify_detect.json').read_text(encoding=\"utf-8\")) extract = json.loads(Path('graphify-out/.graphify_extract.json').read_text(encoding=\"utf-8\")) from graphify.cli import _stamped_manifest_files _corpus = detect.get('all_files') or detect['files'] _manifest_files = _stamped_manifest_files(_corpus, extract, Path('INPUT_PATH')) _sem_types = ('document', 'paper', 'image') _dispatched = {f for t, fl in detect['files'].items() if t in _sem_types for f in fl} _stamped = {f for fl in _manifest_files.values() for f in fl} _cleared = _dispatched - _stamped _scan = {f for fl in _corpus.values() for f in fl} save_manifest(_manifest_files, root='INPUT_PATH', scan_corpus=_scan, clear_semantic=_cleared or None) input_tok = extract.get('input_tokens', 0) output_tok = extract.get('output_tokens', 0) cost_path = Path('graphify-out/cost.json') cost = json.loads(cost_path.read_text(encoding='utf-8')) if cost_path.exists() else {'runs': [], 'total_input_tokens': 0, 'total_output_tokens': 0} cost['runs'].append({'date': datetime.now(timezone.utc).isoformat(), 'input_tokens': input_tok, 'output_tokens': output_tok, 'files': detect.get('total_files', 0)}) cost['total_input_tokens'] += input_tok cost['total_output_tokens'] += output_tok cost_path.write_text(json.dumps(cost, indent=2, ensure_ascii=False), encoding='utf-8') " rm -f graphify-out/.graphify_detect.json graphify-out/.graphify_extract.json \ graphify-out/.graphify_ast.json graphify-out/.graphify_semantic.json \ graphify-out/.graphify_analysis.json find graphify-out -maxdepth 1 -name '.graphify_chunk_*.json' -delete 2>/dev/null

其语义可归纳为四条(均与 graphify/manifest.py 及--update流程配套,由 tests/test_incremental.py、tests/test_stale_prune.py 回归):

  1. manifest 相对化save_manifest(..., root='INPUT_PATH')把键相对化到扫描根,使 manifest 可跨 clone/机器移植,下一次--update能命中缓存文件而不是全部漏判;
  2. 只盖真正产出的章:语义类文件(doc/paper/image)只有实际产出节点/边才盖章;某文件所在 chunk 失败或未派发就必须不盖章,否则下次--update会把它误判为“已完成”而永久丢失内容。代码文件则总是盖章,因为 AST 是确定性的;
  3. 清理陈旧 semantic_hash:本次派发但未盖章的文件携带上一轮的陈旧 hash,clear_semantic参数让detect_incremental重新排队它们而不是当成未变化;
  4. 成本记账graphify-out/cost.json追加每次运行的日期、输入/输出 token 与文件数,并累计历史总量——配合 Honesty Rules 的“报告必须展示 token 成本”。

收尾后向用户报告产物清单(graph.htmlGRAPH_REPORT.mdgraph.json、可选obsidian/),并只粘贴报告中的三个小节——God Nodes、Surprising Connections、Suggested Questions——而不是整份报告;随后从建议问题里挑最“跨界”的一个主动邀请探索(“The most interesting question this graph can answer:[question]. Want me to trace it?”),用户同意后运行/graphify query "[question]"并带着用户沿图结构走,每个回答以自然的追问收尾。手册用一句原话定义了 agent 的终局角色:“The graph is the map. Your job after the pipeline is to be the guide.”

查询面:query、path、explain 与反馈闭环

快速路径之外,graphify-out/graph.json已存在时任何语料问题都应通过查询回答。/graphify query的完整流程在 references/query.md 中,要点包括:

  • 先做受控查询扩展graphify queryCLI 用“大小写折叠子串 + IDF”匹配节点,没有词干还原、同义词或跨语言匹配;因此先从不带数字下划线的 label 分词构建词表(graphify-out/.vocab.txt,长度 3–30 的 token),再从词表中选至多 12 个与查询意图语义匹配的 token,禁止自造 token;选不出任何词表词时如实告知语料无相关词汇并停止;
  • 两种遍历模式:BFS(默认)适合“X 连着什么”的宽上下文,DFS 适合“X 如何到达 Y”的链路追踪;CLI 不可用时按手册内置的 NetworkX 内联脚本执行(BFS 3 层、DFS 深度上限 6、--budget默认 2000 token 约 4 字符/token 截断);
  • 只答图里有的东西:回答仅使用遍历输出,引用具体事实时引用source_location,信息不足就明说,不虚构边;
  • 反馈闭环:回答后用graphify save-result --question ... --answer ... --type query --nodes ...写回(graphify/querylog.py 支撑的 CLI,见 graphify/cli.py),下一次--update会把这个 Q&A 抽取为图节点;再加--outcome useful|dead_end|corrected(配--correction)沉淀经验,会话开始时运行graphify reflect --if-stale并阅读graphify-out/reflections/LESSONS.md(preferred sources / known dead ends / corrections),构成自改进循环;
  • /graphify path "A" "B"求两概念最短路径(CLI 或 NetworkXshortest_path内联脚本),逐跳解释后同样save-result --type path_query/graphify explain "X"给出单节点的 3–5 句通俗解释(来源、类型、度、全部带关系与置信度的邻接边),save-result --type explain

子命令守卫与外围能力

手册还规定了三个外围约定:

  1. 解释器守卫:执行任何子命令(--update--cluster-onlyquerypathexplainadd)前先检查.graphify_python是否存在;缺失(如用户删了graphify-out/)则从which graphify的 shebang 重新解析解释器并落盘,再回退python3
  2. --update/--cluster-only均为非默认子命令:前者只重抽新增/变更文件,后者在既有图上重跑聚类,两条流程都在 references/update.md 中(底层对应 graphify/manifest.py 的增量检测与 build-merge 替换逻辑);
  3. add <url>--watch不属于默认构建:前者抓取 URL 存入./raw并增量更新图,后者监听目录自动重建(纯代码变更不需要 LLM),细节见 references/add-watch.md(--watch由 graphify/watch.py 实现);
  4. commit 钩子与 CLAUDE.md 集成:用户要求安装 post-commit 自动重建钩子或把 graphify 接入项目 CLAUDE.md 时,走 references/hooks.md(底层为 graphify/hooks.py,README 中提到钩子脚本在安装时内嵌解释器绝对路径,因此 GUI git 客户端与 CI 环境同样可靠,升级后需重跑graphify hook install刷新路径)。

Honesty Rules:手册的五条诚实约束

文档以五条不可协商的规则收尾,它们贯穿全文的每一个守卫分支:

  • Never invent an edge——不确定就用AMBIGUOUS标记,而不是省略或杜撰(与 extraction-spec 的置信度量规一一对应);
  • Never skip the corpus check warning——Step 2 的大语料警告不可省略;
  • Always show token cost in the report——cost.json记账数据必须呈现给用户;
  • Never hide cohesion scores behind symbols——社区凝聚度显示原始数值,不做符号化包装;
  • Never run HTML viz on a graph with more than 5,000 nodes without warning——超过 5000 节点先警告(graphify export html此时会自动聚合到社区视图)。

小结与延伸阅读

skill-pi.md本质上是一份“给 agent 看的 SOP”:它把 graphify 的九步流水线(解释器探测 → 文件体检 → AST/语义双通道抽取 → 建图聚类与双守卫导出 → 社区打标 → 可视化 → 记账清理)翻译成可在 Pi 会话中逐条执行的 bash 块,并用 references 目录做按需加载的上下文瘦身。对阅读仓库源码的开发者而言,理解这份手册最快的路径是按其步骤顺序对照模块:graphify/detect.py(Step 2)、graphify/extract.py 与 graphify/extractors/(Part A)、graphify/cache.py(B0/B3)、graphify/build.py + graphify/cluster.py + graphify/analyze.py + graphify/export.py(Step 4)、graphify/diagnostics.py(Step 4.5)、graphify/report.py(Step 5)、graphify/manifest.py + graphify/cli.py(Step 9 与 save-result/reflect)。而 Pi 平台如何拿到这份技能,则由 graphify/install.py 的安装表与 tools/skillgen/platforms.toml 的生成配置共同保证。

【免费下载链接】graphifyTurn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.项目地址: https://gitcode.com/GitHub_Trending/graph/graphify

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 5:26:37

动力电池CCS设计全解析:从电芯连接到采样总成

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 5:26:02

网页模板HTML源码下载后怎么改?从拆解到上线的完整指南

简介&#xff1a;这是一套面向网页开发初学者的基础HTML模板资源&#xff0c;适合希望理解静态网页结构、样式与交互配合方式的读者。压缩包共9个文件&#xff0c;包含一个主HTML页面、配套CSS样式表、JavaScript脚本、jQuery scrollTo滚动插件及相关图片资源。CSS用于定义页面…

作者头像 李华
网站建设 2026/9/7 5:24:46

小米设备接入 Home Assistant 终极指南:ha_xiaomi_home 完整上手

小米设备接入 Home Assistant 终极指南&#xff1a;ha_xiaomi_home 完整上手 【免费下载链接】ha_xiaomi_home Xiaomi Home Integration for Home Assistant 项目地址: https://gitcode.com/GitHub_Trending/ha/ha_xiaomi_home 在 Home Assistant 面板上点开关&#xff…

作者头像 李华
网站建设 2026/9/7 5:24:02

CSDN首页发布文章CSDN同步助手同步电机与构网型变流器的频率稳定特性及多时间尺度交互机理研究(Simulink仿真实现)44 / 100摘要:会在推荐、列表等场景外露,帮助读者快

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 &#x1f381…

作者头像 李华
网站建设 2026/9/7 5:22:36

普中51单片机开发板例程代码包使用详解:从点灯到串口通信

简介&#xff1a;面向51单片机初学者的学习代码包&#xff0c;基于普中开发板整理&#xff0c;覆盖基础外设驱动与常见应用案例&#xff0c;适合嵌入式入门、实验练习及课程设计参考。压缩包共1174个文件&#xff0c;核心代码以C语言为主&#xff0c;含233个.c源文件和174个.h头…

作者头像 李华