首页
/ CodeGraph 索引指南:init 一步建图、增量 sync 与 MCP 会话中的三层自动保鲜机制

CodeGraph 索引指南:init 一步建图、增量 sync 与 MCP 会话中的三层自动保鲜机制

2026-09-06 14:52:53作者:裴麒琰

CodeGraph 把项目预先索引为一张本地代码知识图谱(存储于项目根的 .codegraph/ 目录),供 Claude Code、Codex、Gemini、Cursor、OpenCode、Antigravity、Kiro、CoPilot 等 AI Agent 通过 MCP 调用。本文围绕 官方索引指南 展开:先讲清 init / index / sync 三类命令的分工,再深入文件监听器、防抖同步、按文件陈旧度横幅与连接时追赶这三层"自动保鲜"机制的源码实现,最后说明如何验证索引是否跟手、以及极少数的手动同步场景。读完你可以掌握:如何一步初始化索引、如何让图谱在 Agent 会话期间与磁盘代码保持同步、以及当 Agent 询问"索引是否已追上"时该看哪个输出块。

一步完成初始化与全量索引

cd your-project
codegraph init      # 创建 .codegraph/ 并构建全量图谱 —— 一步到位

codegraph init 在同一个步骤内完成两件事:创建本地 .codegraph/ 数据目录,并构建全量图谱。不存在"init 之后再单独跑 index"的环节——建图完成后,图谱的保鲜就交给后文所述的自动机制。

三个索引命令的分工:

codegraph index           # 全项目全量索引
codegraph index --force   # 从头重建(丢弃既有索引)
codegraph sync            # 增量同步 —— 只重新解析发生变化的文件

sync 之所以快,是因为它只重新解析变化过的文件——文件监听器在每次编辑后替你跑的就是它,日常几乎不需要手动执行。从源码结构看,sync 内部有一条"作用域快速路径":当待处理文件集合是监听事件直接给出的精确文件列表、且规模不超过阈值(watcher.tsSCOPED_SYNC_MAX_PENDING = 500)时,直接把这些路径交给同步流程、跳过 O(仓库规模) 的扫描比对;只有当事件无法完整描述变化(如目录删除、事件风暴超过 500 个文件)时,才回退到全量扫描比对作为"地面真值"。

三层自动保鲜:编辑到下一次查询之间,Agent 不会拿到静默的错答案

在 Agent 会话中你不需要手动跑 codegraph sync 当你的 Agent 通过 codegraph serve --mcp 启动 MCP 服务时,三层机制协同保证索引与代码同步,并且在"编辑发生"到"下一次同步完成"之间那个小窗口里,绝不让 Agent 拿到一个静默的错误答案。

第一层:文件监听器 + 防抖自动同步(始终开启)

MCP 引擎在打开项目后会启动一个原生文件监听器:macOS 上走 FSEvents,Linux 上走 inotify,Windows 上走 ReadDirectoryChangesW,监听范围是整个项目根目录。每个源文件的创建 / 修改 / 删除事件都会被捕获,一个防抖定时器把成串的编辑合并为一次同步。

事件流的典型时序:

agent writes src/Widget.ts
  → watcher fires (event delivery: typically <100ms)
  → 2000ms debounce
  → sync runs; Widget.ts's nodes + edges are in the index
  → next agent query sees it

可调参数:环境变量 CODEGRAPH_WATCH_DEBOUNCE_MS 可覆盖默认 2000ms 的防抖窗口,取值被钳制在 [100ms, 60s]。当构建步骤或格式化工具在短时间内密集写大量文件时,把它调大到 500010000,让监听器把这些写入合并成一次同步。

源码层面这个参数在 engine.tsparseDebounceEnv() 中解析:非数字、非整数或越界值一律视为"忽略这个错误配置",回退到 FileWatcher 的默认 2000ms——设计上选择"不悄悄钳位",因为把 0 或笔误值静默封顶会掩盖真实的配置错误;生效值会打印到 stderr(File watcher debounce: <ms>ms (CODEGRAPH_WATCH_DEBOUNCE_MS))以便排查。

watcher.ts 中的实现还有两个超出文档细节的要点,解释了为什么这套监听器既快又省资源:

  • 平台策略是"有界"的:macOS/Windows 使用单个递归 fs.watch(libuv 映射为一条 FSEvents 流 / 一个 ReadDirectoryChangesW 句柄),无论树多大都只占 O(1) 描述符;Linux 不支持递归监听,因此对每个(非忽略的)目录各挂一个 inotify watch,代价是 O(目录数) 而非 O(文件数)。目录数上限默认 5 万,可用 CODEGRAPH_MAX_DIR_WATCHES 调整;触发 fs.inotify.max_user_watches 内核上限(表现为 ENOSPC)时只告警并停止新增监听,已装的 watch 继续工作,警告信息会直接给出调高上限的 sysctl 命令。
  • 自适应防抖快速路径:待处理文件数不超过 2 个时(一次单独的保存,或"编辑器文件 + 对应测试文件"这种成对出现),防抖窗口缩短为 300ms 的"快速静默窗"(下限 100ms),图谱几乎即时更新;更大的批量变更仍走完整防抖窗口,行为与之前完全一致。防抖语义始终是尾沿(trailing-edge)——每次新事件都会重置计时器。

同步失败的处理同样有界:写锁竞争(另一个进程持有数据库写锁)连续 5 次、或一般性同步失败(解析器崩溃、DB 损坏等确定性错误)连续 5 次后,监听器会永久降级(degrade)而不是无限重试刷日志,并通过回调把"自动同步已禁用,请手动跑 codegraph sync"这类可执行的原因报告给宿主进程;指数退避重试的封顶值为 30 秒。

第二层:按文件陈旧度横幅 —— 覆盖防抖窗口

防抖引入了一个约 2 秒的窗口:刚编辑过的文件已在磁盘上、但还没进索引。CodeGraph 用一个"按文件的陈旧度横幅"封住这个窗口——如果任何 MCP 工具响应引用了当前待重新索引的文件,响应开头就会追加一个 ⚠️ 横幅,点名这些陈旧文件:

⚠️ Some files referenced below were edited since the last index sync —
their codegraph entries may be stale:
  - src/Widget.ts (edited 800ms ago, pending sync)
For accurate content of those specific files, Read them directly.
The rest of this response is fresh.

## Code Context
…

Agent 读到后会直接对点名的文件发起 Read 跟进——官方文档说这一点已经用 Claude Code 端到端验证过:Agent 会字面地说出 "Reading the file directly for the live content" 再去打开文件。也就是说,即使在 2 秒的防抖窗口内,Agent 也绝不会拿到静默的错误答案。

未被响应引用的待处理文件则改以一个小尾注形式呈现(Note: N file(s) elsewhere in this project are pending index sync but were not referenced above: …),保证新鲜度信号始终是显式的,不会悄悄丢失。

源码上,横幅与尾注的文案都由 tools.ts 中的两个纯函数生成:formatStaleBanner()(横幅,逐文件列出 edited <ms>ms agopending sync / indexing in progress 状态)和 formatStaleFooter()(尾注,最多列 5 个文件,超出部分折叠为一行 …and N more)。而"哪些文件是待处理的"来自 FileWatcher.getPendingFiles():每个待处理文件记录首次/最近一次事件时间,且条目只在同步成功提交后、且其最近事件早于同步开始时间时才被清除——同步过程中到达的新事件会继续挂起,留给下一轮同步。注释里写明了取舍偏好:宁可"误报陈旧"(代价至多是 Agent 多 Read 一次),不可"误报新鲜"(会让 Agent 基于过期索引给出错误答案)。

另有一个整索引级别的横幅值得知道:当实时监听永久停止(资源耗尽、锁竞争超过预算等),getPendingFiles() 为空、按文件横幅不会触发,此时读取类工具会改发 ⚠️ CodeGraph auto-sync is DISABLED 横幅,告知 Agent 整个索引已冻结、应直接 Read 文件确认——同样是"绝不静默"原则的延伸。

第三层:连接时追赶同步 —— 覆盖 MCP 服务未运行的空窗

当你的编辑器 / Agent 与 MCP 服务(重新)连接时,CodeGraph 会在回答第一个查询之前先跑一次快速的基于文件系统的对账:先用 (size, mtime) stat 预筛,再对其余文件做内容哈希比对。于是那些在"没有 MCP 服务运行"期间发生的变化——终端里的一次 git pull、从另一个编辑器进来的编辑、一个已经跑完退出的 Agent——都会在下一个会话的第一个工具调用中被自动追上。

源码上这个动作是 engine.tscatchUpSync():在 open() 之后立即在后台执行 cg.sync(),并把返回的 Promise 交给工具处理层作为一个"一次性门闸"——第一个工具调用必须等它完成才返回。这一步的必要性在于:追赶同步不经过监听器,getPendingFiles() 里不会有它的影子,陈旧度横幅帮不上忙;没有门闸的话,抢先于同步完成的查询会返回"文件在磁盘上已不存在"的旧行。同步完成后若有变化,stderr 会打印 Caught up N file(s) changed since last run

验证监听器看到了什么

codegraph_status 工具把待处理集合作为一等公民暴露出来——Agent 问"索引追上了吗"只需一次调用:

codegraph_status →
  ## CodeGraph Status
  …
  ### Pending sync:
  - src/Widget.ts (edited 1200ms ago)

如果响应里没有 Pending sync: 段,就说明当前没有任何同步在途。 对应实现见 tools.tshandleStatus():它除了逐文件列出待处理项(含 edited <ms> agopending sync / indexing in progress 状态),还会报告文件 / 节点 / 边计数、数据库大小、当前 SQLite 后端与日志模式(journal mode 非 wal 时会警告"读取可能被并发写入阻塞")、被中断的解析残留(Pending resolution)以及"自动同步已禁用"段(若监听器永久降级,这里会明确说"索引已冻结,请直接 Read 文件")。

CLI 侧:

codegraph status

报告节点 / 边 / 文件计数、活动 SQLite 后端与日志模式;Agent 会话中的 MCP 侧 codegraph_status 额外给出上面描述的 Pending sync: 块。

什么时候才需要手动 codegraph sync

答案:几乎从不需要。只有两个边缘场景:

  • 监听器被禁用时。沙箱环境会阻止本地文件监听,或者你设置了 CODEGRAPH_NO_DAEMON=1 退出共享守护进程模式——这两种情况下 codegraph sync 是手动兜底。(监听禁用原因由 watch-policy.ts 统一判定,例如 WSL2 下 /mnt/ 挂载盘上的 fs.watch 会长时间阻塞,会被主动跳过并提示手动同步或 git 钩子。)
  • CI 跑之前的预检。如果你是在 Agent 会话之外、通过脚本直接消费索引,在脚本开头跑一次 codegraph sync 可以保证索引反映当前工作树。

除此之外:直接用就行。监听器 + 横幅 + 连接时同步已经端到端覆盖了 AI 辅助工作流。如果你在防抖窗口早已过去之后仍看到文件被真正漏掉,那是一个 bug——请带着复现步骤提 issue。

哪些文件会被索引

所有扩展名映射到支持语言的源码文件,减去以下排除项:

  • 默认排除的依赖 / 构建目录(node_modulesvendordist 等);
  • .gitignore 排除的一切;
  • 超过 1 MB 的文件。

监听器与索引器共用同一套作用域匹配器(内置默认排除 + 项目 .gitignore + codegraph.json 的 include/exclude 规则),两者作用域永远一致;.codegraph/ 数据目录与 .git/ 无论如何都会忽略。完整的排除 / 包含配置与语言清单见官方文档站中的 Configuration 与 Supported Languages 页面。

小结

CodeGraph 的索引模型可以概括为一句话:init 一步建图,sync 只管增量,保鲜交给自动机制。三层机制各管一段窗口——监听器 + 防抖覆盖正常编辑流,按文件陈旧度横幅覆盖防抖窗口内的查询,连接时追赶同步覆盖服务未运行的空窗;codegraph_statusPending sync: 块则是验证一切是否跟手的单一入口。若需进一步阅读源码,建议从 watcher.ts(监听与防抖)、engine.ts(MCP 侧启动、防抖参数解析、追赶同步门闸)与 tools.ts(状态输出与三类陈旧度横幅文案)三个文件切入,配套测试可参考 watcher.test.tsmcp-staleness-banner.test.ts

登录后查看全文
热门项目推荐
相关项目推荐