graphify for Codex:用 /graphify 技能把任意代码库构建成可查询的知识图谱
graphify 把代码、文档、论文、图片甚至视频转成一份带社区检测、诚实审计标记(EXTRACTED/INFERRED/AMBIGUOUS)和查询工具的知识图谱,并产出交互式 HTML、GraphRAG-ready 的 JSON 和纯文本报告。graphify/skill-codex.md 是该项目面向 Codex 平台的 Agent 技能定义文件,规定了 /graphify 被调用时 Agent 必须按顺序执行的完整流水线:从 Python 解释器探测、语料检测,到结构/语义双路提取、建图聚类、社区标注、多格式导出,直到 query/path/explain 问答。读完本文,你能完整复刻这条流水线,理解每个步骤背后的库函数调用关系,并知道 Codex 平台与其他 Agent 宿主在派发子代理时的差异。
技能文件的定位:/graphify 与 graphify CLI 之间的契约
graphify/skill-codex.md 采用 SKILL.md 式的 frontmatter 声明触发条件:
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. ..."
它的职责是:当用户在 Codex 中调用 /graphify 时,让宿主 Agent 知道该跑哪些命令、按什么顺序跑、每一步的成功/失败信号是什么。技能文件本身不实现任何逻辑——所有计算都委托给已安装的 Python 库(graphify.detect、graphify.extract、graphify.build 等模块),Agent 只负责编排与向用户汇报。技能目录中每个平台一份独立的 skill 文件(如 graphify/skill-codex.md、graphify/skill.md),平台差异化的参考资料则放在 graphify/skills/codex/references/ 下,包括 extraction-spec.md、query.md、update.md、add-watch.md、hooks.md、exports.md、github-and-merge.md、transcribe.md 八个文件,由正文各步骤按需引用。
使用方式:/graphify 完整命令参考
技能文件给出的 Usage 块是整条流水线的入口,覆盖全量构建、增量更新、多种导出与查询四类操作:
/graphify # 对当前目录跑完整流水线(HTML 可视化;加 --obsidian 生成 vault)
/graphify <path> # 对指定路径跑完整流水线
/graphify https://github.com/<owner>/<repo> # clone 仓库后对其跑完整流水线
/graphify https://github.com/<owner>/<repo> --branch <branch> # clone 指定分支
/graphify <url1> <url2> ... # clone 多个仓库,各自构建后合并成跨仓库图谱
/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 tokens
/graphify path "AuthModule" "Database" # 两个概念间的最短路径
/graphify explain "SwinTransformer" # 用自然语言解释某个节点
几个值得注意的语义:
--directed会让建图阶段构建DiGraph保留边的 source→target 方向,默认是无向Graph。这个标志要一路传到build_from_json(directed=...)与诊断步骤(见下文 Step 4 / 4.5)。--update是增量构建,依赖首次构建时保存的 manifest(Step 9 写入),只重提取新增或变更文件。- 无路径参数时默认
.(当前目录),技能明确要求不要向用户索要路径。 /graphify --help是特例:只原样打印 Usage 块然后停止,不探测文件、不默认路径为.。
快速路径:图谱已存在时直接走查询
技能文件把"快速路径"放在所有构建步骤之前:如果 graphify-out/graph.json 已存在(相对于当前工作目录,即运行命令的项目根),且用户的问题是关于代码库的自然语言提问("X 是怎么工作的?""谁调用了 Y?""追踪 Z 的数据流"),而不是显式重建命令(--update、--cluster-only 或裸路径/URL),则完全跳过 Step 1–5,直接进入 /graphify query 流程:立即执行 graphify query "<question>",不跑 detect、不检查语料大小、不要求用户缩小范围。
这条规则的意义在于:图谱是持久产物,重复提问不应触发重复构建。后续小节的所有流水线,只在首次构建或显式重建时执行。
Step 1:探测 Python 解释器
graphify 可能装在 uv tool、pipx、虚拟环境或系统 Python 里。技能文件内置了一段解释器探测脚本,按优先级依次尝试:
uv tool run --from graphifyy python拿到 uv 工具安装的 Python(在现代 Mac/Linux 上最可靠);- 读取
which graphify得到的二进制首行 shebang,用import graphify验证其有效性(覆盖 pipx 与直接 pip 安装); - 回退到
python3。
若最终解释器无法 import graphify,则通过 uv tool install --upgrade graphifyy 或 pip install graphifyy(必要时加 --break-system-packages)补装。成功后写两个持久化状态文件,供后续所有步骤复用:
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。技能文件还为此设置了"解释器守卫"——运行 --update、--cluster-only、query、path、explain、add 任何子命令前,先检查 .graphify_python 是否存在,缺失(例如用户删掉了 graphify-out/)则用 shebang 探测重新解析一次再写入。
Step 2:语料检测
$(cat graphify-out/.graphify_python) -c "
import json
from graphify.detect import detect
from pathlib import Path
result = detect(Path('INPUT_PATH'))
# 从 Python 写 sidecar 而不是 shell 重定向,这样同一代码块在
# PowerShell 宿主上渲染时也不会出现控制台编码漂移(#2528)。
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.py 中的 detect(root, *, follow_symlinks, google_workspace, extra_excludes, cache_root, gitignore)(detect.py#L1665)。检测结果写入 graphify-out/.graphify_detect.json,包含文件清单(按 code/document/paper/image/video 分类)、total_files、total_words、scan_root(解析后的绝对路径)、skipped_sensitive 等字段。
Agent 不打印原始 JSON,而是汇总成摘要:
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 ...)
(计数为 0 的类别省略。)摘要之后按规则处置:
total_files == 0:直接停止,提示"No supported files found in [path]";skipped_sensitive非空:报告数量并列出被跳过的文件名,让用户能看到误标记的源文件并可以重命名或移动(对应 #2106);total_words > 2,000,000或total_files > 500:显示警告,并从 detect JSON 读取scan_root,把五类文件列表拼接后过滤掉scan_root + "/graphify-out/"前缀的 sidecar 文件,再按第一级子目录统计文件数、列出 top 5,等用户选择要构建哪个子目录;若所有文件都在(root)无子目录,则建议用--no-cluster跳过昂贵的聚类步骤;- 其余情况直接进入 Step 2.5(有视频时)或 Step 3。
Step 2.5 仅在检测到视频/音频文件时触发:按 graphify/skills/codex/references/transcribe.md 先转写成文本,再把转写稿当作文档进入 Step 3。
Step 3:双路提取——确定性 AST 与 LLM 语义并行
提取分两路,技能文件要求在同一个消息里同时派发:AST 提取是确定性且快速的,语义子代理处理文档/论文/图片,两者作用于不同类型的文件,可以并行(大语料上可省 5–15 秒)。
关于 API key 的关键约定
技能文件对此有非常强的措辞:graphify 不需要 API key,永远不要向用户索要 key 或因缺 key 而阻塞。
- 代码走 AST 结构提取,完全不经过 LLM——纯代码语料(最常见的
/graphify .)直接跳过语义提取,什么都不需要; - 语义提取(仅针对文档、论文、图片)只在
GEMINI_API_KEY/GOOGLE_API_KEY已设置时才使用 Gemini(默认模型gemini-3-flash-preview,可用GRAPHIFY_GEMINI_MODEL或--model覆盖),此时调用graphify.llm.extract_corpus_parallel(files, backend="gemini"); - 两个 key 都未设置时,语义提取由宿主 Agent 自己承担(运行中的会话就是 LLM):在支持派发子代理的宿主上按 Part B 派发,在只能跑 CLI 的终端宿主上则内联提取;
- graphify 不读取
ANTHROPIC_API_KEY、OPENAI_API_KEY或任何其他提供商的 key。若发现自己在因缺 key 而提问或停摆,说明误读了技能——继续执行。
Part A:代码的结构提取
$(cat graphify-out/.graphify_python) -c "
import sys, json
from graphify.extract import collect_files, extract
from pathlib import Path
import json
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.py 的 extract(paths, cache_root, *, root, parallel, max_workers, ...)(extract.py#L5859)。从其 docstring 可见这是一个两遍过程:
- 逐文件结构提取(类、函数、import);
- 跨文件 import 解析:把文件级 import 转成类级 INFERRED 边(例如
DigestAuth --uses--> Response)。
它支持多进程并行(文件数超过阈值时用 ProcessPoolExecutor,GRAPHIFY_MAX_WORKERS 可限流),且内部按语言分派到 extract_python、extract_js、extract_java 等数十个语言提取器。没有代码文件时写入空 AST 文件而不是报错,保证 Part C 合并阶段输入完整。
Part B:语义提取(并行子代理)
快速路径:若检测到的文档/论文/图片均为零(纯代码语料),跳过整个 Part B,但必须先写一个空的语义文件——因为 Part C 的合并无条件读取 .graphify_semantic.json,缺了会 FileNotFoundError:
$(cat graphify-out/.graphify_python) -c "
import json
from pathlib import Path
Path('graphify-out/.graphify_semantic.json').write_text(json.dumps({'nodes':[],'edges':[],'hyperedges':[],'input_tokens':0,'output_tokens':0}), encoding='utf-8')
"
B0——先查提取缓存:派发任何子代理前,用 graphify/cache.py 的 check_semantic_cache(cache.py#L1233)找出已有缓存结果的文件:
all_files = [f for cat in ('document', 'paper', 'image') for f in detect['files'].get(cat, [])]
cached_nodes, cached_edges, cached_hyperedges, uncached = check_semantic_cache(
all_files, root='INPUT_PATH', prompt_file='SPEC_PATH')
两个设计要点值得注意:
- 只有内容文件(document/paper/image)进入语义缓存;代码已由 Part A 的 AST 路覆盖,把代码文件也塞进来会让子代理重读每个源文件(#1392);
prompt_file传的是references/extraction-spec.md的绝对路径。缓存条目按"产生它的那份提示词"归属——graphify 升级改了提取提示词后,旧提示词产生的条目会被重新提取而不是回放,提示词未变则命中缓存(#1939)。同一 SPEC_PATH 在 B0(读)与 B3(写)必须一致。
命中的条目写入 .graphify_cached.json(无命中时删除残留的旧文件,避免 Part C 合并到过期的缓存),未命中清单写入 .graphify_uncached.txt,只对清单里的文件派发子代理。
B1——分块:从 .graphify_uncached.txt 读取文件,每 20–25 个一组;每张图片单独成块(视觉提取需要独立上下文);同一目录的文件尽量同块,提高跨文件关系的提取率。派发前先打印时间估算:agents = ceil(uncached_non_code_files / 22),每批约 45 秒并行。
B2——Codex 平台特有的派发方式:这是 skill-codex.md 与其他平台 skill 的核心差异。Codex 不使用 Claude Code 的 Agent 工具,而是用三个平台原语:
spawn_agent(agent_type="worker", message="Your task is to perform the following. Follow the instructions below exactly.\n\n<agent-instructions>\n[extraction prompt, with FILE_LIST, CHUNK_NUM, TOTAL_CHUNKS, DEEP_MODE substituted]\n</agent-instructions>\n\nExecute this now. Output ONLY the structured JSON response.")
要求:
- 每块调用一次
spawn_agent,全部在同一个响应里发出以获得并行; - 需要
~/.codex/config.toml中[features]下设置multi_agent = true;若spawn_agent不可用,告知用户添加该配置并重启 Codex; - 派发完成后按序收集:
result = wait_agent(handle); close_agent(handle)(每个 handle 重复); - Codex 是内存中收集结果,所以不存在每块的落盘文件——
.graphify_chunk_NN.json的存在性检查(Step B3)在 Codex 上不适用,取而代之的失败信号是某块返回了无效 JSON;所有块的 nodes/edges/hyperedges 累加后写入graphify-out/.graphify_semantic_new.json。
子代理提示词模板在 graphify/skills/codex/references/extraction-spec.md 中:包含规则、节点 ID 格式、置信度评级标准、超边与视觉规则、JSON schema。只在至少一块含有文档/论文/图片时才加载;提示词需原样传给每个子代理,仅替换 FILE_LIST、CHUNK_NUM、TOTAL_CHUNKS、DEEP_MODE 四个占位符(DEEP_MODE 对应 --mode deep,必须从最初调用一路跟踪,不能丢失)。
B3——收集、缓存、合并:等待全部子代理;对每个结果解析 JSON,累加后写入 .graphify_semantic_new.json。真实 token 数需从 Agent 调用结果的 usage 字段读出并回填(块 JSON 里永远是占位零值)。然后把新结果写入缓存(cache.py#L1379 的 save_semantic_cache(nodes, edges, hyperedges, root, allowed_source_files, prompt_file),prompt_file 传同一个 SPEC_PATH),最后把缓存 + 新结果合并为 graphify-out/.graphify_semantic.json:节点按 id 去重,边与超边直接拼接,token 数取自新结果。收尾删除临时文件(.graphify_cached.json、.graphify_uncached.txt、.graphify_semantic_new.json)。
Part C:合并 AST 与语义结果
seen = {n['id'] for n in ast['nodes']}
merged_nodes = list(ast['nodes'])
for n in sem['nodes']:
if n['id'] not in seen:
merged_nodes.append(n); seen.add(n['id'])
merged = {'nodes': merged_nodes, 'edges': ast['edges'] + sem['edges'],
'hyperedges': sem.get('hyperedges', []), ...}
Path('graphify-out/.graphify_extract.json').write_text(...)
规则是 AST 节点优先、语义节点按 id 去重,超边只来自语义路,产出最终提取文件 .graphify_extract.json。
Step 4:建图、聚类、分析与首次导出
这一步是全流水线的计算核心,一次调用串起五个库模块:
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
G = build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED)
关键函数及其源码位置:
| 调用 | 实现 | 作用 |
|---|---|---|
build_from_json(extraction, *, directed, root) |
graphify/build.py#L798 | 从提取 dict 构建 NetworkX 图;directed=True 产出保留 source→target 方向的 DiGraph,默认无向 Graph;root 把语义子代理产生的绝对 source_file 相对化,保证全图节点共享一致的路径键(#932) |
cluster(G) |
graphify/cluster.py#L223 | 社区检测,返回 {社区id: [节点]} |
score_all(G, communities) |
graphify/cluster.py#L357 | 每社区的凝聚度(cohesion)分数 |
god_nodes(G) |
graphify/analyze.py#L109 | 识别"上帝节点"(默认 top 10) |
surprising_connections(G, communities) |
graphify/analyze.py#L133 | 跨社区的意外连接 |
suggest_questions(G, communities, labels) |
graphify/analyze.py#L428 | 生成建议问题(Step 5 会用真实标签重算) |
generate(...) |
graphify/report.py#L96 | 生成 GRAPH_REPORT.md 内容 |
to_json(G, communities, path) |
graphify/export.py#L266 | 导出 graph.json,返回 bool |
build_from_json 内部还做了大量防御性归一化(从源码结构看):把旧版 links 键重映射为 edges、把数值型节点 id 强转为字符串、折叠 source→source_file、name→label、type→relation 等历史字段别名、对缺失 file_type 默认补 "concept",并先跑 validate_extraction 过滤掉"指向不存在节点"这类可预期的悬空边告警。
技能文件在这一步内嵌了两道守卫:
- 空图守卫:
G.number_of_nodes() == 0时打印错误原因(全部文件被跳过、纯二进制语料或提取失败)并SystemExit(1),不允许继续——空提取不应覆盖好的graph.json、GRAPH_REPORT.md与分析 sidecar; - #479 收缩守卫:
to_json返回False表示新图比现有graph.json节点更少,什么都不写。此时中止并提示"如果收缩是故意的(你删了文件),用--force重跑全量构建"。只有图确实写盘后才写GRAPH_REPORT.md与.graphify_analysis.json,保证报告描述的内容永远与 graph.json 一致(#1392)。
分析结果(communities、cohesion、gods、surprises、questions)写入 graphify-out/.graphify_analysis.json,随后打印 Graph: N nodes, M edges, K communities。
Step 4.5:图健康检查(只读完整性门禁)
在标注之前对提取结果做一次非破坏性诊断,专查增量更新与 AST/LLM id 失配会引入的"静默腐化":
from graphify.diagnostics import diagnose_extraction, format_diagnostic_report
summary = diagnose_extraction(extraction, directed=IS_DIRECTED, root='INPUT_PATH')
print(format_diagnostic_report(summary))
对应实现是 graphify/diagnostics.py 的 diagnose_extraction(diagnostics.py#L156)与 format_diagnostic_report(diagnostics.py#L348)。检查项包括:dangling-endpoint 边、missing-endpoint 边、自环边、有向/无向同端点折叠边。任何一类计数非零即打印 GRAPH HEALTH WARNING——只报告、不中止:图仍可用,但完整性问题必须在最终总结中可见(诚实规则要求)。
Step 5:社区标注
Agent 读取 .graphify_analysis.json,对每个社区的节点标签做阅读,人工(由 Agent 承担)给出 2–5 词的自然语言名(如 "Attention Mechanism"、"Training Pipeline")。然后重跑一次标注版流程:
G = build_from_json(extraction, root='INPUT_PATH', directed=IS_DIRECTED)
communities = {int(k): v for k, v in analysis['communities'].items()}
labels = LABELS_DICT # 例如 {0: "Attention Mechanism", 1: "Training Pipeline"}
questions = suggest_questions(G, communities, labels) # 标签会影响问题措辞,重算
report = generate(G, communities, cohesion, labels, ...)
Path('graphify-out/GRAPH_REPORT.md').write_text(report, encoding="utf-8")
Path('graphify-out/.graphify_labels.json').write_text(...)
wrote = to_json(G, communities, 'graphify-out/graph.json', community_labels=labels)
要点:
root=与directed必须与 Step 4 完全一致(--updaterunbook 用同一基线,#1361),保证节点键对齐;- 建议问题必须用真实标签重新生成,因为标签影响问题措辞;
- 重新
to_json时带community_labels=labels,让 graph.json 的节点携带整理后的community_name(#2490);由于与 Step 4 是同一份提取,节点数不变,#479 收缩守卫应当自然通过——若仍拒绝,把守卫消息透传给用户,不许强推。
Step 6–9:可视化、可选导出与收尾
Step 6:HTML 总是生成(除非 --no-viz);Obsidian vault 仅在显式给了 --obsidian 时生成(它每个节点产出一个文件,代价高):
graphify export obsidian # 或 graphify export obsidian --dir ~/vaults/my-project
graphify export html # 节点数 > 5000 时自动聚合到社区视图
Steps 6b–8:wiki、Neo4j、FalkorDB、SVG、GraphML、MCP、token 缩减基准均只在对应标志出现时执行(基准在 total_words > 5000 时触发);不带任何导出标志的默认运行全部跳过。细节在 graphify/skills/codex/references/exports.md。注意 --wiki 导出必须在 Step 9 清理之前运行,因为那时 .graphify_labels.json 还在。
Step 9:保存 manifest、更新成本追踪器、清理临时文件。manifest 通过 graphify/detect.py 的 save_manifest(detect.py#L2112)落盘,几个精细点:
- 用
cli._stamped_manifest_files决定哪些文件算"真正完成了提取":代码文件总是盖章(AST 是确定性的),语义类型(document/paper/image)只在实际产出了输出时才盖章——某个文件的块失败或被漏掉就必须保持未盖章,下次--update会重新排队,否则其内容会永久丢失(#2015); - 本轮派发但未盖章的文件要清掉旧的
semantic_hash,让detect_incremental重新排队而不是当成未变更(#1948); root=把 manifest 键相对化到扫描根,使其跨克隆/机器可移植(#1417),scan_corpus传原始全量语料,这样自上次运行后新被排除的文件会被正确丢弃而不是伪装成删除(#1908)。
成本追踪器 graphify-out/cost.json 追加每次运行的 date/input_tokens/output_tokens/files,并累加全时总量。清理阶段删除 .graphify_detect.json、.graphify_extract.json、.graphify_ast.json、.graphify_semantic.json、.graphify_analysis.json 与所有 .graphify_chunk_*.json。
最后向用户汇报产出物(graph.html、GRAPH_REPORT.md、graph.json,以及仅在 --obsidian 时的 obsidian/),并把 GRAPH_REPORT.md 的 God Nodes、Surprising Connections、Suggested Questions 三个小节贴进对话——明确不要贴完整报告。然后从建议问题里挑跨社区边界最多、桥接节点最意外的那一个,主动问用户:"这个图谱能回答的最有趣的问题是:[问题]。要我追踪一下吗?"——得到肯定答复后跑 /graphify query,沿着图谱结构逐步讲解节点连接、跨越的社区边界与路径含义,每个回答以自然追问收尾。技能文件的原话是:"图谱是地图,你的工作是在流水线之后当向导。"
查询路径:query / path / explain
graphify-out/graph.json 存在且用户提问语料相关问题时,从图谱回答而不是重建:
graphify query "<question>"
遍历之前,先用图谱自身的词汇表扩展问题措辞,避免措辞失配把答案塌缩成噪声;graphify query CLI 不可用时回退到对 graphify-out/graph.json 的内联 NetworkX 遍历。回答只依据图谱输出内容,引用具体事实时引用 source_location。BFS/DFS 遍历模式、--budget 上限、NetworkX 回退、save-result 反馈,以及 /graphify path、/graphify explain 的完整流程见 graphify/skills/codex/references/query.md。
其他子命令的指引
--update与--cluster-only:都是非默认子命令;--update只重提取新增/变更文件,--cluster-only对现有图重跑聚类,两者流程见 graphify/skills/codex/references/update.md;add与--watch:不属于默认构建。/graphify add <url>抓取 URL 进语料,--watch在文件变更时自动重建(不需要 LLM),见 graphify/skills/codex/references/add-watch.md;- GitHub 仓库与多路径合并:仅当参数是
https://github.com/...URL 或需要合并的多个本地子目录时执行 Step 0,克隆、跨仓库合并与 monorepo 流程见 graphify/skills/codex/references/github-and-merge.md; - 提交钩子与 CLAUDE.md 集成:见 graphify/skills/codex/references/hooks.md。
Honesty Rules:技能文件内建的四条诚实约束
这是贯穿整个技能的审计纪律,值得单独列出:
- 绝不编造边——不确定时标记 AMBIGUOUS(这对应图谱中 EXTRACTED/INFERRED/AMBIGUOUS 三级审计标记体系);
- 绝不跳过语料检查警告(Step 2 的 200 万词/500 文件阈值);
- 报告中必须显示 token 成本(Step 9 的 cost.json 累加即为此服务);
- 绝不把凝聚度分数藏在符号后面——显示原始数字;
- 节点数超过 5,000 的图谱跑 HTML 可视化前必须警告用户。
小结:这条流水线的工程要点
graphify/skill-codex.md 本质上是一份"可执行的构建手册",把 graphify 库的模块边界完整映射到了 Agent 的编排动作:
- 检测(graphify/detect.py)→
.graphify_detect.json+ manifest 基础; - 结构提取(graphify/extract.py 的
extract/collect_files)→.graphify_ast.json; - 语义提取(子代理 + graphify/cache.py 的提示词绑定缓存)→
.graphify_semantic.json; - 建图与治理(graphify/build.py 的
build_from_json+ graphify/cluster.py 的cluster/score_all+ graphify/analyze.py + graphify/export.py 的 #479 收缩守卫 + graphify/diagnostics.py 的健康门禁)→graph.json/GRAPH_REPORT.md/ 分析 sidecar。
其中与 Codex 平台强相关的适配点集中在 Part B2:用 spawn_agent/wait_agent/close_agent 替代通用 Agent 工具、要求 [features] multi_agent = true、结果内存收集(无每块落盘文件,失败信号为无效 JSON)。理解这套契约后,无论是排查某次构建为何没走快速路径、增量更新漏了哪些文件,还是扩展到其他 Agent 宿主,都可以直接对照技能文件的步骤编号与 graphify-out/ 下的 sidecar 文件定位问题。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00