这是 Weekend Challenge: Passion Edition 的投稿
我构建的内容
目标是将一个现有的 Claude 技能转换为 Google AI。由于 Gemini 已不再适用于免费计划,因此这里使用的是 Google Antigravity。
每个 AI 编码代理都有相同的失败模式,无论背后是哪个模型:它会以完全自信的语气陈述关于你代码库的内容,但其实是错的,因为自信和验证是两回事,而典型的会话中没有任何机制强制后者。它假设一条回退路径是安全的,因为它看起来应该是安全的。它把对共享类型的修改称为“增量”,因为 diff 看起来是增量的,却没有检查实际谁导入了它。它把绿色的测试套件报告为行为已保留的证据,而实际上绿色套件真正证明的只是对某人已经想到的输入保留了行为。这不是模型不够聪明的问题。随着会话变长,它反而会变得更糟,而不是更好,因为上下文充满了仅仅因为十分钟前被说过而感觉为真的内容。
Session Discipline Kit 之所以存在,是因为“检查你的工作”是一条代理可以点头同意但随后悄悄不执行的指令,就像一个有截止压力的人一样。散文规则会得到不一致的执行,而机制则不会。因此,与其在上下文文件中再加一段要求代理在编辑前验证的文字,不如把这条规则直接写入环境本身:一个钩子,阻止对代理在当前会话中尚未实际打开并读取的文件的任何编辑——彻底阻止,无论它听起来多么自信。这个机制会在错误发布前捕获整个类别的错误,而不是在三周后以“奇怪、罕见、难以复现”的行为出现时才发现,而追踪这种行为所需的时间是当初缺失的读取操作的四倍。
验证是底线,而不是整个系统。其余部分是九项技能,映射到真实变更的实际形态,按实际发生的顺序排列:在任何代码被编写前,先陈述一个具体到可证伪的范围,这样之后就有一个具体的东西来对照 diff 进行检查;在修改共享文件前,枚举它的每一个真实消费者,因为在 monorepo 中 diff 总是看起来很小,而影响范围才是真正重要的数字;为任何正确性取决于输出形态而非单一布尔值的内容搭建黄金快照测试,而这正是绿色测试套件会发布真实回归的地方,因为损坏的输入从未进入任何人手选的集合;像陌生人一样审查 diff,没有编写它的记忆,也不因当时感觉合理的推理而获得功劳;以及在会话结束时根据实际的当前仓库状态重新生成交接文档,而不是根据对话对自身的记忆。
最后这一点值得深思,因为它是这个工具包最终要保护的问题所在。新的 AI 会话从零开始,没有上一个会话的记忆,而这种情况的一切都促使代理要么重新推导它已经拥有的上下文——慢,要么悄悄假设它实际上并未重新检查的内容——快,但最终是错的。从 git 状态和真实 diff 构建的交接,而不是从对话对自身的记忆构建的交接,从根源上打破了这个循环:下一个会话继承的是经过验证的状态,而不是别人未经验证的自信,无论初衷多么良好。
这一切都不是对容易出错之处的猜测。它是基于六个真实的、泛化的失败模式构建的,分阶段形成一个十二点方法论,精确命名每个规则保护变更的哪个阶段,以及一个专门的深入探讨,说明这一切在何处最严重:TypeScript monorepo 中的集中式配置,在这里,一个小的、自信的、错误的编辑会在任何人注意到之前就到达每一个下游消费者。安装它,把两个钩子接入 Antigravity 的钩子系统,然后在上下文文件中指向一行。纪律不再是你每一次会话都必须记住去请求的东西,而是环境自然强制执行的东西。
演示
安装
python3 install.py /path/to/repo
代码
Session Discipline Kit for Antigravity CLI
阻止 Antigravity 自信地猜测——阻止未经验证的编辑的钩子,以及在会话间清晰地界定工作范围并交接的技能。
问题
AI 编码代理开始一个新会话时,没有上一个会话的记忆,没有内置的对共享文件变更影响范围的感知,也没有机制强制它在对文件做出声明前实际读取该文件。如果放任不管,就会产生一组特定且反复出现的失败:回退路径悄无声息地吸收了它们从未被设计处理的用例;对集中式文件的看起来是增量的变更破坏了其他四个包;绿色的测试套件发布了真实的回归,因为损坏的输入恰好不在任何人想到的集合中;会话从一行 bug 修复漂移到无法审查的六文件变更,却没有声明的范围来对照检查。
这都不是……
我是如何构建它的
那个时间线就是它的形态——下面是它的质地。
这个工具包一开始并不是一个开源项目。它最初是一个开发者日常工作的私人纪律系统:一个独立创始人正在构建一个编译器密集型的 TypeScript 平台,厌倦了看到 AI 编码代理自信地陈述关于它实际上并未检查过的代码库的内容。它安静地存在于一个 .claude/ 文件夹中,履行着它的职责,直到它所依赖的基础发生了变化——Google 方面的一个平台转型切断了下一个工具所依赖的免费层访问,而原本为一个工具工作的设置突然需要为一个完全不同的工具工作。
移植过程是它不再是一个常规重写的时刻。第一个目标 Gemini CLI,与原版共享了很多 DNA——相同的 JSON-over-stdin 钩子契约,相同的事件驱动形态——直到它不再相同:钩子配置自信地写入,而 CLI 自己的启动输出立即标记一个事件名称为无效。这不是通过更多研究纠正的猜测,而是真实工具拒绝真实配置并明确说明原因。修复加入后,第二个更微妙的错配以同样的方式出现——工具的内部名称与其显示名称不匹配,这是平台团队自己提交过 bug 的命名怪癖。然后,在该版本甚至还没完全稳定之前,平台本身就被免费层账户弃用,并被替换为全新的东西:一个独立的、闭源的重写,带有几乎没有文档的钩子系统,不同来源对其描述不一致,有时甚至直接相互矛盾。这一次没有干净的主要来源可供查证,所以应对方式是针对分歧进行构建,而不是猜测过去——在每一种合理的命名约定下注册钩子,让验证逻辑尽可能关注文件状态而不是工具特定名称,并在代码本身中明确说明哪些部分已确认,哪些是合理的推测。
这正是值得深思的部分:一个其全部目的都是拒绝信任未经验证的声明的工具包,是通过在每一步都对自己应用完全相同的标准来构建的。目标平台的钩子模式没有因为一篇博客文章自信地说了什么就接受——它是通过与实际工具的实时行为进行对照检查来接受的,就像这个工具包坚持要求代理检查文件而不是信任它对文件的记忆一样。第一次检查失败的地方,它通过同样的方式得到纠正:不是通过更努力地猜测正确,而是通过查看真实输出并更新。方法论不只是被构建出来,然后单独被证明有效。构建它本身就是对它的第一次真实测试。
奖项类别
Best Use of Google AI

0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.