跳到正文
coograph 15

代码图

代码图是一个 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_ofcallees_ofimports_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 力导向视图(不需要服务器)。用任何浏览器打开。拖动节点、悬停看符号详情、按语言或类型筛选。用于检查新构建是否正确、找出孤立模块,以及给队友展示代理实际看到的内容。

Coograph 代码图可视化——节点和边的交互式 D3 力导向视图

为什么选 SQLite

直接走 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-commitpost-mergepost-rewrite)在每次变更后调用 --update。只有内容 SHA-1 变了的文件会被重新解析。从变更文件 import 的文件也会被重新解析,跨文件的边因此保持准确。

局限

在 GitHub 编辑本页 →