CodeGraph 阅读分析与使用笔记
这篇文章解决什么问题
CodeGraph 是 colbymchenry 做的一个本地代码语义索引工具,仓库地址:
它不是代码生成模型,也不是简单的 grep 包装。它的核心做法是:
- 用 tree-sitter 解析项目源码。
- 把文件、符号、调用、引用、继承、实现、路由等关系写入
.codegraph/codegraph.db。 - 通过 CLI 和 MCP tools 给 AI coding agent 查询。
- 让 agent 先查语义图,再决定是否需要读文件。
一句话:
CodeGraph想解决的不是“让模型更聪明”,而是“把模型每次都要重复做的代码搜索和调用链梳理,提前变成本地索引”。
采集时间:2026-06-08。
阅读对象:GitHub main 分支、README、src/bin、src/index.ts、src/extraction、src/resolution、src/graph、src/mcp、src/db、src/sync、src/installer、CHANGELOG。
说明:本文未本地安装、未运行 codegraph init、未执行项目测试,只做源码和文档静态阅读。
先说结论
CodeGraph的核心资产是.codegraph/codegraph.db,不是 MCP server 本身。- 它最适合回答“X 怎么工作”“谁调用了 X”“改 X 会影响谁”“这个目录里有什么”这类代码理解问题。
- 它把 AI 探索代码的成本从
grep + Read + 再 grep改成一次或少数几次图查询。 codegraph_explore是当前主工具,设计目标是一次返回相关符号的源码片段,减少后续 Read。- 它不是编译器,也不是类型检查器;跨文件解析和动态分发是 best-effort。
- 它对大仓库更有价值,对很小、结构很浅的仓库收益有限。
- 当前文档和源码有轻微漂移:README 仍写
codegraph init -i,但源码和 CHANGELOG 显示codegraph init已默认建索引,-i只是兼容旧习惯。 - CHANGELOG 里多次提到
codegraph_trace,但当前src/mcp/tools.ts暴露的 MCP 工具列表里没有它。实际使用应以当前 MCP 工具定义为准。
我的判断:
CodeGraph更像“给 AI coding agent 用的本地代码索引层”,不是替代 IDE、LSP、测试或人工 review 的工具。
它解决的真实问题
AI coding agent 理解代码时,经常走这条路径:
text
找入口
-> grep 文件名/函数名
-> 读几个文件
-> 再 grep 调用方
-> 再读文件
-> 猜调用链这个过程有几个问题:
| 问题 | 表现 |
|---|---|
| 成本高 | 每次新会话都重复 grep / Read |
| 容易漏 | 文本搜索找不到动态路由、框架约定、跨语言桥接 |
| 上下文胀 | 读了一堆旁支文件,真正要改的代码反而被挤掉 |
| 结果不稳定 | 同一个问题,不同 agent 会探索出不同文件 |
| 影响范围难算 | 改一个符号前,很难稳定知道谁依赖它 |
CodeGraph 的解法是先把源码转成图:
text
source files
-> tree-sitter extract
-> unresolved references
-> resolver
-> SQLite graph
-> CLI / MCP tools
-> agent queryAI 不再从空白文件系统开始搜索,而是先问图。
README 给出的 benchmark 结论是:在 7 个真实开源项目上,平均 16% cheaper、47% fewer tokens、22% faster、58% fewer tool calls。这些数字来自项目自己的 headless agent 对比实验,不能直接当成所有仓库的保证,但能说明设计目标很明确:减少探索成本。
核心架构
仓库主要分成几层:
| 目录 | 作用 |
|---|---|
src/bin | CLI 入口,包含 init / index / sync / status / serve / install 等命令 |
src/index.ts | CodeGraph 主类,串起 DB、抽取、解析、图查询、watcher |
src/db | SQLite schema、连接、查询封装 |
src/extraction | tree-sitter 抽取层,按语言生成 nodes / edges / unresolved refs |
src/resolution | 跨文件引用解析、框架解析、动态关系补边 |
src/graph | BFS / DFS、callers / callees / impact 等图遍历 |
src/mcp | MCP server、daemon/proxy、tool 定义和输出策略 |
src/sync | 文件 watcher、增量 sync、git hook fallback |
src/installer | 写入 Claude / Codex / Cursor / Gemini 等 agent 配置 |
1. CLI:项目入口
src/bin/codegraph.ts 是 CLI 入口。核心命令包括:
| 命令 | 作用 |
|---|---|
codegraph install | 给各类 agent 写 MCP 配置 |
codegraph init [path] | 初始化 .codegraph/ 并默认建立索引 |
codegraph index [path] | 全量重建索引 |
codegraph sync [path] | 增量同步变更 |
codegraph status [path] | 查看索引状态、统计、过期提示 |
codegraph serve --mcp | 作为 MCP server 启动 |
codegraph callers / callees / impact | CLI 侧调用图查询 |
codegraph affected | 根据变更文件追踪受影响测试 |
codegraph upgrade | 按安装方式升级 CodeGraph |
这里有一个文档漂移点:
bash
codegraph init -iREADME 仍推荐这个命令,但源码里 -i 已标注为 deprecated,init 默认会建索引。旧写法还能用,只是不再必要。
2. DB:SQLite 是事实层
src/db/schema.sql 定义了核心表:
| 表 | 内容 |
|---|---|
nodes | 文件、类、函数、方法、变量、路由、组件等符号 |
edges | contains、calls、imports、extends、implements、references 等关系 |
files | 文件路径、hash、语言、大小、索引时间、错误 |
unresolved_refs | 抽取阶段暂时无法解析的引用 |
nodes_fts | FTS5 全文索引,支持快速符号搜索 |
project_metadata | 索引版本、抽取版本等元信息 |
DB 层使用 Node 内置 node:sqlite,并启用:
journal_mode = WALforeign_keys = ONbusy_timeout = 5000cache_sizemmap_sizeFTS5
这说明它不是把一堆 JSON 文件塞进 .codegraph/,而是认真把图查询性能和并发读写当成核心问题处理。
3. Extraction:先抽符号,不急着解析所有引用
src/extraction/index.ts 负责扫描项目文件。
扫描策略:
- 优先用
git ls-files找 tracked + untracked 文件。 - 尊重
.gitignore。 - 默认忽略
node_modules、dist、build、.venv、target、Pods等依赖和构建目录。 - 非 git 项目 fallback 到文件系统递归扫描。
- 单文件超过 1 MB 会跳过,避免大 bundle / 生成物拖垮 WASM。
解析策略:
- 用
web-tree-sitter。 - 按项目实际语言懒加载 grammar。
- 解析放进 worker thread。
- 单文件 parse 有 10 秒超时。
- 每解析 250 个文件回收 worker,避免 WASM 线性内存只涨不降。
支持语言来自 src/types.ts 和 src/extraction/grammars.ts,包括:
- TypeScript / JavaScript / TSX / JSX
- Python / Go / Rust / Java / C / C++ / C#
- PHP / Ruby / Swift / Kotlin / Dart
- Svelte / Vue / Liquid / Razor
- Pascal / Scala / Lua / Luau / Objective-C
- YAML / Twig / XML / properties 等文件级或配置型支持
抽取阶段输出三类东西:
text
nodes
edges
unresolvedReferences这点很关键:它不是一边 parse 一边硬猜跨文件引用,而是先把本文件能确定的结构取出来,再交给 resolver 做跨文件解析。
4. Resolution:把 unresolved refs 变成跨文件边
src/resolution/index.ts 是跨文件解析核心。
它会结合多种策略:
- import / export 解析
- 同语言家族匹配
- qualified name 匹配
- tsconfig / jsconfig path alias
- go.mod module path
- workspace package 信息
- 框架 resolver
- callback / dynamic-dispatch synthesizer
- LRU cache 控制内存
这里的价值在于:静态 AST 只能看到“这里有个名字”,但不能天然知道这个名字来自哪个文件。resolver 把这些引用尽量连成真实依赖边。
它也承认边界:动态分发、反射、DI、运行时注册,不可能完全静态还原。所以 CodeGraph 的结果应作为高质量索引和影响面提示,不应替代测试。
5. Framework resolver:补足框架约定
仓库里有大量框架 resolver,例如:
- React / Vue / Svelte
- Express / NestJS
- Django / Flask / FastAPI
- Laravel / Drupal
- Go / Rust / Java / Ruby / Swift / C# 相关框架
- React Native / Expo / Swift-ObjC bridge
这些 resolver 解决的是普通 AST 看不到的关系。
例如:
- 路由文件里的 URL 和 handler。
- React Native JS 调 native module。
- Swift 和 Objective-C bridge。
- SvelteKit 页面和 server load。
- Spring 配置 key 和
@Value。 - MyBatis XML mapper 和 Java mapper interface。
这也是 CodeGraph 和普通符号搜索的差别:它不只索引“这个函数在哪”,还试图把框架运行时会连起来的东西也建边。
6. Graph:调用链和影响面
src/graph/traversal.ts 提供 BFS / DFS。
常用能力:
| 能力 | 关系 |
|---|---|
| callers | incoming calls / references / imports |
| callees | outgoing calls / references / imports |
| impact | 反向追踪依赖者 |
| type hierarchy | extends / implements |
| usages | 所有引用 |
| ancestors / children | contains 层级 |
实现里有不少性能细节,例如批量查 node,避免 N+1 查询。说明它已经针对大图做过实际优化,不是 demo 级遍历。
7. MCP:给 agent 用的工具层
当前 src/mcp/tools.ts 暴露的主要工具:
| MCP tool | 用途 |
|---|---|
codegraph_explore | 主工具,按自然语言或符号名返回相关源码 |
codegraph_search | 搜符号位置,不返回源码 |
codegraph_node | 查一个符号详情,可带源码和 callers/callees trail |
codegraph_callers | 查谁调用它 |
codegraph_callees | 查它调用谁 |
codegraph_impact | 查改它影响谁 |
codegraph_files | 查索引里的文件树 |
codegraph_status | 查索引状态、语言、pending sync |
最重要的是 codegraph_explore。
它不是简单返回搜索结果,而是做了很多输出控制:
- 根据项目大小设置 explore budget。
- 返回相关文件的真实源码片段。
- 行号和 Read 工具保持一致。
- 小仓库更克制,大仓库允许多次 explore。
- 避免把测试、图标、i18n、生成代码排到前面。
- 对多态 sibling 做 skeleton,只保留签名,避免一堆同形实现撑爆上下文。
- 尽量不截断半个方法。
- 对已经返回源码的文件提示 agent 不要再 Read。
这套输出策略说明作者真正优化的是 agent 行为,而不只是提供查询 API。
8. Daemon / watcher:减少多 agent 重复成本
src/mcp/index.ts 里有三种运行模式:
| 模式 | 作用 |
|---|---|
| Direct | 单进程给单个 MCP client 服务 |
| Proxy | client 连接到共享 daemon |
| Daemon | 后台进程共享一个 CodeGraph、watcher、SQLite handle |
这样多个 agent / 多个窗口在同一个项目里不会各自启动一套 tree-sitter、watcher、SQLite 连接。
文件新鲜度靠两层:
- watcher 监听源码变更,默认 debounce 约 2 秒后 sync。
- MCP 响应里会提示 pending sync 文件,避免 agent 用过期索引误判。
watcher 也做了平台差异处理:
- macOS / Windows 用单个 recursive
fs.watch。 - Linux 按目录 watch,不按文件 watch。
- watcher 不可用时,可安装 git hook,在 commit / merge / checkout 后后台跑
codegraph sync。
日常使用方式
最小路径:
bash
codegraph install
cd your-project
codegraph init如果只想 CLI 查询:
bash
codegraph status
codegraph query AuthService
codegraph callers login
codegraph impact User如果走 MCP,agent 应优先这样问:
text
用 codegraph_explore 看 AuthService login session flow。
先不要读文件。而不是:
text
grep AuthService,然后读相关文件。更适合的场景
CodeGraph 适合:
- 大仓库 onboarding。
- 接手陌生模块。
- 改共享函数前看影响面。
- 找调用链、路由链、框架 handler。
- 多语言项目,例如 React Native / Expo / Swift / ObjC。
- 长期项目里让多个 AI agent 使用同一套本地索引。
- CI 或脚本里用
codegraph affected粗筛受影响测试。
不太适合:
- 三五个文件的小项目。
- 没初始化
.codegraph/的一次性临时目录。 - 需要 100% 精确类型推导的场景。
- 高度动态语言运行时行为。
- 秘密配置值排查。它现在会避免主动暴露配置值,但真正需要值时仍应人工读文件。
和 grep / LSP / 测试的关系
| 工具 | 角色 |
|---|---|
| grep / rg | 文本事实确认,适合找字符串 |
| LSP | 当前编辑器语义,适合跳转、补全、类型错误 |
| CodeGraph | 跨文件图索引,适合给 agent 做结构化探索 |
| 测试 / typecheck | 正确性验证 |
不要把 CodeGraph 当测试。它回答的是“可能相关、结构上相关、静态图上相关”,不是“这次改动一定正确”。
更合理的链路是:
text
codegraph_explore 找实现
-> codegraph_impact 看影响面
-> 修改代码
-> test / typecheck 验证落地建议
如果在日常 AI coding 里使用,我会这样定规则:
- 问架构、流程、入口,先用
codegraph_explore。 - 只找位置,用
codegraph_search。 - 查单个函数完整实现,用
codegraph_node includeCode=true。 - 改共享符号前,用
codegraph_impact。 - 看到 pending sync,先读提示里的具体文件,不要全盘否定索引。
- 遇到动态框架、反射、DI,保留人工判断和测试验证。
项目级建议:
- 初始化后把
.codegraph/加入忽略,不提交索引数据库。 - 升级 CodeGraph 后重建索引,避免旧 extraction version 影响新能力。
- 大仓库优先保持 watcher 可用;watcher 不可用时考虑 git hook fallback。
- 对 agent 规则写清楚:CodeGraph 是首选探索入口,但不是验证工具。
边界和风险
1. 索引不是实时真相
watcher 有 debounce。刚编辑完文件时,索引可能落后一两秒。MCP 响应会标 pending 文件,但 agent 必须看懂并处理这个提示。
2. 静态解析不等于运行时
resolver 已经覆盖很多框架和动态分发模式,但仍不可能覆盖所有运行时行为。特别是反射、字符串拼接路由、容器注入、运行时 monkey patch,都可能漏边。
3. 输出策略会影响 agent 行为
codegraph_explore 会为了省上下文裁剪文件、压缩 sibling、跳过低价值文件。这通常是好事,但也意味着如果问题本身就是测试、i18n、生成代码,就要在 query 里明确说出来。
4. 文档和源码存在漂移
当前读到的两个漂移:
- README 仍写
codegraph init -i,源码显示init默认索引。 - CHANGELOG 提到
codegraph_trace,当前 MCP tool list 未暴露该工具。
落地时优先以当前源码和 codegraph --help / tools/list 为准。