用CodeGraph预索引,把AI助手的Token消耗砍掉一半
如果你在用Claude Code、Codex或Cursor处理大型代码库,一定遇到过这个问题:AI每次回答都要反复读文件、调用搜索工具,Token消耗像漏水一样快,回答一长就超上下文。今天要聊的CodeGraph项目,用“预索引知识图谱”的思路,从根本上解决这个痛点。
这不是一篇单纯的项目介绍。我会拆解它的设计逻辑,然后给你一个可以立刻用起来的Skill模板,让你自己也能为任何代码库构建图索引,让AI助手“看一眼图”而不是“读一遍源码”。
这个Skill解决什么具体问题
AI编码助手在理解代码时,通常有两种方式:
- 无状态搜索:每次提问都调用
grep、read_file、list_files等工具,把相关文件内容塞进上下文。 - 预索引查询:提前把代码的结构(函数定义、调用关系、类型依赖等)解析成图(JSON),AI只需要加载一次图数据,后续所有关系查询都基于图进行,不再需要读原始文件。
CodeGraph走的是第二种。它用静态分析(基于TypeScript编译器API)生成一个codegraph.json,包含所有符号、引用、继承、调用等关系。AI代理通过一个简短的查询接口,就能精准获取需要的信息。
好处很直接:
- Token使用量降低40%-60%(实测数据来自项目README,Claude Code在中等项目上从
150K tokens降到60K) - 工具调用次数减少80%以上(因为一次图查询替代了多次文件读操作)
- 响应速度提升2-3倍(减少轮次,且图数据本身很小,通常几十KB到几百KB)
触发条件和适用场景
什么时候值得用这个Skill?
- 代码库超过100个文件,或单文件超过500行
- 需要频繁跨模块理解(如重构、调试调用链)
- 使用Claude Code、Codex、Gemini等支持工具调用的代理
- 本地开发,能运行命令行工具(CodeGraph完全本地)
不适合的场景:
- 一次性脚本或小型项目(<20文件),构建图的成本高于收益
- 代码语言不是TypeScript/JavaScript(目前仅支持,但原理通用)
- AI助手不支持自定义工具或MCP(Model Context Protocol)
完整Skill结构(SKILL.md示例)
下面是一个可直接复用的Skill模板,注册到Claude Code(或兼容MCP的代理)中。这个Skill告诉AI:当用户询问代码结构或关系时,优先查询预生成的codegraph.json,而不是去读文件。
# Skill: CodeGraph Query
## 触发条件
当用户询问以下内容时激活:
- 函数/类的定义位置、调用关系、继承链
- 模块之间的依赖图
- 某个符号的所有引用或实现
- “这个项目里X做了什么?”
## 数据源
项目根目录下的 `codegraph.json`,由 `npx codegraph build` 生成。
## 查询方法
使用以下JSON结构向`codegraph.json`发出查询请求(假设已加载到上下文):
```json
{
"action": "query",
"type": "callers|callees|dependents|dependencies|definition|all_refs",
"symbol": "函数或类名(如loadConfig)",
"maxDepth": 2
}
示例响应
{
"symbol": "loadConfig",
"file": "src/config/index.ts:12",
"callers": [
{"name": "main", "file": "src/main.ts:5"},
{"name": "setupServer", "file": "src/server/setup.ts:34"}
],
"callees": ["readFile", "parseYaml"],
"totalRefs": 5
}
返回格式说明
callers: 哪些函数调用了该符号callees: 该符号调用了哪些函数definition: 定义位置all_refs: 全部引用位置(含类型声明、使用等)- 所有路径相对于项目根目录
```
使用约束
- 如果用户问的是算法逻辑或设计意图,不要优先使用图谱,应结合注释和代码原文
- 如果图谱中查不到(比如动态调用),再fallback到文件搜索
```
实际案例演示
差Prompt vs 好Prompt
差Prompt(无图索引,AI需反复调用工具):
请帮我找到项目中所有调用了getUserData的地方,并画出调用链路。
典型处理过程:AI先grep -r "getUserData"找出所有文件(消耗一轮),然后对每个文件read_file(又几轮),然后手动组装链条。一个20万行项目,光搜索就消耗数十万token。
好Prompt(激活CodeGraph Skill):
请使用CodeGraph Query Skill查询 get_user_data 的所有调用者,深度2层,并展示调用链路。
AI只需读取一次codegraph.json(约200KB,可放于系统prompt或附加上下文),然后执行一次内部查询,直接返回结构化的callers和callees列表。整个过程token消耗不到前者的三分之一。
背后原理
为什么预索引能省token?核心在于信息的稀疏性。
- 原始代码包含大量不相关的格式、注释、import语句。AI读一个文件,可能只有10%是它需要的符号关系。
- 知识图谱只保留结构化的关系:符号名、位置、引用计数、调用方向。这相当于压缩比10:1甚至更高。
- 而且图数据是“一次加载,多次查询”。后续每个问题只需要在图的子集上操作,无需再访问磁盘。
另外,图索引减少了对工具调用的依赖。AI调用工具本身有成本和风险(异步、超时、token溢出)。预索引将工具调用转换为内存中的JSON查询,响应时间从秒级降到毫秒级。
复用和组合技巧
1. 动态更新索引
代码在开发过程中会变。可以设置Git hooks(post-checkout/pre-commit)自动运行npx codegraph build,确保索引最新。Skill里加一条提示:
- 注意检查codegraph.json的修改时间是否晚于最近一次git修改。若不是,请先提醒用户更新索引。
2. 多语言扩展
虽然CodeGraph目前只支持TS/JS,但原理可以用到任何有AST解析器的语言。例如用pyright生成Python的图,用rust-analyzer生成Rust的图。你可以写一个通用的“图索引查询Skill”,只要求数据格式统一为JSON(callers/callees/definition/all_refs)。
3. 与MCP工具配合
如果你用的是支持MCP的Agent(如Claude Desktop),可以把CodeGraph封装成一个MCP工具,通过tools/list和tools/call暴露查询接口。这样AI可以按需调用,而不需要将整个图塞进系统prompt。
// 伪代码 - MCP工具定义
{
"name": "codegraph_query",
"description": "查询预构建的代码知识图谱",
"parameters": {
"type": "object",
"properties": {
"symbol": { "type": "string", "description": "符号名称" },
"depth": { "type": "integer", "default": 2 }
}
}
}
4. 与其他Skill组合
例如“代码审查Skill”在分析变更影响时,先用CodeGraph查询受影响符号的调用者,再结合diff进行风险判断。这种组合能大幅提升AI的上下文利用率。
我的个人看法
CodeGraph的思路并不是全新的——LSP(Language Server Protocol)早就做了类似的事。但把这份数据送给AI代理直接消费,是一个巧妙的桥梁。很多团队在优化AI编码体验时,只想到加长上下文窗口或买更贵的模型,却忽略了“数据预处理”这步。CodeGraph用500行TypeScript代码,证明了减少token消耗的最优解是“少发数据”,而不是“买更大的杯子”。
当然它也不是万能。对于频繁变动的代码,索引过期问题需要额外处理。我建议每次commit前自动重建索引,或者用文件系统watch实时更新。另外,图查询虽然快,但无法表达跨语言调用(比如TS调用Python微服务)。在这些场景下,还是需要传统搜索作为保底。
如果你正在为AI编码助手的Token费用头疼,不妨花10分钟在你的项目上跑一次npx codegraph build,然后按上面的Skill模板配置好。你会发现,原来AI可以既快又省。

附录:快速开始
# 安装
npm install -g @colbymchenry/codegraph
# 在项目根目录构建索引
cd my-project
codegraph build
# 输出 codegraph.json
然后将它传给AI助手的系统prompt或MCP。如果你用Claude Code,可以在.claude中添加一个自定义工具调用。具体集成方法可参考项目README。