首页
/ graphify 跨仓库知识图谱实战:从 GitHub Clone、多仓库抽取到 merge-graphs 统一合并

graphify 跨仓库知识图谱实战:从 GitHub Clone、多仓库抽取到 merge-graphs 统一合并

2026-09-06 18:15:05作者:何举烈Damon

这篇指南讲解 graphify(vscode skill 参考文档 github-and-merge.md 定义的)"克隆 + 跨仓库合并"工作流:当你给出一到多个 https://github.com/... 仓库地址、或几个需要合并为同一张图谱的本地子目录时,如何把每个仓库先转成独立的 graph.json,再用 graphify merge-graphs 合并成一张带来源标记(repo 属性)的统一图谱,并从此对合并图谱直接运行 graphify query。读完你既能照抄单仓库与 monorepo/多服务场景的可运行命令,也能理解 merge-graphs 在源码层如何做节点前缀、去碰撞、社区编号偏移与跨仓库类型连接。

这份参考文档在什么场景下被加载

本文件是 graphify 各 Agent Skill 公共参考之一,位于 github-and-merge.md。在主 Skill 文件(如 skill-vscode.md)中,/graphify 系列斜杠命令支持三种携带仓库的场景,分别对应:

  • /graphify https://github.com/<owner>/<repo> —— 先克隆再跑完整流水线;
  • /graphify https://github.com/<owner>/<repo> --branch <branch> —— 克隆指定分支;
  • /graphify <url1> <url2> ... —— 克隆多个仓库、各自建图、最后合并为一张跨仓库图谱。

当用户消息中出现以上任一形态(或"给出多个本地子目录待合并"),Skill 才加载本参考文档执行 Step 0;纯本地单目录路径会直接跳过此步骤。

单仓库:用 graphify clone 得到本地路径

当输入是单个 GitHub URL 时,先克隆再以克隆结果为后续所有步骤的扫描目标。推荐写法是捕获 graphify clone 输出到变量:

LOCAL_PATH=$(graphify clone <github-url> [--branch <branch>])
# 后续所有步骤都以 $LOCAL_PATH 为目标

该子命令的完整签名(源码位于 cli.py)为:

graphify clone <github-url> [--branch <branch>] [--out <dir>]

底层 _clone_repo 的实现细节(cli.py)决定了如下行为,可直接作为使用依据:

  • 默认缓存位置是 ~/.graphify/repos/<owner>/<repo>:URL 中 github.com 后的 owner/repo 会被正则提取出来拼出目标目录;
  • 重复运行复用已有克隆:若目标目录已存在,不重复 clone,而是执行 git pull 拉取最新(带分支时拉取该分支),并打印 Repo already cloned at ... - pulling latest...
  • 首次克隆是浅克隆:底层执行 git clone --depth 1 [--branch <branch>] -- <url> <dest>
  • URL 会被规范化:末尾多余的 / 会被去掉,缺少 .git 后缀时自动补齐;
  • --out <dir> 可覆盖默认目录,把克隆放到你指定的位置;
  • 命令末尾会把最终可用路径打印到标准输出(print(local_path)),这正是 LOCAL_PATH=$(graphify clone ...) 能拿到路径的原因;
  • 分支名以 - 开头会被判定非法并报错退出,避免参数注入。

多仓库:每个仓库独立建图后再交叉合并

一次处理多个 GitHub 仓库时,参考文档给出的流程是:分别克隆 → 对每个本地路径各跑一次完整 /graphify 流水线产出各自的 graph.json → 最后用 merge-graphs 合并:

# 克隆每个仓库(clone 会自动复用已有克隆)
graphify clone <url1>   # → ~/.graphify/repos/<owner1>/<repo1>
graphify clone <url2>   # → ~/.graphify/repos/<owner2>/<repo2>

# 对每个本地路径运行 /graphify,分别产出各自的 graph.json
# (或在命令行使用 graphify extract,见下文"本地多子目录"一节)

# 然后合并:
graphify merge-graphs \
  ~/.graphify/repos/<owner1>/<repo1>/graphify-out/graph.json \
  ~/.graphify/repos/<owner2>/<repo2>/graphify-out/graph.json \
  --out graphify-out/cross-repo-graph.json

合并结果的两个关键约定(文档明示、源码可印证):

  1. 克隆目录可复用:默认落入 ~/.graphify/repos/<owner>/<repo>,反复跑同一 URL 会执行增量 git pull 而非重复克隆;
  2. 每个节点带 repo 属性:合并图中的每个节点都带有 repo 标签,因此你可以按来源仓库过滤、追溯每个符号究竟来自哪个仓库。

本地多子目录(monorepo / 多服务):先分目录 extract 再在根目录合并

当要合并的不是多个远程仓库、而是同一项目树下的多个本地子目录(monorepo 或多服务布局)时,参考文档特别提醒了一个输出目录冲突陷阱:Skill 流水线会把全部中间产物与最终结果写到当前工作目录graphify-out/;若分别对每个子文件夹各跑一次 Skill,就会反复覆写同一个输出目录。

解决办法是改为对每个子目录直接调用 CLI graphify extract——它的输出目录 graphify-out/ 会落在被扫描路径内部,彼此天然隔离:

graphify extract ./core/     # → ./core/graphify-out/graph.json
graphify extract ./service/  # → ./service/graphify-out/graph.json
graphify extract ./platform/ # → ./platform/graphify-out/graph.json
# 按你已配置的 API key 追加后端参数:
# --backend gemini|kimi|openai|deepseek|claude-cli

# 最后在项目根目录合并:
graphify merge-graphs \
  ./core/graphify-out/graph.json \
  ./service/graphify-out/graph.json \
  ./platform/graphify-out/graph.json \
  --out graphify-out/graph.json

graphify extract 是专为 CI/脚本准备的"无头完整流水线"子命令(见 cli.py),它串起 detect → 代码 AST 抽取 → 文档/论文/图片的语义 LLM 抽取 → merge → build → cluster → 写出结果,与 Skill 内部流程等价但直接调用抽取核心。其完整参数面包括 --mode deep--no-dedup--code-only--no-cluster--max-workers--token-budget 等;后端名称以 --backend 枚举,源码(cli.py 第 3013 行)所示列表为 gemini|kimi|claude|openai|deepseek|ollama,不同版本间名称可能存在细微出入,运行 graphify extract 不带参数可看到你当前版本的确切取值。

merge-graphs 的底层原理:前缀、去碰撞与跨仓库连接

合并并非简单的 JSON 拼接。从源码看(cli.py),graphify merge-graphs <graph1.json> <graph2.json> [...] [--out merged.json] 至少需要两个输入图,缺省时输出到当前工作目录 graphify-out/ 下的 merged-graph.json(可通过 --out 覆盖),完成后打印 Merged N graphs -> X nodes, Y edges 与写出位置。其内部依次执行了以下关键步骤,理解这些有助于你判断合并结果是否合理:

  1. 加载并容错:逐个读取 graph.json;兼容老版本可能用 edges 键而非 links 键的写法;保存并恢复每条边真实的 _src/_tgt 方向标记;从嵌套 graph.hyperedges 槽位或顶层 hyperedges 键中取回超边;
  2. 图类型归一:不同来源的图可能是 DiGraph/MultiGraph/MultiDiGraph,而合并后的跨仓库视图本身是无向的,因此统一归一为普通的无向 Graph,避免 nx.compose 因类型不一致崩溃;
  3. 节点加 repo 前缀:通过 build.pyprefix_graph_for_global,把所有节点 ID 改写为 repo_tag::原ID,同时:repo 属性标记来源仓库;local_id 属性保留可还原的原始 ID;边与超边成员同步改写;超边 ID 同样加前缀防止不同仓库同名超边互相冲突;
  4. 仓库标签去碰撞:朴素的标签取 graphify-out 的父目录名,但 src/graphify-outfrontend/src/graphify-out 会得到相同的 src,导致不同仓库同名节点被错误合并。distinct_repo_tagsbuild.py)在发生碰撞时用上级目录加宽(如 frontend_src)、必要时追加序号后缀,保证每个图有唯一前缀;
  5. 社区编号偏移:每个输入图都从 0 开始给自己的社区编号,直接合并会把互不相关的社区在聚合视图里融合成一个 meta 节点,因此合并时把后加入图的社区 ID 偏移到共享编号空间(local_community 保留各自原始划分);
  6. 超边重挂:修正历史版本中 nx.compose 只保留最后一个输入超边列表的问题,收集全部输入的超边并在 compose 之后重新去重挂接;
  7. 跨仓库同类型声明建链:所有 ID 都被前缀化后,两个仓库各自声明的同一契约类型会成为两个互不相连的节点。link_shared_type_declarationscross_repo_types.py)按"命名空间 + 类型名"找跨仓库匹配,为它们补 same_type_as 边(关系上下文记为 cross_repo,置信度 INFERREDconfidence_score=0.9),从而允许图谱遍历跨过仓库边界——例如一个仓库生产 SyncProductUpsertToSearchEvent、另一个仓库实现 IConsumer<SyncProductUpsertToSearchEvent> 的消息总线代码,正是需要这一步来打通的关键一跳。它只加边、不合并节点,让两侧各自保留成员、文件与出处,避免掩盖契约漂移。

合并完成后的快速路径:直接 query,无需重新抽取

参考文档最后强调:一旦 graphify-out/graph.json 存在,快速路径即刻接管——任何关于代码库的问题都可以直接在合并图上运行查询,不需要重新抽取、也没有规模门槛

graphify query "你的问题"

query 子命令的用法(cli.py)为:

graphify query "<question>" [--dfs] [--context C] [--budget N] [--graph path]

其中 --graph path 可指向任何自定义位置的结果图;对跨仓库合并场景,把 --out 写到的合并图路径(如上面的 graphify-out/cross-repo-graph.json)传给它即可,配合每个节点上的 repo 属性,就能在一个查询里追溯跨仓库调用、依赖与共享契约的完整链路。

使用要点与边界(基于当前仓库源码)

  • 合并至少需要 2 个输入图;输入文件不存在时 merge-graphs 会直接报错退出(error: not found: <path>);
  • 合并产出的跨仓库视图是无向图,边方向信息依靠 _src/_tgt 标记在写出时还原;
  • clone 目前识别 github.com 的 HTTP(S) 地址形态(含 :owner/repo.git 式 SSH 写法中的路径段),无法识别的 URL 会报 not a recognised GitHub URL
  • 已有 Skill 参考中另有一个 git 合并驱动 graphify merge-driver <base> <current> <other>cli.py),用于在 git 层面自动三方合并 graph.json,并对超大/损坏输入设了保护上限后安全退出,与本工作流互补,适合把图谱文件纳入版本管理后使用。

相关文件索引

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388