CodeGraph学习笔记:给代码建索引,节省Token和时间

CodeGraph学习笔记:给代码建索引,节省Token和时间

好家伙,

最近在用 AI 看项目代码时,我开始关注一件事:

text 复制代码
问一个实现问题,
AI 到底花了多少力气在找代码,
又花了多少力气在解释代码?

比如我想知道:

text 复制代码
一条伤害战报在哪里生成?
如果修改战报记录逻辑,哪些地方需要一起检查?

最直接的办法,是搜索 damage、report,打开几个文件,再沿着调用继续找.

这个办法能用.但项目大了以后,找入口、排除同名函数、拼接调用关系,本身就会消耗不少时间和上下文.

所以我想,给ai做一个代码搜索工具,但现在已经有成熟的开源工具了,代码索引CodeGraph

所以这篇研究一个工具:CodeGraph.

正如字典的索引,我们去查某个字"索引"的"索","索"的索引是"s" 它提前给代码建立结构索引,让后续查询能够直接定位符号,沿着已解析的关系继续追查.

然后我们再看一个实际问题:

text 复制代码
使用代码索引前后,
Token 消耗和完成任务的时间,
究竟差了多少?

观察日期:2026-10-10.本文介绍 colbymchenry/codegraph,本机使用版本为 1.6.0.第 6 节引用作者公开基准,第 7 节记录本机实际测试,数据来源分别说明.

0.背景:找到文件,距离找到答案还有多远

先固定问题:

text 复制代码
伤害结算完成后,
战报中的 damage.dealt 事件由哪里写入?

用文本搜索,可以先执行:

powershell 复制代码
rg -n "damage.dealt" src

事件名准确时,可以直接定位写入位置.进一步还要回答:

text 复制代码
这段逻辑通过哪个对象写入?
这个写入方法还有哪些调用者?
宿主能不能换掉这个对象的实现?

还要阅读定义、追踪调用并核对对象来源.代码索引可以提前整理这些关系.

1.先分清:搜字符串、找相关代码、查关系

查代码常见三种需求:

问题 需要的信息 常用方式
哪里出现了damage.dealt 字面量出现的位置 rg 等文本搜索
哪些代码可能与伤害战报有关 与问题相关的代码片段 关键词、语义检索等
谁调用了战报追加方法 符号之间已解析的关系 结构索引与关系查询

假设一个项目里有三个 add:

typescript 复制代码
report.add(...)
inventory.add(...)
queue.add(...)

文本搜索会命中这三种调用.结构查询则要区分:

text 复制代码
我要找的是 Report.add 的调用者.

准确度取决于工具对语言、类型和调用方式的解析能力.

代码关系图也可以作为 RAG 的检索来源,为模型提供函数调用等结构信息.

2.CodeGraph的地图里,到底有什么

符号是可以单独定位的代码实体,例如:

text 复制代码
Report 类
Report.add 方法
damage 函数
runBattle 函数

每个符号还记录文件、行号和对应源码.

关系描述调用、导入、继承等连接.拿战报举例:

text 复制代码
damage
   │ 调用
   ▼
Report.add
   │ 默认实现追加记录
   ▼
Report.entries

顺着箭头可以追执行路径,反向查询可以找调用者,作为修改时的检查清单.业务规则仍要结合源码、配置和运行行为判断.

3.从源码到索引:地图怎么建起来

CodeGraph 的基本流程可以这样理解:

text 复制代码
源码文件
   │
   ▼
解析语法,提取函数、类、方法等符号
   │
   ▼
整理调用、导入、继承等关系
   │
   ▼
保存到本地索引
   │
   ▼
按问题查询,返回相关源码和关系

先看一个很小的例子:

typescript 复制代码
function appendReport() {
  // ...
}

function damage() {
  appendReport();
}

这里需要识别两个函数定义,并将 damage 中的调用解析到 appendReport 的定义.跨文件导入、同名方法和动态调用会增加解析难度.

CodeGraph 使用 Tree-sitter 解析源码,提取符号和关系,并保存到本地 SQLite 数据库中,再进行引用解析和查询上下文整理.官方原理说明

索引可以复用,代码变化后再同步更新.工具提供自动同步和手动同步命令.官方建图与同步指南

4.实战:用索引找到一条伤害记录的来源

假设游戏里有人受到伤害,战报中出现了一条伤害记录.现在我要改记录逻辑,先得弄清两件事:

text 复制代码
谁生成了这条记录?
修改记录方法,还会影响哪些地方?

项目给这类记录起的事件名是 damage.dealt.第一步用 rg 搜这个名字,定位到 src/ops.ts:281,发现它在 damage 函数中调用了 engine.report.add.

这时我们已经知道两个名字:damage 和 Report.把它们交给 CodeGraph 查询,继续找方法定义和调用关系.实际工具参数如下,projectPath 还需指定项目绝对路径:

text 复制代码
codegraph_explore
  query: damage Report
  maxFiles: 3

核对返回的源码后,默认记录路径是:

text 复制代码
damage:算好伤害,组织目标、伤害量等数据
   ↓ 调用
Report.add:给记录编号
   ↓ 追加
Report.entries:保存记录的数组

也就是说,这里的"写战报"就是往数组里加一条记录.关键位置是 src/ops.ts:281 和 src/engine.ts:28.

第二步,查询"谁还调用了这个 add".为了避开其他同名方法,指定文件:

text 复制代码
codegraph_callers
  symbol: add
  file: src/engine.ts
  limit: 6

实际返回了 runBattle、snapshot、phaseInitiative、declareInitiative、phaseEffect、phaseSort 六个调用者.例如 snapshot 写战场快照,phaseSort 写行动排序.这六个是本次查询返回的部分结果,不是全部调用者.

因此,如果只改伤害记录的数据,先看 damage;如果改公共的 Report.add,快照、排序等记录也要一起检查.索引在这里帮我们找到"还要看谁",具体影响仍要读源码确认.

还有一个实际例外:runBattle 可以接收外部传入的记录对象.项目中的 NarrativeSink 就重写了 add,会筛选记录并压缩快照,不能把默认数组实现当作所有入口的行为.第 7 节把这条完整查找任务作为测试题.

5.AI怎么用它:MCP把查询接进来

对 AI 来说,基本过程是:

text 复制代码
用户提出代码问题
   ↓
模型选择查询工具,给出参数
   ↓
CodeGraph 查询索引并组织源码上下文
   ↓
模型根据返回结果解释实现

这次查询的参数:

json 复制代码
{
  "projectPath": "C:/Users/Administrator/Desktop/xxx",
  "query": "src/engine.ts Report add Engine.run src/ops.ts damage",
  "maxFiles": 3
}

codegraph_explore 返回相关源码、行号、调用路径和依赖信息.只查位置或调用者时可以选更窄的工具,具体取决于版本和配置.官方 MCP 文档

查询时先限定问题和范围,多个项目明确指定 projectPath.若结果提示源码截断,继续按准确符号查询.

6.使用前后,Token和时间差多少

**数据来源声明:**本节性能对比数据转引自 CodeGraph 项目作者公开的 Agent A/B 基准测试,本文未独立复现作者这组测试.这些数字不代表本项目的实际收益;自己的引擎项目实测另见第 7 节.
资料查阅日期:2026-10-10.单题数据来源为官方 README 的 Benchmark Results;多轮数据来源为作者的 上下文占用测试报告.

作者公开的单题测试使用 Claude Opus 4.8.同一项目、同一问题,分别开放或关闭 CodeGraph MCP,每组运行四次,报告中位数.两组都保留普通读取、搜索和终端工具,同时阻止通过 CLI 绕过分组限制.测试方法与结果

先说明:这里统计的Token是什么

这里统计任务累计处理的 token.下面是口径示意,数值并非实测:

text 复制代码
第一轮输入:10k token
第二轮输入:14k token
第三轮输入:18k token

三轮累计输入:42k token
最后一轮输入:18k token

多轮请求可能重复携带历史,只看最后一轮会漏算.作者统计逐轮累计的输入、缓存相关输入和输出,时间取任务总墙钟时间.

单题测试:累计Token对比

以下摘取三个项目,k 为千 token.原始数值来自作者,百分比由本文按 (不使用索引 − 使用CodeGraph) ÷ 不使用索引 × 100% 计算;取整数值对应近似比例.

项目 不使用索引 使用CodeGraph 累计Token约减少
VS Code 670k 155k 76.9%
Excalidraw 991k 156k 84.3%
Gin 180k 87k 51.7%

数据来源:CodeGraph 官方 README 的 单题基准原始表格,作者标注测试日期为 2026-08-05.表中结果为每组四次运行的中位数.

同一组测试:完成任务的时间对比

项目 不使用索引 使用CodeGraph 耗时约减少
VS Code 130秒 58秒 55.4%
Excalidraw 162秒 45秒 72.2%
Gin 46秒 28秒 39.1%

数据来源:与上一张 token 表相同,均摘自作者的 单题基准原始表格.耗时为完成任务的墙钟时间;"耗时约减少"由本文按公开数值计算,不属于额外实测结果.

这组三个项目的累计 token 和耗时均下降.我的理解是,收益来自减少寻找实现、排除无关代码和拼接关系的工作,具体幅度受模型、问题和项目结构影响.

多轮测试:Token更少,也可能更慢

另一组三轮对话测试中,VS Code 的结果如下:

指标 不使用索引 使用CodeGraph
累计Token 约1.6M 约940k
总耗时 119秒 179秒

数据来源:作者的 上下文占用测试报告中"Throughput in the same campaign (sonnet · 3 turns)"一节.这是另一组模型与对话轮数不同的实验,不能与前面的单题测试混为同一组结果.

这一组 token 下降、总时间增加.较大的检索结果还可能持续占用上下文.评估时要同时看累计 token、上下文占用、总时间和答案质量.多轮测试及上下文测量

7.本机实测:追查伤害战报,实际省多少

这次实际测试的场景,就是第 4 节的引擎项目.让 AI 完成一道完整的查代码题:

text 复制代码
damage.dealt 事件在哪里写入,最终保存到哪里?
列出公共战报追加方法至少四个不同调用者.
runBattle 能否接收另一种记录实现?
找到仓库内实际注入的例子,解释行为差异,标出文件与行号.

两组条件如下:

  • 测试日期为 2026-10-10,源码 commit 为 3df3c36012e4,测试前后相关源码没有变化.
  • 固定 Codex CLI 0.154.0、模型 gpt-5.6-sol、推理强度 high;CodeGraph 为 1.6.0.
  • 每组各跑三次独立新会话,提示词和输出要求相同,交替安排两组的执行顺序.
  • 无索引组关闭全部 MCP,禁止通过 CLI 或 SQLite 查询索引,日志核查未发现绕过.索引组开放 CodeGraph MCP;两组都允许普通搜索和源码读取.

Token 直接读取 CLI 返回的 turn.completed.usage,统计整个任务的累计输入和输出,不是按源码字符数估算.CLI 统计格式

text 复制代码
累计 Token = input_tokens + output_tokens
cached_input_tokens 已包含在输入中,不再重复相加.

时间从启动 CLI 进程计到退出,包括 MCP 启动、模型推理、工具执行和等待.这测的是 AI 完成查代码任务的总开销.

六次实际运行结果

轮次 不使用索引:累计Token 使用CodeGraph:累计Token 不使用索引:耗时 使用CodeGraph:耗时
1 309,781 214,178 134.6秒 105.7秒
2 430,940 179,921 142.7秒 87.8秒
3 855,806 189,425 175.5秒 92.2秒
中位数 430,940 189,425 142.7秒 92.2秒

数据来源: 以上为 2026-10-10 本机执行六次 codex exec --json 的结果,与第 6 节作者公开的基准分开统计.原始 usage、精确耗时和工具调用记录摘录已在本地留档:codegraph-benchmark-2026-10-10/summary.json.

在这道题上,按三次中位数比较,累计 Token 减少 56.0%,耗时减少 35.4%. 百分比按未四舍五入的耗时计算.

六份答案都经当前源码核对,满足事件写入、默认存储、至少四个调用者、真实注入例子和替代实现行为这五项要求.两组都找到了 NarrativeSink,并区分了默认 entries 数组与它的私有 out、finish() 取出方式.

普通搜索组三次用了 22、21、12 次工具调用,索引组为 5、6、9 次.但普通搜索第三次调用更少,累计 Token 却最高:返回内容的大小和历史累积同样影响消耗.

本次使用已有索引,首次建图和同步成本另计.服务端缓存未强制清空,CLI 后台请求存在失败告警,工具重试和环境等待均保留在统计中.每组三次的小样本,只描述当前模型在这道题上的表现.

完整提示词、运行条件和复跑命令保存在本地测试目录的 README.md;六份回答及核对记录保存在 answers.md.

参考资料

解释源码解析、符号提取、关系解析和本地存储,对应本文"地图怎么建立"的部分.

说明 AI 可以查询哪些信息,以及工具如何返回源码和关系.

提供本文单题 token 与耗时对比的原始数据和实验条件.

补充多轮会话的结果,并解释累计 token、上下文残留及统计口径的问题.

相关推荐
Raas1004 小时前
MAI Gateway(魔芋企业级AI网关)能力解析:AI网关能做故障转移吗?AI网关核心功能详解
大数据·人工智能·网关·ai·gateway·mai gateway
全栈练习生4 小时前
AI Agent 沙箱
python·ai
GlobalInfo7 小时前
2026年推理算力超越训练算力,市场调研该关注什么
大数据·人工智能·ai·芯片
oicola9 小时前
【DSH】DSH配置第三方MCP服务
ai·harness
GlobalInfo9 小时前
2026年全球无人机清洗系统市场深度分析:规模、竞争格局与AI自主作业演进趋势
大数据·人工智能·ai·无人机
wflynn11 小时前
Fold:Effect原生多提供商Agent核心框架解读
ai·技术
敲代码的小小酥12 小时前
Agent 运行机制全景:从工具调用到沙箱隔离
ai·agent
欣欣之王来了13 小时前
国外主流大模型深度对比:GPT、Claude、Gemini技术细节与实战选型指南
人工智能·ai·大模型
MicrosoftReactor13 小时前
技术速递|使用 GitHub Security Lab Taskflow Agent 实现 AI 驱动的模糊测试
人工智能·ai·github·copilot·agent·模糊测试·ai-agent