给 AI 一张代码地图:CodeGraph 为什么能少翻文件
我让 AI 改代码时,经常看到一个熟悉流程。
它先 rg 一下。
打开几个文件。
发现函数又跳到另一个文件。
再搜。
再读。
最后它还没开始解决问题,已经花了一堆工具调用在找路。
如果项目很小,这没什么。一个 grep,两三个文件,马上就能摸到主线。但项目稍微大一点,问题就出来了:AI 不知道这套代码以前怎么长出来的,也没有你脑子里的项目地图。它只能一页页翻。
CodeGraph 治的就是这个问题。
它更像一个本地代码知识图谱工具,再通过 MCP 接给 Claude Code、Codex、Cursor、Gemini 这类 coding agent。
这篇文章要拆的是它背后的一个思路:别让 AI 每次临时找路,先给它一张地图。
1. 先承认问题:AI 找代码太慢
你可以想象一个很普通的问题:
这个请求最后是怎么写进数据库的?
没有 CodeGraph 时,AI 通常会这样走:
找 route
找 controller
找 service
找 repository
找 ORM 调用
再回来拼调用链
这些动作人也会做。区别是,人往往知道项目里哪几个目录最可能有答案,AI 没有这个长期记忆,只能靠 grep、glob、Read 慢慢摸。
CodeGraph 的判断很简单:既然很多问题都要先摸清结构,那就不要每次都重新摸。
它会在项目里创建本地 .codegraph/,把代码里的 symbol、文件、调用关系、引用关系存进 SQLite。等 Agent 想理解结构时,先问 codegraph_explore,再决定要不要打开文件。
它没有让 AI 突然更聪明。它只是让 AI 少走冤枉路。
2. CodeGraph 是什么:本地代码图谱 + 一个主入口
CodeGraph 的定位可以先说得很朴素:
先把代码结构算出来,再让 AI 查这张结构图。
它和普通全文搜索不一样。
普通搜索只告诉你“这个词在哪些文件里出现过”。CodeGraph 想回答的是“这些代码之间怎么连起来”。
作为 MCP server 时,它默认重点暴露一个工具:
codegraph_explore
你问:
How does a request reach the database?
它会尽量返回三类东西:
- 相关 symbol 的源码,而且带行号。
- 这些 symbol 之间的调用路径。
- 改这里可能影响哪些地方,也就是 blast radius。
这个设计挺有意思。
很多工具喜欢把能力拆成一排按钮:search、node、callers、callees、impact、files。CodeGraph 里面这些能力也有,但默认先把 codegraph_explore 推到前面。
因为 Agent 面对太多工具时,经常会选错。一个主入口,反而更容易用对。
3. 它怎么实现:先解析,再存图,最后给 Agent 查
看源码时,我会把 CodeGraph 拆成五层。
第一层,扫描项目文件。
src/extraction/index.ts 里有 ExtractionOrchestrator。它会判断哪些文件该解析,跳过依赖目录、构建目录、缓存目录和太大的文件。
第二层,用 tree-sitter 解析源码。
这一步不是正则扫文本。tree-sitter 会把源码解析成 AST。不同语言有不同的 grammar 和 extractor,用来找函数、类、方法、import、调用等结构。
第三层,把结果写进 SQLite。
数据库 schema 在:
src/db/schema.sql
里面有几张核心表:
nodes
edges
files
unresolved_refs
nodes_fts
nodes 存函数、类、方法这些 symbol。
edges 存关系,比如调用、引用、继承、包含。
files 存文件路径、hash、语言和索引时间。
unresolved_refs 存一开始还没解析出来的引用,后面再做 resolution。
nodes_fts 是 SQLite FTS5 全文搜索,用来快速搜 symbol 名、签名和 docstring。
第四层,做引用解析。
光知道“这里调用了 foo”还不够。项目里可能有多个 foo。CodeGraph 后面还要做 resolution,把调用、import、继承、框架里的特殊连接尽量连到真实定义上。
第五层,通过 MCP 给 Agent 用。
src/mcp/server-instructions.ts 里写了给 Agent 的说明:结构性问题先用 codegraph_explore,不要先 grep,也不要把探索任务丢给另一个只会读文件的 sub-agent。
这一步很关键。工具做得再好,AI 不用也没用。CodeGraph 不只提供工具,还试图改掉 Agent 的默认动作:先问图,再翻文件。

4. 怎么装、怎么用
如果你只是想试,可以把仓库地址给 AI:
https://github.com/colbymchenry/codegraph
然后说:
帮我安装 CodeGraph,并把它接到当前 AI coding agent。然后在当前项目里初始化索引。
按 CodeGraph README 的流程,它分三步:
安装 CLI
codegraph install
codegraph init
这里要分清楚两个动作。
codegraph install 是把 CodeGraph 接到 Agent。它会配置 MCP server,让 Agent 知道有这个工具。
codegraph init 是给当前项目建图。它会创建 .codegraph/,再扫描这个项目的源码。
这两个不能混在一起。只装 CLI,不代表当前项目已经有图;只初始化项目,也不代表你的 Agent 已经会调用 MCP。
如果你让 AI 帮你装,最好直接说清楚:
请完成两件事:
1. 安装并配置 CodeGraph 到当前 Agent。
2. 在当前项目运行 codegraph init,生成 .codegraph 索引。
装完以后,可以先让 Agent 问一个结构问题,比如:
用 CodeGraph 看一下登录请求从 route 到数据库大概经过哪些函数。
如果它第一反应还是 grep,那说明 MCP 或 instructions 没生效,先别急着怪 CodeGraph。
5. 公开反馈:好处明显,坑也具体
我去找了公开反馈。X 和中文社区里能搜到一些转发、介绍和安装笔记,但稳定可打开、细节足够的一手长反馈不多。更有价值的反馈主要在 README benchmark、英文测评文章和 GitHub issues 里。
先看正面。
CodeGraph README benchmark 里拿 7 个开源项目做对比,包括 VS Code、Excalidraw、Django、Tokio、OkHttp、Gin、Alamofire。项目自己的结论是:平均 58% 更少工具调用、22% 更快,file reads 接近 0。
这个数字不能当成所有项目都会这样。README 自己也提醒,成本节省和项目规模有关。小项目里,原生 grep 和 Read 本来就便宜,收益不会那么夸张。
第三方测评更关心“少走弯路”。Andrew 的 CodeGraph review 把它看成 AST + SQLite 的本地代码图谱;Tosea 的安装指南 也把重点放在少 grep、少打开文件、少做发现工作上。它们的判断和我看源码后的感觉是一致的:CodeGraph 没有让 AI 变聪明,它只是把“找代码”这一步提前做了。
本地化也是加分项。它不需要向量数据库,不需要 embedding API,也不需要把代码传到云端。图存在本地 .codegraph/ 和 SQLite 里。对公司项目来说,这比再接一个云端知识库更容易接受。
但负面反馈也很具体。
GitHub issue #1080 提到过一个很典型的问题:在 Codex 里,v1.16 之后频繁调用 codegraph_explore,小任务反而变慢。这说明“默认先查图”也有成本。项目小、问题小、答案就在当前文件里,直接读文件可能更快。
索引性能也不是永远顺滑。GitHub issue #1014 里有用户记录了 Windows 上远程 macOS SMB 共享盘导致索引很慢、MCP 卡住的问题;GitHub issue #1231 里,Windows + 机械硬盘上的索引也明显变慢,还触发了错误的 timeout。
Codex 接入也出过体验问题。GitHub issue #1227 里,第一次 codegraph_explore 等了大约 45 秒,然后返回 busy。工具本来是为了省时间,第一次调用先卡住,这种体验很伤。
准确性也不能当成绝对。GitHub issue #1187 里,Java/Spring 的 caller 结果漏掉了一批字段注入场景;GitHub issue #1259 里,Go 代码的普通 cache.Put("a", 1) 被识别成了 HTTP route。
还有一个对中文读者很相关的问题。GitHub PR #1262 提到,codegraph_explore 对纯中文、日文、韩文 symbol 查询会返回 “No relevant code found”,但 codegraph query 和 codegraph node 能找到同一个 symbol。这个问题已经有修复 PR,但它提醒我们:如果你的代码库里有中文类名、中文路径或中文业务名,要先试一下。
这些反馈放在一起看,我会把 CodeGraph 定位成“减少探索成本的代码地图”,而不是“永远正确的代码理解器”。
它最好的用法,是让 AI 少翻文件;不是让 AI 不读源码。
6. 它最值得学的两个设计
第一个设计,是只推一个主入口。
CodeGraph 内部其实有很多 CLI 命令:
codegraph query
codegraph node
codegraph callers
codegraph callees
codegraph impact
codegraph files
codegraph affected
但 MCP 默认重点推 codegraph_explore。这不是偷懒,是对 Agent 行为的判断。
如果你把十个工具都摆在模型面前,它可能先试一个不合适的,再换另一个,最后还是回到 grep。一个强入口,反而能减少选择错误。
第二个设计,是承认索引会过期。
代码图谱有一个天然问题:代码会变。
如果 Agent 刚改了文件,图里的内容还没更新,下一次查询就可能拿到旧结果。
CodeGraph 对这个问题写了几层保护。README 里提到 auto-sync:MCP server 会监听项目文件变化,做增量更新。更关键的是 staleness banner:如果返回结果引用了还没同步完的文件,工具会提醒 Agent 直接 Read 这些文件。
这点很朴素,也很管用。
任何缓存系统都会遇到“旧数据”问题。好工具不会假装缓存永远新鲜,它要告诉你哪里可能旧。
7. 如果自己实现一套,大概要怎么做
如果要自己做一个简化版 CodeGraph,不要一上来就支持三十种语言。
先做一个很小的版本。
比如只支持 TypeScript,一个项目,一种查询。
适用场景:
让 AI 快速理解一个代码库里的函数、调用关系和影响范围。
触发条件:
用户问“X 怎么工作”“X 调用了谁”“改 X 会影响哪里”。
输入:
项目路径、自然语言问题、函数名或文件名。
输出:
相关源码片段、调用关系、可能影响的文件。
工作流:
1. 扫描 src/ 下的 .ts 文件。
2. 用 tree-sitter 或 TypeScript compiler API 解析 AST。
3. 提取 function、class、method、import、call expression。
4. 存到 SQLite:nodes、edges、files 三张表先够用。
5. 查询时先搜 symbol,再沿 edges 找 callers/callees。
6. 把源码片段和关系整理成 Agent 能直接读的文本。
关键约束:
- 所有索引保存在本地。
- 返回源码要带行号。
- 修改文件后要提示索引可能过期。
- 解析不到的关系要标成 best-effort,不要装成绝对正确。
可选工具:
- tree-sitter。
- SQLite + FTS5。
- MCP server。
- 文件 watcher。
最小版可以没有 MCP。
先做一个 CLI:
code-map init
code-map ask "login 之后怎么写 session"
等 CLI 能稳定返回“相关源码 + 调用链”,再把它包成 MCP 工具给 Agent 用。这样比较稳。

8. 我的判断:它是地图,不是判官
CodeGraph 最有价值的地方,不是支持了多少语言。
我更看重它的三个取舍。
第一,它把代码结构预先算出来,而不是让 AI 每次临时翻文件。
第二,它默认推一个主工具 codegraph_explore,让 Agent 更容易走对路径。
第三,它承认索引会过期,也承认解析是 best-effort。
这三个取舍,比“又多了一个 MCP 工具”更重要。
但它不是编译器,也不是测试。它能帮 AI 找上下文,不能证明代码正确。
所以我会这样看它:CodeGraph 是地图,不是判官。
地图能让你少迷路,但不能替你判断业务逻辑对不对。
如果你只是想用,把 https://github.com/colbymchenry/codegraph 给 AI,让它帮你安装、配置 Agent,并在目标项目运行 codegraph init。
如果你想学着写,先别想着做全语言、全框架、全场景。先做一个很小的代码地图:节点、边、文件、一个查询入口。只要 AI 能少打开几个文件,这个工具就已经有价值。


