一、项目快照

CodeGraphcolbymchenry/codegraph)是 2026 年 1 月由独立开发者 Colby McHenry 创建的开源项目,他在 Medium 个人介绍中自我描述为”15+ 年经验的自学软件工程师”。截至 2026 年 5 月 27 日,仓库已经积累了约 29.1k stars / 1.7k forks / 25+ contributors,5 月 23 日单日新增 2,434 star,登上 GitHub Trending 第二位。

技术栈非常简单:

  • TypeScript 94.8% / JavaScript 5.2% 没有 Neo4j、没有向量数据库、没有外部 LLM API。
  • License:MIT
  • 支持平台:Windows / macOS / Linux,要求 Node ≥18 <25;0.9 起捆绑自己的 Node 运行时,可裸机一键安装

一句话定位:给 Claude Code、Codex CLI、Cursor、OpenCode、Gemini CLI、Antigravity、Kiro、Hermes Agent 做”前置索引”的本地 MCP 服务器

二、它到底要解决什么问题

任何用过 Claude Code 或 Cursor agent 模式的人都见过这一幕:你问”用户认证流程是怎么走的?”,agent 立刻派出一个 Explore subagent,开始 grep -r → ls → Read file:1-200 → Read file:201-400 的循环。等它读完十几个文件,几万 token 已经烧掉,你的问题甚至还没真正开始回答。

作者把这件事量化了。在 Medium 长文里他写道:”我在自己的项目上计时——60 次 tool call、157,800 tokens、近 2 分钟的探索,Claude 才真正开始处理我的请求。”

CodeGraph 的核心立论是:这种探索本质上是把”静态结构信息”用 LLM 的工作记忆反复重算。文件之间的调用、import、继承关系是确定性的、AST 可推导的,没有任何理由每次会话都让 agent 用 grep 重新发现。提前算一次、放在本地 SQLite 里、通过 MCP 直接喂给 agent,就够了。

三、架构:极其工程化的 tree-sitter + SQLite

CodeGraph 的设计可以用一张图概括:

3.1 抽取:tree-sitter,而非 LSP

这里介绍一下"程序怎么理解代码"和相关的工具:

tree-sitter 是什么

tree-sitter 是 GitHub 在 2018 年开源的增量解析器生成器,原本是为 Atom 编辑器做代码高亮做的。它的工作就一件事:把源代码字符串变成一棵语法树(AST)

你给它一段 Python:

def add(a, b):
  return a + b

它返回一棵结构化的树:

function_definition
├── name: "add"
├── parameters: [a, b]
└── body
    └── return_statement
        └── binary_expression (+)
            ├── left: a
            └── right: b

三个让它特别受欢迎的特点:

  • 增量解析——你改一行代码,它只重算受影响的子树,不重头扫整个文件。这是它原本叫这个名字的原因,编辑器实时高亮全靠它。
  • 容错——代码语法错了它照样能解析,给你"尽量正确"的树。LLM agent 写代码常常写到一半,这点很关键。
  • 纯语法、不懂语义——它知道 add(a, b) 是个函数调用,但不知道这个 add 到底定义在哪。它不做类型推断、不做跨文件引用解析。

LSP 是什么

LSP 全称 Language Server Protocol(语言服务器协议),是微软在 2016 年为 VS Code 设计、后来变成业界标准的协议。

它解决的问题是:以前每个 IDE 都得为每种语言单独写一套"代码智能"(跳转到定义、自动补全、找引用、重命名……)。N 种 IDE × M 种语言 = N×M 份重复工作。LSP 把这个矩阵拆成两半:

编辑器 (VS Code / Neovim / Cursor)
        ↕  LSP 协议 (JSON-RPC)
语言服务器 (rust-analyzer / pyright / tsserver / clangd)
        ↕
你的代码

语言服务器是真正懂这门语言的程序——它通常基于编译器本身(rust-analyzer 来自 Rust 编译器团队、pyright 是微软的 Python 类型检查器、tsserver 来自 TypeScript 团队)。它能回答语义级问题

  • "光标下的 validateToken 跳转到哪里?"
  • "这个变量是什么类型?"
  • "谁调用了这个函数?"(不是名字相同的,是真正调用这个定义的)
  • "把这个函数改名,所有引用一起改"

LSP 跑得更准,因为它真的理解类型系统、import resolution、泛型实例化——本质上它在脑子里维护了一份能编译的代码模型。

两者的关键差异

tree-sitter LSP(语言服务器)
回答的问题 语法:"这是个函数吗?" 语义:"这个函数定义在哪?"
需要编译吗 不需要,代码错了也能解析 通常需要项目能编译/类型检查
跨文件理解 没有
每种语言 一份 wasm(小、统一) 一个独立的服务器进程(重、各家实现差异大)
速度 毫秒级,编辑器实时用 大项目首次加载几秒到几十秒
典型用途 语法高亮、代码折叠、批量符号抽取 IDE 跳转、重命名、补全、类型检查

CodeGraph 选 tree-sitter 而不是 LSP,是一个明确的工程权衡

  • 它放弃了"真正理解类型"的精度(比如 obj.foo() 里 obj 到底是什么类的实例,tree-sitter 答不上来)
  • 换来了三件事:不用项目能编译(agent 在写到一半的代码上也能工作)、一份 wasm 覆盖所有平台(部署极简)、索引快到可以毫秒级响应文件保存

CodeGraph 全部走 tree-sitter wasm,对每种语言写一份 query 提取以下节点(来自 CLAUDE.md 列出的 NodeKind):

file, module, class, struct, interface, trait, protocol, function, method, property, field, variable, constant, enum, enum_member, type_alias, namespace, parameter, import, export, route, component

和以下边(EdgeKind):

contains, calls, imports, exports, extends, implements, references, type_of, returns, instantiates, overrides, decorates

这是关键的技术权衡:tree-sitter 比 LSP 弱(没有真正的类型推断、没有跨包符号表),但它有三个决定性优势:(1) 不需要项目能编译;(2) 一份 wasm 二进制覆盖所有平台;(3) 增量解析快到可以毫秒级响应文件保存。对一个面向 agent 的”探索性查询”工具,这个折中是合理的。

支持的语言现在已扩展到 21 种:TypeScript / JavaScript / Python / Go / Rust / Java / C# / PHP / Ruby / C / C++ / Swift / Kotlin / Scala / Dart / Svelte(含 Svelte 5 runes 和 SvelteKit 路由)/ Vue(含 Nuxt)/ Liquid(Shopify 主题)/ Pascal-Delphi(含 DFM/FMX 表单文件)/ Lua / Luau(Roblox)。

3.2 存储:SQLite + FTS5,没有图数据库

这是 CodeGraph 和友商最大的体系差异之一。看 schema(来自 IMPLEMENTATION_PLAN.md)就知道作者在追求什么:

nodes(id, kind, name, qualified_name, file_path, start_line, end_line,
      language, signature, docstring, code_snippet, code_hash, metadata)
edges(source_id, target_id, kind, resolved, target_name, line_number)
files(path, content_hash, language, last_indexed, node_count)
unresolved_refs(...)
nodes_fts USING fts5(...)   -- 全文搜索

节点 ID 就是字符串路径如 "func:src/auth.ts:validateToken:45"。SQLite 在 WAL 模式下并发读写不阻塞,再加上为每种查询模式都准备好索引,BFS/DFS 在 10 万节点级别仍然亚毫秒。

值得注意的是,仓库早期的设计里有 vectors/ 模块(基于 @xenova/transformers 跑 ONNX,存 384 维 nomic-embed-text-v1.5 embeddings,SQLite vss 索引),但在某次提交中被整个移除了——issue #87 里有中国用户 zzqq131 直接问”为什么把整个向量搜索和 embedding 模块删掉?”。这个决策意味深长:作者用实测发现,对”找调用链、找定义、找路由”这类问题,符号名 + FTS5 + 图遍历就足够了,向量检索引入的延迟和不确定性反而是负担。

3.3 引用解析:手写而非 LLM 总结

resolution/ 模块做三件事:

  1. Imports → 文件:识别 tsconfig path alias、Cargo workspace、Python package
  2. Calls → 定义:先用 import 表过滤候选,再做 name matching
  3. Inheritanceextends / implements 双向边

特殊的是 dynamic-dispatch 桥接(synthesizers):识别 callback/observer 注册、EventEmitter、React setState → render、JSX render → child component、Django ORM descriptors 等模式,给图加一条 provenance: 'heuristic' 的合成边。这是让 trace 工具能跨”事件分发、回调、运行时绑定”这些 grep 永远穿不过的边界的关键。

3.4 暴露给 agent 的 10 个 MCP tool

按文档语义分两类。重型工具(agent 主力,main session 应避免直接调用)

  • codegraph_context — 给定一个任务/特性描述,组合 search + node + callers + callees,一次返回”涉及到的入口和上下文”
  • codegraph_trace — “X 是怎么调到 Y 的”,每一跳的函数体内联返回,跨动态分发,一次 trace 调用就结束流程探索
  • codegraph_explore — 一次返回若干相关符号的源码(按文件分组)+ 关系图

轻型工具(main session 可直接用,用于做改动前的精准查询)

  • codegraph_search(按名字找符号,只返位置)
  • codegraph_callers / codegraph_callees(调用链)
  • codegraph_impact(改动影响半径)
  • codegraph_node(单个符号详情,可附源码)
  • codegraph_files(项目文件树,比文件系统扫描快)
  • codegraph_status(索引健康度)

CLAUDE.md 里有一段工程笔记,值得 agent 开发者借鉴:”CodeGraph 影响 agent 行为的渠道是低显著性的——只有 MCP initialize instructions 和 tool descriptions。改 wording 并不能可靠地改变 agent 的 tool 选择风格。真正起作用的是让工具本身一次性给够,让 agent 没有理由 fallback 去 Read。

3.5 框架感知路由

extraction/frameworks/ 识别 14 类 web 框架的路由声明,把它们也变成图节点(kind: 'route'):

Django ( path/re_path/url/include)、Flask、FastAPI、Express、NestJS(含 GraphQL/WebSocket)、Laravel、Drupal( *.routing.yml + hook_*)、Rails、Spring( @GetMapping 等)、Gin/chi/gorilla/mux、Axum/actix/Rocket、ASP.NET( [HttpGet])、Vapor、React Router/SvelteKit

这意味着你可以让 agent 问”POST /api/users 这个接口的实现在哪?影响哪些下游?”——一次 codegraph_impact 直接出结果。

3.6 自动同步

sync/ 用原生 OS 事件 (FSEvents / inotify / ReadDirectoryChangesW),2 秒静默窗口 debounce,只过滤源码文件,做增量 reparse。结果是:你 Cmd-S 保存代码,再问 agent 时图已经更新。

四、横向对比:code RAG 这个赛道分几派

我把目前面向 AI agent 做代码上下文的工具按”如何表示代码”分了五派。CodeGraph 处在”图派 + 本地优先”那一格,相对位置很清楚:

工具 核心表示 索引位置 给 agent 的接口 主要场景
CodeGraph tree-sitter AST → SQLite 图 + FTS5 本地 MCP(10 个工具) Claude Code/Cursor/Codex 等 agent 的探索加速
Aider repo map tree-sitter tags + PageRank 本地 拼到 prompt 里 Aider 终端 pair programming
Cursor 内建索引 文件分块 → embedding 远端 Turbopuffer + Merkle 树同步 @Codebase Cursor IDE 内
Continue.dev tree-sitter 分块 + embedding + FTS 本地 ~/.continue/index @Codebase / @Folder Continue IDE 插件
Sourcegraph Cody SCIP(LSIF 后继)+ embedding 远端 Sourcegraph 实例 内建 + MCP server 企业代码搜索
Augment Code 语义索引(专有 Context Engine) 远端 MCP(远端 HTTPS) 企业级 agent,跨仓
Potpie.ai Neo4j 属性图 服务端(自托管或 SaaS) FastAPI + 专用 agent 企业 spec-driven 大代码库
Greptile 仓库依赖图 远端 SaaS PR review agent AI code review
Bloop 语义搜索 桌面/远端 桌面 UI 自然语言代码搜索
Repomix / Code2Prompt / yek 整库拼成大文本 本地 复制粘贴 / MCP 给长上下文 LLM 做一次性 dump
CodeQL 数据流+控制流 facts → Datalog 本地 QL 查询 安全分析 / variant analysis
Glean (Meta) 通用代码事实库 + SCIP 输入 服务端 Glass API Meta 内部 IDE / RAG

4.1 对比Aider 的 repo map:相似目标,不同形态

Aider 是这条思路的开山者。它同样用 tree-sitter 抽 tags,但用 PageRank 给整个 repo 的符号排序,再在一个 token budget 里塞最重要的 N 个 tags 进 prompt。对比 CodeGraph:

  • Aider 是”预算化的单次上下文“——Aider 官方文档明确写道:
"这个 token 预算受  --map-tokens 参数控制,默认 1k tokens。Aider 会根据对话的当前状态动态调整 repo map 的大小。"(默认 1k tokens 的 repo map 跟着每次对话发,可动态扩展)
  • CodeGraph 是”按需图查询“——agent 自己决定问哪一片,每次只取相关子图。

对 Aider 这种”一次会话改几个文件”的 pair programming 模式,PageRank 静态摘要足够好。对 Claude Code 这种”先 explore subagent 摸清架构”的 agent 流水线,CodeGraph 的按需查询更省 token。

4.2 对比Cursor / Continue:embedding 派和图派的根本差异

Cursor 的做法是教科书级的 RAG,且公开的工程细节最完整:根据 Cursor 官方博客 cursor.com/blog/secure-codebase-indexing 和 turbopuffer 的客户案例页面

"Cursor 用一棵  Merkle 树来构建对代码库的初始视图……每个代码库实例在 turbopuffer 里都是一个独立的命名空间(namespace)。"
"turbopuffer 为 Cursor 提供代码检索能力——在合适的时机,把代码搜索的结果填充进上下文窗口。"。

流程是:本地按 tree-sitter 切块 → 上传 Cursor 服务器 → 算 embedding → 存进 Turbopuffer 向量库 → 本地用 Merkle 树同步差异。Continue.dev 类似,但 embedding 在本地用 transformers.js 算,索引落盘到 ~/.continue/index

Embedding 派的强项:语义模糊查询好,”哪里在处理用户限流”这种问得到答案。短板:精确的”谁调用了 validateToken“是不可靠的,因为相似度排序会把名字相近但无关的函数排上来。

CodeGraph 反过来:结构化关系是精确的,模糊语义靠不上。问”日志系统在哪里实现”,CodeGraph 不一定胜过 embedding;但问”Session.request() 一路调到 URLSession.dataTask() 经过哪 9 个函数”——README 里那个 Alamofire 基准测试给出了答案,一次 trace 调用,depth 3,完整 9 跳链路。这种 call chain 是 embedding 路线几乎不可能做到的。

4.3 对比Sourcegraph Cody:精确性维度类似,部署模型相反

Cody 用 SCIP(Sourcegraph Code Intelligence Protocol,LSIF 的后继协议)——通过 scip-typescriptscip-javarust-analyzer 等真正的编译器/类型检查器精确抽取符号。这比 tree-sitter 更准(懂泛型实例化、懂 import resolution 的所有边角),代价是每种语言都要一个专门的 indexer,要能编译。

部署上:Cody 中心化(数据上传 Sourcegraph 实例),CodeGraph 本地化.codegraph/codegraph.db 文件不离开你的机器)。对个人开发者和不愿外传源码的团队,CodeGraph 的”无 API key、无外部服务”是硬性优势。对需要跨百仓库导航的大型组织,Sourcegraph 仍然是天花板。

4.4 对比Potpie.ai:同样图派,不同重量级

Potpie 也是知识图谱路线,但走的是重型路线:用 Neo4j 存属性图、FastAPI 服务层、Celery 任务队列、CrewAI 编排的 RAG agent。根据 http://itbrief.asia 的融资公告:

"Potpie 的目标客户是 百万行代码量级起步的大型企业……目前 Potpie 已经在为财富 500 强企业、以及医疗健康、保险科技等受监管行业的上市公司提供服务。"

Potpie 于 2026 年 3 月完成 220 万美元 Pre-Seed 融资,由 Emergent Ventures 领投,All In Capital、DeVC 和 Point One Capital 跟投。

CodeGraph 是轻型路线:一个 npm 包、一个 SQLite 文件、一个 MCP server,目标用户是”用 Claude Code 在自己项目里写代码的个人开发者和小团队”。Potpie 的图比 CodeGraph 更”语义化”——每个函数都有 LLM 生成的 docstring 写进图。CodeGraph 坚持”extraction 是确定性的,源自 AST,不被 LLM 总结“(CLAUDE.md 原话)——这让索引完全可复现、无 LLM 调用成本,但也意味着图本身不携带语义注解。

4.5 对比Augment Code:商业 Context Engine

Augment 把”context engine”做成卖点,但其定位明确不是”百万 token 暴力填充派”——其官方博客标题就是 “Context Window Wars: 200k vs 1M+ Token Strategies”,主打 200K 上下文 + 智能检索,索引能力上限按官方页面是 ”up to 500,000 files simultaneously across dozens of repositories”。Augment 的 MCP server 也可以接到 Claude Code/Cursor 上用。

对企业,Augment 的合规(SOC 2 Type II、ISO/IEC 42001)、单租户、BYOK 是 CodeGraph 没有的。对独立开发者,Augment 的远端架构和按 credits 计费是负担——Augment 官方文档 docs.augmentcode.com/context-services/mcp/overview 明确说:

"Context Engine MCP 按查询计费,每次查询消耗的 credits 数量不同——具体取决于底层成本和检索量。根据我们的实际数据,平均每次查询消耗  40–70 credits。"

4.6 对比repomix / code2prompt / yek:完全不同的哲学

这一派是”把整个 repo 拼成一个大文件“。在 Gemini 2.5 Pro 这种百万 token 模型上塞得下时管用,对大型 repo 几乎瞬间失效——Next.js repo 单纯文本就 5600 万 tokens。yek 用 git history 做优先级排序部分缓解了这个问题。

哲学差异:他们假设模型能在长上下文里自己挑相关内容;CodeGraph 假设 agent 应该被引导只看相关子图。 后者在 Claude Opus 4.7 这种 1M 上下文模型上仍然有意义,因为”应付得了”和”花得起钱”是两回事。

4.7 对比CodeQL / Glean:不同层次的目标

CodeQL(GitHub)和 Glean(Meta 开源)也都把代码变成可查询的事实库,但目标是精确语义分析——CodeQL 用 QL 语言查数据流污点分析、Glean 用 Datalog 风格的 Angle 查 facts。表达力远超 CodeGraph,但学习曲线陡、面向静态分析工程师而非 LLM agent。CodeGraph 是把”图查询”包装成 agent 友好的高层意图(”找谁调用了 X”),不是给人写复杂查询用的。

五、上手:三条命令

# 一次性安装(自动检测并配置已安装的 agent)
curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh
# 或:npx @colbymchenry/codegraph

# 在项目里初始化 + 索引
cd your-project
codegraph init -i

# 启动 MCP 服务(agent 会自己拉起来,通常不用手动跑)
codegraph serve --mcp

CLI 还包括 codegraph indexcodegraph sync(增量更新)、codegraph query <name>codegraph context <task>codegraph impact <symbol> 和一个有趣的 codegraph affected——基于图反向追踪”我改了 src/auth.ts,哪些测试文件会被影响”,可以塞进 CI 只跑相关测试:

git diff --name-only HEAD | codegraph affected --stdin --quiet | xargs vitest run

作为库使用(TypeScript):

import CodeGraph from '@colbymchenry/codegraph';
const cg = await CodeGraph.init('/path/to/project');
await cg.indexAll();
const results = cg.searchNodes('UserService');
const callers = cg.getCallers(results[0].node.id);
const context = await cg.buildContext('fix login bug',
  { maxNodes: 20, includeCode: true, format: 'markdown' });
const impact = cg.getImpactRadius(results[0].node.id, 2);
cg.watch();  // 自动同步

六、实测结果(作者基准)

README 里有两组数字——这里我把它们都列出来,因为方法论不同:

早期 README:Claude Opus 4.6,单次运行,每个 repo 一个 Explore agent:

  • VS Code (TS, 4002 文件, 59377 节点) → 3 calls 17s vs 52 calls 97s(94% 更少 · 82% 更快
  • Swift Compiler (25,874 文件, 272,898 节点) → 6 calls 35s vs 37 calls 128s,索引耗时 < 4 分钟
  • 平均 92% fewer tool calls, 71% faster

v0.9.4 (2026-05-24) 重新验证:Claude Opus 4.7、claude -p headless、--strict-mcp-config、每组 4 次取中位数——更严谨的方法论给出更保守的数字:

平均 35% 更便宜 · 57% fewer tokens · 46% faster · 71% fewer tool calls(横跨 7 个真实开源项目)

第二组数字更可信,作者自己也写明大型 repo 收益更明显,像 Gin(约 150 个文件)这种小项目”native search 已经够便宜,差距被压缩”。

七、结论与建议

以下情况考虑用 CodeGraph :

  1. 主力 agent 是 Claude Code / Codex CLI / Cursor agent 模式,且经常在 1 万文件以上的项目里工作
  2. 不能或不想把源码上传到 SaaS(合规、隐私、纯偏好均算)
  3. 看重”调用链、影响分析、impact radius”这类精确结构化问题胜过”语义模糊匹配”
  4. 想要零配置——codegraph init 一条命令就完事,没有 embedding 模型选型、没有向量库、没有 API key

以下情况不建议用 CodeGraph:

  1. 需要跨多仓推理——CodeGraph 是单仓本地索引,不做 cross-repo
  2. 主要场景是”我不记得这段逻辑在哪、按语义找一下”——纯 embedding 工具(Cursor 内建、Continue)在这类查询上更稳
  3. 是企业,需要 SOC 2 / 单租户 / BYOK / 跨百仓——Sourcegraph、Augment、Potpie 是更合适的天花板
  4. 需要真正的类型推断和泛型解析做安全分析——SCIP/CodeQL 路线更准

一个值得借鉴的工程教训

CodeGraph 的演化过程本身比代码更有启发——作者最初设计了向量搜索 + embedding 模块(IMPLEMENTATION_PLAN.md 里有完整 384 维 sqlite-vss 设计),但在生产实测后删掉了整个模块。理由很简单:对 agent 的探索性查询,”按名字 + 结构边 + FTS5”已经把 95% 的问题解决了,引入 embedding 增加的延迟和不确定性反而把好不容易省下的 tool call 又花了回去。

这给所有 AI agent 工程师一个提醒:code RAG ≠ document RAG。代码有 AST,有调用图,有静态可推导的关系——把这些先吃掉,再考虑用 embedding 补语义层。CodeGraph 选了相反的优先级,并且效果不错。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐