看起来真的很不错!不过有一点让我担心:只有 26 个 MR?我们有 40 多个项目,是不是漏了一些……有些项目用的是标准库 errors,而不是 cockroachdb/errors?如果是这样,那就意味着我们还得再做一轮。

Dev.to AI 2026-11-08T03:33:25.441887

我大概九点半上床。睡前,我对会话敲下的最后一段话是:

我现在要去睡了。不过我希望你继续推进迁移,把第 1 到第 5 批的 MR 全部创建出来,但不要合并;我们早上一起 review。

整个治理模型,就压在这最后一句上。一次覆盖整个代码库的迁移:把几十个模块从第三方 errors 库换到我们自己的库。这活机械又枯燥,正适合交出去;也恰恰是那种一旦出错也不吭声的活。我敢交出去然后睡觉,是因为只要没按合并键,一切都还能恢复……分支、合并请求,全都算。四十个合并请求开一整夜,最坏也不过是早上关掉四十个请求(外加一点“白烧了一晚上算力”的微妙感觉)。合并是恢复能力的终点,所以我把停止点设在了合并。想明白这个停止点该由我来设之后,让它跑一整夜就没那么像赌博了。

早晨,以及我先做了什么

工作看起来不错,真的不错。于是我回了一段话,但没有直接批准:

看起来真的很不错!不过有一点让我担心:只有 26 个 MR?我们有 40 多个项目,是不是漏了一些……有些项目用的是标准库 errors,而不是 cockroachdb/errors?如果是这样,那就意味着我们还得再做一轮。

那时我一份 diff 都没读,也没点开任何一个合并请求。我只是看了个数量,拿它和我碰巧知道的一个数字对了一下,发现对不上。

智能体并没有犯错

从某个角度看,这一夜过得非常顺利。任务要求是迁移所有使用那个第三方库的模块;而每个使用该库的模块都已经迁移好了,没出错,一个模块一个合并请求,并且按我的要求没有合并。拿结果对照指令去审计,完全合格。

漏洞出在指令本身。代码库里有一大块本来就没用那个库:这些模块用的是标准库的 errors,而它们同样需要迁移,理由完全一样。

二十六个对四十个

它们没被纳入范围,是因为晚上九点半,我这个拿着地图的人压根没想到它们属于另一类。所以智能体完全照我说的做了,只是我说漏了,少说了一打模块。换更好的智能体也没用(换个更完整的任务说明才有用)。

一支智能体团队没法自查的东西

发现问题的,是算术。二十六个,对四十多个!既不是代码审查,也不是测试,只是把返回结果的数量和我脑子里一直记着的一个数字做了个对比——而这个数字,智能体团队不可能知道。它只知道被指派了多少个项目,那是另一个数字,两者之间的落差从内部根本看不见。

这是我对无人值守工作所做的最有价值的审查,而我花了不少时间才把它看成一个规律,而非侥幸的一瞥。我倾向于认为,它很少是在读代码差异。差异是机器擅长的部分(大多数时候),而在这种量级下逐行审查,主要就成了走过场,至少对于像这次迁移规划得这么好的东西来说是这样。真正有用的,是类似这样的问题:东西的数量对吗?这个总数像我记忆中的那份资产清单吗?为什么这一项的规模是其他项的三倍?这些又便宜、又即时,而智能体团队偏偏做不到,因为每一个问题都需要它上下文里没有的东西。

它也做不了的判断

审查没有停在计数上。这次会话标记了三个它有疑虑的合并请求,留给我决定,而不是自作主张——这正是我想要的行为,而每一个都需要人来拍板。

有一个引入了弃用(把一段功能标记为过时)。我把它改成了直接删除。被弃用的其实是一个临时凑合的方案,而且还是最近才加的,就算我判断错了,也很容易回退。这里有三条背景信息只在我的脑子里,不在代码里:它有多旧、我当初写它时怎么看它、反悔的代价有多大。

另一个改动,是把一条面向用户的错误提示文字改掉,而那条文字上一个版本才刚发布。我原样接受了。

二十六比四十

发布窗口很短,项目还处于预发布阶段,所以平时那套兼容性上的讲究在这里用不上。第三处改动是靠往依赖白名单里加一条记录让测试通过的,用来覆盖一个还没迁移的相邻模块。等我看到时,那个会话已经把它改成了一条带“绊线”的临时豁免:一旦那个依赖被移除、这条记录不再需要,就会有测试失败,提醒你把它删掉。这样处理我挺满意,就保留了。

这几个决定,我都宁愿自己做;而且我觉得这三处光看 diff 是做不出来的。

真正费脑子的,其实是那件枯燥的事

合并四十多个互相依赖的模块,不是跑个循环就能了事。随便挑个顺序动手,每次合并都会在下游所有模块里触发升级依赖的合并请求,这些请求互相抢跑,CI 反复折腾,大部分毫无意义。所以发布是从叶子节点开始,沿着依赖图往上推,这样每个模块发布时,它依赖的东西都已经安顿好了。那天上午这一段是真正动过脑子的,我怀疑无人值守的自动运行最不可能做对的就是这里。它要求你同时把整张依赖图看在眼里,还得让你去操心一堆烂摊子——而那堆烂摊子并不在你脚下。

收尾,三天后的深夜

另一个晚上,几乎一模一样的授权,措辞也差不多:我现在要去睡了,请在睡着期间把这件事办了,我授权你创建一个私有仓库。到早上,skillup 已经从零建了出来。

这件事答应起来容易得多,原因一说就明白:一个用完就扔的私有仓库,几乎是最容易撤销的东西了。同样的模式,不同的最坏情况,所以“刹车”踩在了不同的位置。

二十六比四十

那个数字我后来想了很久。它花了大约四秒钟,谈不上聪明,也不需要任何专业本事——只是大概知道总共有多少个项目而已……而这种判断,只有你一个一个亲手建起这些项目才会有。

原文发表于 phpboyscout.uk,2026 年 11 月 8 日。

我九点半左右上床睡觉。睡前我在会话里敲下的最后一段话是这样的:我现在要去睡了,不过我希望你继续推进发布,把第 1 到第 5 批(waves 1-5)的 MR(合并请求)全部创建出来,但先不要合并,早上我们一起 review。

整套治理模型(governance model),就落在最后那句话上。

这是一次覆盖整个代码库的迁移:涉及几十个模块,全部从第三方错误处理库换到我们自研的库上。活儿机械又枯燥,正是那种你巴不得赶紧甩手交出去的工作。

查看原文