代码图
代码图是一个 SQLite 数据库——.code-graph/graph.db——保存仓库的结构关系。定义、调用、导入、文件 → 文件的边、语言元数据。你的 AI 代理通过 MCP 工具查询它,而不是为每个问题重新 grep。
图里有什么
两张表,纯 SQL:
CREATE TABLE nodes (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
kind TEXT NOT NULL, -- 'function', 'class', 'method', 'file', 'module'
file_path TEXT NOT NULL,
line INTEGER,
language TEXT
);
CREATE TABLE edges (
src_id INTEGER NOT NULL REFERENCES nodes(id),
dst_id INTEGER NOT NULL REFERENCES nodes(id),
kind TEXT NOT NULL, -- 'calls', 'imports', 'defines', 'inherits'
PRIMARY KEY (src_id, dst_id, kind)
);
想直接用 sqlite3 查也行。MCP 服务器只是一层类型化的便利封装。
支持的语言
tree-sitter 解析器支持:Python、TypeScript、JavaScript、Go、Rust、Java、C#、Ruby 等。没有 tree-sitter 包的语言自动回退到正则解析器——覆盖度下降,但构建不会失败。
完整列表见 .github/code-graph/requirements.txt。
MCP 工具
MCP 服务器向代理暴露以下查询:
| 工具 | 用途 |
|---|---|
get_minimal_context(task) | 根据任务描述返回 4–6 个相关文件。默认在任何 read_file 之前先调用。 |
query_graph(kind, target) | 通用图查询:callers_of、callees_of、imports_of 等。 |
get_impact_radius(symbol) | 修改某个定义会影响到的文件。 |
get_review_context(diff) | 代码评审任务用:diff 引用的文件加上它们的直接邻居。 |
find_large_functions(threshold) | 超过 N 行的函数——技术债扫描。 |
detect_changes() | 自上次更新后 SHA-1 变化的文件。 |
update_graph() | 增量重新解析变化的文件。 |
build_graph() | 从零完整重建。 |
graph_stats() | 节点 + 边数量、上次更新时间、按语言分的文件数。 |
visualize_graph() | 在 .code-graph/graph.html 渲染交互式 HTML 图。 |
可视化
uv run --with-requirements .github/code-graph/requirements.txt \
.github/code-graph/server.py --visualize
输出 .code-graph/graph.html——独立的 D3 力导向视图(不需要服务器)。用任何浏览器打开。拖动节点、悬停看符号详情、按语言或类型筛选。用于检查新构建是否正确、找出孤立模块,以及给队友展示代理实际看到的内容。

为什么选 SQLite
- 查询零依赖。 任何装了
sqlite3的人都能直接戳图,不用启动 MCP 服务器。 - 便宜。 5 万行代码库的图通常只有几 MB。
- 跨机器稳定。 队友从同一个提交重建图能拿到同样的数据库——测试夹具级别的可复现性。
直接走 SQL
如果没有 MCP,数据库就是一个文件:
sqlite3 .code-graph/graph.db "
SELECT n2.file_path, n2.line, n2.name
FROM edges e
JOIN nodes n1 ON e.src_id = n1.id
JOIN nodes n2 ON e.dst_id = n2.id
WHERE n1.name = 'OrderService' AND e.kind = 'calls'
"
这是 MCP 服务器没注册时的官方回退方案。Coograph 项目里的代理知道先试 MCP,再回退到 sqlite3,只有两者都失败时——才用 grep。
自动更新
.github/code-graph/ 里的 git 钩子(post-commit、post-merge、post-rewrite)在每次变更后调用 --update。只有内容 SHA-1 变了的文件会被重新解析。从变更文件 import 的文件也会被重新解析,跨文件的边因此保持准确。
局限
- 图捕获的是结构关系,不是语义关系。它知道
place_order调用validate;但不知道加缓存会影响下游的计费逻辑。 - 覆盖度依赖于你所用语言的 tree-sitter 可用性。回退的正则解析器能找符号,但会漏掉一些边(比如动态分发)。
- 图按文件粒度重建。如果你提交了千文件级的重构,增量更新就是 O(千文件)。