


















分析日期:2026-06-08
项目来源:GitHub Trending(2026-06-07)
| 属性 | 详情 |
|---|---|
| 项目名称 | graphify |
| 项目地址 | https://github.com/safishamsi/graphify |
| 官方网站 | https://graphifylabs.ai |
| Star / Fork | 57,994 / 6,063 |
| 主要语言 | Python |
| 创建时间 | 2026-04-03 |
| 开源协议 | MIT License |
| GitHub Topics | antigravity, claude-code, codex, gemini, graphrag, knowledge-graph, leiden, openclaw, rag, skills, tree-sitter |
graphify 是一个 AI 编程助手的 Skill(技能插件),它可以把任意文件夹中的代码、SQL Schema、Shell 脚本、文档、论文、图片或视频,转化为一个可查询的知识图谱。最终输出为代码 + 数据库 Schema + 基础设施架构,整合在一张图谱中。
graphify 目前原生支持以下 AI 编程助手作为 Skill 安装:
| 支持的 AI 编程助手 | 状态 |
|---|---|
| Claude Code | ✅ 原生支持 |
| Codex CLI | ✅ 原生支持 |
| OpenClaw | ✅ 原生支持 |
| Cursor | ✅ 支持 |
| Gemini CLI | ✅ 支持 |
graphify 的核心价值在于,它让 AI 编程助手在面对一个陌生的代码库时,不再需要"逐文件阅读"来理解项目结构,而是可以:
这解决了 AI 编程助手最大的痛点之一:上下文窗口不足以容纳大型项目的完整信息。通过将项目压缩为结构化的知识图谱,AI 只需要在查询时引入相关子图,就能准确回答问题。
graphify 并不依赖 LLM 来理解代码结构(那会非常昂贵且不稳定),而是使用 tree-sitter——一个高性能的增量解析器生成器。
extract_<lang>() 函数这种方案的优势:
在 cluster.py 中,graphify 使用 Leiden 算法 对知识图谱做社区发现(Community Detection)。
Leiden 相比经典的 Louvain 算法的优势:
networkx.algorithms.community 的实现聚类结果会在报告中标注"核心模块",帮助 AI 快速聚焦项目最重要的部分。
graphify 对每一条关系都标注了置信度:
| 标签 | 含义 |
|---|---|
| EXTRACTED | 从源代码中"字面"读取到的关系(如 import 语句、直接函数调用) |
| INFERRED | 通过合理推断得出的关系(如调用图二次遍历、上下文共现) |
| AMBIGUOUS | 关系不确定,需人工审查(会在 GRAPH_REPORT.md 中标出) |
这让下游的 AI Agent 可以根据置信度来决定是否信任某条关系,避免"基于幻觉构建架构"。
项目架构的一大亮点是 Pipeline 设计:
detect() → extract() → build_graph() → cluster() → analyze() → report() → export()
每个阶段都是一个独立模块中的纯函数,它们之间通过 Python dict 和 NetworkX Graph 通信,没有共享状态,除 graphify-out/ 目录外不产生副作用。
这种设计带来了:
extract.py,其余管道保持不变cache.py 实现了语义缓存,已解析过的文件无需重复处理extract() 阶段可完全并行graphify 对所有外部输入都经过严格校验:
| 输入类型 | 校验方式 |
|---|---|
| URL | validate_url(),仅允许 http/https,阻止 file:// 重定向 |
| 抓取内容 | safe_fetch() / safe_fetch_text(),限制大小和超时 |
| 图文件路径 | validate_graph_path(),必须在 graphify-out/ 目录内 |
| 节点标签 | sanitize_label(),清除控制字符、限制 256 字符、HTML 转义 |
完整的威胁模型参见 SECURITY.md。这使得即使在不受信任的代码库上运行 graphify,风险也是可控的。
export.py 可以将图谱导出为多种格式:
| 格式 | 用途 |
|---|---|
| Obsidian Vault | 直接生成一个 Obsidian 知识库,每个节点一篇笔记 |
| graph.json | 结构化 JSON 数据,供其他程序或 AI 读取 |
| graph.html | 交互式 HTML 可视化(可缩放、拖拽、点击) |
| graph.svg | 静态矢量图,可嵌入文档或 README |
| Mermaid 调用流程图 | callflow_html.py 生成 Mermaid 架构/调用流程图 HTML |
这让 graphify 的输出不仅服务于 AI Agent,也对人类开发者直接有用。
在 serve.py 中,graphify 提供了一个 MCP 标准输入输出服务器,这意味着:
这是开源社区中文档质量相当高的项目。
| 要求 | 条件 |
|---|---|
| Python | ≥ 3.10(推荐 3.11+) |
| 操作系统 | Linux / macOS / Windows(全平台) |
| 磁盘空间 | ~50 MB(项目本体 + tree-sitter 依赖) |
| 内存 | 推荐 4 GB+(大型项目解析时可能更高) |
| 网络 | 首次安装需下载 tree-sitter 语言包;运行时可完全离线 |
根据项目特性,主要依赖如下:
| 依赖 | 用途 |
|---|---|
| tree-sitter + tree-sitter-languages | 多语言代码解析(Python/TS/Go/Rust/Java/C++/SQL/Shell 等) |
| networkx | 图数据结构、Leiden 社区发现、图算法 |
| beautifulsoup4 + requests | HTML/网页内容解析与抓取 |
| pyyaml | 配置文件读写 |
| markdown | Markdown 文档解析 |
| pytest(开发依赖) | 单元测试 |
| pre-commit(开发依赖) | 代码质量检查 |
# 在 Claude Code 中,只需告诉 Claude:
# "Install the graphify skill from github.com/safishamsi/graphify"
# 或者手动 clone 后激活:
git clone https://github.com/safishamsi/graphify.git
cd graphify
# 在 Claude Code 的 Settings → Skills → Add local skill → 选择此目录
然后对 Claude 说:
请对 ./src 目录运行 graphify,然后告诉我项目的核心架构。
from graphify import detect, extract, build_graph, cluster, analyze, report, export
# Step 1: 收集文件
files = detect.collect_files("./my-project")
# Step 2: 提取实体与关系
extractions = [extract.extract(f) for f in files]
# Step 3: 构建图
G = build_graph(extractions)
# Step 4: 社区发现
cluster.cluster(G)
# Step 5: 分析
analysis = analyze(G)
# Step 6: 生成报告
report_text = report.render_report(G, analysis)
# Step 7: 导出
export.export(G, out_dir="./graphify-out")
docker build -t graphify .
docker run -v $(pwd)/my-project:/corpus -v $(pwd)/graphify-out:/output \
graphify python -m graphify.serve /corpus
然后通过 MCP 协议从 AI Agent 调用。
以一个典型项目扫描为例:
用户在 Claude Code 中:"graphify ./backend"
↓ detect.py: collect_files() —— 扫描目录,识别代码文件
↓ extract.py: extract() —— 逐文件 AST 解析,提取节点与关系
↓ build.py: build_graph() —— 合并为 NetworkX 图
↓ cluster.py: cluster() —— Leiden 算法社区发现
↓ analyze.py: analyze() —— 识别关键节点、意外关系、提出问题
↓ report.py: render_report() —— 生成 GRAPH_REPORT.md
↓ export.py: export() —— 导出 Obsidian/JSON/HTML/SVG
结果:graphify-out/ 目录下生成 5-10 个文件,
其中 GRAPH_REPORT.md 由 Claude 直接读取为上下文。
graphify/
├── graphify/ # 🔴 核心 Python 包
│ ├── __init__.py # 包入口,暴露公共 API
│ ├── detect.py # 文件检测:遍历目录,过滤文件类型
│ ├── extract.py # 提取:AST 解析,提取节点/关系
│ ├── build.py # 构图:将提取结果合并为 NetworkX Graph
│ ├── cluster.py # 聚类:Leiden 算法社区发现
│ ├── analyze.py # 分析:识别关键节点、意外关系、提出问题
│ ├── report.py # 报告:生成 GRAPH_REPORT.md
│ ├── export.py # 导出:Obsidian/JSON/HTML/SVG
│ ├── callflow_html.py # Mermaid 调用流程图 HTML 生成
│ ├── ingest.py # 摄取:URL → 本地 corpus 目录
│ ├── cache.py # 缓存:语义级 cache(文件内容哈希→提取结果)
│ ├── security.py # 安全:所有外部输入的校验
│ ├── validate.py # 验证:提取结果的 schema 验证
│ ├── serve.py # MCP 服务器:通过 stdio 协议提供工具
│ ├── watch.py # 监听:文件变更时自动重建图谱
│ └── benchmark.py # 基准:corpus 与 subgraph token 对比
│
├── tests/ # 🧪 测试套件(每个模块一个测试文件)
│ ├── test_detect.py
│ ├── test_extract.py
│ ├── test_build.py
│ ├── test_cluster.py
│ ├── test_analyze.py
│ ├── test_report.py
│ ├── test_export.py
│ ├── test_languages.py # 每种语言的提取测试
│ ├── test_security.py
│ └── test_validate.py
│
├── docs/ # 📖 文档体系
│ ├── ARCHITECTURE.md # 架构说明(官方由 graphify 自己生成)
│ ├── SECURITY.md # 安全威胁模型
│ ├── how-it-works.md # 内部工作原理详解
│ ├── docker-mcp-sqlite.md # Docker + MCP + SQLite 部署
│ ├── superpowers/ # 未来功能规划
│ │ ├── plans/ # 功能计划文档
│ │ └── specs/ # 详细设计规范
│ └── translations/ # 32 种语言的 README 翻译
│
├── .github/
│ ├── FUNDING.yml
│ └── workflows/ci.yml # CI(pytest + lint)
│
├── Dockerfile # 单阶段 Docker 镜像
├── .pre-commit-config.yaml # pre-commit hooks
├── .gitignore
├── .gitattributes
├── .dockerignore
├── AGENTS.md # 支持的 AI Agent 清单
├── CHANGELOG.md # 121 KB 版本更新记录
├── LICENSE # MIT License
├── pyproject.toml # Python 包配置
└── README.md # 主文档(40 KB)
┌──────────────────────────────────────────────────────────────────────────────┐
│ graphify 核心 Pipeline │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ detect.py│ │ extract.py│ │ build.py │ │ cluster.py│ │
│ │ │ │ │ │ │ │ │ │
│ │ 遍历目录 │────▶│ tree-sitter│───▶│ 合并节点 │────▶│ Leiden │ │
│ │ 过滤文件 │ │ AST 提取 │ │ 与关系 │ │ 社区发现 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ [Path] {nodes,edges} nx.Graph 带 community 属性 │
│ │
│ ↓ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ analyze.py│ │ report.py│ │ export.py │ │
│ │ │ │ │ │ │ │
│ │ 关键节点 │────▶│ Markdown │────▶│ 多格式 │ │
│ │ 意外关系 │ │ 报告生成 │ │ 导出 │ │
│ │ 提出问题 │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ analysis dict GRAPH_REPORT.md Obsidian / JSON / HTML / SVG │
│ │
│ ════════════════════════════════════════════════════════════════════════ │
│ 辅助模块(横切关注点): │
│ ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ security.py│ │ cache.py │ │ serve.py │ │ watch.py │ │
│ │ 输入校验 │ │ 语义缓存 │ │ MCP 服务 │ │ 文件监听 │ │
│ └────────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌────────────┐ ┌──────────────┐ │
│ │ validate.py│ │ benchmark.py │ │
│ │ schema │ │ 基准测试 │ │
│ │ 验证 │ │ │ │
│ └────────────┘ └──────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
# 伪代码
CODE_EXTENSIONS = {
".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".rs",
".java", ".c", ".cpp", ".cs", ".rb", ".php", ".swift",
".kt", ".scala", ".sql", ".sh", ".bash", ".zsh",
".yml", ".yaml", ".json", ".toml", ".ini",
".md", ".mdx", ".rst",
".html", ".css",
}
IGNORED_DIRS = {"node_modules", ".git", "venv", "__pycache__", "dist", "build"}
def collect_files(root: Path) -> list[Path]:
"""递归遍历 root 目录,返回符合扩展名的文件列表"""
for path in root.rglob("*"):
if path.is_file() and path.suffix in CODE_EXTENSIONS:
if not any(part in IGNORED_DIRS for part in path.parts):
yield path
设计要点:
# 伪代码
def extract(path: Path) -> dict:
"""解析单个文件,返回 {nodes, edges} 字典"""
lang = _detect_language(path) # 根据扩展名判断语言
parser = tree_sitter.get_parser(lang)
tree = parser.parse(read_file(path))
nodes, edges = [], []
# 第一遍:收集定义节点(函数、类、表等)
_walk_collect_definitions(tree, nodes)
# 第二遍:收集调用/导入关系
_walk_collect_relations(tree, nodes, edges)
return {"nodes": nodes, "edges": edges}
# 每个语言都有特定的 extract_<lang> 函数
def extract_python(path: Path) -> dict: ...
def extract_typescript(path: Path) -> dict: ...
def extract_sql(path: Path) -> dict: ...
def extract_go(path: Path) -> dict: ...
# ... 等等
提取输出 Schema(由 validate.py 强约束):
{
"nodes": [
{
"id": "module.submodule.function_name",
"label": "function_name",
"type": "function",
"source_file": "backend/module/submodule.py",
"source_location": "L42-L58"
}
],
"edges": [
{
"source": "module.submodule.function_name",
"target": "other.module.ClassA",
"relation": "calls",
"confidence": "EXTRACTED"
}
]
}
import networkx as nx
def build_graph(extractions: list[dict]) -> nx.Graph:
G = nx.Graph()
for extraction in extractions:
for node in extraction["nodes"]:
G.add_node(node["id"], **node)
for edge in extraction["edges"]:
G.add_edge(
edge["source"],
edge["target"],
relation=edge["relation"],
confidence=edge["confidence"]
)
return G
要点:
relation 属性)path + entity_name 组合而成)def cluster(G: nx.Graph) -> nx.Graph:
"""使用 Leiden 算法识别社区,结果写入节点的 community 属性"""
# 使用 networkx.algorithms.community 的 Leiden 实现
communities = nx.community.louvain_communities(
G,
weight="confidence_score", # EXTRACTED=1.0, INFERRED=0.5, AMBIGUOUS=0.2
resolution=1.0, # 社区大小的"分辨率"
seed=42 # 可复现
)
for idx, community in enumerate(communities):
for node in community:
G.nodes[node]["community"] = idx
# 识别"枢纽节点"(连接多个社区的节点)
for node in G.nodes:
neighbor_communities = {
G.nodes[nbr].get("community", -1) for nbr in G.neighbors(node)
}
if len(neighbor_communities) >= 3:
G.nodes[node]["hub"] = True
return G
def analyze(G: nx.Graph) -> dict:
"""产生三类分析输出,供 report.py 生成报告"""
return {
# 1. 关键节点(度数、中介中心性、PageRank 综合排序)
"god_nodes": top_10_by_centrality(G),
# 2. 意外关系(跨社区连接,可能揭示架构问题)
"surprises": cross_community_connections(G),
# 3. 自动生成的"值得询问 AI"的问题
"questions": [
f"模块 A(community 3)为何依赖模块 B(community 7)?",
f"节点 db.connection_pool 同时连接 8 个社区,是否符合预期?",
# ...
]
}
render_report() 将图结构、分析结果、社区信息汇总为 GRAPH_REPORT.md。报告结构:
# Graph Report for <project>
## Overview
- Nodes: X
- Edges: Y
- Communities: Z
## Communities
- Community 0: <模块描述>
- Community 1: <模块描述>
...
## Key Nodes (God Nodes)
- node1 (degree: 42, betweenness: 0.18)
...
## Surprises
<意外关系列表>
## Questions for AI
<问题列表>
def check_semantic_cache(files: list[Path]) -> tuple[list[Path], list[Path]]:
"""返回 (已缓存的文件, 未缓存的文件)"""
cached, uncached = [], []
for f in files:
file_hash = hash_file_content(f) # 基于内容的哈希
if file_hash in cache_db:
cached.append(f)
else:
uncached.append(f)
return cached, uncached
对于大型项目,这是重要性能优化:增量更新时,只有修改过的文件会被重新解析。
# 通过 Model Context Protocol 暴露为 AI Agent 工具
def start_server(graph_path: Path):
tools = [
{"name": "graphify_get_summary", "desc": "返回图的整体统计"},
{"name": "graphify_get_subgraph", "desc": "返回指定节点的局部子图"},
{"name": "graphify_find_paths", "desc": "查找两节点间的路径"},
{"name": "graphify_search_nodes", "desc": "按关键词搜索节点"},
{"name": "graphify_get_communities", "desc": "列出社区/模块"},
{"name": "graphify_get_report", "desc": "返回完整 GRAPH_REPORT.md"},
]
# 启动 MCP stdio 服务器,监听 stdin/stdout 与 Agent 通信
| 场景 | 描述 | graphify 的角色 |
|---|---|---|
| 💼 新人代码库上手 | 新成员加入团队,面对陌生代码库 | 10 分钟生成项目全景图 + 引导式问题清单 |
| 🔍 大型项目架构审计 | 面对 10 万+ 行代码的遗留系统 | 自动识别"上帝节点"(god nodes)和跨层依赖 |
| 🧠 科研论文阅读 | 阅读带代码的论文复现仓库 | 快速建立论文与代码的对应关系图谱 |
| 🤖 AI Agent 知识库前置 | 让 Agent 在编码前先理解项目 | 图谱比全文阅读节省 90%+ 的上下文 token |
| 📝 技术文档自动生成 | 自动维护项目架构文档 | 代码变更 → 重建图谱 → 报告反映最新状态 |
| 🐛 调试与影响分析 | "修改这个函数会影响哪些模块?" | 图的路径搜索给出精确影响范围 |
| 🏢 企业微服务架构梳理 | 梳理数十个服务之间的调用关系 | 需要配合 URL 摄取(ingest.py)构建跨服务图谱 |
| 📚 个人学习记录 | 把读过的代码、文档、笔记建图 | Obsidian 导出形成永久知识资产 |
| 方案 | 核心思路 | 优点 | 缺点 |
|---|---|---|---|
| graphify | tree-sitter 解析 → NetworkX 图 → Leiden 聚类 → 多格式导出 | 轻量、零 LLM 依赖、确定性、支持 MCP | 深度分析仍需下游 AI |
| GraphRAG(Microsoft) | LLM 提取实体 → 向量检索 → 图索引 → LLM 综合回答 | 深度语义理解能力强 | 依赖 LLM(成本高)、非确定性、较重 |
| Sourcegraph / CodeLlama | 代码索引 + 语义搜索 | 行业级产品 | 需要部署基础设施、商业授权 |
| 手动阅读代码 | 人类开发者逐文件理解 | 最准确(经验丰富的开发者) | 极慢(大型项目需要数周) |
| LLM 直接阅读代码 | 把代码塞进 context window,让 LLM 分析 | 零配置、快速启动 | token 限制严重、大项目不可行、幻觉风险高 |
graphify 的定位:"轻量级结构分析器"——让 AI 在阅读代码之前先看到项目骨架。它不求替代 LLM,而是让 LLM 的工作更高效。
✅ 1. 零 LLM 依赖的核心流程
最核心的"解析 → 建图 → 聚类 → 分析"链路 完全不依赖任何大模型。这意味着:
✅ 2. 清晰的纯函数管道架构
7 个主要函数依次传递数据,无共享状态、无副作用(除输出目录)。这让代码极易测试、扩展和维护。
✅ 3. tree-sitter 带来的多语言能力
借助 tree-sitter,graphify 天然支持数十种编程语言,新增语言只需实现一个 extract_<lang>() 函数 + 一个 tree-sitter 依赖。
✅ 4. 完善的安全模型
security.py 的存在表明项目对安全问题有系统性思考——URL 校验、路径隔离、内容大小限制等,这对一个接受任意代码库输入的工具尤为重要。
✅ 5. MCP 原生集成
在 MCP 协议正迅速成为 AI Agent 标准的当下,graphify 的原生 MCP 支持使其天然适用于下一代 AI 开发工具链。
✅ 6. 文档质量
32 种语言的 README、专门的 ARCHITECTURE.md、SECURITY.md、how-it-works.md——文档体系在开源项目中属于顶级水准。
问题:tree-sitter 只能解析静态可见的结构。对于 Python 的 getattr()、JS 的 eval()、Java 的反射调用等动态行为,graphify 会遗漏这些关系。
影响:在大量使用动态特性的项目(如某些 Python Web 框架、元编程密集的库)中,图谱会缺失重要关系,AI 基于图谱做出的推断可能不完整。
可能的改进:
问题:当前实现是单进程遍历所有文件。对于百万行级的代码库(如大型 monorepo),解析时间可能达到小时级。
可能的改进:
concurrent.futures.ProcessPoolExecutor)watch.py 已实现文件监听,但初始全量扫描仍需优化问题:graphify 知道"函数 A 调用函数 B",但不知道"这个调用的业务意义是什么"、"这个关系是核心业务路径还是边缘工具函数"。
可能的改进:
docs/superpowers/specs/ 中有规划问题:对 SQL 文件的解析目前只提取表和字段,不处理外键关系、索引、JOIN 模式等。
可能的改进:
belongs_to、SQLAlchemy 的 relationship)问题:当前的 HTML 可视化导出是静态的,没有查询、过滤、跳转等交互功能。
可能的改进:
现状:虽然有 tests/ 目录和 CI,但 README 未公布具体覆盖率数据。对一个以"正确性"为卖点的工具而言,公开测试覆盖率数据会增强用户信任。
| 维度 | 评分 | 说明 |
|---|---|---|
| 功能完整性 | ⭐⭐⭐⭐ | 核心链路完备,导出格式丰富,但仍在积极扩展高级功能 |
| 代码质量 | ⭐⭐⭐⭐⭐ | 纯函数管道架构,模块化极好,安全和验证模块设计周到 |
| 文档质量 | ⭐⭐⭐⭐⭐ | 32 种语言 + 架构文档 + 安全文档 + 详细规划 |
| 性能 | ⭐⭐⭐⭐ | 中小型项目极快,大型项目需优化 |
| 易用性 | ⭐⭐⭐⭐ | 作为 Claude Code Skill 零配置;独立使用需要一点 Python 基础 |
| 生态契合度 | ⭐⭐⭐⭐⭐ | MCP 原生支持,完美契合当前 AI Agent 生态趋势 |
| 隐私/安全 | ⭐⭐⭐⭐ | 可完全离线,有系统的安全模型 |
| 可扩展性 | ⭐⭐⭐⭐ | 管道式架构易扩展,新增语言仅需一个 extract 函数 |
| 综合推荐度 | ⭐⭐⭐⭐ | 推荐给任何使用 AI 编程助手的开发者 |
| 人群 | 推荐度 | 理由 |
|---|---|---|
| 使用 Claude Code / Codex 的开发者 | ⭐⭐⭐⭐⭐ | 原生 Skill,一键安装,立竿见影 |
| 大型项目维护者 | ⭐⭐⭐⭐ | 快速扫描遗留代码,发现架构问题 |
| 团队 Tech Lead / 架构师 | ⭐⭐⭐⭐ | 自动生成架构报告,辅助决策 |
| 研究人员 / 学生 | ⭐⭐⭐⭐ | 快速理解开源项目结构 |
| 企业 AI 平台建设者 | ⭐⭐⭐⭐⭐ | 作为 Agent 的代码理解前置工具,大幅降低 token 消耗 |
| 仅写小型个人项目的开发者 | ⭐⭐⭐ | 价值较低,小项目直接让 AI 读文件即可 |
graphify 不只是又一个"让 AI 读代码"的工具——它用 tree-sitter + NetworkX 构建了一个确定性、可缓存、零成本的代码"结构化骨架",让 AI Agent 在编码前先看项目全景,在大型项目中节省 90%+ 的上下文 token。在 MCP 生态快速成型的当下,它的定位正从"有趣的 Skill"演变为"AI 编码的基础设施"。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。