【木子狸的Vibe Coding随笔】01 从《人月神话》谈起

L3

使用了AI的代码,所以只能归为L3。
然后 正文使用 AI 进行头脑风暴,但不是AI生成内容。

我想说的是,为了写代码而写代码,是写不好代码的。
编程是硬实力和软实力结合的体现,也许我们需要首先学习前人留下的经验来丰富自己。

写给自己,可能大家过于追求效率,性能。反而忽略了自身发展,已经静不下心来看这些了吧。

代码已经不是必须品,任何一个AI都能写点东西出来。AI也能考虑架构,算法,设计。
对设计规划的影响,最后还是历经各种问题后,那个设计者的直觉。

迈出第一步

最简单的 Vibe Coding 是什么?你可以打开 gemini 输入 “帮我做一个贪吃蛇游戏” 回车。

好了,你现在已经是一个合格的 Vibe Coder 了。

这里可以试玩

这确实很爽,也能玩。但是这个代码真的写的好吗?我们可以分析一下。
如果你不会,也可以丢给其他AI进行分析一下。

1. 提速逻辑失效 (核心逻辑 Bug)
// 在 update 内部修改了 speed 变量
if (score > highScore) { ... }
if (speed > 50) speed -= 1; 

// 但是计时器是在 startGame 启动时一次性绑定的
gameLoop = setInterval(update, speed); 

分析: setInterval 一旦启动,其执行频率就固定了。虽然你吃到苹果后修改了全局变量 speed 的值,但计时器不会重新读取这个值。这导致无论玩家得多少分,蛇的速度永远是初始的 100ms。

2. 棋盘 tileCount 非整数导致的边界判定漂移 (数据类型 Bug)
const size = Math.min(window.innerWidth - 40, 400);
canvas.width = size;
tileCount = canvas.width / gridSize; // 结果可能是小数,如 18.75

分析:tileCount 为小数时,边界判定 head.x >= tileCount 会出现偏差。例如,蛇头在坐标 18 时视觉上已经触边,但逻辑判定 18 < 18.75 依然存活,导致蛇能跑出网格线或在空隙处突然死亡。

3. 缺乏输入缓冲可能导致“自杀” (交互 Bug)
function changeDir(dir) {
    switch(dir) {
        case 'up': if (dy !== 1) { nextDx = 0; nextDy = -1; } break;
        // ... 其他方向同理
    }
}

分析: 如果蛇向右走(dx=1),玩家在极短时间内按下“上”紧接着按“左”。因为 update 还没执行,此时 dx 依然是 1,按“左”会被视为合法。下一帧更新时,蛇会瞬间 180° 原地回头撞死在自己脖子上。

4. 窗口缩放导致重置 (体验 Bug)
window.onresize = initGame; 

function initGame() {
    // ...
    resetGameState(); // 内部重置了所有蛇的位置和分数
}

分析: 玩家在手机上不小心旋转屏幕或调整窗口大小时,onresize 会立即触发 resetGameState。这意味着玩家无论玩到多高分,都会因为一次窗口抖动而瞬间被迫重新开始。

5. 递归堆栈风险 (性能 Bug)
snake.forEach(part => {
    // 递归调用自己
    if (part.x === food.x && part.y === food.y) createFood();
});

分析: 在游戏后期,当蛇占据了 90% 以上的格子时,随机生成的坐标极大概率落在蛇身上。这会导致 createFood 进入极其密集的递归调用,造成画面瞬间掉帧,甚至在极端满屏情况下导致浏览器崩溃。

这些问题如果你碰到了,也不是不能让AI再次改。但你的时间精力是有限的,同时也不可能碰到所有的bug。如果一直这样进行抽卡,运气好能出来个能用的东西,运气不好就是一堆跑不通的垃圾。

从《人月神话》谈起 —— Vibe Coding

Vibe Coding 的本质不是祈祷,不是许愿。借用《人月神话》中作者强调的一个词语来说就是:

贵族专制(Aristocracy)

在 1975 年,Fred Brooks 在《人月神话》里提出了一个非常令人不快的观点:“为了获得概念的完整性,设计必须由一个人,或者非常少数互有默契的人员来实现。”

多年前,他认为,你是用户的Agent代理人,必须运用专业知识支持用户和自身的利益。
而现在,AI是你和你要做的软件之间的“代理人”
所以我们不能站在维护方——之前是程序员,现在是AI——的立场上进行辩护。

先来高兴一下,看别人碰见这些

可能你看到了会笑一笑,但是如果发生在你自己的身上了呢?

毕竟AI喜欢能不做就不做;用漂亮话糊过去;即使不确定也装得确定;过度保守或过度敷衍;为了好生成而牺牲用户真实需求。

也许是我们给AI训练的语料就是这样的 :rofl:

究其原因,写代码的时候我们没有确保AI服务用户和你。

然后这里有个短语“概念的完整性”需要解释一下。


也就是说:

为了反映一系列连贯的设计思路,我们宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。

AI 已经学习了Github上可能几十亿行的代码,它也可能已经学会了各种语言风格,但如果没有指定方向,AI会随机进行预测。因为 AI 的输出本质上是基于上下文的 Token 概率推导。

具体原理可以查看这位佬的帖子:

随便可不是个好事情,如果我们不保证约束,我们就不能保证代码的整洁。你可以一行都不亲自动手写代码,但你必须强制 AI 遵循你的指导,你的定义。

这便是 Vibe Coding 中的贵族专制——核心是审。通过个人的直觉和 AI 的效率,从繁琐的语法中解脱,省下的时间用于系统的审计。

重新定义代码

谈到审,可能会有人会问:我都开始使用自然语言描述了,这种新型的“编程语言”已经快替代已有的编程语言了。代码迟早要消失,为什么我们还要去费劲心思审阅呢?不能让AI生成总结报告吗?

先来回看过去。

2008 年 《代码整洁之道》发布,作者Martin在书的开篇说:

我们正在临近代码的终结点。很快,代码就会⾃动产⽣出来,不需要再⼈⼯编写。程序员完全没⽤了,因为商务⼈⼠可以从规约直接⽣成程序。

现在,我们到达了他的未来,代码已经终结。正如开篇的迈出第一步,你只要有想法,AI 就能源源不断的为你提供代码。

但我们永远抛不掉代码,因为代码呈现了需求的细节。

十几年前,有一群人盼望着,有一天创造出一种机器:只要我们想一想,嘴巴都不用张就能叫它依计行事。那机器能透彻的理解我们,只有这样,它才能把含糊不清的需求翻译为可完美执⾏的程序,精确满⾜需求。

到了现在,即使有了 AI 这种情况永远不会发生。

我们可以创造帮助把需求解析和汇整为正式结构的各种⼯具。然⽽,我们永远⽆法抛弃必要的精确性——所以代码永存。

困难重重

为什么代码所代表的“精确性”难以被 AI 彻底取代?

早在1986年,有人便替我们回答了这一点。

软件开发的困难可以分为两类:一类是次要的困难;另一类是根本困难。次要困难指的是那些非必要的,由于所使用工具,或者语言本身带来的困难;而主要困难则是指的那些软件本身无法避免的困难——复杂性,依从性,可变性和不可见性。

软件是复杂的,随着规模扩大,会变得理解困难,Bug频发,管理失控;代码是依从的,代码会随着时间无条件的适应,所有人为的设定;能力是可变的,软件功能是纯粹的思维产物,它面临着持续变更的压力;最后软件是无形的,你即使借助了各种图形,我们也很难构建出真正的模型。

软件的主要困难是无法消除的。Vibe Coding 只是高效的解决了一些次要困难,它可以瞬间写好代码,能消除拼写等语法错误。但构建复杂的概念结构,完善的软件功能——这些靠的是人来完成的智力活动。

AI 生成的代码好比是砖块,解决了你盖房子的材料有没有的问题。它不知道砖块的作用,是用来建高楼大厦还是别墅。你需要审阅代码,去观察,去确认。只有这样,你才能明确 AI 给你看的,是不是真正你脑海中的真正样子。

目光所至

软件是天生不可见的,我们无法避免这一点。许多人 Vibe Coding 出来的软件也大多都是能跑,但不可维护的。

这种情况不外乎就是没有审阅其中的逻辑,或者仅仅看似审阅了逻辑,但是是AI总结出来的。这种行为,为你的软件构建了一个巨大的黑盒。

一旦出现了问题,或者有了很好的点子,这个黑盒就会成为你 Vibe Coding 路上的噩梦。

设计要可见,以便审查和调试。——《UNIX 编程艺术》

你能一眼看出来的——就是软件的透明度。作为预测机,AI 生成的代码往往倾向于掩盖细节,或者为了满足你的“一句话”需求而堆砌复杂逻辑。

你的需求应该是具体的,清晰的,明确的。即使开始不明确,你也可以和 AI 进行讨论——让它列出有关的一些方向。审阅文字,也是审计的一种。当一些想法清晰后再进行开始。

帮我做一个贪吃蛇游戏。但是先不开始做,先和我讨论可能的设计考虑方向 给出10个点

制作一个“贪吃蛇”看似简单,但要做到体验流畅、代码优雅,有很多值得探讨的维度。以下是我们开发前可以考虑的 10 个设计方向:


  1. 核心逻辑:坐标与移动

蛇的身体本质上是一个坐标队列

  • 移动机制:是每一帧都重新渲染所有格子,还是仅仅“增加一个新的头部,删除一个旧的尾部”?后者在性能上更优。
  • 网格系统:游戏区域是基于像素移动(平滑但逻辑复杂),还是基于固定网格(经典且易于实现)?
  1. 碰撞检测逻辑

这是游戏胜负的核心判断:

  • 边界碰撞:撞墙是直接游戏结束(Game Over),还是像某些版本那样可以从另一侧穿出(环形空间)?
  • 自身碰撞:如何高效检测蛇头是否触碰到了身体的其他部分?
  1. 食物生成算法
  • 随机性与合法性:食物必须随机生成,但绝对不能生成在蛇的身体上。如果蛇占据了 90% 的屏幕,你的算法如何快速找到剩下的空位?
  1. 速度与难度曲线
  • 动态加速:随着蛇变长,移动速度是否应该加快?
  • 阶梯难度:是线性加速,还是每吃 5 个食物提升一个“等级”?
  1. 输入处理(输入缓冲)
  • 转向保护:这是新手最容易忽略的。如果蛇向右走,玩家快速按下“上”接着“左”,可能会导致蛇直接“自杀”撞向自己。我们需要一个输入缓冲区来确保每一步转向都是合法的。
  1. 渲染技术选择
  • HTML5 Canvas:适合高性能、流畅的动画。
  • DOM 元素:适合简单的逻辑学习,通过操作 <div> 的位置来实现。
  • 游戏引擎(如 Phaser.js):如果你想加入复杂的粒子效果或物理特性。
  1. 视觉风格与 UI
  • 美术风格:极简像素风、复古 GameBoy 风,还是现代发光特效(Neon Style)?
  • UI 元素:实时分数显示、最高分记录、暂停菜单、以及醒目的 Game Over 界面。
  1. 游戏状态管理
  • 我们需要一个清晰的状态机来切换:等待开始进行中暂停游戏结束
  1. 扩展功能(进阶考虑)
  • 特殊食物:比如金色苹果(双倍积分)、缩小药水(减短长度)或减速道具。
  • 障碍物:随机生成的墙壁,增加走位难度。
  1. 持久化存储
  • 本地最高分:使用浏览器的 localStorage 来保存玩家的历史最高分,增加游戏的重玩价值。

先不看这些输出是不是对的,但它可以给你一些清晰的可能方向,这时贪吃蛇可能就会在你脑海中逐渐显现了。

这部分需要学习 提问的艺术 后面有时间会写到单独的帖子里面

做为一个 Vibe Coder 我们要做的就是逐渐清晰框架,即使人不可能考虑到方方面面,我们也可以让 AI 仅仅实现我们想过的内容,而不进行自由发挥。如果进行了自由发挥,也要强硬的要求 AI 进行重构和缩减。

正如 Eric Raymond 所说:“如果一个程序的运行逻辑并不复杂——也就是说,人们不必绞尽脑汁就能推断出所有可能情况——那么它就是简洁的。”

草稿也是成品

正如我在序言中提到,编程可以看作是绘画,不是工程。在 Vibe Coding 中,代码既是最终的软件,也是你思考过程的草稿。

AI 给了我们以极低成本获取“初稿”的能力。这意味着我们有了更多的时间去修正 ,去打磨 ,去审视

我们不应该期待 AI 直接给你成品。我们应该把它生成的代码看作是一块画布上的底色。需要通过不断的 Prompt 交互(也就是“再设计”),去覆盖那些错误的逻辑,去擦除那些多余的修饰。

这里化用一下这句话。

清水出芙蓉,天然去雕饰

希望我们的思想:自然、清新。
这时——代码自然生发。

此刻

好的设计往往是“再设计”(Redesign)的结果。很少有人能一次就把事情做对,就像油画允许画家反复涂抹一样,AI 生成的代码给了我们一次次涂抹的机会。

先写出粗陋的初稿,然后斟酌推敲,直至达到我们心目中的样子。在 Vibe Coding 中,AI 帮我们完成了那个“能跑但丑陋”的初稿,而我们的任务,是运用我们的品味去剔除那些多余的“雕饰”,让代码回归逻辑的本质。

这一过程消除了 Bug,同时展现了对美的追求。
当我们删繁就简,让逻辑如清水芙蓉般自然显现时,快乐自然发生。

以 《只是为了好玩》 结束

那种创建事物的纯粹快乐,那种看着自己亲手组装的零部件精妙运行的魔力。这种快乐,如同上帝创造世界,也如同孩子在玩泥巴。 —— 《人月神话》

当我们剥离了繁琐的语法记忆,越过了枯燥的代码,Vibe Coding 让我们重新直面这种最原始的冲动。

从生存(Survival),到社会秩序(Social Order),最后到达娱乐(Entertainment)。

你需要做的仅仅只是做出选择,承担代价,然后享受就好。

这,只是为了好玩(Just for Fun)。


写的好累,第一章的第一个小节就结束了。可喜可贺。

我知道很多人都看不下去这种,但是我还是写了。

我想说的是,如果只是为了完成任务而写代码,最好的方式是花钱找人写,你的钱包厚度决定了软件的好坏。

没有什么东西是一蹴而就的,失败也在所难免。

也不用焦虑,毕竟几十年前的思想现在也还没有过时。不过是新瓶装旧酒而已。

写这些更多还是一种思想,技术的话会单独写的。

PS: 多来点反馈吧
能力有限,不能保证对错。有问题可以指出来。
风格啥的 都可以交流

评价一下
  • 可以
  • 一般
  • 不行
0 投票人
65 个赞

长篇干货,先收藏,明天看

1 个赞

前面没看后面没看
感谢分享 :face_savoring_food:

5 个赞

总之在AI能够正确解决编码时候的设计问题之前,人都需要明确的控制代码的质量和思路。

1 个赞

想看佬的提示词。因为知识不够完善我在实际用中总是会下意识的切成“询问口吻”,但实际“命令型”才执行的更准确,所以经常性的打完字再删改一轮发给ai

1 个赞

写得非常好,所有的事情回归本质,vibe 是一把双刃剑,取决于你本身对于编程和工程的理解。

1 个赞

非常好的思考,AI 编码时代估计需要一个新的开发方式才能满足对 vide coding /spec coding等方法的需求, 大家都在不断摸索和探索过程中。

写的雅啊我应该写不出这种。按其我们就要好好提升自己内在的本质,最重要我们的思维和使用工具不能给夺舍了,不然就像一副无情的编码机器。

虽然上班来说大部分可能效率优先,不过开发是一个终身学习的过程,不能AI出现后放弃了学习新的基础的过程

谢谢夸奖 佬的文章写的也很好 :heart_eyes:

1 个赞

干货。写出了对vibe coding的思考,语言风格有趣。

追更追更

生动有趣:tieba_003:

一字不拉的看完了~

1 个赞

很真实~
几乎就是我遇上的困难写照,思考的方向也差不多。
【开发日记】记录三无小白从0到1开发一个战棋游戏的完整过程(断更超1周没JJ版) - 开发调优 - LINUX DO
我开始的时候充满激情,想法很简单,但开始vibe之后,发现小功能ai确实易如反掌(就像佬的贪吃蛇例子)。
但稍微深入的时候,其实还不用ai做,我已经预估到了后面庞大的体系、模块、代码耦合问题……如果不解决,就像在沙滩上建城堡————指日可塌
还是得做好框架和 review 啊~
:tieba_022:

1 个赞

vibe coding兴起之后现在感觉很空虚,刚刚让大模型给我推荐了几本需求和架构设计的实体书,马上下单了,其中一本就是人月神话,来L站一看没想到有道友

no sliver bullet, 只记得这句话了。 ai 算是 silver bullet 吗?

不算,因为 AI 只能解决次要困难——思想转化为代码
现在还解决不了对现实业务逻辑抽象的这种根本困难,还是需要人参与

但是怎么说,离得很近了 Agent 算是雏形。

写的挺好的,刚接触代码几天一大堆的语言,什么网络接口,数据库,前端,后端,又是java,pathon,php,vue等等英文的单词,各种词汇给我搞的晕头转向的,一开始想仔细了解一下就跟在迷雾里面一样根本看不清,太多的东西了,辛苦作者写了那么多东西,让我感同身受

好文,大佬期待下次更新

都更新好多了hhh