code-review-graph
本地优先的代码智能图工具,通过 Tree-sitter 解析代码结构并为 MCP/CLI 提供上下文压缩,让 AI 编码工具在代码审查时只读取必要文件。基准测试显示每查询可减少约 82 倍 token(最高 528 倍),支持 30+ 语言和增量更新(2秒内)。亮点还包括 GitHub Action 集成、风险评分 PR 审查和跨仓库搜索,适合大型 monorepo 优化 AI 编码体验。
README
code-review-graph
停止燃烧 token。开始更智能地审查。
English | 简体中文 | 日本語 | 한국어 | हिन्दी
使用说明 · 命令列表 · 常见问题 · 故障排除 · GitHub Action · 复现基准测试 · 路线图
AI 编程工具在审查任务中往往会重新读取你代码库中的大部分内容。code-review-graph 解决了这个问题。它利用 Tree-sitter 构建代码的结构化映射,增量地跟踪变更,并通过 MCP 为你的 AI 助手提供精确的上下文,使其只读取关键部分。
快速开始
pip install code-review-graph # 或者:pipx install code-review-graph
code-review-graph install # 自动检测并配置所有支持的平台
code-review-graph build # 解析你的代码库
一条命令即可完成所有设置。install 会检测你拥有的 AI 编程工具,为每个工具写入正确的 MCP 配置,在支持的地方安装平台原生的 hooks/skills,并将图感知的指令注入到平台规则中。它会自动检测你是通过 uvx 还是 pip/pipx 安装的,并生成相应的配置。安装后重启编辑器/工具。
要针对特定平台进行配置:
code-review-graph install --platform codex # 仅配置 Codex
code-review-graph install --platform cursor # 仅配置 Cursor
code-review-graph install --platform claude-code # 仅配置 Claude Code
code-review-graph install --platform gemini-cli # 仅配置 Gemini CLI
code-review-graph install --platform kiro # 仅配置 Kiro
code-review-graph install --platform copilot # 仅配置 GitHub Copilot(VS Code)
code-review-graph install --platform copilot-cli # 仅配置 GitHub Copilot CLI
code-review-graph install --platform codebuddy # 仅配置 CodeBuddy Code
需要 Python 3.10+。为获得最佳体验,请安装 uv(MCP 配置将优先使用 uvx,否则将直接回退到 code-review-graph 命令)。
要从 Git 或 SVN 项目中移除 CRG,可以使用对称的卸载命令,在工作树中的任意位置执行。目标路径会被规范化为工作树根目录,非仓库目录将被拒绝。它仅移除 CRG 拥有的文件和条目;无关的 MCP 服务器、hooks、skills 和 JSONC 注释保持不变。共享配置的更改使用原子替换,因此写入失败时原始文件不会被破坏。
code-review-graph uninstall --dry-run # 预览所有操作;不实际写入
code-review-graph uninstall # 预览,请求确认,然后执行
code-review-graph uninstall --yes # 直接执行,无需提示
code-review-graph uninstall --all-repos # 同时清理所有已注册的仓库
code-review-graph uninstall --keep-data # 移除集成但保留图数据库
code-review-graph uninstall --keep-user-configs --repo . # 仅清理当前项目
然后打开你的项目,向 AI 助手提问:
Build the code review graph for this project
对于一个 500 文件的项目,初始构建大约需要 10 秒。之后,监视模式和支持的 hooks 可以自动保持图更新。
工作原理
你的仓库被解析为 Tree-sitter 的 AST,存储为包含节点(函数、类、导入)和边(调用、继承、测试覆盖)的图,然后在审查时进行查询,计算出 AI 助手需要读取的最小文件集。
影响范围分析
当一个文件发生变更时,图会追踪所有可能受影响的调用者、依赖者和测试。这就是变更的“影响范围”。你的 AI 只读取这些文件,而无需扫描整个项目。
增量更新(< 2 秒)
当 hooks 或监视模式启用时,文件保存和受支持的 commit hooks 会触发增量更新。图通过 SHA-256 哈希检查未更改的文件,仅对变更的文件进行差异分析和重解析。一个 2,900 文件的项目可在 2 秒内完成重新索引。
解决单体仓库问题
大型单体仓库是 token 浪费最严重的地方。图可以穿透噪音——27,700+ 个文件从审查上下文中排除,实际只读取约 15 个文件。
广泛的语言支持 + Jupyter notebook
解析器支持覆盖函数、类、导入、调用点、继承和测试检测,在当前的解析器范围内使用 Tree-sitter,并在需要时使用有针对性的回退。当前支持的语言包括:Python、JavaScript/TypeScript/TSX、Go、Rust、Java、C/C++、C#、Ruby、Kotlin、Swift、PHP、Scala、Solidity、Dart、R、Perl、Lua/Luau、Objective-C、shell 脚本、Elixir、Zig、PowerShell、Julia、ReScript、GDScript、Nix、Verilog/SystemVerilog、SQL、Vue/Svelte SFC、通过 TypeScript 解析器解析的 Astro 文件、Jupyter/Databricks notebook(.ipynb)以及 Perl XS 文件(.xs)。
PHP 项目额外获得仓库限定的 Composer PSR-4 解析、Blade 模板引用,以及当源代码包含显式框架导入、模型继承和接收者证据时的 Laravel Route/Eloquent 语义边。
添加你自己的语言(无需 fork)
如果你的仓库使用了解析器尚未覆盖的语言,可以在 .code-review-graph/ 下放入一个 languages.toml 文件,将文件扩展名映射到 tree_sitter_language_pack 中捆绑的任意语法,以及函数、类、导入和调用的 tree-sitter 节点类型:
[languages.erlang]
extensions = [".erl"]
grammar = "erlang"
function_node_types = ["function_clause"]
class_node_types = ["record_decl"]
import_node_types = ["import_attribute"]
call_node_types = ["call"]
通用的 tree-sitter 遍历器会从中提取信息——无需修改代码,内置语言永远不会被覆盖。参见 docs/CUSTOM_LANGUAGES.md 了解模式引用、验证规则以及完整的端到端示例。
CI 中的风险评分 PR 审查(GitHub Action)
相同的分析以复合 GitHub Action 的形式运行——并且保持本地优先:知识图完全在你的 CI 运行器上构建和查询,不会将任何源代码发送到外部服务。在每个 pull request 上,该 action 会发布一个固定的评论,其中包含风险评分的函数、受影响的执行流程和测试缺口,并在每次推送时原地更新。可选的 fail-on-risk 输入可以将审查变为合并门控。
# .github/workflows/code-review-graph.yml
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: tirth8205/code-review-graph@v2.3.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
参见 docs/GITHUB_ACTION.md 了解输入参数、风险级别和缓存细节,或查看本仓库自身运行的 dogfood 工作流 .github/workflows/pr-review.yml。
基准测试
核心数据:6 个仓库中每个问题的 token 减少中位数约为 82 倍(全语料基线 vs 图查询)。经常被引用的 528 倍是最大值 —— 来自单个最佳情况的仓库(fastapi),并非典型结果。
所有数字来自针对 6 个真实开源仓库(共 13 个 commit)的自动化评估运行器。每次配置固定上游 SHA,Leiden 社区检测使用固定种子运行,embedding 在 CPU 上确定——因此在不同机器上的两次运行会产生相同的数字。完整的复现配方及预期输出见 docs/REPRODUCING.md。每周在 .github/workflows/eval.yml 中针对两个最小配置运行一次仅报告模式的测试。
对于典型的 agent 问题(例如“认证是如何工作的”、“主入口点是什么”等),图返回约 2,000–3,500 个 token 的定向搜索命中结果及邻居边,而不是强制 agent 读取所有源文件。下表综合了 code_review_graph/token_benchmark.py 中定义的 5 个示例问题的平均值。
| 仓库 | 快照 SHA | naive_corpus_tokens | avg graph_tokens | 减少倍数 |
|---|---|---|---|---|
| fastapi | 0227991a |
951,071 | 2,169 | 528.4x |
| code-review-graph | 84bde354 |
208,821 | 2,495 | 93.0x |
| gin | 5c00df8a |
166,868 | 1,990 | 91.8x |
| flask | a29f88ce |
125,022 | 1,986 | 71.4x |
| express | b4ab7d65 |
135,955 | 3,465 | 40.6x |
| httpx | b55d4635 |
89,492 | 2,438 | 38.0x |
6 个仓库的每问题减少中位数:~82x。范围是 38x – 528x,其中 528x 是最佳情况(fastapi,最大语料),并非核心数据。
上述全语料基线是一个上限,没有真正的 agent 会付出这样的代价:一个合格的 agent 会通过 grep 搜索标识符,只读取匹配最好的文件。agent_baseline 评估基准测量的是更现实的基线——纯 Python grep 在语料中搜索,取匹配数最多的 top-3 文件,进行 token 计数,并与图查询成本比较(evaluate/results/<repo>_agent_baseline_*.csv)。
正式的 eval/benchmarks/token_efficiency.py 基准测量的是另一种场景——完整的 get_review_context() JSON 与仅变更文件内容的 commit 比较——对于小 commit,其比值小于 1,因为审查上下文响应包含影响半径边和源片段,其大小可能超过微小的单文件 diff。这不是 bug;两个基准回答的是不同问题。有关完整方法,请参见 docs/REPRODUCING.md。
自 v2.3.4 起,审查和影响工具会附加一个紧凑的 context_savings 估计值,以便 MCP 客户端可以看到每次调用节省的大致上下文。在 v2.3.5 中,CLI 将其显示为上方所示的框格“Token Savings”面板(参见使用说明中的“Token Savings 面板”),并添加了 --verify 来与 OpenAI 的 cl100k_base 分词器进行交叉验证。docs/REPRODUCING.md 中的校准数据显示,在 222 个样本文件的汇总中,该估计值与真实 GPT-4 token 的误差在约 1% 以内。
影响范围分析在全部 13 个评估 commit 中恢复了地面真值中的每一个文件——但请将其视为一个上限,而非“100% 召回率”:在这种模式下,地面真值(变更文件 + 具有调用/导入边进入这些文件的文件)是从预测器遍历的同一个图中导出的,因此它是循环的。精度列中可见的过度预测是故意权衡的结果:宁可标记过多文件,也不能遗漏一个损坏的依赖。
| 仓库 | Commits | 平均 F1 | 平均精度 | 召回率(图导出上限) |
|---|---|---|---|---|
| httpx | 2 | 0.864 | 0.786 | 1.0 |
| fastapi | 2 | 0.834 | 0.750 | 1.0 |
| code-review-graph | 2 | 0.734 | 0.584 | 1.0 |
| express | 2 | 0.667 | 0.500 | 1.0 |
| flask | 2 | 0.628 | 0.481 | 1.0 |
| gin | 3 | 0.609 | 0.439 | 1.0 |
| 平均 | 13 | 0.714 | 0.578 | 1.000 |
基准测试还运行了一个诚实的共同变更模式:预测器以单个变更文件为种子,并根据同一 commit 中作者实际触碰的其他文件进行评分——这些证据来自 git 历史,与图无关。两种模式在结果 CSV 中并列显示(ground_truth_mode 列)。一旦评估运行器捕获到共同变更数字,它们将被添加到标准统计数据中;在测量之前,我们不会引用这些数字。
| 仓库 | 文件数 | 节点数 | 边数 | 流程检测 | 搜索延迟 |
|---|---|---|---|---|---|
| express | 141 | 1,910 | 17,553 | 106ms | 0.7ms |
| fastapi | 1,122 | 6,285 | 27,117 | 128ms | 1.5ms |
| flask | 83 | 1,446 | 7,974 | 95ms | 0.7ms |
| gin | 99 | 1,286 | 16,762 | 111ms | 0.5ms |
| httpx | 60 | 1,253 | 7,896 | 96ms | 0.4ms |
局限性与已知不足
- 影响“召回率 1.0”源自图,是循环的: 历史地面真值来自预测器遍历的同一个图边,因此它天然是一个上限。诚实的共同变更模式(根据同一 commit 中实际共同变更的文件进行评分)与之并列测量;预计这些数字会显著降低。
- 小的单文件变更: 对于琐碎的编辑,图上下文可能超过原始文件读取(参见上方的 express 结果)。开销来自实现多文件分析的结构化元数据。
- 搜索质量(MRR 0.35): 对于大多数查询,关键字搜索会在 top-4 中找到正确结果,但排序需要改进。Express 查询因模块模式命名而返回 0 个命中。
- 流程检测(召回率 33%): 框架和常规入口模式在 Python 和 PHP/Laravel 中表现最强。JavaScript 和 Go 的流程检测需要改进。
- 精度与召回率的权衡: 影响分析故意保守。它标记可能受影响的文件,这意味着在大型依赖图中会有一些误报。
特性
| 特性 | 详情 |
|---|---|
| 增量更新 | 仅重解析变更的文件。后续更新在 2 秒内完成。 |
| 广泛的语言 + notebook 支持 | Python、JavaScript/TypeScript/TSX、Go、Rust、Java、C/C++、C#、Ruby、Kotlin、Swift、PHP、Scala、Solidity、Dart、R、Perl、Lua/Luau、Objective-C、shell 脚本、Elixir、Zig、PowerShell、Julia、ReScript、GDScript、Nix、Verilog/SystemVerilog、SQL、Vue/Svelte SFC、通过 TypeScript 解析器解析的 Astro 文件、Jupyter/Databricks (.ipynb) 以及 Perl XS (.xs) |
| 框架感知的 PHP 解析 | 仓库限定的 Composer PSR-4 导入、Blade 模板引用,以及基于证据的 Laravel Route 到控制器和 Eloquent 关系边 |
| 影响范围分析 | 显示哪些函数、类和文件可能受到变更影响 |
| 自动更新 hooks | Hooks 和监视模式可以在文件保存和受支持的 commit hooks 上更新图 |
| 语义搜索 | 可选的向量 embedding,通过 sentence-transformers、Google Gemini、MiniMax 或任何兼容 OpenAI 的端点(真正的 OpenAI、Azure、new-api、LiteLLM、vLLM、LocalAI) |
| 交互式可视化 | 基于 D3.js 的力导向图,支持搜索、社区图例切换和按度数缩放的节点 |
| 枢纽与桥接检测 | 通过介数中心度找到连接最多的节点和架构瓶颈 |
| 惊喜评分 | 检测意外的耦合:跨社区、跨语言、外围到枢纽的边 |
| 知识缺口分析 | 识别孤立节点、未测试的热点、薄弱社区和结构弱点 |
| 建议问题 | 从图分析中自动生成审查问题(桥梁、枢纽、惊喜) |
| 边置信度 | 三级置信度评分(EXTRACTED/INFERRED/AMBIGUOUS),边附带浮点分数 |
| 图遍历 | 从任何节点进行自由形式的 BFS/DFS 探索,可配置深度和 token 预算 |
| 导出格式 | GraphML(Gephi/yEd)、Neo4j Cypher、Obsidian 库(含 wikilinks)、SVG 静态图 |
| 图差异 | 比较不同时间点的图快照:新增/移除的节点、边、社区变化 |
| token 基准测试 | 测量朴素的全语料 token 与图查询 token 的每问题比率 |
| 估算上下文节省 | 在相关的 MCP/CLI 审查输出上附加紧凑的 context_savings 元数据,标记为估计值并控制在三个小字段内 |
| 记忆循环 | 将问答结果持久化为 markdown 以便重新摄取,使图从查询中增长 |
| 社区自动拆分 | 过大的社区(超过图的 25%)通过 Leiden 算法递归拆分 |
| 执行流程 | 从入口点追踪调用链,按加权关键性排序 |
| 社区检测 | 通过 Leiden 算法对相关代码进行聚类,支持大图的分辨率缩放 |
| 架构概览 | 自动生成带有耦合警告的架构图 |
| 风险评分审查 | detect_changes 将差异映射到受影响的函数、流程和测试缺口 |
| 自定义语言 | 通过 .code-review-graph/languages.toml 添加新语言——无需 fork 或代码变更 |
| GitHub Action | CI 中固定的风险评分 PR 审查评论,带有可选的 fail-on-risk 合并门控 |
| 重构工具 | 重命名预览、框架感知的死代码检测、社区驱动的建议 |
| Wiki 生成 | 根据社区结构自动生成 markdown wiki |
| 多仓库注册 | 注册多个仓库,跨所有仓库搜索 |
| 多仓库守护进程 | crg-daemon 作为子进程监视多个仓库,带有健康检查和自动重启 |
| MCP 提示 | 5 个工作流模板:审查、架构、调试、入职、合并前检查 |
| 全文搜索 | 基于 FTS5 的混合搜索,结合关键字和向量相似度 |
| 本地存储 | SQLite 文件存储在 .code-review-graph/ 中。核心图存储无需外部数据库或云服务。 |
| 监视模式 | 在工作中连续更新图 |
使用说明
斜杠命令| 命令 | 描述 |
|---|---|
/code-review-graph:build-graph |
构建或重建代码图 |
/code-review-graph:review-delta |
审查上次 commit 以来的变更 |
/code-review-graph:review-pr |
完整 PR 审查,包含影响范围分析 |
code-review-graph install # 自动检测并配置所有平台
code-review-graph install --platform <name> # 针对特定平台
code-review-graph uninstall --dry-run # 预览安全移除已安装的组件
code-review-graph build # 解析整个代码库
code-review-graph update # 增量更新(仅变更的文件)
code-review-graph status # 图统计信息
code-review-graph watch # 文件变更时自动更新
code-review-graph visualize # 生成交互式 HTML 图
code-review-graph visualize --format graphml # 导出为 GraphML
code-review-graph visualize --format svg # 导出为 SVG
code-review-graph visualize --format obsidian # 导出为 Obsidian 库
code-review-graph visualize --format cypher # 导出为 Neo4j Cypher
code-review-graph wiki # 从社区生成 markdown wiki
code-review-graph detect-changes --brief # 风险面板 + token 节省(只读)
code-review-graph update --brief # 刷新图 + 相同面板
code-review-graph detect-changes --brief --verify # 与 tiktoken 交叉验证
code-review-graph register <path> # 在多仓库注册表中注册仓库
code-review-graph unregister <id> # 从注册表中移除仓库
code-review-graph repos # 列出已注册的仓库
code-review-graph daemon start # 启动多仓库监视守护进程
code-review-graph daemon stop # 停止守护进程
code-review-graph daemon status # 显示守护进程状态和仓库
code-review-graph eval # 运行评估基准测试
code-review-graph serve # 启动 MCP 服务器
Token 节省面板:detect-changes --brief vs update --brief
两个命令都打印相同的紧凑面板,显示与将变更文件直接交给 agent 相比,图为你节省了多少 token。它们仅在一点上不同:图是否先被刷新。
┌─────────────────────── Token 节省 ────────────────────────┐
│ 完整上下文将会是: 12,921 tokens │
│ 图上下文使用: 762 tokens │
│ 节省: 12,159 tokens (~94%) │
│ 细分:函数 244 · 测试 191 · 风险 244 · 其他 83 │
└──────────────────────────────────────────────────────────────┘
| 命令 | 功能 | 何时使用 |
|---|---|---|
detect-changes --brief |
只读。 查看当前变更,查询现有图,打印面板。约 1 秒。 | 大多数情况下——hooks(或 crg-daemon)在后台保持图更新,因此这就足够了。 |
update --brief |
先重解析变更文件到图中,然后打印相同的面板。约 5 秒。 | 在 rebase、大量变更集之后,或任何你认为图可能过期时。 |
两者最终都打印相同的面板,因为两者都在最后调用相同的 analyze_changes() 步骤。区别仅在于图本身是否在分析之前被刷新。
为任一命令添加 --verify 以与 OpenAI 的 cl100k_base 分词器(GPT-4 系列)进行交叉验证。需要 pip install tiktoken。在典型的变更集上,估计值保持在真实 token 的约 1% 以内——参见 docs/REPRODUCING.md 获取校准数据。
同样的 context_savings 元数据也会自动附加到 get_impact_radius、get_review_context、detect_changes 和 get_architecture_overview MCP 工具的 JSON 响应中,因此 AI agent 可以在聊天中向用户展示节省情况,无需额外提示。
如果你的编辑器不支持 hooks(例如 Cursor、OpenCode),或者你只是希望图在后台保持新鲜而不需要任何编辑器集成,那么守护进程就是为你准备的。它会监视你仓库中的文件变更,并自动重建图——无需手动执行 build 或 update 命令。
守护进程随 code-review-graph 一起提供——无需单独安装。
快速设置:
# 1. 注册你想要监视的仓库
crg-daemon add ~/project-a --alias proj-a
crg-daemon add ~/project-b
# 2. 启动守护进程(在后台运行)
crg-daemon start
# 3. 就这样——图保持自动更新
crg-daemon status # 检查守护进程和每个仓库监视器的状态
crg-daemon logs --repo proj-a -f # 查看特定仓库的日志(持续跟随)
crg-daemon stop # 停止守护进程和所有监视器进程
也可作为 code-review-graph daemon start|stop|status|... 使用。
在底层,crg-daemon add 将配置写入 ~/.code-review-graph/watch.toml 的 TOML 文件中。你也可以直接编辑该文件:
[[repos]]
path = "/home/user/project-a"
alias = "proj-a"
[[repos]]
path = "/home/user/project-b"
alias = "project-b"
守护进程会监视此配置文件的变更,并在仓库被添加或移除时自动启动/停止监视器进程。每 30 秒一次的健康检查会重启已失效的监视器。无需外部依赖。
有关完整配置参考和所有可用选项,请参见 [docs/COMMANDS.md](docs/COMMANDS.md#standalone-daemon-cli-crg