$catMANUAL||~26 min

AI Agent 终于能看懂你的代码库了:codebase-memory-mcp 实战体验

advertisement

AI Agent 终于能看懂你的代码库了:codebase-memory-mcp 实战体验

最近 GitHub Trending 上有个项目火得不行,一天涨了 1000 多 star。叫 codebase-memory-mcp,做的事情说白了就是——让 AI 编程 Agent 真正理解你的代码结构,而不是一个个文件瞎翻。

我花了一下午折腾了一下,感觉这东西可能是 MCP 生态里目前最实用的工具之一。今天聊聊它到底解决了什么问题,怎么用,以及跟其他方案比有什么不同。

问题:AI Agent 看代码的方式太蠢了

用过 Claude Code 或者 Codex CLI 的人都有这种体验:你让 Agent 帮你改一个函数,它先用 grep 搜一圈,然后 read_file 一堆文件,再 grep 一轮,再读一堆文件。一个简单的问题,来回折腾十几轮,烧掉几万 token。

为什么会这样?因为 Agent 看代码的方式跟人类完全不同。人类看代码是有结构感的——你知道 auth 目录管认证,api 目录管路由,改一个函数你会先看它被谁调用、调用了谁。但 AI Agent 不知道这些,它只能一个个文件地 grep,像是在图书馆里蒙着眼睛找书。

大型项目尤其痛苦。一个十万行的代码库,Agent 光是找到"这个函数在哪里被调用"就得花好几轮交互,每次都消耗大量 token。更别说理解模块之间的依赖关系了。

我之前在用 Claude Code 改一个 Node.js 项目的时候,想改一个中间件函数。Agent 先搜函数名,找到定义,读完之后又要搜谁 import 了这个模块,然后又要看那个文件里的其他函数……来来回回 8 轮工具调用,烧了将近 3 万 token,才搞清楚一个简单的调用链。当时我就想,这也太蠢了。

codebase-memory-mcp 的思路很简单:既然 Agent 不懂代码结构,那我帮你建一张知识图谱,把整个代码库的函数、类、调用关系全部索引好,Agent 查的时候直接查图谱就行了。

它是怎么做到的

核心是两个技术:tree-sitter 和知识图谱。

tree-sitter 是一个增量解析器,能快速把源代码解析成 AST(抽象语法树)。codebase-memory-mcp 内置了 158 种语言的 tree-sitter 语法,直接编译进了二进制文件里,不需要你额外安装任何东西。

解析完 AST 之后,它会提取出所有的函数、类、接口、枚举、HTTP 路由这些符号,然后分析它们之间的关系——谁调用了谁、谁实现了谁、谁导入了谁——最后存成一个知识图谱。

这个图谱用 SQLite 存储,支持 Cypher 查询语法(就是 Neo4j 那种图查询语言)。Agent 可以直接用图查询来搞清楚代码结构,而不是靠 grep 碰运气。

举个例子,你想知道 handleLogin 函数的调用链:

  • grep 方式:搜 handleLogin,找到定义文件,读文件,搜调用方,读文件,搜调用方的调用方…… 可能要 5-8 轮交互
  • 知识图谱方式:一个 trace_path 调用,直接返回完整调用链,1 轮搞定

官方给的数据是:5 次结构化查询只需要约 3,400 token,而文件级搜索需要 412,000 token。差了 120 倍。这不是玄学,是实打实的性能差距。

而且 tree-sitter 的解析是精确的。它不是靠正则匹配函数名(那种方式会漏掉匿名函数、箭头函数、重载等),而是真正理解语法结构。这意味着它能区分 function handleLogin()const handleLogin = () =>,甚至能识别 class 里的 method 和 standalone function 的区别。

Hybrid LSP 是什么

tree-sitter 负责结构分析,但有些信息光看 AST 拿不到——比如一个变量的实际类型、一个函数的返回值类型。这时候就需要 LSP(Language Server Protocol)了。

codebase-memory-mcp 做了一个叫 Hybrid LSP 的东西:在 tree-sitter 解析的基础上,对 Python、TypeScript/JavaScript、Go、Rust 等 9 种语言做进一步的语义类型解析。比如一个函数参数类型是 User,tree-sitter 只知道它叫 User,Hybrid LSP 能解析出 User 实际定义在哪个文件、有哪些字段。

这对理解代码很有帮助。比如你想改一个 API handler 的返回值,Hybrid LSP 能告诉你返回值的完整类型定义在哪里,不用你再去翻文件。

安装和配置

安装出乎意料地简单。一行命令:

bash
1
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash

它会自动检测你机器上装了哪些编程 Agent(Claude Code、Codex CLI、Gemini CLI、Aider、OpenCode、OpenClaw、Kiro 等 11 个),然后自动配置 MCP 服务器条目、instruction 文件、pre-tool hooks。重启 Agent 就能用了。

如果你想带图形化的知识图谱可视化界面:

bash
1
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash -s -- --ui

装完之后在浏览器打开 localhost:9749,可以看到一个 3D 的交互式图谱,挺炫酷的。虽然日常开发不一定用得上,但第一次看的时候确实会被震撼到——整个代码库的结构一目了然,节点和边的关系清清楚楚。

整个工具是一个纯 C 写的静态二进制,零依赖。不需要 Docker,不需要 runtime,不需要 API key。下载、安装、完事。这点必须给好评,太多 MCP 服务器装起来一堆依赖地狱,搞半天环境都配不对。

Windows 用户

Windows 用 PowerShell:

powershell
1
Invoke-WebRequest -Uri https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.ps1 -OutFile install.ps1
2
.\install.ps1

macOS 和 Linux 都支持 arm64 和 amd64,Windows 只支持 amd64。二进制文件大概 30-50MB,比那些动辄几百 MB 的 Docker 镜像轻量多了。

手动配置

如果你用的 Agent 不在自动检测列表里,也可以手动配置。以 Claude Code 为例,在 .claude/settings.json 里加:

json
1
{
2
  "mcpServers": {
3
    "codebase-memory": {
4
      "command": "codebase-memory-mcp",
5
      "args": ["serve"]
6
    }
7
  }
8
}

其他 Agent 类似,具体参考文档。

14 个 MCP 工具

装好之后,Agent 就多了 14 个工具可以用。挑几个重要的说说。

search_graph — 图谱搜索

按标签、名称模式、文件模式搜索图谱节点。比如搜所有名为 auth 的函数:

code
1
search_graph(label="Function", name="*auth*")

或者搜 src/api 目录下的所有类:

code
1
search_graph(label="Class", file="src/api/**")

支持分页(limit/offset),结果多了不会一次性全返回。

trace_path — 调用链追踪

BFS 遍历调用链。给一个函数名,返回谁调用了它、它又调用了谁。深度 1-5 可调。这是我用得最多的工具。

code
1
trace_path(name="handleLogin", depth=3)

返回的结果是一个树形结构,每个节点都有文件路径和行号。Agent 看到这个就能直接理解函数的上下文,不用再去 grep 了。

detect_changes — 变更影响分析

把 git diff 映射到受影响的符号,计算爆炸半径。改了一个函数,哪些上游调用者会受影响?哪些测试需要跑?

这个在做 code review 的时候特别有用。你改了 UserService.validate 方法,它会告诉你 AuthController.loginAuthController.registerMiddleware.checkSession 都依赖这个方法,需要重点 review。

get_architecture — 代码库概览

返回语言分布、包结构、HTTP 路由、热点文件(被修改最频繁的文件)、代码聚类。让 Agent 快速了解项目全貌。

我一般在新项目第一次用 Agent 的时候先调这个,相当于让 Agent 快速"读"了一遍项目结构。

query_graph — Cypher 查询

直接写 Cypher 查询语句。这是最灵活的工具,能做的事情远超预置的工具。

找所有没有调用者的函数(死代码检测):

cypher
1
MATCH (f:Function)
2
WHERE NOT EXISTS { (f)<-[:CALLS]-() }
3
AND NOT EXISTS { (f)-[:HANDLES]->(:Route) }
4
RETURN f.name, f.file, f.line

排除掉 HTTP 路由处理器(那些虽然没有显式调用者但会被框架调用的),剩下的基本就是可以安全删除的死代码。

找循环依赖:

cypher
1
MATCH (a:Module)-[:IMPORTS*2..6]->(a)
2
RETURN a.name

找最复杂的函数(被最多其他函数调用的):

cypher
1
MATCH (f:Function)<-[:CALLS]-(caller)
2
RETURN f.name, count(caller) as callers
3
ORDER BY callers DESC
4
LIMIT 10

这些查询在大型代码库里特别有价值。手动去做这些分析可能要花好几天,一条 Cypher 语句几毫秒就搞定了。

get_code_snippet — 读取源码

按 qualified name 直接读取函数源码。不需要 Agent 先搜文件再定位行号,直接一步到位。

qualified name 的格式是 <project>.<path_parts>.<name>,比如 myapp.src.auth.handlers.handleLogin。如果不知道 qualified name,先用 search_graph 搜一下。

manage_adr — 架构决策记录

管理 Architecture Decision Records。这个比较小众,但对于团队协作来说挺有用,可以在图谱里记录"为什么我们选了这个方案"。ADR 会作为节点存入图谱,跟代码符号关联起来。

跟其他方案的对比

市面上让 AI Agent 理解代码库的方案,大致分三类。

文件级搜索(grep/ripgrep)

这是最原始的方式,Claude Code 和 Codex CLI 默认就是这么干的。优点是零配置,任何项目都能用。缺点是效率极低,Agent 需要反复搜索才能拼凑出代码结构。对于"这个函数在哪"这种问题够用,但对于"这个函数的完整调用链是什么"就很痛苦了。

RAG(检索增强生成)

把代码切块、嵌入、存向量数据库,Agent 查询时做语义搜索。GitHub Copilot 的 Workspace 和一些代码助手工具就是这个思路。

问题是代码不像自然语言。语义搜索对结构化查询("谁调用了 X?"、"Y 的依赖有哪些?")效果很差。代码的"语义"是调用关系、继承关系、导入关系,不是文字相似度。两个函数名字完全不同,但功能互补、经常一起调用——向量搜索根本发现不了这种关系。

而且 RAG 方案需要把代码切块,切块的粒度很难把握。切太细了丢失上下文,切太粗了检索不精确。

知识图谱(codebase-memory-mcp)

用 tree-sitter 做精确的 AST 分析,把代码结构完整地提取成图谱。查询的时候走图遍历,结果精确且完整。

我个人的体感是:对于结构性问题(调用链、依赖分析、影响范围),知识图谱方案碾压前两种。对于语义性问题("这段代码是干什么的?"),差别不大,因为那本身就是 LLM 擅长的事。

arXiv 上有篇论文(2603.27277)做了对比测试:在 31 个真实代码库上,知识图谱方案的回答质量 83%,token 消耗减少 10 倍,工具调用次数减少 2.1 倍。数据说话。

不过 RAG 方案也不是一无是处。对于自然语言查询("帮我找处理用户注册的代码"),语义搜索有时候比结构化查询更方便。理想情况下两者结合使用效果最好。实际上有些团队就是在用 RAG 做初步定位,再用知识图谱做精确分析,两层过滤下来又快又准。

还有个容易忽略的地方:codebase-memory-mcp 的图谱支持 Infrastructure-as-Code 索引。Dockerfile、Kubernetes manifest、Kustomize overlay 这些都会被解析成图谱节点,Resource 节点代表 K8s 资源,Module 节点代表 Kustomize overlay,它们之间有 IMPORTS 边。如果你的项目涉及容器化部署,这个能力很实用。

实际使用场景

说说我实际用下来的几个场景。

场景一:快速理解陌生代码库

接手一个新项目,不知道代码怎么组织的。以前我会先看目录结构,然后读 README,然后东翻西翻。现在直接让 Agent 调 get_architecture,几秒钟就能拿到语言分布、包结构、主要路由、热点文件。比自己摸索快十倍。

特别是那种文档写得很烂的项目,get_architecture 简直救命。它能告诉你哪些文件最常被修改(说明是核心逻辑),哪些模块之间有紧密的依赖关系。

场景二:影响范围分析

要改一个公共函数,但不确定会影响哪些地方。以前是靠 grep 搜调用方,但 grep 只能搜字符串匹配,搜不到通过别名、重导出等方式的间接调用。知识图谱能追踪完整的调用链,包括跨模块的间接依赖。

detect_changes 工具更进一步:它直接读 git diff,告诉你这次改动影响了哪些符号,每个符号的风险等级是什么。做 PR review 的时候特别好用。

有一次我改了一个 utility 函数的返回值类型,detect_changes 告诉我这会影响到 12 个下游函数,其中 3 个是 API handler。如果没有这个工具,我可能就漏掉了,上线之后才发现某个接口返回格式变了。

场景三:死代码检测

代码库里肯定有一堆没人调用的函数。用 Cypher 查询一行搞定:

cypher
1
MATCH (f:Function)
2
WHERE NOT EXISTS { (f)<-[:CALLS]-() }
3
AND NOT EXISTS { (f)-[:HANDLES]->(:Route) }
4
RETURN f.name, f.file, f.line

排除掉 HTTP 路由处理器和测试函数,剩下的基本就是可以安全删除的死代码。我在一个 5 万行的项目里跑了一下,居然找到了 47 个没人调用的函数,清掉了将近 2000 行代码。

场景四:跨服务调用追踪

如果你的项目有多个微服务,codebase-memory-mcp 能识别 HTTP 调用关系,把不同服务之间的调用链串起来。HTTP_CALLS 边类型就是干这个的。

比如你在 Service A 的代码里有 axios.get('http://service-b/api/users') 这样的调用,图谱会自动建立从 Service A 的函数到 Service B 的 /api/users 路由的边。你就能清楚地看到跨服务的调用拓扑。

场景五:理解测试覆盖

图谱里有 TESTS 边类型,表示测试函数和被测函数之间的关系。你可以用 Cypher 查询找出哪些函数没有对应的测试:

cypher
1
MATCH (f:Function)
2
WHERE NOT EXISTS { (f)<-[:TESTS]-() }
3
AND f.name STARTS WITH "handle"
4
RETURN f.name, f.file

这对提升测试覆盖率很有帮助。

一些注意事项

用了一下午,踩了几个坑,分享一下。

索引大型项目需要时间。官方说 Linux 内核(2800 万行代码)索引要 3 分钟。普通项目几秒到几十秒不等。第一次在项目里用的时候别急,等索引完成再开始问问题。可以用 CBM_DIAGNOSTICS=true 环境变量来看索引进度。

内存占用。索引过程中内存占用会比较高,因为它把所有数据都加载到内存里处理,索引完成后释放。大项目注意留够内存。我试了一个 10 万行的项目,索引时峰值内存大概 1.5GB,完成后降到 50MB 左右。

SQLite 存储。索引结果存在 ~/.cache/codebase-memory-mcp/ 目录下,用的 SQLite WAL 模式。如果你想重新索引,直接删这个目录就行。索引是持久化的,重启 Agent 不需要重新索引。但是代码改了之后需要重新索引才能反映变化。

自动索引。可以用 codebase-memory-mcp config set auto_index true 开启自动索引。Agent 启动的时候会自动检测代码有没有变化,有变化就重新索引。auto_index_limit 可以设最大文件数,超过就不自动索引了。

不支持所有语言的语义分析。tree-sitter 解析是全语言支持的(158 种),但 Hybrid LSP 语义分析(类型解析等)目前只支持 Python、TypeScript/JavaScript、PHP、C#、Go、C/C++、Java、Kotlin、Rust 这 9 种。其他语言只有结构分析,没有类型推断。不过对于大多数项目来说,这 9 种语言覆盖了 90% 以上的场景。

安全考虑。这个工具会读取你的代码库并写入 Agent 配置文件。所有处理都在本地完成,代码不会离开你的机器。官方说每个 release 都有签名、checksum 和 70 多个杀毒引擎扫描。但如果你在公司环境里用,最好先跟安全团队打个招呼。毕竟它确实会修改你的 Agent 配置文件。

自定义文件扩展名。有些框架有特殊的文件扩展名,比如 Laravel 的 .blade.php、ES 模块的 .mjs。可以在项目根目录创建 .codebase-memory.json 来映射:

json
1
{
2
  "extra_extensions": {
3
    ".blade.php": "php",
4
    ".mjs": "javascript"
5
  }
6
}

11 个 Agent 兼容

codebase-memory-mcp 的 install 命令支持自动配置以下 Agent:

  • Claude Code
  • Codex CLI
  • Gemini CLI
  • Zed
  • OpenCode
  • Antigravity
  • Aider
  • KiloCode
  • VS Code(通过扩展)
  • OpenClaw
  • Kiro

基本上主流的 AI 编程工具都覆盖了。如果你用的不在列表里,手动配置 MCP server 也很简单。

跟我的 MCP 服务器列表配合

之前我写过一篇"我每天都在用的 10 个 MCP 服务器",里面提到的 MCP 工具大多是功能性的(GitHub、数据库、文件系统等)。codebase-memory-mcp 不一样,它是基础设施级别的——给 Agent 一个代码理解层,上面所有的编程任务都能受益。

我现在的工作流是:开一个新项目,先让 Agent 跑一遍 get_architecture,建立全局认知。然后在写代码的过程中,遇到需要理解现有结构的地方,就用 trace_pathsearch_graph 查。比以前 Agent 瞎 grep 高效太多了。

特别是在做重构的时候,detect_changes 简直是神器。每次改完代码,跑一下看看影响范围,心里有底。不用提心吊胆地提交了。

常见问题

Q:跟 GitHub Copilot 的 codebase indexing 有什么区别?

Copilot 的索引是基于向量搜索的,擅长语义查询("找处理用户注册的代码"),但对结构化查询("谁调用了 X")效果一般。codebase-memory-mcp 是基于 AST 的图谱,结构化查询是强项。两者可以互补,不冲突。

Q:索引会不会很慢?

普通项目(几千到几万行)几秒到十几秒。官方测试 Linux 内核 2800 万行,3 分钟。关键是索引是一次性的,之后增量更新很快。

Q:支持 monorepo 吗?

支持。它会自动检测项目结构,monorepo 里的每个包都会被正确索引。跨包的导入关系也能追踪。

Q:会不会影响 Agent 的启动速度?

基本不会。MCP server 是按需启动的,Agent 不调用相关工具就不会加载。索引数据存在 SQLite 里,查询走内存映射,延迟在毫秒级。

Q:开源的吗?

是的,MIT 协议。GitHub 仓库:DeusData/codebase-memory-mcp。

Q:能用在私有代码库上吗?

可以。所有处理都在本地完成,代码不会发送到任何外部服务。这点很重要,很多公司不让代码出内网。

写在后面

codebase-memory-mcp 的思路让我想到一个更大的命题:AI Agent 需要的不只是能读文件,而是要有"代码感知力"。就像人类开发者脑子里有一张代码地图一样,Agent 也需要某种结构化的代码理解能力。

MCP 协议的美妙之处在于,这种能力可以被模块化地添加。不需要每个编程 Agent 自己去实现代码分析,一个 MCP 服务器搞定,所有 Agent 都能用。这也是为什么 MCP 生态越来越繁荣——每个工具做好一件事,Agent 负责组合。

后面打算在 Hermes Agent 上也配一下这个 MCP 服务器,到时候再写写实际效果。如果你也在用 MCP 做编程,强烈建议试试。特别是大项目(几万行以上),效果差距会非常明显。小项目可能感知不强,毕竟 grep 也能凑合用。有啥问题评论区聊。

advertisement

AI Agent 终于能看懂你的代码库了:codebase-memory-mcp 实战体验 — AI Hub