30K Star 神器,给 Claude Code 装上代码地图,Token 中位数省 65 倍

上周我让 Claude Code 改一个支付回调的 bug。

它先 grep 了一遍 payment,读出 12 个文件。然后发现回调逻辑在 OrderService 里,又顺着 import 读了 8 个。改完跑测试挂了,因为它漏看了一个被继承的基类方法。接着它把整个 service/ 目录都读了进来。

等它终于改对,我看了一眼 token 用量,单次会话烧掉 18 万 input token。问题改对了,但我心里在滴血。

这不是 Claude 不够聪明,是它没有「地图」。它像一个被蒙着眼塞进陌生城市的快递员,只能挨家挨户敲门问路。

今天要聊的 code-review-graph,就是给 AI 配一副 GPS。GitHub 30,608 stars,2,787 forks,MIT 协议,项目创建于 2026 年 2 月 26 日,半年冲到 30K star。最新版本 v2.3.7,2026 年 7 月 18 日发布。

它的口号很直接,Stop burning tokens. Start reviewing smarter.

我实测了一周,把安装、使用、原理、benchmark 猫腻、适用边界全摸了一遍。这篇不做 README 翻译,只讲我真正跑过之后的判断。

它到底解决什么问题

先说结论,code-review-graph 不是又一个 RAG 代码搜索工具。

它做的事情是,用 Tree-sitter 把你的代码库解析成一张「结构图谱」,节点是函数、类、文件,边是调用、导入、继承、测试覆盖关系。这张图存在本地 SQLite 里。AI 通过 MCP 协议按需查询,比如「这个函数被谁调用了」「改了这个文件会波及哪些测试」,而不是把整个文件塞进 context。

官方在 6 个真实仓库上跑了基准测试,中位数 token 减少 65 倍,范围从 36 倍到 376 倍。

我知道你看到这个数字第一反应是「吹的吧」。我也是。所以后面会专门拆 benchmark 是怎么测的,baseline 是什么,哪些地方有水分。

但先让它跑起来。

手把手实战

环境准备

需要 Python 3.10 或更高版本。我用 uvx 跑,不污染全局环境。你也可以用 pipx,效果一样。

bash 复制代码
# 方式一,uvx,推荐,零安装
uvx code-review-graph --version

# 方式二,pipx
pipx install code-review-graph

# 方式三,pip 全局装
pip install code-review-graph

如果要用语义搜索功能,需要额外装 embeddings 扩展。

bash 复制代码
pip install "code-review-graph[embeddings]"

默认不带 embedding 是刻意的,因为本地模型首次使用会从 HuggingFace 下载,几百兆,不是每个人都需要。

安装到 Claude Code

一条命令自动检测平台并写入 MCP 配置。

bash 复制代码
code-review-graph install --platform claude-code

它支持 14 个以上的平台,Claude Code、Cursor、Codex、Windsurf、Zed、Continue、OpenCode、Antigravity、Gemini CLI、Qwen、Kiro、Qoder、Copilot、CodeBuddy。装完要重启编辑器,MCP 服务才会拉起。

MCP 绑定的是 localhost,数据全在本地,零遥测。这一点对代码隐私敏感的团队很重要,后面原理部分还会讲。

构建图谱

进到你的项目根目录,执行。

bash 复制代码
code-review-graph build

它会用 git ls-files 列出所有被 git 跟踪的文件,gitignore 的自动跳过。500 个文件的项目首次构建大约 10 秒。3000 个文件的项目增量更新大约 2.5 秒,其中 1.4 秒是 Python 进程启动开销。

构建完你会发现项目根目录多了一个 .code-review-graph/ 文件夹,里面是 graph.db,就是那张三张表撑起来的 SQLite 图谱。记得把它加进 .gitignore

在 Claude Code 里用

重启 Claude Code 后,你会多出一组斜杠命令。

复制代码
/code-review-graph:build-graph
/code-review-graph:review-delta
/code-review-graph:review-pr

review-delta 是我用得最多的。它会检测你当前工作区相对 git 的改动,沿着图的边追踪影响半径,然后告诉 AI「只看这些文件就够了」。

我改完一个函数,直接在 Claude Code 里敲 /code-review-graph:review-delta,它返回的不是整个 diff,而是一份结构化的审查简报,包含,

  • 变更了哪些节点
  • 这些节点被哪些上游调用
  • 哪些测试覆盖了这些节点
  • 一个 0 到 100 的风险评分
  • 建议的最小审查文件集

整个过程 AI 读入的 token 从「整个仓库」降到「两三千 token 的结构化摘要」。

Token Savings 面板

detect-changes --brief 命令会输出一个 Token Savings 面板,长这样。

text 复制代码
Files changed: 3
Nodes impacted: 47
Review set: 8 files (2,840 tokens)
Full corpus: 142,356 tokens
Savings: 50.1x

这里的 token 估算是用 chars/4 算的。我一开始担心这个估算不准,专门翻了 REPRODUCING.md,官方用 222 个文件做了校准,chars/4 跟 tiktoken cl100k_base 的偏差在正 0.5% 以内。也就是说它稍微高估一点点节省,但偏差可以忽略。

watch 模式

开发时不想每次手动 build,可以开监听。

bash 复制代码
code-review-graph watch

文件保存时它自动增量更新。增量靠 SHA-256 hash 比对,只重新解析内容真正变化的文件,然后沿边更新受影响的节点关系。实际体验几乎无感。

visualize 交互式图谱

bash 复制代码
code-review-graph visualize

它会起一个本地 web 服务,在浏览器里画出交互式的依赖图谱。你可以点节点看上下游,可以按社区着色,可以看到哪些是 hub 节点,哪些是 bridge 节点。这个功能对 onboarding 新同事或者理解遗留系统特别有用,比在 IDE 里点「find usages」一个个看直观太多。

.code-review-graphignore

有些目录你不想索引,比如生成的代码、migrations、前端构建产物。在项目根目录建一个 .code-review-graphignore,语法跟 gitignore 一样。

text 复制代码
**/generated/**
**/migrations/versions/**
frontend/dist/

GitHub Action 集成

它还提供了 GitHub Action,可以在 PR 上自动发风险评分评论,甚至可以设置 fail-on-risk 作为合并门禁。

yaml 复制代码
name: Code Review Graph
on: [pull_request]
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: tirth8205/code-review-graph-action@v2
        with:
          fail-on-risk: 70
          github-token: ${{ secrets.GITHUB_TOKEN }}

风险分超过 70 就阻止合并。这个分数不是拍脑袋的,它综合了变更节点的 hub 程度、影响半径内的测试覆盖率、以及边的置信度。

Benchmark 数字怎么来的

好,到了最关键的部分,65 倍这个数字能不能信。

官方在 6 个真实开源仓库上测的,我把原始数据拉出来。

仓库 全量语料 token 图谱返回 token 节省倍数
fastapi 948,793 2,653 375.6 倍
flask 143,594 2,196 71.0 倍
code-review-graph 自身 208,821 3,190 68.1 倍
gin 166,868 2,766 61.9 倍
httpx 142,356 2,661 60.6 倍
express 136,052 3,936 36.0 倍

中位数 65 倍。fastapi 那个 375.6 倍是极端案例,因为 fastapi 的 __init__.pyapplications.py 集中导出了大量符号,全量喂入时这些文件反复出现在 context 里,而图谱只返回真正相关的调用链。

但这里有个你必须知道的 caveat。

baseline 是「全量语料」,也就是把整个仓库所有源码文本都塞给 AI。这不是一个聪明的 baseline。现实中一个有经验的 Claude Code 用户会用 grep、glob、find references 来缩小范围,不会真的把 fastapi 全部 94 万 token 塞进去。所以 65 倍是跟「最粗暴的做法」比,不是跟「熟练工程师手动筛选」比。

这一点官方没有藏着掖着,写在 REPRODUCING.md 里了,但它不在 README 的显眼位置。我的判断是,即便跟聪明的 grep 策略比,图谱依然有明显优势,因为 grep 只能做文本匹配,它不知道调用关系和继承链。但优势肯定没有 65 倍那么夸张,我自己体感在 5 到 15 倍之间,取决于代码库的耦合度。

再看准确性数据。影响分析的 F1 是 0.69,precision 0.546,recall 1.0。recall 1.0 看起来完美,但 ground truth 是从同一张图导出来的,属于循环论证,这个数字不能当真。真正诚实的 co-change 模式,对比 git 历史中实际共同修改的文件,目前预测为 0,官方自己标了「还不可用」。

多跳检索基准是 0.909 分,测的是 11 个手工任务跨 6 个仓库,这个数据相对可信,因为它测的是「沿图的边遍历能不能找到正确答案」,不依赖循环论证。

所以我的结论是,token 节省的方向是对的,数量级可信,但别把 375 倍当成你每天都能看到的数字。中位数 65 倍是跟全量喂入比的乐观值。

原理拆解

Tree-sitter 解析出节点和边

核心是 Tree-sitter,一个增量解析库,GitHub 自己的 Atom 编辑器当年搞出来的,现在几乎是所有代码结构分析工具的事实标准。

它把每个文件解析成 AST,抽象语法树,然后从中提取,

  • 节点,函数定义、类定义、方法、导入声明、文件本身
  • 边,CALLS,函数 A 调用了函数 B;IMPORTS,文件 A 导入了文件 B;INHERITS,类 A 继承自类 B;TESTED_BY,函数 A 被测试文件 T 覆盖

每条边还带一个置信度标签,EXTRACTED 表示从 AST 直接提取的,确定性高;INFERRED 表示通过命名约定或导入路径推断的;AMBIGUOUS 表示有多个可能的解析目标。AI 拿到这些标签可以判断哪些关系值得信任。

为什么不用 LSP

你可能会问,LSP,Language Server Protocol,不是也能做这些事情吗,find referencesgo to definition,都是编译器前端做精确类型推导出来的。

区别在于精度和广度的取舍。

LSP 精确但重。每个语言一个 daemon,Python 要起 pyright,Go 要起 gopls,Java 要起 jdtls,吃内存吃 CPU。而且 LSP 的引用列表是「100% 精确或 nothing」,对于动态语言或者 monkey patch 的场景经常直接罢工。

Tree-sitter 是启发式的 AST 解析,不做类型推导,一个进程覆盖 35 种以上语言,Python、JavaScript、TypeScript、Go、Rust、Java、C/C++、C#、Ruby、Kotlin、Swift、PHP、Scala、Solidity、Dart,一直到 Zig、Nix、Verilog、Terraform、Vue SFC、Jupyter notebook。它不保证 100% 精确,但它保证「不会漏掉可能受影响的文件」。

Code review 场景要的恰恰是后者。你宁愿多看两个文件,也不想漏掉一个导致线上事故。这是工程上的务实取舍。

影响半径分析

这是整个工具最核心的算法。

你改了一个函数,它做的事情是,

  1. 找到变更文件对应的图节点
  2. 沿 CALLSIMPORTS 边反向遍历,找到所有依赖这个节点的上游
  3. 沿 TESTED_BY 边找到覆盖这些节点的测试
  4. 对遍历到的节点按距离和边置信度加权
  5. 输出一个最小但充分的审查文件集

这个过程叫 blast radius analysis,爆炸半径分析。传统的静态分析工具也做类似的事情,但它们通常输出几百个文件让你自己筛。CRG 的不同在于它把结果裁剪到 AI context window 能舒服处理的体量,通常是两三千 token。

增量更新

首次全量构建后,每次更新只做三步。

  1. git diff 拿到变更文件列表
  2. 对每个文件算 SHA-256 hash,跟上一次的 hash 比对
  3. 只重新解析 hash 变化的文件,删除旧节点和边,插入新的,然后沿边更新引用关系

MCP 协议,30 个工具

AI 不是拿到整张图,而是通过 MCP 工具按需查询。CRG 暴露了 30 个 MCP 工具和 5 个 prompt 模板。

工具包括查询节点详情、找调用者、找被调用者、影响半径分析、搜索符号、获取社区结构、获取 hub 节点、获取风险评分等等。5 个 prompt 模板是 reviewarchitecturedebugonboardpre-merge,对应不同的审查场景。

关键设计是,AI 决定查什么,图返回什么。AI 不会一次性拿到全部数据,而是像查数据库一样,先查一个节点,根据结果决定下一步沿哪条边走。这就是多跳检索,也是它比 RAG 强的地方。

为什么它不是 RAG

这是最多人误解的点。

RAG,检索增强生成,把代码切成文本块做向量化,查询时用余弦相似度找最接近的块。它回答的问题是「哪些文本里提到了 X」。

CRG 存的是 AST 解析出的结构边,回答的问题是「谁调用了 X」「X 的子类有哪些」「改了 X 哪些测试会挂」。

embedding 在 CRG 里只是可选的辅助,用来找到遍历的起始节点。一旦起始节点确定,后续完全沿真实的结构边走,不涉及向量相似度。

打个比方,RAG 像在书里搜关键词,CRG 像看目录和交叉引用。搜关键词能找到提到的地方,但目录能告诉你「这一章影响了哪三章」。

官方在多跳检索任务上拿了 0.909 分,而纯 RAG 方案在这类需要沿关系链推理的任务上普遍表现差,因为向量相似度不传递,A 跟 B 相似,B 跟 C 相似,不代表 A 跟 C 有结构关系。

Leiden 社区检测和风险评分

图谱还跑了 Leiden 社区检测算法,把高度互连的节点聚成社区,这对应代码里的模块或子系统。hub 节点是被大量其他节点依赖的节点,改它们风险高。bridge 节点是连接两个社区的节点,改它们可能产生跨模块影响。

风险评分综合了这几个因素,变更节点的 hub 程度,影响半径内的节点数量,边的置信度,社区跨越数,测试覆盖率。输出一个 0 到 100 的分数,给人类 reviewer 和 CI 门禁一个快速判断依据。

跟其他工具怎么选

我在之前的 073 篇文章里对比过 sense、codegraph、CodeGraph 三个工具。这次加上 CRG,再补两个常被拿来比的。

Serena,走的是 LSP 路线,语义精确,但每个语言要起 language server,重,资源占用高。适合需要精确重命名、类型推导的场景。CRG 走 Tree-sitter 路线,轻量,语言覆盖广,适合 review 和影响分析这种「宁滥勿缺」的场景。

repomix,做的是把整个仓库打包成一个大文本文件喂给 AI。它解决的是「怎么把代码塞给 AI」,CRG 解决的是「该把哪些代码塞给 AI」。两者可以配合,repomix 打包的同时用 CRG 筛选文件。

claude-context 类 RAG 工具,做向量检索,适合「找哪里提到了某个概念」的模糊查询。CRG 适合「找这个函数被谁调用了」的结构化查询。一个找文本,一个找关系。

sense / codegraph,073 篇聊过,sense 偏向 IDE 内的实时可视化,codegraph 偏向生成静态架构图。CRG 是唯一一个深度集成 MCP、以「给 AI 消费」为第一目标的图谱工具,它输出的不是给人看的图,而是给 AI 读的结构化 JSON。

简单的选择建议,

  • 代码库超过 500 个文件,AI 经常读太多无关代码,上 CRG
  • 需要精确的类型感知重构,用 Serena
  • 只是想把仓库一次性喂给 AI 做总结,repomix 够用
  • 想找「哪里提到了 XXX」的模糊搜索,RAG 类工具更直接

什么时候不该用

这篇文章不是软文,有些场景 CRG 反而帮倒忙。

小项目别装。 几百个文件以下的项目,AI 本来就能把相关代码读进 context。CRG 的结构元数据本身有开销,小改动时 graph response 可能比原始 diff 还大。官方文档明确写了这个限制。

琐碎改动别用。 改个文案、调个 CSS、加个日志,直接让 AI 看 diff 就行,绕一圈查图谱纯属浪费。

JavaScript 和 Go 的流检测目前较弱。 官方 benchmark 里 JS/Go 的数据流检测 recall 只有 33%,意味着三分之二的数据流关系会漏掉。这两个语言的动态分发和接口隐式实现让 Tree-sitter 级别的启发式分析很吃力。如果你的核心诉求是追踪 JS 或 Go 的数据流,目前要降低预期。

搜索功能本身不强。 符号搜索的 MRR 只有 0.35,Mean Reciprocal Rank,一个衡量搜索结果质量的指标,0.35 意味着正确结果平均出现在第三个位置左右。它不是搜索引擎,别指望它当 Sourcegraph 用。它的强项是找到起点之后沿边遍历,不是找到起点本身。

co-change 预测还不可用。 就是「改了这个文件,历史上通常还会一起改哪些文件」,这个功能基于 git 历史挖掘,目前预测准确率为 0,官方自己标了 experimental。别用它做决策。

FAQ

Q,它会把我的代码传到云端吗。

不会。图谱存在本地 SQLite,MCP 绑定 localhost,零遥测,不发任何网络请求。唯一的网络行为是可选的 embedding 模型从 HuggingFace 下载,下载完也全本地跑。

Q,支持私有仓库和 monorepo 吗。

支持。它只看 git ls-files,不关心仓库在哪。monorepo 可以在根目录 build,也可以在子包目录分别 build。大 monorepo 建议分模块建图,避免单张图过大。

Q,跟 Claude Code 内置的代码搜索有什么区别。

Claude Code 内置的是 glob 和 grep,基于文件名和文本匹配。CRG 给的是结构关系,「谁调用了这个函数」「这个类被谁继承了」「改了这个文件影响哪些测试」,grep 答不了这些问题。两者是互补的,不是替代关系。

Q,构建图谱会不会很慢。

500 文件首次约 10 秒,3000 文件增量约 2.5 秒,其中 1.4 秒是 Python 启动。日常开发开 watch 模式,文件保存自动更新,体感是秒级。

Q,30 个 MCP 工具会不会让 AI 选择困难。

实际不会。AI 通过工具描述选择,而且大部分场景用的是 review-deltareview-pr 这两个封装好的 prompt 模板,不需要手动挑工具。30 个工具是给高级场景用的,比如调试某个函数时手动沿调用链查。

写在最后

我用了一周,最大的感受不是「省了多少 token」,而是 review 质量确实变了。

以前 Claude Code review 代码时,它只会看你给它的 diff,最多 grep 一下相关引用。现在它会顺着图查,「你改了这个函数,但它的子类重写了这个方法,你没改」「这个函数被三个上游调用,其中一个没处理你新加的错误码」。这种 review 是以前做不到的,不是因为模型变聪明了,是因为它终于有了地图。

Token 经济学里有个常被忽略的点,context window 越大,越有人觉得「全塞进去就行」。但大 context 有两个隐性成本,一是钱,input token 按用量计费,二是质量,lost in the middle 效应,模型对 context 中间位置的信息关注度显著下降。把 94 万 token 塞给模型,效果未必好过精准的 2600 token。

code-review-graph 证明了这件事。它不是让 AI 更聪明,是让 AI 少走弯路。

项目地址 github.com/tirth8205/code-review-graph,MIT 协议,自己拿去跑。


🔧 文中用到的完整 Prompt

以上我分享了最核心的几条,完整版合集(共 42 条,涵盖 Code Review · 重构 · 单测生成 · 架构设计 · AI Agent 调教)已整理好。

回复「prompt」即可获取,持续更新。


如果这篇对你有帮助,转发给你的程序员朋友 --- 大家都在摸索 AI 提效,你的分享可能帮他省很多时间。

相关推荐
带电的小王3 小时前
Claude Code + Agnes:接入无限期免费文本、图片、视频模型,告别 Token 焦虑
claude code·agnes
znnnk3 小时前
【AI应用】Agent:AI 为什么需要“自主决策”?
ai·prompt·agent·workflow·ai应用·skill·mcp
Byron07074 小时前
Skill-First 懒加载方案:无向量库的200+ Skill生产级落地方案
skill·claude code
youcans_6 小时前
【嵌入式软件AI编程】12. Claude Code的基本操作
stm32·单片机·ai编程·嵌入式软件·claude code
云浪7 小时前
从 0 手写一个 MCP Server:让 Copilot 调用 Tool 完成四则运算
javascript·node.js·mcp
sarasuki1 天前
MCP 客户端接入:一行注册一个 GitHub 工具
人工智能·agent·mcp
youcans_1 天前
【嵌入式软件AI编程】09. 使用VS Code调试STM32程序
stm32·mcu·ai编程·嵌入式软件·claude code
码哥字节1 天前
给Claude Code装上40个Skill后,我才发现之前都白用了
claude code·ai编程工具