你的代码库有你看不到的问题——knowledge graph如何揭示grep无法发现的内容
开发者70%的时间在读代码,不是在写。而这时间里的大头是在找东西。不是找某个具体的函数——那个用 grep 2秒搞定。问题是找那些你压根不知道存在的东西:隐藏依赖、看起来活着其实死了的代码、没人注意到的模块耦合、没有任何东西引用的完整 workflows。
我们给自己的 codebase 构建了一个 knowledge graph,第一次跑查询就发现了:229个孤立 artifacts、2个完全脱离系统的 workflows、改动一个 agent 会级联影响31个其他 artifacts。这些问题一直存在——好几年了,没人知道。
grep 能找到什么,grep 永远找不到什么
grep 是一个”存在性”工具。你搜”parseConfig”,它告诉你5个文件里有这个字符串。完美。
但 grep 回答不了这些问题:
- 改了 parseConfig 会发生什么?——grep 能找到5个直接调用者。但这5个又调用了另外23个模块,它们传递依赖于这个函数。真实的 blast radius 是28,不是5。
- 哪些函数存在但没人调用?——grep 找的是”存在”。孤立代码的定义是没有被引用。你得把每个函数跟所有其他代码对比——组合爆炸。
- 有多少模块依赖这个?——你打开
auth.js,能看到它的 imports(它消费了什么)。但看不到谁 import 了它(谁依赖它)。fan-in 在单个文件里是不可见的。 - 有没有循环依赖?——A→B→C→A。每个文件只显示一条边。循环只有在你拼出完整的图之后才会浮现。
微软研究院的一项研究(Nagappan et al., ICSE 2006)表明,基于依赖图的指标能预测73%的变更后缺陷。只检查直接调用者(grep方式)的开发者,会漏掉60%发生在传递依赖者身上的 break。
也就是说:grep 给你一张快照。图给你一张地图。
没人看到的那一层
任何 codebase 都有3个理解层次:
- 微观(可读)——单个函数、类、文件。打开就能读。
- 宏观(有文档)——系统架构、diagram、README。
- 中观(不可见)——文件之间的真实连接。谁调用谁,谁依赖谁,改这里会破坏什么。
中观层是分散的:每个文件包含一个片段(它的 imports),但完整的图需要把所有片段聚合起来。面对几百个文件,这在认知上是不可能靠脑子维持的。
Fowler 和 Whitehead 在《Building Evolutionary Architectures》里记录了一个完美说明问题的案例:
“我们把依赖图投影到墙上。CTO说:’这不是我们的架构。’我们说:’这就是你们的架构。’他们以为自己有8个模块的系统,实际上是2个超级集群,中间有个路由节点承载了67%的流量。”
他们读这份代码读了5年,对此一无所知。因为没有图,根本看不到。
我们做的:两个 graph,一个 codebase
我们在用 AIOS——一个用于 full stack 开发的 AI agents 编排系统。里面有 agents(@dev、@qa、@architect)、tasks(qa-gate、dev-develop-story)、workflows(story-development-cycle、epic-orchestration)、专家 squads,以及 minds(Alex Hormozi、Paul Graham、Seth Godin 等 thought leaders 的认知克隆)。
问题是:每次 Claude Code 需要理解这些 artifacts 之间的关系,它都要重新读文件。12个 agents × 5,000 tokens 每个 = 60,000 tokens 就为了回答”@dev 是干什么的?”。
于是我们构建了两个互补的 knowledge graphs:
1. code-review-graph——用于代码
code-review-graph(fork 自 tirth8205 的原始项目)用 Tree-sitter 把源码解析成 AST,然后构建一个包含函数、类、imports 和调用关系的 SQLite graph。
平均结果:每次 review 操作少用8.2倍 tokens。在有27,000个文件的 monorepo 里,graph 能过滤到约15个相关文件。
在我们的 fork 里,我们贡献了 PR #95,添加了10个 CLI 子命令和 CommonJS require() 解析支持。
2. aios-graph——用于非代码 artifacts
但代码只是故事的一半。我们的系统有206个 tasks、14个 workflows、13个 agents、93个 squads 和115个 minds——全都定义在 YAML 和 Markdown 里,超出了 code-review-graph 的覆盖范围。
于是我们构建了 aios-graph:一个本地 knowledge graph(Python + SQLite + PyYAML),解析这些 artifacts 并映射 DEPENDS_ON_TASK、ASSIGNED_TO、MIND_IN_SQUAD、DELEGATES_TO 这类关系。
市面上没有任何工具做这件事。Augment Code、codebase-memory-mcp、GitHub Stack Graphs——全都聚焦于代码实体。把 agents、tasks 和 workflows 做成图是一个新类别。
aios-graph query agent dev # @dev 是干什么的?
aios-graph impact agent:dev # 改 @dev 的 blast radius
aios-graph who-uses qa-gate # 谁依赖 qa-gate?
aios-graph mind-search --tier S # 生产就绪的 minds
aios-graph dead # 没人引用的 artifacts每次查询200 tokens。之前是60,000。
第一天发现了什么
我们跑了 aios-graph build,查询结果揭示了任何 grep 都不可能发现的东西:
229个孤立 artifacts
48个 tasks(占总数23.5%)存在于仓库里,但没有任何 agent 在依赖声明里引用它们。这些都是编排、安全和构建方面的 tasks,实际上在运行——但系统不知道它们的存在。
这很关键:如果有人把它们当”死代码”删掉,会破坏那些隐式依赖它们的 workflows。
在 Instagram 关注我 @murilloimparavel——我在那里不加滤镜地分享我日常用 AI 的幕后细节。
@dev 的 blast radius 是31
@dev(我们的主要实现 agent)有43个依赖和24个依赖者。改动它的接口——一个命令、一个 input 格式——会影响31个 artifacts,深度两层:8个 workflows、6个 rules、10个 agents、7个间接 workflows。
没有 graph,有人会去编辑 @dev 以为”就是一个文件”。实际上,它是整个系统里耦合度最高的节点。
2个幽灵 workflows
epic-orchestration 和 development-cycle 作为完整的 YAML 文件存在,写得很工整,定义了阶段和 agents。但 graph 显示0条边——没有任何东西引用它们,没有任何东西把它们连接到系统的其余部分。这是有人创建、提交、然后忘了接进去的 workflows。
我们发现是 parser 不理解它们的 YAML 格式(用的是 phases 作为 dict,而不是 sequence 作为 list)。修复 parser 之后,突然出现了12条新边。这些 workflows 复活了。
98.3%的 minds 没有提取 frameworks
115个 minds(thought leaders 的认知克隆)里,只有2个提取了可操作的 frameworks(Gary Vaynerchuk 和 Pedro Sobral)。另外113个是原始素材库——agent 每次都要重读所有源材料才能推导出原则。
这就像有一本包含115本书的菜谱集,但只有2本准备好了索引。其他的,你得把整本书读完才能找到你要的东西。
不可见的重复
squads/copy/ 和 squads/copy-squad/ 有字节级完全相同的 agents。没有 graph,这看起来是2个不同的 squads(名字不同、目录不同)。对比 CONTAINS_AGENT 的边关系后发现它们是同一个东西。
Token 经济账——粗算一下
根据 Codebase-Memory 论文,一次 graph query 大约返回 ~200 tokens 的结果。手动读同样的文件要花8,000到60,000 tokens。
来算个账:
| 操作 | 读文件 | Graph query | 节省 |
|---|---|---|---|
| “@dev 是干什么的?” | 60,000 tokens(12个 agents) | 200 tokens | 300x |
| “谁用了 qa-gate?” | 15,000 tokens(搜索 tasks/agents/rules) | 200 tokens | 75x |
| “@dev 的 blast radius” | 100,000+ tokens(手动 BFS) | 200 tokens | 500x |
| “Tier S 的 minds” | 50,000 tokens(读115个 minds) | 200 tokens | 250x |
用 Claude Opus 4.6,$9/1M input tokens,一次消耗500K tokens 的重度探索 session 要花 $4.50。换成 graph queries,同样的 session 花 $0.45。一个月50次 session,$225 vs $22.50。光是从 grep 换到 graph,每月节省 $200。
这还没算定性收益:context 越少,模型表现越好。Factory.ai 证明无关 context 会降低模型性能——不只是更贵,还会让模型表现变差。
为什么选 CLI 不选 MCP
说点有点争议的。整个生态都在推 MCP(Model Context Protocol)作为连接 AI agents 和工具的方式。我们最初也用 MCP server(FastMCP)构建了 aios-graph。后来删了。
数据很清楚:
| 维度 | CLI(--json) | MCP Server |
|---|---|---|
| 每次调用 tokens | ~200(仅 stdout) | ~6,500+(schema overhead) |
| 每个 task 成本 | 1x | 32x(ScaleKit 2026) |
| 可靠性 | 100% | 72%(ScaleKit) |
| 运行中的进程 | 0(按需 spawn) | 1个持久进程 |
| 所需配置 | 无 | settings.json + env vars |
| 崩溃恢复 | 每次调用独立 | server 崩了 = 全挂 |
aios-graph 对 SQLite 做 stateless 查询。没有 connection pooling,没有 streaming,没有双向通信——这些才是 MCP 真正有价值的场景。其他情况,一个带 --json 的 CLI 就够了。
Nx 也以同样的原因删掉了大部分 MCP tools。Perplexity 的 CTO 在内部放弃了 MCP。趋势很明显:开发工具用 CLI,需要 auth 的外部集成才用 MCP。
怎么自己构建一个
aios-graph 大概用了两小时构建,架构是这样的:
aios_graph/
graph.py — SQLite store(WAL mode,参数化查询)
parser.py — 7个 parsers(agent、task、workflow、squad、mind、rule、framework)
tools.py — 核心函数(stateless 查询)
cli.py — 入口,带全局 --json flag依赖:pyyaml。就这一个。
pipeline 很简单:
- 发现——对 artifacts 目录做
rglob - 解析——从 markdown 里提取 YAML blocks,加载纯 YAML
- 索引——用 SHA-256 做变更检测,upsert nodes + edges 到 SQLite
- 查询——BFS 做 impact、in-degree=0 找孤立节点、LIKE 做搜索
完整构建:420个节点,993条边,不到15秒。增量更新:不到2秒。
代码是开源的。code-review-graph 的 fork 在我的 GitHub 上,带着 PR #95(CLI-first 扩展)。aios-graph 在 mvp-system 里。
未来:每个 AI 工作区都应该有一个 graph
学术研究正在往这个方向收敛。2024-2026年,至少发表了7篇关于 graphs + AI agents 的论文:
- CodeXGraph(NAACL 2025)——LLM agents 对代码图写 Cypher 查询
- GraphCodeAgent——GPT-4o 用 dual graph,pass rate 提升43.8%
- Codebase-Memory——用10倍少的 tokens 达到83%的质量
- Augment Code——graph context 带来+70%质量提升
正在浮现的标准模式:
| 层级 | 工具 | 捕获的内容 |
|---|---|---|
| L0:什么都没有 | Claude Code vanilla | 每次 session 靠 Grep/Read |
| L1:摘要 | Aider repo-map | 每个文件的符号,PageRank |
| L2:Embeddings | Cursor | 语义相似度 |
| L3:结构化 graph | code-review-graph,aios-graph | 实体之间的真实关系 |
| L4:语义 + 结构 | Augment Context Engine | Graph + embeddings |
我们用 $0 基础设施投入跑在 L3。零服务器,零 embedding model,零 API key。SQLite + Tree-sitter + PyYAML。
如果这篇文章对你有用,把它分享给需要看的人。如果想聊 knowledge graphs、AI agents,或者怎么把这些整合起来,来 Instagram 找我。
FAQ
什么是 codebase 的 knowledge graph?
就是一个图数据库(节点 + 边),映射你代码里的实体(函数、类、模块)以及它们之间的关系(谁调用谁,谁 import 谁,谁测试谁)。和搜索索引不同,它支持关系查询:”改了 X 会破坏什么?”或者”哪些函数没人用?”。
需要 Neo4j 或者什么图数据库吗?
不需要。code-review-graph 和 aios-graph 都用纯 SQLite。两张表(nodes 和 edges)加上索引,对大多数场景够用了。Neo4j 在你需要复杂 Cypher 查询或者千万级节点规模时才有意义。对一般的 codebase(<100K 文件),SQLite 搞定。
我的 codebase 大概有多少死代码?
根据 FlagShark,典型仓库有10-30%的死代码。存活5年以上的 enterprise codebase 可以到20-35%。并购后可能到50%。一家 SaaS 公司发现大约50%的代码从没被用过。
给 AI agent 服务 graph 用 MCP 还是 CLI?
CLI 加 --json。benchmark 显示 MCP 消耗多32倍 tokens,可靠性72% vs CLI 的100%。MCP 适合数据库连接(connection pooling)、浏览器自动化(持久状态)和 OAuth delegation。对 SQLite 的 stateless 查询,CLI 是严格意义上的更优选。
这只适用于代码,还是其他 artifacts 也行?
适用于任何有结构化关系的东西。aios-graph 解析 YAML 和 Markdown——agents、tasks、workflows、squads、minds。同样的模式可以用于 Terraform modules、Kubernetes manifests、GitHub Actions workflows,或者任何引用其他配置的声明式配置。