工具库Cursor2026/06/0911 分钟

别再让 Agent 从零翻代码了:CodeGraph、GitNexus、LSP 谁更省 token?

最近我在看一个很具体的问题:Coding Agent 读代码这件事,怎么才能少花 token?

最近我在看一个很具体的问题:Coding Agent 读代码这件事,怎么才能少花 token?

不是让它“不读代码”。这个方向基本不现实。Agent 真要改代码、修 bug、做重构,最终一定要看到相关实现。真正浪费 token 的地方,往往发生在它还不知道该读哪里的阶段。

你应该见过类似流程:

先 ls 看目录
再 grep 搜关键词
读几个文件
发现不是这里
继续 grep
追调用链
再读几个文件
最后才找到真正相关的代码

人接手陌生项目也会这么做,只是人翻文件不按 token 计费。Agent 不一样,它每多读一段代码、每多跑一次搜索、每多拿回一段工具输出,都会进入上下文预算。

所以这篇文章想聊的不是“哪个工具最火”,而是一个更底层的问题:

如何让 Agent 在读代码之前,先知道自己应该读哪里?

这也是 CodeGraph、GitNexus、LSP、Aider Repo Map、Serena、Cursor/Sourcegraph 这类方案共同在解决的问题。它们看起来都是“代码理解工具”,但省 token 的方式不一样。

先说结论:省 token 的关键不是压缩,而是定位

很多人一聊 token 优化,第一反应是压缩上下文。比如把代码总结一下,把文件摘要一下,把 README 写详细一点。

这些当然有用,但只解决了一部分问题。

Coding Agent 真正贵的地方,是在大项目里做无效探索。它不知道一个登录 bug 跟哪些文件有关,于是只能先看目录,再搜 loginauthtokensession,然后读一堆看起来相关但其实不关键的文件。

如果我们提前给代码库建一层结构,Agent 就可以先问结构,再读代码。

这层结构可能是:

结构类型代表方案Agent 能问什么
仓库摘要Aider Repo Map这个项目有哪些重要文件、类、函数?
符号索引LSP、Serena这个函数定义在哪?谁引用了它?
代码图谱CodeGraph、GitNexus这个函数调用了谁?改它会影响哪些路径?
语义索引Cursor、Sourcegraph 类工具跟“登录过期处理”语义相关的代码在哪?

它们都在省 token,但省的不是同一笔账。

Repo Map 省的是“第一次理解仓库”的 token。LSP 省的是“精准跳到符号”的 token。CodeGraph 省的是“追关系、追调用链”的 token。语义索引省的是“关键词搜不到但意思相关”的 token。

如果一句话概括:

最好的代码上下文,不是把更多代码塞给 Agent,而是让 Agent 更快拿到下一步需要的最小证据。

CodeGraph:先给代码库建一张图

先说 CodeGraph。这是上周 RTK 项目介绍贴图下 @胡琦 推荐的项目,他说最近用 CodeGraph 比较多,在这里也感谢下他的推荐。

它的项目名片大概是这样:

const CodeGraph = {
  地址: "github.com/colbymchenry/codegraph",
  类型: "本地代码知识图谱 + MCP",
  开发语言: "TypeScript",
  特点: [
    "Tree-sitter 解析",
    "本地索引",
    "MCP 接入",
    "调用关系和影响分析",
  ],
};

截至 2026 年 6 月 9 日,我在 GitHub 页面看到它大约是 45k star。这个数字变化很快,大家看文章时可以以 GitHub 实时页面为准。

CodeGraph 的思路很直接:与其让 Agent 每次都从文件系统开始探索,不如先把代码库整理成一张可查询的图。

这张图里会有很多节点和边:

文件 -> 定义了哪些函数
文件 -> import 了哪些模块
函数 -> 调用了哪些函数
类 -> 有哪些方法
符号 -> 被哪些地方引用

Agent 要理解一个功能时,不需要一上来就读十几个文件。它可以先查图:

搜索 UserService
查看 createUser 的 callees
查看 validateUser 的 callers
查看 auth.ts 的影响范围

这样一来,Agent 的探索路径就从“盲搜 + 大量读文件”变成了“先查结构,再按需读实现”。

CodeGraph 官方也把重点放在这个地方:它把代码库预先索引成本地 knowledge graph,再通过 MCP 暴露给 Claude Code、Cursor、Codex、OpenCode、Gemini 等工具。它的 README 里还给了一个 benchmark 结论:在 7 个真实开源代码库上,平均更便宜、更少 token、更快、更少 tool calls。

这里不要迷信具体百分比,因为 benchmark 跟项目类型、任务、模型、Agent 工具策略都有关。但方向是成立的:如果 Agent 原本需要反复 grep/read 才能追出调用关系,那么提前建图确实会减少探索成本。

CodeGraph 最适合的场景也很清楚:

场景为什么适合
大型项目文件多,目录结构无法直接说明业务关系
调用链复杂需要频繁查 callers、callees、impact
多 Agent 工具MCP 可以让不同 Agent 复用同一份本地索引
经常做重构改一个函数前先知道影响范围

它省的是哪部分 token?

Agent 为了找到相关代码而消耗掉的上下文。

注意,是“找到相关代码”的 token,不是“理解相关代码”的 token。真正要改逻辑时,Agent 还是要读关键文件。CodeGraph 的价值,是让它少读那些后来发现没用的文件。

GitNexus:更像一个代码理解工作台

再看 GitNexus。这里要先说明一下,社区里有几个名字相近的项目,本文主要讨论的是 nxpatterns/gitnexus,它在 README 里把自己叫做 Zero-Server Code Intelligence Engine。

GitNexus 和 CodeGraph 有相似之处:都希望把代码库变成结构化的知识图谱,都希望通过 MCP 给 Agent 提供代码上下文。

但它的产品形态更“工作台”一点。

它不只是给 Agent 一个查图工具,还强调:

本地 / 浏览器侧代码图谱
Graph RAG Agent
交互式知识图谱
CLI 分析仓库
MCP server
代码 Wiki
PR blast radius analysis
多仓库支持

从使用方式看,GitNexus 的 CLI 推荐路径类似:

npx gitnexus analyze
npx gitnexus setup
gitnexus mcp

它的定位更像是“代码库理解层”。你可以让人通过图谱看代码,也可以让 Agent 通过 MCP 调用图谱,还可以围绕索引结果生成文档、做 PR 影响范围分析。

所以如果说 CodeGraph 更像一张给 Agent 用的“结构地图”,GitNexus 更像一个带 UI、索引、MCP、文档、工作流的代码理解系统。

这两者的差异可以这样理解:

对比项CodeGraphGitNexus
核心定位给 Agent 的本地代码知识图谱代码图谱 + Graph RAG + 工作台
使用感更轻,偏 CLI/MCP更完整,偏平台/系统
主要价值少 grep、少读文件、少追调用人和 Agent 都能围绕图谱理解项目
引入成本相对低相对高
适合团队个人开发者、Agent 重度用户需要可视化、文档、PR 分析的团队

如果你只是想让 Claude Code、Codex、Cursor 少一点无效探索,CodeGraph 更轻。如果你想把代码库长期沉淀成可查询、可视化、可给团队看的知识系统,GitNexus 的想象空间更大。

LSP:被低估的“精准跳转层”

很多同学一看到 CodeGraph,会觉得这是一个全新的方向。但如果你用过 VS Code、JetBrains,就已经每天在用一类类似能力:LSP。

LSP,全称 Language Server Protocol,是编辑器和语言服务器之间的协议。它让编辑器可以拿到:

跳转到定义
查找引用
工作区符号
补全
诊断
重命名
调用层级

对人来说,这些能力是 IDE 体验。对 Agent 来说,这些能力就是省 token 的工具。

想象一个 TypeScript 项目里,Agent 要修改 validateToken。如果没有 LSP,它可能会:

grep validateToken
读 auth.ts
读 middleware.ts
读 session.ts
读测试文件
继续 grep token

如果接了 LSP,它可以更直接地问:

validateToken 的定义在哪里?
有哪些引用?
当前文件有哪些 symbol?
这个调用的类型签名是什么?

这比全文搜索可靠很多。因为 grep 只知道字符串,LSP 知道符号。

举个小坑。项目里可能同时有:

// TODO: validateToken
const validateTokenMock = ...
function validateToken() {}

grep 会把它们都搜出来。LSP 更有机会告诉你“当前位置这个符号真正解析到哪个定义”。

不过 LSP 也有局限。它擅长回答符号级问题,但不一定知道业务级问题。

比如你问:

登录过期后为什么没有跳回登录页?

LSP 不会天然知道“登录过期”这个业务概念在哪。它需要你先定位到某个符号、文件或入口,然后才能发挥威力。

所以 LSP 更适合作为“精准跳转层”,不是完整的“业务理解层”。

Serena:把 LSP 能力包装成 Agent 工具

Serena 值得单独提一下,因为它的思路很实用。

它不是单纯告诉你“这里有一个语言服务器”。它是把 IDE 级别的语义代码能力,通过 MCP 包装成 Agent 更容易使用的工具,比如符号检索、引用查询、代码编辑、重构、调试相关能力。

这点很关键。

LSP 原始能力对人很好用,但 Agent 不一定会天然用好。你把底层接口暴露给它,它可能还是回到自己熟悉的 grep/read 流程。

Serena 的价值在于:它把“编辑器能力”变成了“Agent 工具”。

也就是说,Agent 不用只会按行号做文本手术,而可以围绕 symbol 做操作:

找到这个类
查看这个方法
查谁引用了它
做跨文件重命名
只读取某个 symbol 的实现

这类方案非常适合中大型项目,尤其是类型系统比较完整、语言服务器比较成熟的技术栈,比如 TypeScript、Python、Java、Go、Rust。

如果用一句话概括 Serena 和 CodeGraph 的区别:

Serena 更像给 Agent 装了一个 IDE,CodeGraph 更像给 Agent 一张代码关系地图。

一个偏“精确操作”,一个偏“关系理解”。两者不是替代关系,反而可以互补。

Aider Repo Map:把仓库地图压进上下文

Aider 的 Repo Map 是另一个经典方案。

它不一定通过 MCP,也不一定需要 Agent 主动查工具。它的做法更直接:给整个 git 仓库生成一份简洁地图,里面包含重要文件、类、函数、签名,以及关键定义行。

然后,Aider 会把 repo map 随用户请求一起发给模型。

它的好处是简单:模型一开始就能看到项目大概轮廓。Aider 官方文档也说,repo map 会包含仓库里重要的类和函数,帮助模型理解正在编辑的代码和其他部分的关系;当 repo map 过大时,它会根据 token budget 选择更相关的部分。

这个方案很适合解释“省 token”的第一层:

与其让 Agent 自己到处翻,不如先给它一份仓库缩略图。

但 Repo Map 的局限也明显。它更像“摘要”,不是“查询系统”。它能告诉 Agent 项目里有哪些关键符号,但如果要做复杂的调用链分析、影响范围分析,还是需要继续查文件或借助其他工具。

可以把它理解成一张纸质地图。

地图很好,但你不能点一下某条路,就自动展开它经过的所有路口。

Cursor / Sourcegraph:平台级索引和语义搜索

还有一类方案是平台级代码索引,比如 Cursor、Sourcegraph 这类工具。

它们通常会结合几种能力:

全文搜索
符号索引
语义搜索
embedding 召回
代码导航
跨仓库上下文

这类工具的优势是体验完整。你不需要自己拼装 Tree-sitter、LSP、向量库、MCP server,平台已经帮你做了很多工程化工作。

但从“省 token”角度看,这类方案也有一个问题:它们的召回过程对用户和 Agent 来说不一定完全透明。

也就是说,Agent 拿到了某些上下文,但你未必总能知道:

为什么召回这些文件?
有没有漏掉关键文件?
语义搜索命中的代码是否真的相关?

所以平台级索引适合提高日常体验,但在一些高风险重构里,我还是建议配合更确定的符号工具或图谱工具,比如 LSP 的 references、CodeGraph 的 callers/callees、GitNexus 的 blast radius analysis。

语义搜索负责“可能相关”,符号和图谱负责“结构确定”。

这几种方案的本质区别

现在我们把它们放到一张表里。

方案底层依赖查询方式最适合的问题省 token 的方式
Aider Repo MapTree-sitter、图排序、token budget直接放入 prompt这个仓库大概有哪些关键结构?少做初始探索
LSP语言服务器definition、references、symbols这个符号在哪、谁引用了它?少做字符串搜索和整文件阅读
SerenaLSP/IDE 语义能力 + MCPAgent 工具调用如何围绕 symbol 阅读、编辑、重构?少做脆弱的文本级操作
CodeGraphTree-sitter、SQLite、本地图谱、MCPsearch、context、callers、callees、impact代码之间是什么关系?改这里影响谁?少追调用链、少读无关文件
GitNexus代码图谱、Graph RAG、MCP、UICLI、Web UI、MCP如何让人和 Agent 都理解代码库?少重复探索,沉淀代码知识
Cursor/Sourcegraph搜索、符号索引、embedding、平台索引IDE/平台内召回哪些代码语义上相关?跨仓库怎么找?少手动搜索和上下文拼接

这里最容易混淆的是 LSP 和 CodeGraph。

LSP 的核心是“从一个位置找到符号关系”。它很准,但通常要有一个起点。

CodeGraph 的核心是“把整个代码库作为图查询”。它更擅长从结构层面回答:

这个模块有哪些核心节点?
从入口 API 到数据库写入经过哪些函数?
改这个函数可能影响哪些调用路径?

Repo Map 又不同。它不是查询工具,而是上下文压缩工具。它把重要结构提前放进 prompt,让模型少问一些初级问题。

语义搜索再换一个维度。它不关心符号解析是否精确,而是找“意思接近”的代码。比如用户说“登录过期”,代码里可能叫 sessionExpiredrefreshTokenFailedUnauthorizedHandler,这时语义搜索比 grep 更容易召回。

所以它们不是谁替代谁,而是站在不同层级:

Repo Map:先知道全局轮廓
语义搜索:找到可能相关的区域
LSP / Serena:精确跳到符号
CodeGraph / GitNexus:追关系和影响范围

如果自己实现一个简化版,核心流程是什么?

为了更好理解这些工具,我们可以自己想象一个“低配 CodeGraph”怎么做。

第一步,解析代码。

你需要用 Tree-sitter 或语言编译器 API,把源文件解析成 AST。不要只靠正则,因为函数、类、import、调用表达式在不同语言里差异很大。

第二步,抽取节点。

File
Module
Class
Function
Method
Variable
Interface
Type

第三步,抽取边。

CONTAINS:文件包含函数
IMPORTS:文件导入模块
CALLS:函数调用函数
REFERENCES:符号引用符号
EXTENDS:类继承类
IMPLEMENTS:类实现接口

第四步,做符号解析。

这一步最难。你不能只知道代码里出现了 createUser(),还要知道它到底指向哪个 createUser。同名函数、重导出、别名 import、动态导入、框架约定都会让解析变复杂。

第五步,存储索引。

可以用 SQLite、图数据库、嵌入式 KV,甚至一组 JSON 文件。重点不是数据库多高级,而是查询要快、结果要小、更新要增量。

第六步,暴露给 Agent。

通过 MCP 提供工具:

search_symbol(name)
get_context(symbol)
get_callers(symbol)
get_callees(symbol)
get_impact(symbol)
list_files(pattern)

第七步,控制返回内容。

这一步经常被低估。工具返回太多,还是会浪费 token。一个好的代码图谱工具,不应该把整段实现全吐给 Agent,而应该先返回结构化摘要:

符号名
文件路径
起止行
签名
调用关系
少量必要代码片段

Agent 需要更多细节时,再进一步读具体文件。

所以,省 token 不只是“建图”,还包括“查询结果设计”。MCP 工具如果每次返回一大坨 JSON,也可能把省下来的 token 又花回去。

到底哪种方案最省 token?

如果必须给一个排序,我会这样判断。

小项目里,最省事的是 Repo Map。

项目只有几十个文件时,复杂图谱的收益没有那么明显。一个 repo map,加上普通搜索和少量读文件,已经够用了。

中型项目里,LSP/Serena 的性价比最高。

因为中型项目最常见的问题不是“完全不知道项目是什么”,而是“知道大概方向,但需要精确跳到定义和引用”。这时 LSP 的价值很大,尤其是类型系统完整的项目。

大型项目里,CodeGraph/GitNexus 更值得上。

当文件很多、调用链复杂、模块之间关系绕时,Agent 靠 grep/read 探索会很贵。图谱方案能把“代码结构理解”提前做掉,让 Agent 查询关系而不是反复翻文件。

企业级多仓库里,平台级索引更现实。

如果你有多个仓库、多个团队、权限系统、PR 流程、代码搜索平台,那么 Sourcegraph/Cursor 这类平台能力会更完整。只是高风险改动时,仍然建议结合符号级和图谱级工具做验证。

可以总结成这张表:

项目规模推荐组合
小项目Repo Map + grep/read
中型项目Repo Map + LSP/Serena
大型单仓库CodeGraph + LSP/Serena
多仓库团队Sourcegraph/Cursor 类平台 + CodeGraph/GitNexus
长期重构项目CodeGraph/GitNexus + 测试/类型检查/PR 分析

我个人更推荐的组合是:

Repo Map 做全局缩略图,语义搜索找可能区域,LSP 做精准跳转,CodeGraph/GitNexus 追调用和影响范围。

这比只押注某一个工具更稳。

最后:不要让 Agent 读更多,要让它读得更准

回到文章开头的问题:代码读取这部分如何节省 token?

答案不是简单地“压缩代码”。

真正有效的方式,是把 Agent 的代码探索过程拆开:

先看全局轮廓
再定位相关区域
再精确跳到符号
再追调用关系
最后只读关键实现

如果没有这些结构,Agent 就只能像刚接手项目的新同事一样,靠目录、关键词和直觉慢慢摸。它不是不能摸出来,只是每一步都在花 token。

CodeGraph 这类工具的价值,就是提前给代码库建一张结构地图。GitNexus 往前走了一步,把图谱、RAG、UI、MCP 和文档工作流结合起来。LSP/Serena 则补上了 IDE 级别的精确符号能力。Repo Map 提供了最轻量的全局缩略图。语义索引负责处理“用户说的是业务词,代码里不是这个词”的情况。

所以,未来 Coding Agent 的上下文优化,大概率不是把整个仓库塞进超长上下文。

更好的方向是:

仓库越来越大,但 Agent 每次看到的代码越来越少,而且越来越准。

这才是真正的省 token。

参考资料