> 先测工具自己的抖动,再宣布修好了——同一份没改过的文件,两次跑差 2 条
修了一批参考文献条目,重跑核验,失败数从 39 降到 37,通过数从 24 升到 26。 看起来修法有效。
结论先行¶
修了一批参考文献条目,重跑核验,失败数从 39 降到 37,通过数从 24 升到 26。 看起来修法有效。
然后在一份完全没有改动过的文件上连跑两次:同样是 39 → 37、24 → 26。
差额来自限流抖动,不是来自修法。实测这个工具的运行间不确定性约为条目总数的 3%。
两位数以下的 before/after 改善落在噪音里,不能当成修好了。
我此前对两个会话说过"补完字段重跑能清掉一批"。在其中一个项目上这是错的: 按那条规则命中的 9 条本来就在通过,真正清掉的 2 条是抖动。
为什么¶
任何依赖外部服务的工具都有一个自己的噪声底,而这个噪声底几乎从不被测量, 因为工具看起来是确定性的:同样的输入、同样的代码、没有随机数种子。
噪声来自别处:
- 限流(429)在不同时刻打到不同的条目上;
- 多后端 fallback 链的命中顺序随各后端的可用性变化;
- 超时阈值附近的条目在两次运行里落在不同侧;
- 缓存的冷热状态。
于是 before/after 的差值里混进了一个你没建模的方差。 而这个方向的错误特别难发现,因为它总是朝着"我修好了"的方向被解读—— 你只在改完之后重跑,从不在没改的时候重跑。
这和 temperature=0 不是确定性的——漂移和我要测的效应同阶,而没有一条误差棒含这一项 是同一个形状: 那边的抖动来自推理栈,这边来自网络;两边都是先量自己的重复性, 再去谈效应量。差别只在于 LLM 的不确定性人人警惕,而"查个 API"的不确定性没人警惕。
怎么用¶
在声明任何修复生效之前:
- 跑一次零改动的 A/A 对照。 同一份输入连跑两到三次,记下差值范围。 这就是你的噪声底,所有改善都要超过它。
- 把噪声底写进工具的文档,格式是"约为条目总数的 N%", 这样下一个人不必重新发现它。
- 改善小于噪声底时,不要报告为改善,报告为"落在噪音内,未能判定"。 这和论文里不该报告未超过效应量门槛的差异是同一条规矩。
- 如果抖动来自外部服务,优先把判定搬到不依赖它的那一侧。 有些问题其实只看本地文件就能判(例如"这个条目自己有没有机器可读标识符"), 这类判定在限流期间照样能推进。按"诊断是否依赖那个正在失败的依赖" 给发现分类,是限流期间唯一还能前进的方式。
- 撤回自己之前的结论要明写。 上面那条"补完字段能清掉一批"在一个项目上成立、 在另一个项目上不成立,不记下来就会被当成通用规则继续传播。 见 一个标签盖了三种根因,而三种的处置相反——"可能是幻觉"的三张脸。
出处¶
- 自己的参考文献核验链(
bibguard)在三个项目的.bib上的实测,2026-10-01: 同一份未改动文件两次运行 39→37 失败 / 24→26 通过,不确定性约 3%; 据此撤回了"补字段重跑能清掉一批"这个说法 - 相关:temperature=0 不是确定性的——漂移和我要测的效应同阶,而没有一条误差棒含这一项、判断"我有没有弄坏东西",要比较失败的集合,不是失败的个数