← 查看文章

Agent 工具

给 AI 一张代码地图:CodeGraph 为什么能少翻文件

深拆 colbymchenry/codegraph:它把代码结构提前建成图,再通过 MCP 给 Agent 用。

给 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 没有这个长期记忆,只能靠 grepglobRead 慢慢摸。

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 的默认动作:先问图,再翻文件。

CodeGraph 的技术实现:扫描文件,用 tree-sitter 提取 symbol 和 edge,写入 SQLite,再通过 MCP 的 codegraph_explore 返回源码、调用路径和影响范围

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 自己也提醒,成本节省和项目规模有关。小项目里,原生 grepRead 本来就便宜,收益不会那么夸张。

第三方测评更关心“少走弯路”。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 querycodegraph 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 用。这样比较稳。

如果自己实现一个简化版 CodeGraph,可以先做单语言、三张表、一个查询入口,再逐步加 MCP、watcher 和影响分析

8. 我的判断:它是地图,不是判官

CodeGraph 最有价值的地方,不是支持了多少语言。

我更看重它的三个取舍。

第一,它把代码结构预先算出来,而不是让 AI 每次临时翻文件。

第二,它默认推一个主工具 codegraph_explore,让 Agent 更容易走对路径。

第三,它承认索引会过期,也承认解析是 best-effort。

这三个取舍,比“又多了一个 MCP 工具”更重要。

但它不是编译器,也不是测试。它能帮 AI 找上下文,不能证明代码正确。

所以我会这样看它:CodeGraph 是地图,不是判官。

地图能让你少迷路,但不能替你判断业务逻辑对不对。

如果你只是想用,把 https://github.com/colbymchenry/codegraph 给 AI,让它帮你安装、配置 Agent,并在目标项目运行 codegraph init

如果你想学着写,先别想着做全语言、全框架、全场景。先做一个很小的代码地图:节点、边、文件、一个查询入口。只要 AI 能少打开几个文件,这个工具就已经有价值。