
CodeGraph 是什么?
一句话:CodeGraph 是一个本地运行的代码知识图谱工具——它把你整个代码库解析成符号关系图存在本地 SQLite 里,再通过 MCP 协议让 Claude Code 这类 AI 编程助手"像查 IDE 一样"秒速理解项目。
为了让定义不抽象,先把"是什么"和"不是什么"拆开讲:
| 维度 | 它是 | 它不是 |
|---|---|---|
| 形态 | 一个 npm 包 @colbymchenry/codegraph | SaaS、云服务、IDE 插件 |
| 运行位置 | 你的本地电脑,作为后台 stdio 子进程 | 远程服务器 |
| 数据存储 | 项目下的 .codegraph/codegraph.db(SQLite) | 上传到云端 |
| 使用者 | Claude Code 等支持 MCP 的 AI 客户端 | 给人类直接看的可视化工具 |
| 核心能力 | 提供 8 个语义化查询工具:搜符号、查调用、看影响、构建上下文…… | AI 模型,本身不生成代码 |
| 依赖 | 只要 Node 18–24,零网络、零 API key | OpenAI 或任何外部 API |
类比一下:IDE 的「跳转定义、查找引用」是给人用的;CodeGraph 把同样的静态索引能力以 AI 友好的接口暴露给 LLM。你装好它之后基本不会再手动打开它——Claude Code 会自动在后台调用,你只会感觉到「Claude 突然对这个项目熟悉多了」。
官方实测效果(6 个真实代码库 benchmark):
- 工具调用次数 减少 92%
- 探索速度 提升 71%
- 0 次文件 Read——Claude 完全信任 CodeGraph 返回的结果
下面这篇文章会按以下顺序展开:从「为什么需要它」起步,依次讲清楚它的架构、工作原理、安装方式,以及它与 Claude Code 的具体交互方式。
为什么需要 CodeGraph
当 Claude Code(或任何 LLM 编程助手)面对一个陌生代码库被要求"实现用户认证"或"修复登录 bug"时,它的标准动作是派出 Explore agent,用 grep、glob、find、Read 在文件系统里盲扫——一遍遍读文件、找符号、追调用、回退、再扫。每一次工具调用都消耗 token、消耗时间,而其中绝大部分操作不过是在重建一个 IDE 早已具备的"项目索引"。
CodeGraph 的核心洞察非常朴素:
既然 IDE 通过静态索引就能秒级跳转定义、查找引用、构建调用图,那 AI 助手也应该有同样的预计算索引,而不是把每次提问都当作冷启动。
它做的事情可以用一句话概括——用 tree-sitter 把整个代码库解析为符号-边构成的知识图谱,存入本地 SQLite,再通过 MCP 协议把这个图谱的查询能力以一组结构化工具暴露给 AI。结果是:
| 指标 | 没有 CodeGraph | 有 CodeGraph | 提升 |
|---|---|---|---|
| VS Code (TypeScript, 4002 文件) | 52 次工具调用,1m 37s | 3 次调用,17s | 94% / 82% |
| Swift Compiler (Swift+C++, 25874 文件) | 37 次调用,2m 8s | 6 次调用,35s | 84% / 73% |
| Excalidraw | 47 次调用,1m 45s | 3 次调用,29s | 94% / 72% |
这不是"AI 加速器"那种营销话术,而是把已经在 IDE 里被实践了几十年的静态索引技术,重新打包成 LLM 时代的一等公民。
系统架构
CodeGraph 的设计哲学有四条贯穿始终的红线:
- Local-first:数据永远不离开机器,没有 API key、没有外部服务,只有项目根目录下的
.codegraph/文件夹。 - Headless library:CodeGraph 本身没有 UI,纯粹是一个 Node.js 库 + CLI + MCP server 的组合,可独立运行、可被嵌入 Electron、可作为 npm 依赖被任何工具调用。
- Deterministic extraction:所有抽取出来的节点和边都来自 tree-sitter AST 的确定性遍历,不依赖 LLM 生成摘要,因此结果稳定、可重现、可审计。
- Per-project isolation:每个项目一份独立的 SQLite 数据库和配置,互不干扰,可单独删除。
整体分层如下:

核心工作流
CodeGraph 的所有功能都建立在一条贯穿的核心管线上。理解了这条管线,就理解了 CodeGraph 的全部。

#文件扫描:git 优先,文件系统兜底
优先调用 git ls-files -c --recurse-submodules 拿到项目可见文件列表。这一步带来三个隐藏好处:
- 自动遵守
.gitignore:所有层级的.gitignore规则被 git 原生兼容,不需要 CodeGraph 自己再实现一遍。 - 子模块支持:
--recurse-submodules解决了 monorepo 用子模块时主仓库索引只有 commit pointer、抽到 0 文件的著名问题(issue #147)。 - untracked 文件也被纳入:未被 git 追踪、但又不在
.gitignore里的新文件也会被git ls-files -o --exclude-standard抓到。
当项目不是 git 仓库时,scanDirectoryWalk() 会回退到递归 readdirSync,期间通过 realpath 检测符号链接循环、识别 .codegraphignore 标记文件、并按 config.exclude 的 glob 模式裁剪目录。
#多语言抽取:tree-sitter + WASM + worker 线程
CodeGraph 把所有 19+ 种语言的 grammar 编译成 WASM 后嵌入分发包。这带来两个工程性收益:
- 零 native 编译依赖:用户安装时不需要 C 工具链。
- 跨平台一致:Windows / macOS / Linux 跑同一份 WASM,行为可重现。
但 WASM 也带来一个棘手问题:WebAssembly 的线性内存只能涨不能降——tree-sitter 一旦在某个大文件上吃掉 200MB,剩余的解析任务也吃不回去。CodeGraph 的解法是把解析跑在独立 worker 线程里,每 250 个文件就把整个 worker 销毁重建一次,让 V8 isolate 连同 WASM 堆一起被 GC。
对于解析卡死的文件(典型场景:Swift 编译器测试集里 90% 是 CHECK 注释的怪异源文件),会触发三层降级:
- 超时(默认 10s)→ 重启 worker 重试
- 重启后仍失败 → 用全新 worker 再试一次
- 还失败 → 把注释行替换为空行后再试(保持行号不变以维持节点位置正确)
这种"清理-重试-降级"循环让 CodeGraph 在 25,874 文件的 Swift 编译器源码上仍能跑完。
#节点与边:22 种 NodeKind × 12 种 EdgeKind
抽取阶段把每个源文件解析为两类对象写进 SQLite:
- 节点(NodeKind):22 种,覆盖你能想到的所有代码符号——文件、类、接口、结构体、函数、方法、属性、字段、变量、常量、枚举、类型别名、命名空间、导入、导出、路由、组件……
- 边(EdgeKind):12 种,描述符号之间的关系——
contains(包含)、calls(调用)、imports(导入)、extends(继承)、implements(实现)、references(引用)、type_of(类型)、returns(返回)、instantiates(实例化)、overrides(覆盖)、decorates(装饰)。
每个节点都带有完整的位置(起止行/列)、签名、文档字符串、可见性、修饰符(async/static/abstract)、装饰器和泛型参数。节点的 id 是「文件路径 + 限定名」的哈希,保证跨索引会话稳定可比。
#引用解析:三层策略
抽取阶段会留下一批"暂时无法解析"的引用——比如 foo() 是哪个 foo?import { Bar } 中的 Bar 来自哪个文件?这些被批量写入 unresolved_refs 表,全索引完成后由 ReferenceResolver 统一处理。解析策略按优先级有三层:
- 框架识别(
src/resolution/frameworks/):自动识别 13 个框架——React、Express、Django、FastAPI、Laravel、Rails、Spring、Go (Gin/chi/gorilla/mux)、Axum/actix/Rocket、ASP.NET、Vapor、SvelteKit、Vue/Nuxt。识别后会注入对应的route节点和references边,把 URL 模式直接连到 handler。 - 导入解析(
import-resolver.ts):基于已经入库的import节点和re-export链,按文件路径推导符号定义位置。支持 tsconfig/jsconfig 的paths别名。 - 名字匹配(
name-matcher.ts):当前两种都失败时回退到限定名/全局名匹配,配合内置的 stdlib 黑名单(JS built-ins、Python built-ins、Go stdlib 等)排除噪音。
解析时大量使用了缓存(nodeCache、fileCache、importMappingCache、reExportCache),并支持分批解析以避免大代码库 OOM——典型场景下解析十几万条 unresolved refs 的内存峰值能控制在 1GB 以内。
#增量同步:git status 快路径
文件改动后不需要重建整个索引。sync() 优先调用 git status --porcelain --no-renames,只拿到 modified / added / deleted 三个名单,然后:
- deleted:直接从 DB 删(
ON DELETE CASCADE级联清理 edges 和 unresolved_refs)。 - modified:算 SHA-256 哈希对比
files.content_hash,没变就跳过,变了就重新抽取。 - added:直接抽取入库。
由于解析范围被收窄到"git 实际改动的那几个文件",typical 单文件保存触发的增量同步通常在 50ms 内完成。无 git 仓库时回退到全量扫描,性能会差一些但功能正常。
#文件监听:原生 OS 事件 + 2 秒防抖
FileWatcher 用 fs.watch({ recursive: true })——背后是 macOS FSEvents、Windows ReadDirectoryChangesW、Linux inotify(Node 19+)。事件经过两层过滤:
- 忽略
.codegraph/内部写操作(避免自反馈循环)。 shouldIncludeFile()按 include/exclude 模式过滤。
之后用 2 秒滑动防抖窗口聚合多次保存,最后调用 sync()。这意味着你在编辑器里疯狂保存 10 次,CodeGraph 也只会在最后一次保存后 2 秒触发一次同步。
#上下文构建:5 步混合搜索
ContextBuilder.findRelevantContext() 是整个系统最精巧的部分。给定一个自然语言查询(例如 "how does collaborative editing work"),它会按如下顺序构建一个最相关子图:
- 符号抽取:用 6 种正则模式(CamelCase / snake_case / SCREAMING_SNAKE / ALL_CAPS / dot.notation / 普通小写词)从 query 中识别可能的代码符号,并用一份精心整理的"英文常用词黑名单"过滤掉
the/and/flow/level这类噪声。 - 精确匹配:对抽取出的符号在
nodes.name上做精确查询,命中后给"同一文件下多个符号同时命中"额外加分(co-location boost),因为这通常意味着用户找的就是那个文件。 - 前缀 / 词干匹配:把符号 title-case 后查找以它开头的类/接口名(比如 query 写了 "REST" 会匹到
RestController),并通过getStemVariants把 "caching" → "cache" 拓展。 - FTS5 全文搜索:对查询词单独走 FTS5 索引,对命中多个查询词的节点给"multi-term hit"加分。
- CamelCase 边界与复合匹配:用 LIKE 查询找出名字内部包含查询词的类(如
TransportSearchAction内部的Search),按多词共现做指数级加分。
得到搜索结果后再做三件事:
- 测试文件降权(除非 query 本身是 "test/spec")
- per-file diversity cap:任何一个文件最多占 20% 节点预算
- import/export 解引用:搜到
import { TerminalPanel }会自动追到TerminalPanel类定义本身
最后从这些 entry points 出发做 traverseBFS,遍历优先 contains > calls > 其它边,并自动展开类型层级(找父类、子类、兄弟类),构建出一个最多 maxNodes 节点的最小相关子图。buildContext() 在此基础上抽取 code blocks 并按 Markdown 或 JSON 格式输出。
关键功能

#8 个 MCP 工具——给 LLM 的"代码 API"
| 工具 | 作用 |
|---|---|
codegraph_search | 按名字快速查符号(只返回位置) |
codegraph_context | 主力工具:给一个任务描述,返回完整上下文 |
codegraph_callers | 谁调用了 X |
codegraph_callees | X 调用了谁 |
codegraph_impact | 改 X 会影响哪些代码 |
codegraph_node | 单个符号详情(可选包含源码) |
codegraph_explore | 深度探索:一次返回多文件源码 + 关系图 |
codegraph_status | 索引健康度与统计 |
codegraph_files | 项目文件树(比 Glob 快) |
codegraph_explore 尤其值得注意:它会根据项目大小自动调整探索预算——500 文件以下只用 1 次调用,2 万 5 千文件以上最多 5 次。tool description 里还直接教 LLM 怎么写好 query:「Bad: 'how are agent prompts loaded' / Good: 'readAgentsFromDirectory createClaudeSession agents.ts'」——这个 prompt engineering 细节正是 benchmark 数据漂亮的关键。
#框架感知的路由识别
CodeGraph 不只是抽 AST,它能识别 web 框架的路由约定,并把 URL 模式作为一等公民的 route 节点纳入图谱:
| 框架 | 识别形式 |
|---|---|
| Django | path()、re_path()、url(),CBV .as_view(),dotted path |
| Flask / FastAPI | @app.route() / @router.get() |
| Express | app.get()、router.post() 含中间件链 |
| Laravel | Route::get()、Route::resource()、Controller@action |
| Rails | get '/x', to: 'users#index' |
| Spring | @GetMapping、@RequestMapping |
| Go (gin/chi/mux) | r.GET()、router.HandleFunc() |
| Rust (axum/actix/Rocket) | .route("/x", get(handler)) |
| ASP.NET | [HttpGet("/x")] |
| Vapor | app.get("x", use: handler) |
| SvelteKit / Vue/Nuxt | 基于文件名约定的页面/API 路由 |
这让你问 LLM "这个 URL 哪个 controller 处理" 时,它能一步走到正确文件。
#codegraph affected —— 给 CI 用的 test impact analysis
git diff --name-only | codegraph affected --stdin --quiet这条命令传递性追踪 import 依赖,从改动文件出发反向找出受影响的测试文件。配 CI hook 用就是一个本地版的 [Nx affected]:
#!/usr/bin/env bashAFFECTED=$(git diff --name-only HEAD | codegraph affected --stdin --quiet)if [ -n "$AFFECTED" ]; then npx vitest run $AFFECTEDfi#双 SQLite 后端 + 性能可观测性

CodeGraph 把 better-sqlite3(native)声明为 optionalDependencies,并自带 node-sqlite3-wasm 作为回退后端。当 native 模块装不上(缺 C 工具链、Node 升级后 ABI 不匹配)时自动切到 WASM——但 WASM 慢 5-10 倍且使用让 writer 阻塞 reader 的 journal mode。CodeGraph 在 codegraph status 命令里直接告诉你当前用的是哪一个,并附上修复 recipe:
Backend: wasm ← 慢路径xcode-select --install # macOSsudo apt install build-essential python3 make # Linuxnpm rebuild better-sqlite3这种"不假装正常、显式暴露降级状态"的工程纪律在开发者工具里很罕见、也很好用。
#文件锁 + 进程内互斥
CodeGraph 实例同时持有两把锁:
indexMutex:进程内 mutex,防止同一个 CodeGraph 实例并发索引。fileLock:.codegraph/codegraph.lock文件锁,防止 CLI、MCP server、git hook 三个进程同时写 DB。
这是为什么你可以在 MCP server 正在自动 sync 时手动运行 codegraph index 而不损坏数据库——它会显式失败并报告"另一个进程正在索引"。
安装与使用
CodeGraph 的安装策略分两层:机器级别一次性配置和项目级别按需初始化。
#一键交互安装
npx @colbymchenry/codegraph交互式 installer(基于 @clack/prompts)会引导你完成:
- 全局安装
@colbymchenry/codegraph(MCP server 需要全局命令)。 - 配置 MCP server:写入
~/.claude.json或当前项目的.claude.json。 - 设置自动允许权限:把
mcp__codegraph__*系列工具加入~/.claude/settings.json的 allow 列表,免去每次工具调用都弹权限确认。 - 写入全局 CLAUDE.md 指令:告诉 Claude Code 在
.codegraph/存在时优先用 MCP 工具,不存在时主动询问用户是否初始化。 - 可选:立即在当前目录运行
codegraph init。
#手动安装(适合 CI/不喜欢交互的场景)

npm install -g @colbymchenry/codegraph~/.claude.json 加上:
{"mcpServers":{"codegraph":{"type":"stdio","command":"codegraph","args":["serve","--mcp"]}}}如果不想每次工具调用都弹权限确认,在 ~/.claude/settings.json 的 permissions.allow 数组里加入所有 mcp__codegraph__* 工具即可(或直接用交互式 installer 自动处理)。
#项目初始化
cd your-projectcodegraph init -i # -i 表示初始化后立即跑一次全量索引初始化会创建:
your-project/└── .codegraph/ ├── config.json # 配置(include/exclude/maxFileSize ...) ├── codegraph.db # 主数据库(SQLite) └── codegraph.lock # 跨进程文件锁之后只要在 Claude Code 里打开这个项目,MCP server 会自动检测到 .codegraph/ 并加载,无需重启。

Coding Agent 如何使用 CodeGraph 获取项目代码信息
一个关键的问题:Claude Code(或任何 coding agent)实际在跑任务时,是怎么通过 CodeGraph 把代码信息"喂"进自己的推理链路的? 这一节把整个交互链路拆开看。
#通信链路:MCP 子进程 + stdio JSON-RPC
整个交互发生在 AI 客户端和 CodeGraph 的一个本地 stdio 子进程之间,没有任何网络流量:
Claude Code 主进程 ←——— JSON-RPC over stdio ———→ codegraph MCP 子进程 │ ▼ .codegraph/codegraph.db启动时 MCP 服务端会像 git 找 .git 一样向上查找最近的 .codegraph/ 目录,找到就打开并启动文件监听。几个让体验顺滑的细节:
- 延迟初始化:服务端先开始监听消息再尝试打开数据库。如果项目还没 init,也不会退出——每次工具调用都会重试一次。你在 IDE 里现场跑
codegraph init之后不需要重启 MCP server。 - 自动监听:启动时就开启了 2 秒防抖的文件监听;每次同步完成把日志写到 stderr,不污染 JSON-RPC 通道。
- 跨项目缓存:当 AI 工具调用里传
projectPath指向另一个仓库,首次打开后会缓存连接,后续查询直接命中。 - 优雅退出:监听 stdin 关闭,父进程关闭时自动清理资源,不留孤儿进程。
#工具语义:8 个工具按意图分工
服务端在 initialize 响应里返回一段 instructions 字段,MCP 客户端会自动把它注入 agent 的 system prompt,所以 AI 一上来就知道每个工具该用在什么场景:
| AI 的意图 | 调用的工具 | 返回的数据 |
|---|---|---|
| "X 这个符号是什么?" | codegraph_search | 名字、kind、文件位置、签名(不含源码) |
| "帮我理解这个任务/功能/区域" | codegraph_context ★ 主力 | 入口符号 + 关键源码片段 + 关系总结 |
| "谁调用了 X?" | codegraph_callers | 入边 calls 列表 |
| "X 又调用了谁?" | codegraph_callees | 出边 calls 列表 |
| "改 X 会破坏什么?" | codegraph_impact | 影响半径子图(默认 depth=2) |
| "看 X 的源码/签名/docstring" | codegraph_node | 单符号详情(includeCode 默认 false) |
| "调研一个我陌生的模块/模式" | codegraph_explore ★ 深挖 | 多文件源码块 + 关系图(一次性给够) |
| "X 目录里都有什么?" | codegraph_files | 文件树(比 Glob 快) |
| "索引健康吗?" | codegraph_status | 统计 + backend(native/wasm) + lastUpdated |
每个工具调用的入口是 MCPServer.handleToolsCall → ToolHandler.execute(toolName, args),按工具名分发到对应的 CodeGraph 实例方法(searchNodes / getCallers / buildContext 等)。
#关键纪律:主会话 vs Explore subagent
这是 CodeGraph 让"工具调用次数从 50 降到 3"的真正秘诀,写在全局 CLAUDE.md 模板里:
主会话(context 寸土寸金) │ ├─ 只允许用「轻量工具」:search / callers / callees / impact / node │ ↓ 每次调用返回 < 1000 token │ ↓ 用于"编辑前的快速体检" │ └─ 探索类问题 → 派出 Explore subagent │ └─ Explore agent 在隔离的 context 里 ↓ 调用「重型工具」:context / explore ↓ 单次返回 10+ 文件源码 + 关系图(万级 token) ↓ 在 subagent 内部读完、推理完、生成总结 ↓ 只把精炼答案(~500 token)回传主会话为什么这么分?因为 codegraph_explore 一次返回 6000-10000 token 的源码块——如果在主会话直接调,后面所有编辑、规划、测试任务都得背着这块上下文跑,等同于把 IDE 的 minimap 永久贴在屏幕上。把它隔离在 subagent 里,主会话只接收"提炼后的结论"。
codegraph_explore 的 tool description 里还做了 prompt engineering,直接教 AI 怎么写 query:
Bad: "how are agent prompts loaded and passed to the CLI"Good: "readAgentsFromDirectory createClaudeSession chat-manager agents.ts"
这把 AI 引导到"先用 codegraph_search 找几个符号名 → 再把这些名字喂给 explore"的最优路径。
错误的反模式是:
主会话 → 自己直接调 codegraph_explore → 返回 8000 token 源码塞进主会话上下文 → 后续每一个 prompt 都背着这 8000 token 跑#一次真实任务跑下来是什么样子
"这个项目的认证系统是怎么实现的?"
[主会话] 1. 识别为探索类问题 → spawn Explore subagent[Explore subagent] 2. 调 codegraph_search("auth") → 拿到 AuthService、SessionManager 等符号名 3. 调 codegraph_explore( 一次返回: "AuthService SessionManager ├─ auth/service.ts 相关段 loginUser signIn session.ts") ├─ auth/middleware.ts 相关段 ├─ session/manager.ts 相关段 ├─ types/user.ts 类型定义 └─ 调用关系图(谁调谁、谁继承谁) 4. 直接基于返回的源码答题,不再 Read 文件 5. 回传主会话一段 300 字总结 + 关键文件清单[主会话] 6. 收到精炼总结,开始 plan/edit3 次工具调用、0 次 Read、约 17 秒——而没有 CodeGraph 时同样问题要 50+ 次 grep/glob/Read、1m37s。
#主会话直接做轻量查询的时机
不是所有情况都要派 subagent。当 AI 写代码、即将做一次具体编辑时,会直接在主会话里调轻量工具:
[主会话写到一半] 我要给 UserService.updateProfile 增加一个参数 ↓ 先调 codegraph_callers("updateProfile") ← 看谁会被影响 ↓ 再调 codegraph_impact("updateProfile", depth=2) ← 看影响半径 ↓ 确认 5 个调用点都在 src/users/ 下 → 编辑这种"编辑前体检"只花几百 token,但能避免破坏式改动——它替代了"先 grep updateProfile 再 read 10 个文件"的老路。
#自动新鲜度:AI 不需要操心同步
整个过程中 AI 不需要管索引是否最新——Watch 在 MCP server 启动时就开启了
你保存 user.ts → fs.watch 触发 → 2 秒防抖 → git status 找到变更文件 → 重新解析、更新数据库 → 下一轮 AI 调工具时拿到新数据唯一的限制——MCP server instructions 里直接告诉了 AI:刚编辑完文件就立即查询可能拿到旧数据,等下一轮再查。这是因为 500ms 防抖窗口里同步还没完成。这种"把已知限制写进 AI 的 system prompt"是个非常聪明的做法——不要指望 AI 自己发现 race condition,告诉它就好了。
#总的来说
Coding agent 把 CodeGraph 当作一个"装在本地的 IDE 服务"使用——通过 MCP 协议拿到 8 个语义化工具,按"重 → subagent / 轻 → 主会话"的分工原则调用,背后由 fs.watch 自动同步保证数据始终新鲜。AI 不需要知道 SQLite、tree-sitter、FTS5 的存在;它看到的只是"问一个问题,得到一份结构化答案"。
这就是 CodeGraph 与传统 LSP / IDE 索引的本质差别:LSP 是给人用的,CodeGraph 是给 AI 用的——同样是静态索引,但接口语义、返回格式、token 预算、调用纪律全部按 LLM 的工作模式重新设计过。
深度使用
CodeGraph 的进阶用法。
#CLI 速查表
codegraph # 跑交互式安装器codegraph init [path] # 初始化(--index 立即全量索引)codegraph uninit [path] # 移除(--force 跳过确认)codegraph index [path] # 全量索引(--force 强制重建、--quiet 静默)codegraph sync [path] # 增量同步(git 快路径)codegraph status [path] # 显示统计 + backend(native|wasm)codegraph query <search> # 按名搜符号(--kind / --limit / --json)codegraph files [path] # 显示文件树(--format tree|flat|grouped)codegraph context <task> # 构建任务上下文(--format / --max-nodes)codegraph affected [files...] # 求改动影响的测试集codegraph serve --mcp # 启动 MCP server(供 Claude Code 调用)#用作 Node.js 库
CodeGraph 是纯 headless 库,可以直接在你自己的脚本里 import 使用,几行就能跑起来:
importCodeGraphfrom'@colbymchenry/codegraph';const cg = awaitCodeGraph.init('/path/to/project');await cg.indexAll();const ctx = await cg.buildContext('fix login bug', { format: 'markdown' });console.log(ctx);cg.close();主要 API 包括 searchNodes / getCallers / getCallees / getImpactRadius / buildContext / watch,名字基本自解释。详细签名见 types.d.ts[1]。
#高级配置
.codegraph/config.json 控制索引行为,常用字段就是 include / exclude(glob 列表)、languages(语言白名单,留空自动检测)、maxFileSize(默认 1MB)。三条实战建议:
- 巨型仓库:
maxFileSize别放大,否则 WASM 堆会爆。 - monorepo:用
.codegraphignore文件(在子目录里放一个空文件即可)排除单个目录,比改 config 更轻量。 - 多语言混合:让
languages留空自动检测,比手写白名单稳。
#CI 集成:只跑受影响的测试
CodeGraph 最被低估的特性之一是 codegraph affected。把它装进 pre-push 钩子或 GitHub Actions:
# .github/workflows/test.yml-name:Findaffectedtestsid:affectedrun:| AFFECTED=$(git diff --name-only origin/main...HEAD \ | codegraph affected --stdin --quiet --depth 5) echo "tests=$AFFECTED" >> $GITHUB_OUTPUT-name:Runonlyaffectedtestsif:steps.affected.outputs.tests!=''run:npxvitestrun${{steps.affected.outputs.tests}}对于动辄上千测试的项目,这个优化能把 PR 验证时间从十分钟压缩到一分钟。
#跨项目查询
每个 MCP 工具都支持可选的 projectPath 参数,指向另一个已 init 过 CodeGraph 的项目:
codegraph_search({ query: "DatabasePool", projectPath: "/Volumes/code/other-service" })ToolHandler 内部维护一个 LRU 风格的项目连接池(projectCache),首次访问会 CodeGraph.openSync,之后命中缓存。这让你可以在主项目里追问"我们的另一个服务里同名类怎么实现的",而不需要切换工作目录。
#故障排查
- 索引超慢且
status显示Backend: wasm→ 没装 native sqlite。按上文 5 节修复。 - MCP server 连不上 → 命令行先单独跑
codegraph serve --mcp,看是否报错;再检查~/.claude.json的路径与权限。 - 缺符号 → MCP server 保存后会自动 sync(2 秒防抖)。若手动
codegraph sync也不出现,确认文件语言在支持列表里、且未被exclude命中。 database is locked→ 通常是 WASM backend 在跑大索引时阻塞读,等几秒重试即可;长期方案还是修 native sqlite。- 节点数明显偏少 → 大概率是文件超过
maxFileSize被静默跳过。检查codegraph status的 errors 列表。
#你也可以用 CodeGraph 做的事
CodeGraph 不只是给 Claude Code 用的:
- 新人 onboarding 工具:内部脚本调
cg.buildContext("我们的支付系统")直接生成 onboarding 文档。 - 代码评审辅助:CI 在 PR 上跑
cg.getImpactRadius(changedNode, 3),把可能被影响的下游代码贴到 PR 评论里。 - 死代码扫描:
cg.findDeadCode()找出 0 引用的导出符号。 - 循环依赖检测:
cg.findCircularDependencies()返回所有文件级依赖环。 - 复杂度审计:
cg.getNodeMetrics(id)给出节点的入边/出边/调用次数/被调次数。
最后
CodeGraph 之所以能跑出 92% 工具调用减少的成绩,根本原因不在于"用了 tree-sitter"或"用了 SQLite"——这些技术早就存在。真正的差别在于它把已经被证明可行的静态索引技术,重新打包为 LLM 的工具调用接口,并且把每一个工程细节做到位
CodeGraph 的本质是给 AI 编程助手装上一双"IDE 的眼睛"——它让 LLM 不再是在文件系统里盲扫的考古学家,而是站在一个完整代码地图上的城市规划师。
代码不再是 LLM 一次次重新发现的混沌,而是被 tree-sitter 解析、被 SQLite 索引、被 BFS 遍历、被 FTS5 检索的、结构化的、可查询的、永远 fresh 的知识图谱。
94% 工具调用减少不是魔法。是把已经被 IDE 实践了几十年的事情,做了一遍给 LLM 用。
夜雨聆风