【Graphify知识图谱执行设计实践】

知识图谱执行流程

面向新人的 Graphify 知识图谱系统完整链路说明
精确到每个文件和关键函数,方便定位和调试


一、系统总览

运行时(AI 查询)

开发时(构建图谱)

源代码变更

graphify update .

AST 解析

构建图

社群聚类

导出 graph.json

Cursor 启动

MCP Server

加载 graph.json

等待查询

AI 发起查询

返回相关节点

核心文件位置.venv\Lib\site-packages\graphify\

文件行数职责
__main__.py4583CLI 主入口,命令分发
serve.py1312MCP stdio 服务器 + 查询引擎
extract.py11658AST 提取(tree-sitter,30+ 语言)
build.py490NetworkX 图构建
cluster.py273Leiden/Louvain 社群聚类
report.py生成 GRAPH_REPORT.md
export.py导出 JSON/HTML
watch.py增量更新 + 文件监听
cache.pyAST 缓存管理
manifest.py文件变更清单追踪

二、链路一:Cursor 启动 → MCP 服务就绪 → AI 查询

这是运行时的核心链路:AI 如何查询知识图谱。

Claude/AIgraph.jsonserve.pyPython 进程Cursor IDEClaude/AIgraph.jsonserve.pyPython 进程Cursor IDE启动时读取 .cursor/mcp.json🟢 服务就绪,等待请求启动 python.exe -m graphify.serve graphify-out/graph.json__main__.py → serve.py:serve()_build_server(graph_path)_load_graph() → 读取 JSONNetworkX Graph 对象(2494节点)asyncio.run() → stdio_server 就绪call_tool("query_graph", {question: "保存接口"})_maybe_reload() → 检查文件是否变化_query_terms("保存接口") → 分词_score_nodes(G, terms) → IDF 评分_pick_seeds(scored) → 选种子节点_bfs_context(seeds, depth=3) → BFS 遍历_format_result() → 按社群分组 + Token 裁剪返回相关节点和关系文本

关键文件调用栈

.cursor/mcp.json                          ← 配置入口
  └─ command: ".venv/Scripts/python.exe"
     └─ args: ["-m", "graphify.serve", "graphify-out/graph.json"]

graphify/__main__.py :: main()            ← Python 包入口
  └─ 检测 sys.argv → cmd = "serve"
     └─ serve.py :: serve(graph_path)     ← MCP 服务入口
        ├─ _load_graph(path)              ← 加载图谱
        │   └─ json.load() → nx.node_link_graph()
        ├─ _build_server(graph_path)      ← 注册 MCP 工具
        │   ├─ list_tools()               ← 声明可用工具
        │   └─ call_tool(name, args)      ← 工具调度路由
        └─ asyncio.run(main())            ← 启动 stdio 事件循环

查询引擎内部逻辑

serve.py :: _query_graph_text(G, question, mode, depth, token_budget)

  Step 1: 分词
  ├─ _query_terms(question)
  │   ├─ 中文 → jieba.cut() 分词
  │   └─ 英文 → re.findall(r"\w+")

  Step 2: 节点评分
  ├─ _score_nodes(G, terms)
  │   ├─ 精确匹配 × 1000
  │   ├─ 前缀匹配 × 100
  │   ├─ 子串匹配 × 1
  │   └─ 源文件路径匹配 × 0.5

  Step 3: 选择种子节点
  ├─ _pick_seeds(scored, max_k=3, gap_ratio=0.2)
  │   └─ 按分数排序,取 Top-K(置信度间隙过滤)

  Step 4: 图遍历
  ├─ _bfs_context(seeds, depth=3)  或  _dfs_context()
  │   ├─ 层 0: 种子节点
  │   ├─ 层 1: 直接邻居
  │   ├─ 层 2: 二度关系
  │   └─ 层 3: 三度关系

  Step 5: 格式化返回
  └─ _format_result(nodes, edges, token_budget)
      ├─ 按 community 分组
      ├─ 去重
      └─ 截断至 token 限制

MCP 暴露的 5 个工具

工具名功能关键参数
query_graph自然语言查询图谱question, mode(bfs/dfs), depth, token_budget
get_node获取节点详情label(节点标签或 ID)
get_neighbors获取邻居节点label, relation_filter
list_communities列出所有社群
get_community获取社群内节点community_id

三、链路二:代码变更 → 图谱更新

这是构建时的核心链路:代码变更后如何更新知识图谱。

graphify-out/report.pycluster.pybuild.pyextract.pymanifest.jsonwatch.pygraphify CLI开发者graphify-out/report.pycluster.pybuild.pyextract.pymanifest.jsonwatch.pygraphify CLI开发者tree-sitter AST 解析图谱更新完成 ✅graphify update . [--force]__main__.py → _rebuild_code()读取 manifest.json(历史 hash)扫描文件系统 → 对比 mtime + hash标记变动文件列表extract(changed_files)collect_files() + .graphifyignore 过滤并行: extract_csharp() / extract_js() / ...{nodes: [...], edges: [...]}build_from_json(extraction)三层去重 + NetworkX 构建nx.Graph 对象cluster(G, resolution=1.0)Leiden 算法 → 社群分割 → ID 稳定化{community_id: [nodes]}generate(G, communities)GRAPH_REPORT.mdgraph.json + manifest.json + .graphify_labels.json

关键文件调用栈

命令行: .\.venv\Scripts\graphify update . [--force]

graphify/__main__.py :: main()                ← CLI 入口
  └─ cmd = "update"
     └─ watch.py :: _rebuild_code(path, force, no_cluster)
        │
        ├─ 1. 增量检测
        │   ├─ manifest.py :: load_manifest()     ← 读取历史清单
        │   ├─ 扫描文件系统 mtime
        │   └─ 对比 ast_hash → 识别变动文件
        │
        ├─ 2. AST 提取
        │   ├─ extract.py :: extract(target)      ← 主提取函数
        │   │   ├─ collect_files()                ← 收集文件(.graphifyignore 过滤)
        │   │   ├─ extract_csharp(path)           ← C# 提取器
        │   │   ├─ extract_js(path)               ← JS/Vue 提取器
        │   │   ├─ extract_python(path)           ← Python 提取器
        │   │   └─ ... (30+ 语言)
        │   └─ cache.py :: load_cached() / save_cached()
        │       └─ 缓存位置: graphify-out/cache/ast/<hash>.json
        │
        ├─ 3. 图构建
        │   └─ build.py :: build_from_json(extraction)
        │       ├─ _normalize_id()                ← 节点 ID 标准化
        │       ├─ _deduplicate_by_label()        ← 三层去重
        │       └─ nx.Graph.add_node() / .add_edge()
        │
        ├─ 4. 社群聚类
        │   └─ cluster.py :: cluster(G, resolution=1.0)
        │       ├─ _partition(G)                  ← Leiden 优先,Louvain 备选
        │       ├─ 社群分割(>25% 图 → 递归)
        │       └─ remap_communities_to_previous() ← ID 稳定化
        │
        ├─ 5. 报告生成
        │   └─ report.py :: generate(G, communities)
        │       ├─ analyze.py :: god_nodes()
        │       └─ analyze.py :: surprising_connections()
        │
        └─ 6. 导出保存
            ├─ export.py :: to_json(G) → graphify-out/graph.json
            ├─ export.py :: to_html(G) → graphify-out/graph.html
            └─ manifest.py :: save_manifest() → graphify-out/manifest.json

增量 vs 全量

模式命令行为
增量(默认)graphify update .只提取变动文件,保留旧节点
全量(强制)graphify update . --force重新扫描全部文件

增量更新的判定逻辑:

manifest.json 中的 ast_hash ≠ 当前文件内容 hash → 需要重新提取
manifest.json 中的 ast_hash = 当前文件内容 hash → 跳过,复用缓存

四、链路三:入图规则(何时触发更新)

命中

未命中

L0

L1

L2

L3

AI 会话开始

路由器查询图谱

命中?

返回相关节点,继续工作

触发入图流程

分级处理

补充 reference 文件
→ graphify update .

已有文件未索引
→ graphify update .

需新增 Spec/CHG
→ graphify update . --force

路径被 .graphifyignore 过滤
→ 编辑过滤 + --force

图谱更新完成

下次查询命中 ✅

配置文件对应

规则/配置文件路径作用
入图规则.cursor/rules/05-graphify-entry.mdc定义何时必须查图、未命中怎么处理
运维操作.cursor/skills/20-capabilities/10-graphify-ops/SKILL.mdL0~L3 分级操作手册
过滤清单.graphifyignore哪些路径不纳入图谱
MCP 配置.cursor/mcp.json服务启动命令

五、数据流全景图

消费层

服务层(serve.py)

产物层(graphify-out/)

构建层

提取层(extract.py)

源码层(输入)

.cs 文件
NRD.WebAPI.New/

.vue/.js 文件
nrd-eln/src/

.md 文件
docs/ + .cursor/skills/

.ps1 脚本
.cursor/hooks/

tree-sitter AST 解析

缓存
cache/ast/<hash>.json

NetworkX Graph
build.py

Leiden 聚类
cluster.py

报告生成
report.py

graph.json
2494 节点 · 3038 边

GRAPH_REPORT.md
统计 + 社群导航

graph.html
可视化界面

manifest.json
文件变更追踪

.graphify_labels.json
社群命名

MCP stdio Server

查询引擎
分词→评分→BFS→格式化

Claude / AI 助手

路由器
00-router-skill


六、热重载机制

AI 发起查询
     ↓
serve.py :: _maybe_reload()
     ├─ 检查 graph.json 的 mtime
     ├─ 如果文件变化 → 重新加载
     │   └─ _load_graph() → 新的 NetworkX Graph
     └─ 如果未变化 → 使用内存缓存
     ↓
继续执行查询

这意味着:你执行 graphify update 后,无需重启 Cursor,下次 AI 查询会自动使用最新图谱。


七、常用命令速查

# 增量更新图谱(日常使用)
.\.venv\Scripts\graphify update .

# 全量重建图谱(大改后使用)
.\.venv\Scripts\graphify update . --force

# 仅重新聚类(不重新提取)
.\.venv\Scripts\graphify cluster-only graphify-out/graph.json

# 给社群命名(需要 LLM API Key)
.\.venv\Scripts\graphify label graphify-out/

# 手动启动 MCP 服务(调试用)
.\.venv\Scripts\python.exe -m graphify.serve graphify-out/graph.json

# 查看当前图谱统计
打开 graphify-out/GRAPH_REPORT.md

# 可视化浏览图谱
打开 graphify-out/graph.html

八、新人快速理解要点

1. 两条独立链路

链路触发时机关键文件产物
构建链路手动执行 graphify updateextract.py → build.py → cluster.pygraph.json
查询链路Cursor 启动后 AI 自动调用serve.py(MCP 协议)文本上下文

2. 三个核心概念

概念解释类比
节点(Node)代码里的类、方法、配置项、业务术语百科词条
边(Edge)节点之间的关系(调用、继承、引用)词条之间的超链接
社群(Community)紧密关联的一组节点百科的分类目录

3. 为什么需要这个系统?

没有图谱:AI 要全局搜索 337 个文件 → 慢、不准、带入无关代码
有了图谱:AI 查一次图 → 精准定位 3-5 个相关节点 → 快、准、上下文紧凑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值