
这是什么
CodeGraph 把代码库变成 agent 能检索的东西:tree-sitter 抽出函数、类、接口、导入与调用,FalkorDB 连同有效期区间一起存下,于是问题可以按某个时间点来问;五个 MCP 工具——analyze、codebase、knowledge、query、search——把它暴露给 agent。它可以在 Linux 与 Apple 芯片上用内嵌数据库运行,其它平台接外部 FalkorDB;六种语言一等支持,之外靠通用 tree-sitter;同时以 npm 包和 Claude Code 插件两种形态发布。
谁做的GitHub 账号 Phoenixrr2113,522 次提交里有 516 次挂在已关联账号上。历史里出现过三个地址——一个个人 Gmail、第二个个人地址,以及一次来自企业域名的提交;而项目的 npm 包发布在 @agntk 这个 scope 下,仓库里没有解释。这个仓库上的自动化审查量远大于它的读者量,所以提交历史反而是「它是怎么做出来的」最好的证据。
制作过程
8 个阶段- 01
三分之二的提交写明了共同作者
522 次提交里有 342 次带一条写明模型的共同作者尾注——66%,和 AI Comic Builder 同一区间,低于 gate4agent 的 71%。模型构成被一个模型主导:百万上下文的 Claude Opus 4.7 独占 139 次,随后是 Sonnet 4.6 的 100 次、同样上下文的 Opus 4.6 的 59 次、Fable 5 的 21 次、普通 Opus 4.6 的 18 次。AI Comic Builder 记录的是一个项目从某个模型换到另一个,gate4agent 记录的是一大片分布,而这一个记录的是安定下来:五分之四的尾注指向同样三个模型,同样的几个家族在八个月里反复出现。pull request 也用同样的方式签名,有几条末尾就写着由 Claude Code 生成;而这个仓库比多数走得更远——它本身就是以 Claude Code 插件的形式发布的,
.claude-plugin/hooks/里有一个 post-tool-use 钩子和一个 pre-compact 钩子。 - 02
它做什么
问题在于,agent 回答一个关于大型代码库的问题时,会把上下文花在读文件上。CodeGraph 改为解析代码——函数、类、接口、变量、类型、导入、调用——把关系写进 FalkorDB,然后从图上回答。有两个设计选择值得点名。事实带着
valid_at与invalid_at时间戳,所以这张图是双时间的,一次查询可以问「代码在某个时间点是什么样」,而不是只能问现在。五个工具也刻意做得少,并按它们回答的问题命名——analyze、codebase、knowledge、query、search——而不是把图直接暴露出去。TypeScript、JavaScript、Python、Go、Rust、Markdown 一等支持,之外靠通用 tree-sitter;运行方式有两种:Linux x64 与 Apple 芯片用内嵌,其余平台接外部 FalkorDB。npm 包装出两个命令——一个 MCP 服务和一个面板——README 明确说它们是各自独立的入口,可以同时对着同一条数据路径跑。 - 03
一个脚本,会禁止它自己曾经要求的措辞
这个仓库的脚本里有一个是用来审计自己声明的,而宣布 npm 发布的那条 pull request 描述了它如何调转枪口:0.1.0 上线之后,每一处表述都不该再写成「待发布」,于是那个审计脚本被改成禁止它此前一直要求的那种门禁措辞。同一条 PR 还记下:每周下载量的徽章「在 npm 给出计数之前,会诚实地显示 too new」,而不是把它藏起来;发布被验证为「registry 上的 tarball 与 release 产物逐字节相同,且两种公开调用形式都能从 registry 启动」。后面一条 PR 拿文档对着已合并的源码逐条校正,并找出真实的漂移:某个 README 让人把环境变量设成
1,而代码检查的是字面字符串true;代码明确拒绝的一个 provider 仍被文档推荐,于是被全局删除;内嵌存储被写成需要先跑一个数据库服务,而包里其实自带二进制;还有一个包文档里的类型边清单与代码中实际的十八个成员的联合类型对不上。被脚本检查的文档仍然会漂移,但它漂移得看得见。 - 04
侦察者去跑了实验,而不是去推理
有一条 pull request 用一段话说明它为什么阻塞了发布:一个「侦察者」——这是项目的用词——去跑实验而不是去推理,找出了三个阻塞项。两个进程指向同一个内嵌数据目录时,会拉起两个数据库服务,而一个关闭顺序的测试抹掉了一张已建索引的图。从包自己的目录里执行打包,产出的是一个里面没有服务端的归档。而空数据库不是一个能用的首次运行:两个二进制都返回服务端错误和裸露的空键信息,「而这正是线上面板第一次加载时撞上的东西」。修复分五波依次落地,其中第一波最有意思——一套共享的内嵌存储:第一个进程取得原子属主租约并记下自己的 socket,后来的进程作为客户端通过该 socket 接入,被杀的属主留下的过期租约能被安全回收,启动竞争收敛到唯一属主,伪造的租约会被拒绝。文中写明的收益是:Claude Code 和面板可以同时打开同一个数据库。
- 05
一次 CI 失败,根因是一个环境变量
bootstrap 发布跑失败了两次,报的是同一句话:并发的两个二进制没有共享唯一那个内嵌服务端 socket。根因属于那种通常靠重跑就能糊过去的东西:validation 任务为自己的外部存储通道导出了数据库主机与端口变量,冒烟测试把环境原样传给了两个已安装的二进制,而驱动选择只要看到这些变量就优先用远端——于是两个进程都在跟 CI 的远端数据库说话,内嵌 socket 计数必然为零。有意思的是他在相信这个结论之前做了什么:为了排除属主竞争的可能,他写了一个同时冷启动两个二进制的压力装置,跑六十次,并在修复前后各跑一遍,合计一百二十次。每一次都恰好得到一个租约、一个 socket、一个服务端,而两个二进制在不同轮次里分别赢得竞争,五十八比二。这就是「区分竞争与 bug,然后证明你手上是哪一个」的样子。
- 06
以契约定义的增量
一条 bug 报告描述的是只有用户才会注意到的事:双击一个节点展开邻居时,整张图会跳。原因是展开回调跑了一次带 fit 的全图布局,然后又对邻域动画了第二次 fit,于是所有已存在的节点都动了,镜头也跑了。修复写成了契约而不是补丁——planner 返回一个表示「保持视口」的标志,不做布局也不 fit;视口在请求邻居之前就被捕获;已存在的位置不被触碰;新邻居按确定性环形种子撒在展开节点周围。Fit 和重置保留全图行为,理由也给了:那些是真的改变了画面,所以它们有权移动镜头。验证在同一口气里交代:红先的 planner 测试(先写成为失败)、面板测试套件 88/88、Vite 与 Turborepo 构建各 21/21。
- 07
数字是重新测的,不是回忆的
落地页被按「产品优先」重写,而那条 pull request 记下:页面上每一个指标都是重写期间重新测的,不是从旧版搬过来的——一个千节点项目的窗口,旧格式下是 750,767 字节,新的紧凑格式下是 305,248 字节,小了 59%。同一处改动还用五张真实的、脱敏后的截图替换了合成插图。这是件小事,但它正是「一个页面在描述这个软件」与「一个页面在描述这个软件过去某个时刻的样子」之间的差别——而这个差别,正是本档案花大量篇幅在别人项目里记录的那种失效方式。
- 08
七个星,和一大堆机器人
读者极少:7 星、1 fork、0 watcher。但 pull request 队列很热闹——几乎全是 Dependabot,提议更新 Next.js、Hono、Zod、Vitest、Shiki、tree-sitter 语法乃至 GitHub Actions 本身,而几乎没有一条被合并。有一条被关掉,理由是这些依赖可以用别的方式更新、这个改动不再需要;其余的开着,有的已经一个月。每一条下面都会多出三个机器人的评论——Vercel 报部署预览、Augment 贴摘要、还有一个工具贴出五份彼此独立的审计报告,覆盖安全证据、风险分类、参考集就绪度、推广就绪度、配置与 harness 检查。而那些机器人的消息里反复承认自己发不出结果,因为 check 权限从未被授予。12 个 issue 开着。结果就是:一个自动化审查量远大于人类读者的仓库。这值得如实记下——这里的流程异常好,而流程并不是那个能告诉你「有没有人需要这个软件」的东西。
相关档案
全部档案 →第 054 号
gate4agent
一套 Rust 工作台,用来跨机器运行、观察和编排命令行编码 agent——把 Claude Code、Codex、Kimi 和 Grok 包在同一个传输层、同一个中继和同一个操作协议后面。
第 046 号
ORCH
一个把多个编码 agent 同时跑在一个项目上的运行时:你定义一个团队、给它一个目标,一个 CTO agent 把目标拆成任务,其余的按各自绑定的 CLI 接手——Claude、Codex、Cursor、Grok,甚至一个普通 shell——而全部状态都存在文件里,没有数据库。
第 039 号
Vibe Projects
一个人的 monorepo:六个由 AI 生成的项目——一个 Android agent 运行框架、一个按 hunk 审阅改动的 VS Code 扩展,以及四个小型 Android 应用——被刻意当作「模型现在能造出什么」的持续标尺。