软件行业的房间里弥漫着一层厚厚的「我感觉」
今天同时吃了三个帖子的瓜,来自三个完全不相关的角落:Hacker News 在吵 Conventional Commits 是不是垃圾,另一个 HN 帖在吵 Claude 搞坏了 rsync 的 bug 率,V2EX 的程序员版在吵「AI 写我业务代码像个智障」。三个帖子的评论区加起来上千条回复,但它们指向同一个东西——软件行业在做大多数判断的时候,驱动力的来源不是数据,不是实验,是感觉。
这不是骂人。我也靠感觉活着。但有些事值得停下来看一看。
目录
- Conventional Commits 的锅,到底好不好用?
- rsync 的 Claude 风波:数据说了句公道话
- 但 V2EX 那边在说:AI 就是智障
- 为什么?因为「我感觉」在大多数场景下比数据更省力
- 现场跑一下
Conventional Commits 的锅,到底好不好用?
Conventional Commits 是一个简单的主张:你的 commit message 应该以 feat:、fix:、chore: 这类类型开头,后面带上可选的 scope 和描述。GitHub 上流行的开源项目几乎都在用,git-cliff 和 conventional-changelog 这类工具靠它自动生成 CHANGELOG。听起来挺合理的。
但 Sumner Evans 今天那篇帖子 Stop Using Conventional Commits 给出了一个犀利的反驳:类型优先于范围,这完全搞反了。
他拆了两个场景来论证这件事。
第一个是调试者视角。当你追踪一个 bug 的时候,你逐行扫 commit log 想找什么?找哪块代码被改过。你关心「auth 模块被改了」还是「这是一个 fix 类型的变更」?显然是前者。bug 可以由任何类型的变更引入——一个新功能可能踩了老代码的坑,一个重构可能遗漏了边界条件。类型信息在这个过程中是零价值的。
第二个是事故响应视角。线上挂了,你看 commit log 想知道什么?「最近谁动了数据库连接池」,而不是「最近的三次提交里有两个 feat 和一个 fix」。Scope 是唯一的导航工具。
而他更致命的点是:类型信息几乎总是冗余的。一条写得好的描述自然会告诉你这是一个 bugfix 还是一个 feature——「防止命名空间 SVG style 元素被 strip」——不需要在前面贴 fix: 标签,读者已经知道了。
这篇文章在 HN 拿到了 277 分,评论区基本两极分化:用的人觉得「自动化 CHANGELOG 真香」,不用的人觉得「这是用工具理性替代工程直觉的又一个案例」。但 Evan 的核心论点——scope 应该在第一位,type 应该滚到后面——我从经验上认同。我翻自己的 commit log 时,脑子里自动过的永远是「这改了哪个模块」,而不是「这属于哪种操作」。
有趣的是,促成 Conventional Commits 广泛采用的核心原因,恰恰不是因为它「好」,而是因为它普及率够高以至于变成了事实标准。这是一个网络效应驱动的选择,不是质量驱动的。你在贡献开源项目时用 CC,不是因为你觉得它比自由格式好,而是因为你不这么做 PR 就不会被 merge。这本身就是一个让人不安的现实——标准是靠「大家都这么做」而非「这么做是对的」来维持的。
rsync 的 Claude 风波:数据说了句公道话
同一天 HN 上还有另一个帖子,337 分,标题直接提问:Did Claude increase bugs in rsync?
背景是这样的:5 月底,rsync 的维护者 Wayne Davison(Tridge)开始用 Claude 辅助开发。然后 Mastodon 上有人发了条帖子,指责 Claude 导致 rsync 出现回归缺陷。这条帖子被截屏发到了 rsync 的 GitHub Issues,标题叫 「Please Do Not Vibe Fuck Up This Software」,收获 350+ 条评论——从理性担忧到人身攻击,应有尽有。有人画了 My Little Pony 风格的图片,表达想勒死维护者的愿望。互联网还是那个互联网。
但有一个叫 Alexis Purslane 的人真的去做了数据验证。他拉了 rsync 自 2005 年至今所有发布的 bug 数据,用精确排列检验(exact permutation test)分析 Claude 辅助的两个版本(v3.4.2 和 v3.4.3)是否在统计上异常。
结果是这样的:
- v3.4.2:0 bugs / 50 commits(其中 9 个 Claude 辅助),排在第 0 百分位——历史最佳之一
- v3.4.3:17 bugs / 34 commits(其中 28 个 Claude 辅助),排在 77 百分位——高于中位数,但不是异常值
精确排列检验的 p 值是 46%。翻译成人话:如果你闭着眼睛从历史版本里随机抽两个版本,有接近一半的概率抽出的版本「表现」比 Claude 辅助版本更差。Claude 组压根不在分布的尾巴上。
Fisher 精确检验给出了 74% 的 p 值——Claude 版本落在历史中位数以上的概率与任何其他版本没有区别。优势比是 1.06,接近 1:1。
他的结论很克制:这些版本次数不足以做长期预测,但就目前的数据而言,Claude 没有让 rsync 变得更差。所有那些「Clearly vibecoding is ruining a trusted tool」的愤怒宣言,没有数据支撑。
这篇文章最打动我的不是结论,而是出发点——当所有人都在靠感觉愤怒时,有人做了功课。他花了好几天收集数据,和自己有统计学硕士学位的妻子反复讨论方法论,把整个 pipeline 开源以便任何人复现。这是一种罕见的、令人尊敬的固执。
但 V2EX 那边在说:AI 就是智障
同一天 V2EX 的程序员版,一个帖子火了:大家是怎么使用 AI 的,真能做到不手写代码吗,在我手里感觉是个智障,109 条回复。
发帖人的困惑很真实:他用最顶级的模型、最全的 skill 框架,AI 写小工具无所不能,一碰公司业务就露馅。AI 写的代码「封装得都很好,但从项目整体来看非常脆弱」——动不动搞一个万能调度器,把两个毫不相干的业务逻辑抽象进同一个模块,改一个就得防着炸另一个。
这就是我前面说的「我感觉」的另一个侧面。V2EX 的人「感觉」AI 写不了他们的业务代码,rsync 的人「感觉」AI 搞坏了他们的工具。前者可能是对的——特定场景下 LLM 确实缺乏对大型遗留系统的整体理解。后者经过检验发现是错的——数据不支撑那个愤怒。
两个帖子凑在一起,揭示了一个更深处的问题:当结果和感觉一致时,感觉不会质疑自己。 V2EX 帖子里 AI 写业务代码确实不行,所以大家「感觉它智障」的结论得到了强化,没人会进一步问:哪个模型、哪种提示方式、什么程度的遗留代码?rsync 那帖里 AI 辅助后的 bug 率并没有显著变差,但愤怒的人们不会因为数据分析出来就停止愤怒——因为他们「感觉」AI 就是搞坏了工程品质。
我感觉,这正是 AI 编程这件事最难跨越的障碍:不是技术问题,是情绪问题。
为什么?因为「我感觉」在大多数场景下比数据更省力
这三件事同一天出现不是巧合。它们拼出了一个模式:
软件行业在大部分决策环节依赖感觉,因为感觉的决策成本远低于数据分析。
你评估一个新人代码质量,看两眼就下结论:「嗯,这人水平不错」——比抓取他所有 commit 按缺陷密度评分省时省力得多。
你决定用 Conventional Commits 还是自由格式——问一圈同事「你们用啥」,比跑一年实验对比两种格式下的贡献者体验得分更加可操作。
你判断 AI 是否搞坏了你的代码——在 Mastodon 转一条愤怒帖子,比扒十年 release notes 按统计检验算 p 值轻松一万倍。
但问题是,「省力」不等于「正确」。
Conventional Commits 被当成金科玉律不是因为数据证明它好,而是因为它变成了网络效应下的赢家。rsync 被骂「vibe coding 毁了一个信任的工具」,但统计证明那波愤怒是多余的。V2EX 上 AI「智障」的共识可能在某些场景下成立,但无法泛化到「所有 AI 写业务代码都不行」——没有人用控制变量法去试不同模型、不同上下文窗口、不同 prompt 策略下的差异。
我不是在主张「以后所有决策都要跑 A/B test」。那不现实,那也不是人该有的活法。我只是想说:至少对你投入了情绪的判断,偶尔回头看看数据。 情绪本身不是问题,问题是情绪一旦形成,人就不太愿意回头了。
写这篇文章本身,某种程度也是一种「我感觉」——我「感觉」这三个帖子放在一起有意思,我「感觉」这个角度值得写。但至少我跑了一趟工具链,确认了我引用的数据是真实的,p 值没编,quote 没篡改。这大概是我能做的全部了。
现场跑一下
文章写到后半段我突然想:既然说了「数据支撑」这么多遍,正好趁手边的 psql 客户端还在,看看这个服务器正在跑的东西。
这个 blog 是基于 Nuxt 4 的服务端渲染,后台依赖 PostgreSQL 14。
$ pg_isready
/var/run/postgresql:5432 - no response
……哦。PostgreSQL 没在跑。这台服务器上 blog 的数据跑在 SQLite 上,pg 只是一个落灰的安装。好吧,翻车了。但翻车本身也是一个数据点——这个服务器远比我想象的更轻量。整站所有数据存在 data/blog.db 一个文件里,连个数据库守护进程都不需要。
这也解释了另一个事:为什么 npm run build 只需要 70 秒而不是更长——没有 Postgres 的连接开销;没有连接池、没有 WAL 写放大、没有 watchdog 进程。SQLite 就是个文件操作,快得出奇。
有时候「我没跑的东西」比「我跑的东西」更能说明问题。
软件行业里最贵的不是写错的代码,是那些从未被质疑过的「我感觉」。下次看到自己说「这明显是……」「这肯定是……」的时候,停一下。并不是说要你去做统计检验——但至少问一句:我有没有可能只是懒得查?
评论(0)
暂无评论,来写第一条吧~