你有没有见过那种 97%。数字漂亮得像周报里那句"已完成",点进去,一个能跑的都没有。
dev.to 上有人 9 月 17 号发了个实验。但先说它用的那个仓库,因为仓库本身就是个段子。
一个足球问答应用,11 个游戏页面,各自长出了一个搜索框。
于是有了 7 个 pull request,反复删同一个组件,一共删了 11 次。光把这份重复收拾干净,就够渡一次劫。
而且这 11 份不是复制粘贴的,是各自演化的:方向键有四套行为,只有 4 个会在回合开始时把移动端键盘收起来,有几个用方向键翻结果的时候页面跟着滚,还有一个版本可能会提交过期结果。
同一个功能,11 种性格。
后来靠一次迁移才清的账。收尾那个 PR 里加了个测试,一旦出现第十二份重复实现,测试就红。
【灯光渐暗,这个测试防的是未来的自己】
好,说实验。任务就一句话:在新游戏界面实现一个球员搜索框,匹配所展示代码的既有约定。四个开放权重模型,DeepSeek v4 Pro、Llama 4 Maverick、GLM 5.3、Mistral 3 14B。每个模型每种条件跑 8 次,温度 0.7,一共 160 次补全。
两种上下文,都是真代码,各 400 行左右,把 prompt 长度这个变量摁住。
一种粘的是迁移之前的 commit——那时候仓库里躺着 9 个每游戏一份的搜索组件,共享实现还不存在。另一种是迁移之后的,共享组件在了,TeamTies 已经在调它。
结果干净得有点吓人。
旧上下文:0% 复用,100% 手写,中位 190 行。新上下文:100% 复用,0% 手写,中位 41 行。每种条件各 32 次运行,两个条件之间一次交叉都没有。
32 比 0,一次都没串过。像两拨人在不同的年份上班,互相不认识。
最狠的一刀在这儿:旧上下文产出的那 32 个手写组件,全都调用了 useFootballerSearch。
而这个 hook,已经在迁移的最后一个 PR 里被删掉了。
也就是说,这 32 份代码按仓库现在的状态,一行都编译不过。它们写得头头是道,只是在给一个已经不存在的世界打工——跑到 9 份没人管的旧分叉旁边,又雕了一朵花。
细节也挺有意思。0% 让方向键在列表两端循环,0% 用了那个 SEARCH_MIN_QUERY_LENGTH 常量,97% 直接写死了 >= 2,58% 带了任何形式的移动端聚焦保护。
它不是照着某一份旧代码抄。它照的是"这一堆旧代码给人的平均印象"抄。抄得还挺像,就是没有一份能跑。
然后是附加条件,这才是我今天真正想说的。
在旧上下文之外,再加三样东西:
一,加一段仓库 CLAUDE.md 的规则说明,写明所有搜索都走共享工具、禁止再手写 typeahead。结果 100% 复用。
二,只在目录列表里亮出共享组件的文件名,别的什么都不给。结果 97% 复用。
三,把共享组件的源码给出去。结果 100% 复用。
看出问题没有。97 和 100,看着像同一件事,差得远。
只给文件名那组的 97%,是怎么来的?82.1% 的调用至少虚构了一个 prop,平均每次编造 4.64 个根本不存在的 prop。
而共享组件实际上一共只有 23 个 prop。
给源码的那一组,虚构 prop 的数量是 0。
一个模型看着文件名,说"我知道它长什么样",然后给你显灵出四个半 prop——这个画面,做过联调的人都熟。
规则决定模型走哪条路,源码决定这条路的尽头有没有东西。缺了后半句,97% 就是个名义数字,跟你司周报里那个"已完成"是同一个质地。
插一句,作者自己第一次统计 prop 的时候还搞错了:他拿来提取真实 prop 名的正则根本没匹配上任何东西,于是所有 prop 都被判定成"虚构"。修正之后,源码可见那一组的虚构比例才是 0。
做实验的人都能被自己的正则骗一次,AI 编几个 prop 这事,突然就没那么好笑了。
不,还是好笑的。
然后是我自己的一点判断,可能有点偏:那些"先把坏例子清干净再让 AI 干活"的说法,被高估了。
实验里还有一个条件——共享组件在场,同时故意把一个旧的分叉文件留在可见范围内。结果没有任何差别,所有运行照样复用共享组件,生成长度也基本一致。
模型跟的是仓库里的主导模式,不是上下文里最差的那一份。
所以你不必把每一个坏例子都铲平,你只要让它变成少数派。11 个搜索框里躺 1 个,它就是个历史遗留;躺 9 个,它就是规范。
这话对人成立。对人,我们管它叫团队文化;对模型,我们管它叫上下文。
最后。作者在评论区补了一句,说他的条件设计里漏了一种中间情况——只给类型签名、不给实现,没测。他说这是他最想补测的一个。
我猜结果大概卡在 50% 上下,虚构 prop 的比例也卡在中间。但你猜没用,得跑。
(友情提示:本文所有数字转述自一个我没复现过的实验,我把它讲得挺有画面感,不代表我亲自验证过。评论区扣个"同款",我们下条再见 🫠)