左脚踩右脚的上升飞轮,没那么容易实现
想法很美
「码农早餐」是我们的日更技术公众号,每天早 8 点一篇,稿子由一条 LLM 管线生成。9 月 11 日,我给它加了一个自优化循环,设想是这样的:
- 每天 08:50 拉公众号官方数据(阅读、推荐、转发、关注、完读)
- 给昨天那篇所属的「写作版本」打分,和父版本比:低于 0.8 倍回滚,不低于 1 倍保留
- LLM 读数据、提方案,在 25 个类型化旋钮里最多改 3 处,成为新版本
- 旋钮覆盖选材门禁、标题和开头附注、篇幅、幽默密度、封面风格、主题色、关注钩子文案
判定写成代码,不交给 LLM;底线(事实校对、来源真实、不编造亲历)不在旋钮里,任何版本都碰不到。数据好 → 写得更好 → 数据更好,左脚踩右脚往上走。
40 天后回头看,这个飞轮一圈都没真正转起来。
40 天的账
| 数字 | |
|---|---|
| 版本数 | 18(优化器提案 12,人工设置 6) |
| 被回滚 | 8 个,其中 3 个是人工版本 |
| 循环上线后的文章 | 47 篇,合计 2818 阅读、44 次转发、7 个文内关注 |
| 阅读 ≤ 50 的文章 | 28 篇(六成) |
| 转发集中度 | 44 次转发里 21 次来自两篇(eBPF 开销砍 90%、LiteLLM 换 Rust 内核) |
三个细节比总数更说明问题:
- v10 的旋钮和父版本 v6 一模一样(那天优化器没提出有效方案,直接沿用父版本),照样被判回滚。这就是一次意外的 A/A 测试:同一套配置,换两天的文章,分数差到了回滚线以下。
- 封面风格在绕圈:dark → light(v3)→ dark(v5)→ flat(v9,回滚)→ light(v14,回滚)。首屏定位行在 v8、v11 两次被提出、两次被回滚,最后是人在 v17 定的。
- 「停掉硬菜」这个决定,人设了三次:09-16 看完 10 天数据拍板停掉千字长段(v4),09-18 优化器拿 1 篇的分数把它回滚了——那篇最终 387 阅读,是循环上线以来最高的一篇;09-19 再设(v7),又被回滚;直到 10-12 的 v17 第三次设。
为什么转不起来
1. 信号量不够,噪声比旋钮效应大
循环上线后,平均每篇 60 阅读,转发率 1.56%,文内关注率 0.25%。一个版本跑满一周(7 篇,约 420 阅读),预期关注数是 1 个。拿 1 个和 0 个比出来的「版本分」,跟掷硬币没区别。
换成转发率算一下样本量:想以常规的 80% 功效、5% 显著性分辨「转发率差 20%」,每个版本需要约 2.5 万阅读。日均 60 阅读,就是一个版本 400 多天。
起初我们 1~3 篇就判定。10-12 改成至少 7 篇,噪声小了一些,代价是一周只能完成一次判定——40 天里最多五六个独立实验,还远远不到 400 天。门槛设多少都两难:判得快就是在追噪声,判得准就慢到没有意义。
2. 旋钮管不到结果的大头
这个号 93% 的阅读来自平台推荐流。09-07 那篇「把 .gitignore 反过来写」一篇 1358 阅读,占那 10 天总阅读的 78%。决定一篇能不能被推荐的,主要是当天有什么选题,其次是标题;封面是暗底还是亮底、幽默密度高一档还是低一档,都是二阶效应。
而当天有什么选题不在旋钮里,它来自外部新闻流。把一阶变量当噪声、在二阶变量上做优化,优化器只能学到「哪几天运气好」。
3. 指标会被循环自己刷
最初的打分是推荐 0.4 + 关注率 0.25 + 点赞率 0.2 + 评论率 0.15。早在 08-28,日报就开始在文末放「评论区站个队」的二选一提问;循环上线后,评论率进了打分,旋钮里还有一个标注影响评论的「文末提问附注」,v16 时优化器就提案把这道题写得更精确。结果大约 40 篇站队提问,只换来 1 条读者留言,而且不是站队。
10-12 我们逐条看了全部留言:读者留言只来自三种情况——标题被拆穿、细节没讲清来追问、行家补充反驳,另有我们自己发的勘误。像 08-31 那条作者勘误,按旧公式会算成加分:文章写错了,分数反而涨了。评论这个指标在这个规模下根本号召不出来,放进打分只会让循环去优化号召话术。
4. 环境会变,循环看不见
10-16 起推荐流断崖归零:10-15 还有 29 次推荐,之后每篇 0~1。那段时间版本一直是 v17,稿件结构没变,发文链路没有代码提交。我们判断是账号级的变化(平台侧限流或新号扶持期结束),原因至今未确认。
对循环来说,这只是「某个版本之后分数暴跌」。它会把锅甩给当时生效的旋钮,回滚、再提案,在一个与旋钮无关的断崖上认真地做优化。
5. 人和循环在打架
人看的是跨文章的结构性结论(「多篇加发不叠加流量」「硬菜把完读率拖到 6-16%」),循环看的是单版本的分数。两者冲突时,每天 08:50 自动运行的那一方总能赢。我们先加了「人工版本观测不足 3 篇不判」的锁定期,后来统一成所有版本至少 7 篇——本质上是承认:战略决策不该交给一个靠单周噪声下判断的循环去推翻。
真正起作用的是什么
回看两个月,几次有效的改版都来自人读数据,而不是旋钮 A/B:
- 09-16:看 10 天逐日数据,停掉多图文加发和硬菜(多篇加发各 1~22 阅读、推荐 0)
- 09-19:从官方数据里翻出平均阅读时长和五等分跳出位置,发现读者预算固定在 40
60 秒,与篇幅无关;配菜改成只留标题、头菜压到 400500 字。只看阅读 ≥ 10 的篇目,完读率均值从此前的约 23% 升到之后(至 10-15)的约 29%(同期选题也在变,只能算相关) - 10-12:逐条读完全部留言,删掉文末提问,评论移出打分,纠错留言改为扣分
这三次的共同点:都是把几十篇放在一起看结构,而不是比较两个版本的均值;结论都是定性的(「读者预算是 40 秒」),旋钮只是落地的载体。
带走的教训
- 自动化一个实验循环之前,先算样本量。 用真实基线率算出「分辨 X% 差异需要多少样本」,再除以日流量。算出来是一年,就别上自动判定。
- 先确认旋钮能管到结果的大头。 如果最大的方差来自不可控输入(选题、平台流量),先把它纳入(分层、或当协变量),否则优化器学到的只是哪天运气好。
- 打分只用循环刷不动的指标。 能被号召话术直接拉动的指标(评论、点赞),会被优化器当成捷径。我们的号现在已经去掉了全部关注号召,只靠内容本身。
- 给循环一个「环境变了」的刹车。 全局指标断崖时(比如推荐流整体归零),应该暂停判定、通知人,而不是继续回滚旋钮。
- 战略决策不进循环。 循环适合在一个已定方向里做小步微调,前提是信号量够;方向本身该由人看结构做决定,循环无权推翻。
这个循环现在还在跑,每天照常拉数据、记账、提方案。复盘下来的结论是:在信号量足够之前,它更适合当一个勤快的数据员和提案者;「左脚踩右脚」的那一步——自己判定、自己升级——应该交还给人。飞轮的第一推,终究是内容本身有没有价值。