2026 年 8 月 6 日,我开始牵头十年之约的改版。10 月 4 日凌晨,新版上线,之后三天里,我们又根据成员的反馈和后台数据改了几百次。

新版长什么样、logo 怎么画出来的,我在另一篇改版手记里写过了。这一篇换个角度,用产品经理和项目经理的眼光,聊聊背后的事:为什么先改这个、后改那个,中间哪里判断错了,又是怎么改回来的。每一处用到的方法,我也尽量点出来,希望换一个项目也能用上。前半篇讲十年之约本身,后半篇讲我一个人怎么借 AI 把它做完。这次开发这一侧只有我一个人,具体执行几乎都交给了 AI,两个月里代码提交了 682 次,其中 626 次集中在 10 月 1 日到 6 日。

开工前我给自己定了一条规矩:每做一个决定,先回答「这对访客和成员有什么好处」,回答不出来就不做。


一、现状诊断:数据里看到的问题

十年之约是一个独立博客的公益项目。博主承诺自己的博客十年不关站、持续更新,项目把博客收进名录,再通过一个叫「虫洞」的功能,把访客随机送到成员的博客上。最早一批博客在 2017 年签约,到 2027 年 8 月 30 日,第一位成员就满十年了。现在在约的博客大约有 1,900 个。

这将近十年,项目一直靠几位志愿者的热情撑着。周边是大家自己掏钱做的,成员一年年坚持写下来,项目能回馈的还不多,送上的是一句「再来一个十年」。

开工第一天,我没有先去看页面,而是把生产数据库导到本地,把能算的都算了一遍。最先让我停下来的是虫洞。

虫洞累计送出访客 61.3 万次,这是项目最大的家底。我把在约博客按最近 90 天有没有更新分成两组:

分组 博客数 平均被送达
最近 90 天有更新 547 309 次
最近 90 天没更新 1,366 325 次

最近没更新的博客,反而被送得更多,它们占了 72.4% 的送达。访客点四次虫洞,差不多有三次会落到一个三个月内没有更新的博客上。全站的评论数只有浏览量的 0.1%,我想这是原因之一。

接着往下算,又看到了几件事:九成博客的签约日没有记下来,有的博主重复收到了成就邮件,审核主要靠人工一个个点开看,技术上也有几处缺口,后台还有一个安全漏洞。这些问题是项目运转多年慢慢积下来的,靠志愿者的业余时间,很难一一顾到。它们有的影响访客,有的影响成员,有的随时可能出事故,但没有一个是页面好不好看的问题。下面讲到每一件事是怎么解决的时候,我再把它摊开说。

先建立数据基线,再定先改什么,是我这次做产品的第一步。凭感觉,最想先动的往往是页面;把数据摆出来,才看得出哪些问题真正影响着访客和成员,改版之后也才有东西可比。


二、定方向:访客是因,成员是果

8 月 7 日,我和项目持有人羽忆聊了一次,定下这次迭代的总基调:以商业落地的标准做公益项目。

公益是项目的性质,我们不以盈利为目的。商业标准指的是做事的方法:用数据说话,算清成本,让价值经得起验证,让项目的开销有稳定的来源,不再只靠个人掏钱,能长期、稳定地运转下去。这些年有三件事主要靠大家的热情:周边是大家自己掏钱做的,推荐谁由人来定,给成员的回馈是一句「再来一个十年」。这份热情很珍贵,也正因为珍贵,不能一直只靠它。

「商业标准」听起来有点虚,我把它拆成了五个能回答的问题,任何需求进入开发前,都要先挨个问一遍:

  1. 成本谁来付? 要多花多少服务器、AI、人力的钱,这笔钱从哪来。
  2. 结论有数据支持吗? 推荐、上榜、荣誉都按可以复算的数据来,不设人工指定的例外。
  3. 用户为它付出了什么? 零门槛、人人都有的东西,很难让人有获得感。
  4. 用户感受得到吗? 只写在公告和公约里的价值,不算交付。
  5. 别人都在做,我们为什么还要做? 所以我们不做社交平台。

这五个问题,合起来是需求进入开发前的一道准入关,每一条都是必过的判据。需求一多,最难的不是做,而是决定不做哪些。把门槛事先写下来,放下一个需求时就有据可依,不用每次重新争论。

在这五个问题之前,还有三个更基本的:谁会来,他此刻想要什么?他要做判断,需要看到哪几条信息,现在给了吗?几方的需求之间,谁是因,谁是果?

最后一个问题,成了整个改版最核心的一条判断。十年之约其实是一个双边平台:一边是写博客的成员,是供给侧;一边是来读博客的访客,是需求侧。访客能在这里找到还在更新的好博客,十年之约才有口碑;有了口碑,博客挂在这里才有分量,成员的年份徽章也才会被更多人看见。所以访客是因,成员的荣誉是果,两边冲突的时候,先照顾访客。

这条判断还纠正过我自己。整理题材分类时,我发现 53% 的老博客没法从现有字段里归类,第一反应是把分类降级,改用签约年份做名录的第一层筛选。后来回头一想,这正好把因果弄反了:年份服务的是已经加入的成员,分类服务的是第一次来的访客。最后名录的第一层还是题材,年份只做辅助筛选。

需求之间常常会打架,这时先分清谁是因、谁是果,就知道该先保哪一边。照顾了果,却伤了因,最后两边都保不住。

想清楚因果,主次也就清楚了:先改虫洞,让访客点开的博客大多还在更新;再做十年荣誉,把成员十年的坚持,变成他自己能感受到的收获。其余的事都围绕这两件展开。


三、需求侧:访客得到了什么

虫洞:把分发规则公开

改虫洞之前,我原以为它是「加入越久,推得越多」,打算削弱年限的影响。读了代码才发现,虫洞是纯随机,根本没有权重。老成员被送得多,只是因为待得久,次数一年年累计起来了。要做的不是削弱一套权重,而是从零建一套。

新的虫洞是这样送访客的。

只送半年内有更新的博客。 抓不到文章的、被判定不是原创内容的,不进虫洞。半年没更新的博客暂时退出,恢复更新后会自动回来,这不算违约。

按更新情况加权随机。 每个博客的权重是「活跃度 + 规律性 + 2」:

  • 活跃度看最近一篇文章:30 天内 2 分,90 天内 1.5 分,180 天内 1 分,一年内 0.5 分。
  • 规律性看近 12 个月里有几个月更新过:9 个月以上 2 分,6 个月以上 1.5 分,3 个月以上 1 分,1 个月以上 0.5 分。
  • 每个博客先有 2 分保底,所以权重在 2 到 6 之间,最多和最少只差 3 倍。

我用 8 月的数据模拟了 10 万次:半年内有更新的博客占总数的 38.6%,能拿到 58.8% 的曝光。差距看得出来,也不会让少数几个博客把流量吃光。

加入年数不算分。 签约十年,说明这个博客不会明天就消失,但说明不了它写得好不好。年数只放在卡片的角标上,让访客自己判断。

不收点击和停留数据。 点击、停留、跳出率这类要靠目标站回传的数据,我们都不收,权重只用我们自己抓到的文章来算。想刷「近 12 个月有几个月更新」,最省事的办法就是真的每个月都写,刷的成本和达成目标差不多,所以规则可以放心地公开。送得多也不会让权重变高,分发里没有「曝光越多、权重越高」的正反馈。设计排名或激励时,我都会先问一句:想钻空子的人,最省事的办法是什么?如果答案接近老老实实去做,这套规则才敢公开。

规则全部公开。 网站上有一页虫洞规则,写明哪些博客会被送到、权重怎么算、我们不看什么。

送达次数的算法也改了。以前抽中就算一次,现在要访客真的点进去,或者倒计时结束自动前往,才算一次;同一个人 24 小时内去同一个博客,只算一次。旧的累计数保留作底数,不清零。指标怎么算,要先于指标本身定下来;口径不对,数字再好看,也说明不了访客真的去了。

题材:让搬不走的内容更显眼

名录现在有九个题材:摄影、视觉、旅行、美食、影音、读书、生活、技术、财经。技术和财经也是九个题材之一。

把摄影、视觉、旅行放在前面,是因为偏技术的博客已经有不少目录站在收;摄影、旅行这类内容要自己去拍、去走才写得出来,很难被搬运,我们想让它们在名录里更显眼一些,这也是在鼓励原创。九个题材放在一起,是希望访客在这里能看到各种各样的博客。

题材由博主自己选,最多两个,审核时核对,不符合会退回并写明原因。我们也试过用关键词自动归类,误判超过一半,比如「UX」这两个字母,在九万多篇文章里刷出了两千多次假命中,所以不用关键词自动归类。

首页只放值得点开的文章

上线后,我在首页看到一篇占位用的文章,正文只有一个字符。原来首页只按博客过滤,从没看过单篇文章的内容。

所以加了单篇把关:每篇新文章入库时,让 AI 判一次,分成三档。占位稿、测试稿、加密读不到的、空壳,不推,列表和首页都不放;节日祝福、一两句话的近况、站务通知,只进列表;值得点开读的,可推荐,首页只放这一档。最新 500 篇里,不推 13 篇,只进列表 39 篇,可推荐 461 篇。这件事不算违约,不给博主发信,后台也可以撤销。

这里踩过一个坑:抽查时发现,从文章页面提取的正文,有的只抓到了评论区,有的只有作者名和日期,AI 据此把两篇有内容的文章判成了空壳。后来改成正文和订阅摘要一起交给 AI,代码里也加了兜底:页面没读到正文,或者以图片为主时,「空壳」这个结论不算数。上线前,我们在正式服上用影子模式,也就是「只判不写」,跑了真实的最新 180 篇,一条条看,三轮才收敛。


四、供给侧:成员得到了什么

十年荣誉:是数据的读数,不额外加分

做十年荣誉,第一个拦路的是签约日。在约的 1,913 个博客里,有 1,739 个的签约日期是空的。我一开始以为数据丢了,往下查才发现没有丢:2019 年底之后,审核通过的那段代码就没再写入这个字段。

好在有一个替代来源:审核通过时,系统会自动写一条「加入十年之约」的大事记,它的日期就是真实的通过时间。所以签约日按三层来取:先看签约日字段,没有就看这条大事记,再没有就用申请时间,这样每个博客都能取到。两个日期都有记录的博客共 144 个,两者相差天数的中位数是 0。补出来的签约日只在读取时临时使用,不写回数据库,因为证书编号里含有签约日期,改了数据库,就会改变已经发出的证书。算下来,2027 年满十年的有 32 人,2028 年 84 人,2029 年 65 人,单年最多的是 2034 年,有 533 人。

荣誉本身,复盘时调整了三个旧方向。

第一,不再有「续约」。满十年,什么都不会被收走,继续写就继续被推荐,不需要再签一次「下一个十年」。

第二,年限只用来展示,不参与分发。十年成员真正得到的好处,是他的持续性分数本来就是满档。荣誉是数据的读数,我们不额外给老成员加分。任何人做到同样的事,就拿同样的权重,一个人拿到荣誉,也不会挤掉别人的份额,这是一个非零和的设计。

第三,荣誉榜从「名单」改成「内容流」。如果按「满十年」上榜,榜单只会越来越长:2027 年的 32 人单独做一个页面内容还不多,到 2034 年单年就有 533 人,又变成了名录的副本。所以改成列出「这些老博客最近写了什么」,人越多,内容越丰富,它本身也成了一个发现好内容的入口,服务的还是访客。

荣誉要同时给三种人看:还没加入的人,看到加入的理由;还没满十年的人,看到坚持的理由,他们占在约成员的 96%;已经满十年的人,看到兑现。只照顾最后一种人,前两种人就被落下了。设计一个功能之前,先列出它要服务哪几类人,再看方案能不能同时照顾到,可以避开很多「做出来只有少数人用得上」的情况。

上线时间是倒推出来的。用来评判的数据,要在评判之前很久就让大家看得到,年底突然冒出一个大奖,大家很难信服。第一位成员 2027 年 8 月 30 日满十年,所以权重的展示必须在 2026 年内上线,公开运行满一个观察周期,荣誉才能发放。这条时间线压缩不了。这是逆向排期:先钉住不能动的里程碑,再沿着依赖关系往回推,每一步最晚什么时候必须完成就清楚了。年限角标、证书和周年徽章,现在已经上线了。

成员状态:只说事实,不下结论

以前前台会给一些博客挂上红色的「异常」角标,成就页上还写着「被标记异常后便再也没有恢复」,而这句话出现在一封祝贺博主坚持五年的邮件里。

我去查了数据。被标记为「终止」的 757 个博客里,56% 我们连一篇文章都没有抓到过。也就是说,我们并不知道他还在不在写,只知道我们没抓到。对这些博客写「停更」「不活跃」,并不符合事实。所以这次把状态拆细了,前台只写我们观测到的事实;已经离约的博客,整张卡片变灰,不用红色。那段措辞也整段删掉了。

长期没更新,先问一声

公约规定,12 个月不更新算违约。以前人手有限,很难逐个去查,也没办法先和博主确认。

现在系统每天找出订阅正常、但 12 个月没有新文章的博客,先发一封信,问一句「你还在写吗」。信里有一个链接,点一下就记为「还在写」,12 个月后再问。30 天没有回应,才记违约;违约后 30 天内恢复更新,会自动恢复。

切成自动之前,我用国内网络把待处理的 81 条全部人工复核了一遍:79 条确认 12 个月没有更新,误判 0 条,另有 2 条在国内也打不开,不该发这封信。核对完才放开,每天最多发 100 封。会直接影响到人的动作,我们都是先人工核一遍,再加上发送上限兜底,才放开的。

重复的成就邮件:一个幂等性问题

满五年的成就邮件,有 14 位博主在同一年收到了好几封,最多的一位多收了 8 封。原因是程序先写记录再发信,发信失败会重试三次,每重试一次,就多写一条记录、多发一封信。重试本身没有错,错在写记录和发信这两步没有做成幂等的,重试一次,就多产生一次副作用。

这件事之前被说成「281 位博主收到重复成就邮件」,前后被四份文档引用过。我重新拆了一遍,发现它把「每年各收一封」也算了进去,真正在同一年收到多封的只有 14 位。问题是真的,规模被高估了 20 倍。一个数字被引用得越多,越要回头核一遍它是怎么算出来的。

成就邮件后来停发了。但停掉一个功能,不等于它带出来的问题都跟着消失:成就页上那句不妥的措辞和旧链接都还在,这两件都另外做了处理,现在已经修好。


五、运营自动化:把日常运营交给 AI

为什么交出去

以前,新申请要管理员在 7,000 多行的总表里筛出来,一个个打开网站看,再点按钮发信。系统不记录是谁审的、为什么驳回,退回信里的原因占位符也一直没有换成具体原因。

10 月 2 日,我做了一个影响很大的决定:以前靠人工完成的日常运营工作交给 AI,人负责兜底、复核和看数据。 理由有三个。一是工作量太大:1,900 多个在约博客要巡检,每天还有新申请、改资料、大事记、评论,人力只会跟着成员数一起涨,这样的设计我们不采用。二是口径难统一:审核员都是志愿者,没有固定岗位,同一种情况,不同的人难免判出不同的结果。三是上线后没有开发在场:我日常用的 AI 编程工具,线上都调用不到。

线上的 AI 只用 DeepSeek 一家,预计每月十几元;全站做一次全量内容判定,大约 3 元。交出去的工作一共 18 类,包括新申请审核、题材修改、大事记、评论、网站打不开、12 个月未更新、原创性、水文、网站性质变了、题材与内容不符、申诉、改网址、改资料、留言分拣、单篇文章能不能上首页等。

分工的原则是:能用规则判的,不调 AI;AI 只判需要读内容的事。 域名层级、能不能打开、过了多少天、是不是重复申请,用规则判;原创不原创、是不是水文、题材符不符合,交给 AI。DeepSeek 不能上网,也看不了图,所以服务器先把网页的文字抓下来,再交给它。规则优先、模型兜底,成本更低,结果也更好解释。

怎么让 AI 值得信任

AI 判错一次,代价可能是把一个原创博客误移出去。所以我们给它加了一组护栏:

  • 只按公约原文判,不自创标准。 公约里写着审核人员不得把非强制条件当成核心标准,AI 也受同样的约束。
  • 对博主不利的动作,要两次判定一致。 驳回、记违约、移出虫洞,都要两次独立判定结论相同。不一致就跑第三次,三选二;还定不下来,就按对博主有利的方向处理:申请放行,不处罚,申诉恢复。
  • 随机度设为 0。 同样的材料,必须得到同样的结论。
  • 每个动作都留痕,可以一键撤销。 撤销了多少条,是观察 AI 判错最直接的信号。
  • 影响博主的动作,一律发信。 信里写清做了什么、依据哪一条、证据是什么、怎么申诉。
  • 虫洞规则不算违约。 退出虫洞、权重变低,都只影响推荐,不发违约信。
  • 随时能刹车。 运营开关有三档,另外还有全局暂停、熔断和每日预算。

人在回路:「拿不准就交给人」,交给了谁

上线第一天晚上,我打开后台,想看看 AI 审得怎么样。22 份加入申请,DeepSeek 一份都没真正读到内容:备案号、子域名、门槛这些前置检查把它们全拦了下来,转给了人。还有一批调用,因为返回格式不对,全部失败了。

我这才意识到,这个结果是我们自己设计出来的。当初觉得「AI 拿不准就交给人」最稳妥,听起来也很负责。可审核员都是志愿者,没有固定岗位,案子交出去,很可能就一直放在那里没人接。我们把活交给 AI,本来就是看中它能按同一个标准来判。它一拿不准就往回推,等于又把担子放回了最缺人手的地方。

后来改成:拿不准的时候,由事先写好的规则给结论,转人工只能是论证过的例外。现在还会交给人的只剩几种:涉及政治、法律、人身攻击的;疑似提示词注入的;运营开关不在自动档的;技术故障重试用尽的。人在回路的设计,关键不在「有人」,而在升级路径:什么情况交给人,交过去有没有人接得住。

如果你也在给自己的项目接 AI,可以留意一下:说是「兜底」,最后兜在了谁身上。

55 条,一条条对

怎么证明它判得对?AI 上线以来一共只有 55 条结论,抽样没有意义,所以全量对比。我借助 Claude 把 55 条连同证据逐条独立判断一遍,做成对照表;之后每改一版代码,就让正式服上真实的审核代码把 55 条全部重判,每条都在数据库事务里跑完再回滚,发信和队列全部拦截,不留痕迹,再逐条比对。这相当于给 AI 审核建了一套回归测试。

一致率从 80% 提高到了 95%,最后两轮的结论逐条相同,剩下 3 条稳定的分歧都是边界情况。这个过程还顺带查出了十几个缺陷,比如:黑灰产营销站、公司品牌站被放行;取证时只认一种网页标签,站点地图里又混进了分类页、标签页,没看到文章也放行;熔断把「通过」也算成了处罚;三次一致驳回,却因为把握程度是「中等」被放行;随机度没固定,同样的材料判出相反的结论;香港的服务器连不上国内网站,被判成「打不开」。

还没解决的:从香港看国内

新服务器在香港。有些博客只对国内开放,从香港打不开,在国内其实正常。我们随机抽了 300 个在约博客,在国内和香港各测一遍,约 3.7% 只有国内能打开。所以在国内检测节点接上之前,「网站打不开满 15 天」这一项不自动处理,由人用国内网络核实。国内节点接上以后,规则计划改成「任意一边能打开,就算能打开」,网站上关于「从哪里检测」的说法也要一起改。


六、上线前后

四天走完一遍

9 月 30 日,我离开三周后回来,给项目定了一个硬前提:三四天之内,把需求、设计、开发完整走一遍,服务器迁移放到最后。计划档里写的不只是步骤,更多的是什么算完成、什么绝对不能碰,比如「一封信都不发」「系统不得自动判定终止」。工期越紧,越要把「不做什么」写清楚,红线写在前面,赶工的时候才不会为了快而越界。

10 月 1 日,定下设计方向和虫洞的数值;10 月 2 日,技术地基、前端、数据订正、AI 离线判定四条线同时开工;10 月 3 日,测试服交给我人工校验;10 月 4 日凌晨,正式上线。

先把地基立起来

技术债,是开工第一天就看到的:系统上线七年,数据库除了主键还没有加过索引;实际运行的框架版本和依赖清单差了 46 个小版本,有人执行一次安装命令,线上环境就可能变样;24 个测试文件里有 20 个是 Telegram 机器人的,虫洞、名录、申请这些核心功能还没有测试。后台框架还受一个公开漏洞影响,可能被人借后台账号在服务器上执行代码,而它的上游已经三年没有更新,没有修复版本。

AI 最初排的关键路径是「新服务器什么时候到位」,这是从硬件出发的看法。我的想法是:地基要在测试服上就立起来,后面的代码都写在新地基上,否则以后再迁,等于重写、重测一遍。排关键路径时,我看的不是哪件事最显眼,而是哪件事做晚了,会让后面的工作全部返工。所以改虫洞之前,先给虫洞、名录、申请、抓取补上测试;依赖版本按清单统一;13 张表从 MyISAM 转成 InnoDB,避免抓文章时锁住整张表;后台漏洞加了两道防线,上传目录禁止执行脚本,程序里也打了补丁。框架大版本的升级定了方案,还没有执行,这是接下来要还的账。

前端做完后,先部署测试服,运营总开关设为全局暂停,不开定时任务,发信只写日志,我人工校验确认了才上正式服。测试服部署了三次,前两次因为依赖版本不一致、迁移目录混进苹果系统的隐藏文件,以及给老表加索引超出 MySQL 长度限制而回退,第三次成功,我提的 9 项反馈后来扩展成 23 项,修完才上线。教训是:本地的 SQLite 测试和「只预演」的迁移,都发现不了 MySQL 的索引长度限制,这类迁移要拿真实备份在本地 MySQL 上完整演练一遍。

上线后的三天

上线后三天的提交量是全期最高的,10 月 5 日一天就有 277 次,大多来自真实的反馈和数据,谢谢每一位提反馈的朋友。一位成员说高配笔记本进站也卡,原来是浏览器没用上显卡时,整屏细点绘制太重,动画又没有帧率上限,240Hz 的屏幕每秒要重画 240 次,我们加了帧率上限和自动降画质。截图上的周年徽章挡住了博客的 logo,挪到了右下角。首页划过卡片时整屏明暗突变,改成了 0.2 秒渐变。个人中心常用入口在第三到第六屏,当天重做。Telegram 群公布后只有 10 个人进群,缺的不是知名度,是进群的理由,所以先上线了绑定博客、状态提醒、每日推荐、查进度这几项服务,再发邀请。数据上,合并了 46 对重复登记,清掉了 1 万多条重复和错挂的文章;判断是不是同一个人时,邮箱不同不能当证据,要看文章署名这类直接证据。

出过的几次事故

上线后出过几次事故,给受影响的朋友添了麻烦,在这里说声抱歉。每次事故之后,我们都做一次事后复盘,不只修好这一次,还要定一条规矩,防止同类的事再发生。

  • 发信邮箱被封。 上线当天用旧企业邮箱群发 386 封信,账号被服务商判为风控,验证码也一起停了约 9.5 小时,31 位用户收不到登录验证码,页面却还提示「发送成功」。后来换成阿里云邮件推送,验证码和通知信分开两个账号;凡是群发,先发样信给我看。
  • 文章日期变成了「现在」。 有的博客在订阅里用中文写日期,我们解析失败后当成了「现在」,旧文章被刷成刚发布,一直排在首页前面。问题出在我们的解析,不在博主。原计划的处罚方案如果上线,警告信会发给三个正常的博主,那两家反而查不出来。之后,外部数据入口的改动必须拿真实样本跑过。
  • 另外三次:发信线路晚高峰丢包 90%,切换接口时整站报错约 32 秒,当场回滚;一次部署用管道串了两个脚本,失败被当成成功,个人中心报错约 25 分钟;为了核对一个周报任务,我凌晨手动执行了它,给两位真实成员发出了周报。之后的规矩分别是:改启动配置前先模拟启动,部署的每一步单独看退出码,会发信的任务核对时只发预览给我。

上线后我还检查了备份,发现数据库导出和网站放在同一台服务器上,截图、上传文件、配置都没有备份,也没有告警。现在每天加密增量备份到 Cloudflare R2,本机留 7 份,远端按天留 7 份、按周 4 份、按月 12 份,多留周、月两档,是因为数据改错了常常隔几天才被发现;每月自动做一次恢复演练,失败了会告警。


七、一个人加 AI,怎么做成的

改版手记里我讲过七条方法,这里讲得更具体一些,也讲讲方法本身这两个月是怎么变的。

谁做什么

这次我用了五个 AI。Claude Code 是中枢,拆需求、查数据、写计划档、验收结果;Codex 负责执行,地基改造、前端、AI 运营的前几段、插图和备份方案都是它做的;Claude Design 出视觉设计稿,从第 6 版迭代到第 16 版;豆包写文案候选,我来挑;DeepSeek 是线上唯一的 AI。

分工中途调整过一次。最早 Claude 只做中枢,不直接改代码,因为在我这个项目里,Codex 的成本低一个数量级。到了 10 月 2 日,Codex 一批活经常要跑一到三个小时,四天的工期等不起,我就让 Claude 自己动手了。

再往前,还有一次额度上的教训。项目早期,我让 Claude 带着一群子助手干执行的活,一轮下来用了 138 万 token;第一次修复用了 38 万,五个助手全部在写入结果前因为服务端报错中断,活干完了,一个字也没留下;第二次修复用了 65 万,又有两条线因为我同时开了两个大任务、占满并发额度而失败。合计 240 万以上,其中几十万是白白用掉的。从那以后:执行的活交给成本更低的一方,不同时开两个大任务。

一条主线跑到底

让 AI 开一堆助手并行干活,看起来很快,我自己也这样用过,后来发现有三笔隐藏成本。每个新助手都要从零读一遍资料,缓存用不上,全部重新计费;主线和助手之间来回传的摘要算输出 token,单价是输入的五到十倍;摘要一定会丢东西,丢掉的地方就是后面返工的地方。前两笔是钱,最后一笔丢了就补不回来。

所以我现在的默认做法是一个窗口、一个主 agent、一条主线跑到底。分界线是:查问题可以分出去,改东西不分出去。 大范围翻代码、找问题、对抗式复核,可以派只读的助手去看,它们只交回结论和文件位置;动手修改,由掌握完整情况的主线自己来。真要并行,我宁可多开几个窗口,每个窗口一个主题。大规模的助手编队要我每次单独授权,这两个月授权过三次,都是只读的取证:公约第六次修订时,把 431 个提交分四组对照代码核查、逐条对抗复核,保留 32 条、驳回 9 条;导出全站邮件和通知文案时,5 个助手分区导出、各配 1 个助手复核,共 440 条;评审 AI 运营规格时,5 个视角提出的 7 个阻断项全部采纳。

先写成文件,再动手

复杂的任务,先把计划写成文件,我看过,再对着文件执行。文件里写的是判断标准和约束:要什么,不要什么,做到什么程度算完成。我能在计划阶段就拦住方向错误;AI 每完成一个阶段也回头读一遍,确认自己没被眼前的细节带偏。

需求也是这样管起来的。改版开始时,项目里有 L1、R01、A、X-1 等六套需求编号,是不同时期、不同的人留下的,同一件事在三份文档里有三个名字。我统一成一套 REQ-<数字> 编号,全局唯一、永不复用;每条标上 P0 到 P3 的优先级,从「能指出具体受害者和具体伤害」到「补丁和长尾」,标准事先写清;旧文档全部冻结,复盘一条解冻一条。最后从零整理出 48 条需求。优先级的标准要在排序之前写好,不然每条需求都会被说成最急的。

复盘完,积压了 60 多项等我决定的事,三周没动。信息其实是够的,卡住我的是形式:每一项都要读完一整份文档才能定。9 月 3 日,我让 AI 把它们改成选择题,一次三四题,每题两三个选项,推荐的排第一,每个选项写清代价。一个下午,我定下了 16 项主要的决定,另外约 30 项授权按推荐执行。所有决定只写进一份裁决记录,其余 17 份需求文档只加一行指针,保证单一事实来源,不然以后就会有 17 个慢慢走样的版本。决定积压的时候,与其催自己快点拍板,不如先把决定变得容易做。

项目里还有一份台账,记着每一轮做了什么、为什么、没做什么、学到了什么,它是跨会话的记忆。这些做法,现在有个说法叫上下文工程。按我自己的使用经验,上下文超过五十万 token 左右,AI 出错就明显变多,这时我会先更新台账,再手动压缩,并要求它带走五样东西:前因后果和试过的方案、已经总结的原则、接下来要做的事、要避开的坑、我提过的全部要求。不留缩写和代号,压缩以后,「按之前那样」谁也看不懂。

交接说明的第一句话

把活交给 Codex 时,我给的是文件路径,让它自己去读,提示词里只写目标、边界、红线和验收标准。

最关键的是第一句话。同一天派出去的几件活里,有一件开头写的是「逐条核对断言,不成立就写证据」,Codex 把它理解成了审查任务,自己拉了三个只读助手去审,最后交回一份报告,一个文件都没改;同一件事重新派一次,开头改成「这是编辑任务,不是调研任务,交付物是被修改的文件本身」,它就改了二十处。

我第一反应是怪那条调用通道。后来才发现,那一轮我同时改了通道和提示词两样东西,没法说是哪个起的作用;同一条通道下,另一件开头写「接管收尾脏活」的任务是正常改完了的。这至少说明通道不是原因,嫌疑最大的,是第一句话怎么框定任务。我也多了一条规矩:出事当时写下的结论只能当线索,几个变量同时在变的时候,不急着下因果结论。

如果你给 AI 派活时,它总是只交回一份报告,可以先看看第一句话写的是什么。

规矩交给机器,验收只看证据

靠人记住的规矩,很容易被忘掉,所以能检查的,我都写成检查脚本,不通过就报错。文档登记检查在上线当场抓出了 20 份没登记的文档,起因是冻结需求时漏掉过一份文档,而那份文档里恰好有两件核心的事之一;断链检查在搬文档目录时抓出了 50 处断链;自动化测试从 109 个加到了 852 个,每次改动都跑全量,通过的数量不能比上次少。

AI 说「做完了」,不算完成。验收固定三步:先看实际改了哪些文件,什么都没改的直接退回;再跑测试,和上次对比;最后抽几处改动看内容,重点查三种情况:以修 bug 为名删掉了原有功能,同一个功能留下了两份实现,只写了注释、没有真的实现。

上线后我经常同时开五六个窗口,又冒出两个问题:一个会话提交时,把另一个会话暂存的文件一起带走了;一个会话部署到正式服、却没合进主线,下一个会话拿主线版本一覆盖,前一个功能就没了。现在每个会话在自己的 git worktree 分支里工作,提交只加写明的文件名,推送前确认只推自己的。部署则交给一个叫「电子狗」的脚本,一天里改了七版。它只认一个判据:要上传的每个文件,正式服上现在的版本必须出现在这次部署的提交历史里,不在就停下,并指出是哪个分支没合并。它还负责按先来后到排队,进程退出后号和锁自动收回;上传前查语法,装完核对校验值,不一致自动回滚;改了配置会重建缓存、平滑重启队列,部署完再自检;成功后自动合进主线。脚本本身更新时先写新文件再整体替换,免得正在跑的部署读到半截脚本。

每次纠错,留下一条原则

AI 犯了错,我纠正以后,记下来的是一条下次还能用的原则,写法固定成「凡是什么情况,就怎么做,因为什么」。说不清「因为什么」的不写,只会发生一次的事也不写。现在攒了 54 条,挑几条:

  • 统计时间,先换时区。 数据库导出的时间是 UTC,文档里几乎都是北京时间,AI 在这上面连错了三次,每次都差点报告「文档写错了」。
  • 视觉改动,看真实截图,不看推算。 首页的点阵数字,AI 按算法推算「字号一致」就交付了,我一看,0 和 8 分不清。后来固定在桌面、中屏、手机三种宽度下截图验收。
  • 讲事实之前,先查最新的记录。 文档经过很多轮修订,只读一份,很容易拿到已经作废的结论。
  • 来源只回答「这话是谁说的」,不回答「这话对不对」。 写需求依据时,要做到来源失效了,理由还站得住。
  • 代码只说做什么,不说为什么。 有一处五年成就的判断用的是申请时间而不是签约时间,AI 认定是写错了。可九成人的签约日是空的,那是对数据现状的妥协,照着「订正」改了,这些人会永远拿不到成就。判断一处实现对不对,要同时看代码和它面对的真实数据。
  • 能读到的,就别想象。 AI 从「虫洞」这个名字想象出一个「穿越转场」,还替我安排好了设计素材,读了代码才知道虫洞实际做什么。功能名是营销用的词,不是交互说明。
  • 验收既要查有没有违规,也要查有没有做。 有一轮设计交付,四份页面里图片和图形一共 0 个,却满分通过了全部验收判据,因为判据只查「有没有违规」。

规则也不能越攒越多。铁律多到读不完,就等于没有铁律。


接下来

这次改得对不对,最终要看数据。上线时间还短,现在下结论太早。我们在看的有这几个数:虫洞的送达里,半年内有更新的博客占多少,上线前模拟是 58.8%;评论数和浏览量的比例,改版前是 0.1%;AI 的结论被撤销了多少条;全量对比的一致率,目前是 95%。

首轮全站 AI 内容判定跑完之后,还要再做一次全量对比。原创性等几项会影响推荐资格,没证明判得准之前,不切成自动。国内检测节点、每周和每月的运营报告、程序框架升级,都在计划里,还没有排期。十年荣誉这条线,计划先让虫洞权重公开运行满一个观察周期,再上线内容流荣誉榜和名人堂,在约满 8 年就可以上榜;2027 年 8 月 30 日,第一位成员满十年。更远一些,我们也在考虑按数据评选的话题类年度评选,比如「最搞笑博客」,不是人人都有,让荣誉有个性,而不是分等级。

商业化也在考虑之中,方向包括服务商赞助、周边预售和线下活动,现在只上线了 Telegram 付费置顶这一条渠道。不管做哪一项,都守三条底线:不强推;广告密度守住初心,让赞助方本身就是博主需要的服务;每一笔收入都回到项目里,能说清付了哪一笔支出。


写在最后

这两个月里,AI 写了几乎全部的代码和文档。但先改虫洞而不是先改页面,访客是因、成员是果,年限不进权重,日常运营交给 AI、拿不准时按规则给结论,准确率全量对比,上线前先过测试服,这些取舍是我做的决定,也由我负责。AI 擅长把一个方向执行到底,也擅长从数据里找出我没想到的问题,但「这件事对用户好不好」「这个取舍值不值」,只能由对项目负责的人来判断。

做完回头看,这次迭代归结起来是三件事:让访客点开的博客,大多还在更新;让推荐和荣誉的规则,写在明处;让项目不再只靠几个人的热情撑着。

十年之约最珍贵的,是成员们一年一年写下来的内容,和访客一次一次的到访。把分发规则公开以后,推荐谁、为什么推荐,所有人都看得到,这对我们自己也是一种约束。页面和代码都会过时,能让人一直信任的,是一件件做到的事。做得不好的地方,欢迎大家指出来。

也谢谢这些年加入十年之约的每一位博主,和每一个为这个项目出过力、掏过钱的人。


文中数据除特别说明外,来自 2026 年 8 月的生产数据快照、上线后的正式服运行记录和项目内的测算记录。

Share this post