Codex 接入 CodeGraph 后的 Token 与进程开销实测

太阳作者太阳
原创内容采用 CC-4.0 协议发布,转载请注明出处

我安装 CodeGraph 的目的很简单:让 Codex 少读文件。它预先整理符号和调用关系,遇到陌生模块时,一次查询就能给出相关源码、调用路径和影响范围。CodeGraph 的文档把这称为“精确上下文”,理论上可以省掉反复搜索和读取文件的过程。

麻烦很快就来了。一次普通的文档整理让对话上下文迅速膨胀,后面的每一轮都变得很重。Windows 后台还留下了 13 套 CodeGraph 进程树。内存占用看得见,但更先影响使用的是 token。

Token 是怎么被吃掉的

这里很容易误判。后台的 Node.js 进程不会直接消耗模型 token,真正进入上下文的是 CodeGraph 返回的文本。

在 Codex 调用工具后,工具结果要交还给模型,模型才能继续判断和修改文件。如果结果包含几千行源码,这些内容会成为当前推理输入,并留在后续对话历史中。对话越长,前面的大块工具结果被携带得越久,直到应用对上下文进行压缩。

OpenAI 的 Responses API 文档说明,长对话可以通过 compaction 压缩,压缩结果也有单独的 cached、reasoning 和 total token 统计。压缩可以腾出上下文空间,但前面的大块工具输出已经参与过推理,代价不会凭空消失。

Codex App 没有给出这几次 CodeGraph 调用各自用了多少 token,所以无法把总消耗精确拆到某一个命令。可以确认的是,工具输出进入了对话,之后的回合一直带着它们:

宽泛问题
  -> CodeGraph 返回大量逐字源码
  -> 工具结果进入当前上下文
  -> 后续回合继续携带这些结果
  -> 对话更早触发压缩,输入规模持续偏大

两次查询就把范围带偏了

项目大约有 600 个索引文件。我当时只是整理 apps/server/README.md,却问了“README 记录了什么,以及涉及哪些脚本、配置、API 模块和部署文件”。这个问题太宽。CodeGraph 返回 55 个符号、5 个文件,还带出了 apps/webapps/desktopapps/miniapp 的源码。

第二次为了确认 Server 架构,我又询问路由挂载、认证边界、OpenAPI 和数据库结构。结果除了目标文件,还出现了 Desktop 代码和归档目录内容。工具倾向于返回“相关符号的逐字源码 + 调用关系 + blast radius”,问题写得越宽,返回内容越容易扩散。

工具只是按查询展开,问题也出在我的用法。项目规则要求有索引时优先使用 CodeGraph,于是 README 和已知路径也走了图查询;提问同时塞进多个主题,没有限定符号;输出上限又给得过大。三个条件叠在一起,结果自然失控。

CodeGraph 官方说明确实建议对结构问题优先使用 codegraph_explore,而且这个工具会返回相关符号的逐字源码。这个默认策略适合追踪陌生调用链,却不适合所有仓库操作。文档、配置和已知文件通常不需要语义图。

进程也没有及时回收

Token 异常后,我又看了 Windows 进程。所有目标都从同一个 codex.exe 派生,共有 13 套 CodeGraph 进程树、39 个相关进程。每套大致是:

codex.exe
└─ cmd.exe
   └─ node.exe
      └─ node.exe

这些进程在十几分钟内陆续启动,旧实例没有随着查询结束退出。它与此前遇到的 STDIO MCP 生命周期问题相似,但仅凭本机现象还不能断定缺陷位于 Codex 还是 CodeGraph。可以确认的是:对话只有一个可见任务时,13 套常驻进程没有实际必要。

执行下面的卸载后,CodeGraph 命令消失,相关 cmd.exenode.exe 进程也归零:

codegraph uninstall

项目中的 .codegraph/ 索引目录仍然存在。它只是本地索引,不会在 CodeGraph 已卸载后自行启动 MCP;是否保留可以单独决定。不要为了清理进程直接执行 taskkill /IM node.exe,那会误伤开发服务器和其他 Node.js 工具。

MCP 进程的完整排查方法放在另一篇文章:Codex App 中 MCP 进程重复启动与无法回收问题排查

rg 替代后发生了什么

卸载 CodeGraph 后,我把同一组 Server 问题换成 rg 重查了一遍。

查看路由挂载:

rg -n '\.route\(|\.get\("/docs"|\.get\("/openapi\.json"' apps/server/src/index.ts

查看数据库事务边界:

rg -n 'transaction\(|getDatabase\(' apps/server/src/db/queries.ts

检查 README 的本地文档链接:

rg -n '\]\(docs/[^)]+\.md' apps/server/README.md

三次查询都只有十几行,足够确认路由、事务和文档入口。没有跨 workspace 的源码,也没有重复打印完整文件。

rg 当然不能替代调用图。遇到接口动态分发、回调链或跨语言桥接时,CodeGraph 仍可能更有效。区别在于,这类需求应该是少数明确场景,而不是所有读取操作的默认入口。

如果继续使用 CodeGraph

卸载后,我也删除了项目规则中“有索引时优先使用 CodeGraph”的要求。如果以后重新安装,我只会在这些情况下使用:

  • 只用于陌生模块的调用链、动态分发和跨文件影响分析。
  • 查询里写明文件或符号,一次只问一个主题,并限制输出长度。
  • README、AGENTS、配置、精确文本和已知路径默认使用 rg
  • 结果开始跨 workspace 时立即停止,不再重复读取同一批源码。
  • 偶尔检查 MCP 进程数,看任务结束后能否回到基线。

如果它仍然频繁返回大段无关源码,我会直接关闭。代码图本来是为了少读上下文,稳定增加 token 就没有继续常驻的必要了。

结论

CodeGraph 对复杂调用链有用,但“任何代码问题都先查图”不适合这个项目。宽泛查询会把多个 workspace 的逐字源码塞进上下文,后面的对话还会继续携带。几十兆的后台进程很显眼,持续膨胀的上下文反而容易被忽略。

目前的处理是卸载 CodeGraph、保留索引目录、移除强制优先规则,并把 rg 恢复为默认搜索工具。等到确实需要动态调用链时,再评估是否临时接回 CodeGraph。

参考资料