☰
Vibe Coding 实战:从模糊意图到可运行原型的完整链路
2026/10/14 7:30:00 网站建设 项目流程

1. 从“氛围”到“代码”:Vibe Coding 到底在解决什么问题

第一次听到“Vibe Coding”这个词,是在一个开发者小圈子的闲聊里。有人半开玩笑地说:“现在写代码,先别急着打开编辑器,先找找感觉。”当时我以为这只是又一个新的网络热词,直到自己在一个小工具项目上完整跑了一遍这套流程,才发现它背后其实对应着一类非常真实的开发痛点——在需求模糊、边界不清、灵感先于逻辑的阶段,如何让代码快速跟上直觉,而不是被工程规范拖死。

Vibe Coding 的核心,不是“不写代码”,也不是“让 AI 替你写代码”这么简单。它更像是一种以氛围和意图为起点的编程实践:先用自然语言、草图、伪代码甚至一段情绪描述把“我想要什么”表达清楚,再借助现代工具链把这个模糊意图逐步收敛成可运行、可迭代的代码。它适合谁?适合那些脑子里有画面但还没想清楚架构的独立开发者、适合需要快速验证想法的产品原型阶段、也适合在业余时间做小项目但不想被过度设计拖垮的爱好者。

我自己的理解是:传统编程是“先定义问题,再解决问题”,而 Vibe Coding 是“先捕捉感觉,再逐步定义问题”。这两者并不冲突,只是适用阶段不同。当你面对的是一个全新领域、一个还没被验证的交互方式、或者一个你自己都说不清但就是觉得“应该这样”的体验时,Vibe Coding 能让你在半小时内看到东西跑起来,而不是花三天画 UML 图。

这篇文章会围绕我实际跑过的一个小项目展开,把 Vibe Coding 的完整链路拆开:从怎么把“感觉”翻译成可执行的提示,到工具选型的取舍,到代码生成后的收敛与重构,再到那些只有踩过才知道的坑。全程不涉及任何具体平台推荐,只讲方法和逻辑,你可以直接抄作业。

2. 把“感觉”翻译成机器能懂的东西:意图表达的三层结构

2.1 为什么直接说“帮我写个 App”一定会失败

很多人第一次尝试 Vibe Coding 时,会对着工具说:“帮我做一个记账 App。”然后得到一堆看起来像那么回事但完全跑不起来的代码。问题不在工具,在于意图表达的粒度太粗。机器不知道你要的是本地存储还是云端同步,不知道你是要极简单页还是多标签导航,更不知道你所谓的“记账”是流水账、预算管理还是多人分账。

我试过最有效的方式,是把意图拆成三层:氛围层、行为层、约束层。氛围层描述“这个东西用起来应该是什么感觉”,行为层描述“用户能做什么操作”,约束层描述“技术上必须满足什么条件”。这三层不需要一次写全,但至少要有个雏形。

举个例子,我当时想做一个“每日灵感碎片收集器”。氛围层我写的是:“打开就能看到今天收集的碎片,像翻便签墙一样,没有压力,不需要登录。”行为层是:“可以快速输入一句话,自动打时间戳,可以按标签筛选,可以随机回顾一条。”约束层是:“纯前端,数据存本地,不依赖后端,手机浏览器能用。”

这三层写下来不到两百字,但已经足够让任何代码生成工具产出一个可运行的骨架。关键在于,氛围层决定了交互的松弛感,行为层决定了功能边界,约束层决定了技术选型。很多人只写行为层,结果出来的东西功能对但用起来别扭;只写氛围层,出来的东西好看但点不动。

2.2 用“反例”代替“正例”往往更有效

还有一个反直觉的经验:告诉工具“不要什么”比告诉它“要什么”更能收敛结果。比如我在做那个碎片收集器时,第一版生成出来的界面带了一个巨大的顶部导航栏和一个侧边抽屉菜单。功能上没问题,但完全破坏了“像便签墙一样”的氛围。于是我加了一句:“不要任何全局导航,不要汉堡菜单,所有操作都在当前页面完成。”第二版就干净多了。

这背后的逻辑是:代码生成工具在缺乏约束时,会倾向于选择“最常见”的方案,而最常见的方案往往是“最通用”的方案,通用就意味着冗余。你用反例把那些通用但不符合氛围的选项排除掉,剩下的自然就更贴近你的感觉。

我后来养成了一个习惯:每次生成代码前,先写三条“不要”。不要登录、不要弹窗、不要二级页面。这三条一写,生成结果的复杂度直接降一个量级,可读性也上来了。

2.3 把伪代码当“情绪草图”来用

很多人觉得伪代码是给算法题用的,但在 Vibe Coding 里,伪代码可以更感性一点。我经常写这样的东西:

当用户打开页面 看到一片空白,但中间有个闪烁的光标 光标旁边有一行很淡的字:“今天想到了什么?” 当用户输入文字并回车 文字变成一张小卡片,随机旋转一点角度 卡片背景色从预设的柔和色板里随机取 当用户点击卡片 卡片放大,显示完整时间和编辑按钮

这不是严格的伪代码,更像是一个交互剧本。但它比“做一个卡片列表”这种描述有用得多,因为它包含了节奏、动效和情绪。代码生成工具拿到这种东西,产出的代码会自带一些细节,比如随机旋转、柔和色板、淡入效果,这些细节如果靠后期手动加,至少多花两小时。

提示:伪代码里的形容词不要省。“很淡的字”“随机旋转一点角度”“柔和色板”这些词,就是氛围本身。省掉它们,代码就失去了灵魂。

3. 工具链的取舍:为什么我最后只留了两个窗口

3.1 编辑器、生成工具、预览窗口的三方博弈

Vibe Coding 的典型工作流涉及三个东西:代码编辑器、代码生成工具、实时预览窗口。我试过把这三个东西塞进一个屏幕,结果就是不断在窗口间切换,思路频繁被打断。后来我固定成两个窗口:左边是生成工具的对话界面,右边是浏览器预览。编辑器只在需要手动改代码时才打开,而且改完立刻关掉。

为什么这样?因为 Vibe Coding 的核心是保持氛围不被打断。你一旦打开编辑器,看到缩进、括号、类型定义,大脑就自动切换到“工程模式”,那种松弛的、探索性的状态就没了。预览窗口则相反,它让你看到的是结果,是氛围本身,能帮你判断“感觉对不对”。

我试过用分屏把编辑器和预览放一起,结果发现眼睛总是不自觉地瞟向代码,然后就开始纠结变量命名。后来干脆把编辑器最小化,只在生成结果明显跑偏时才打开。这个习惯让我的原型产出速度至少快了一倍。

3.2 生成工具的选择逻辑:快比准重要

市面上的代码生成工具很多,各有侧重。我的选择逻辑很简单:在 Vibe Coding 阶段,生成速度比生成质量重要。因为你要的是快速看到东西,然后基于看到的东西调整感觉。如果每次生成要等半分钟,你的思路就断了。

我试过几个不同工具,最后固定用一个响应最快的。它的代码质量不是最好的,经常有冗余样式和重复逻辑,但它能在两三秒内给出可运行的结果。这就够了。冗余代码可以后期清理,但断掉的思路接不回来。

另一个考虑是是否支持增量修改。有些工具每次生成都是全量替换,你改了一个小地方,它把整个文件重写一遍,之前手动调过的细节全没了。我最后选的那个支持“只改这一块”,比如我说“把卡片背景色改成从图片取色”,它只改相关函数,不动其他部分。这个特性在迭代阶段非常关键。

3.3 本地存储与状态管理:越简单越好

Vibe Coding 阶段最忌讳引入复杂的状态管理库。我见过有人在原型阶段就上 Redux,结果光是配 store 就花了一下午,氛围全没了。我的做法是:能用浏览器本地存储就用本地存储,能用全局变量就用全局变量。

那个碎片收集器项目,我全程只用了localStorage和一个全局数组。所有操作都是直接读写这个数组,然后重新渲染列表。没有状态管理库,没有数据流框架,代码量少到可以一口气读完。这样做的好处是,当你想改一个交互时,你知道改哪里,不会在层层抽象里迷路。

当然,这仅限于原型阶段。一旦你确认这个方向可行,准备正式开发了,再引入正经的架构也不迟。Vibe Coding 的产出本来就是一次性的,它的价值在于验证感觉,不在于长期维护。

阶段推荐做法不推荐做法理由
原型验证全局变量 + 本地存储Redux / MobX减少配置时间,保持思路连贯
交互调整直接操作 DOM虚拟 DOM 框架改起来直观,不用理解 diff 逻辑
样式调整内联样式 + CSS 变量CSS-in-JS 方案改一个颜色不用重新编译
数据模拟硬编码数组接口 Mock 服务省去网络层,专注界面感觉

4. 从“能跑”到“像那么回事”:收敛阶段的四个动作

4.1 第一轮收敛:删掉所有“通用但没用”的东西

生成出来的第一版代码,通常会有很多“通用但没用”的东西:用不上的导入、没绑定的按钮、空的事件处理函数、占位的注释。我的做法是先删再改。把所有不参与当前核心流程的代码全部删掉,哪怕它看起来“以后可能用得上”。

为什么?因为 Vibe Coding 的产出是氛围的载体,不是工程的起点。那些通用代码会干扰你对氛围的判断。比如一个“设置”按钮,虽然没绑定任何逻辑,但它的存在会让界面看起来更“完整”,从而掩盖了核心交互的不足。删掉它,你才能看清这个页面到底有没有传达出你想要的感觉。

我通常删到只剩三个东西:一个输入框、一个列表、一个渲染函数。然后在这个最小骨架上重新加东西,每加一个都问自己:这个对氛围有帮助吗?没有就不加。

4.2 第二轮收敛:把“看起来对”变成“用起来对”

删完之后,开始调交互细节。这一步的关键是把自己当成第一次使用的用户,而不是开发者。我通常会做三件事:

第一,关掉开发者工具。只要控制台开着,你就会不自觉地去修警告和错误,而不是感受交互。第二,用手机打开。很多氛围问题在手机上才暴露,比如按钮太小、滚动卡顿、输入框被键盘挡住。第三,连续操作十次。比如连续添加十条碎片,看看列表滚动是否流畅,随机回顾是否真的随机。

我印象很深的一个细节:第一版碎片卡片的随机旋转角度是Math.random() * 10 - 5,看起来没问题。但连续添加十条后,发现有些卡片旋转角度几乎一样,视觉上显得很呆。后来改成从预设的几个角度里随机取,比如[-3, -1, 0, 1, 3],看起来就自然多了。这种细节,不连续操作根本发现不了。

4.3 第三轮收敛:给“感觉”加上时间维度

氛围不只是静态的视觉,还包括动效的节奏。Vibe Coding 生成的第一版通常没有动效,或者只有默认的过渡。我的做法是手动加两三个关键动效,但只加在核心交互上。

比如碎片收集器里,我只加了两个动效:新卡片出现时的淡入上浮,和点击卡片时的放大回弹。其他所有地方都保持瞬时响应。为什么?因为动效太多会拖慢节奏,而 Vibe Coding 的氛围往往是“轻快”的。两个动效足够让用户感觉到“这个东西是活的”,又不会觉得卡顿。

动效的参数也有讲究。淡入上浮我用的是opacity: 0 -> 1配合translateY: 10px -> 0,时长200ms,缓动ease-out。放大回弹用的是transform: scale(1) -> scale(1.05) -> scale(1),时长150ms。这些参数不是随便写的,200ms是大多数人感知不到延迟但又能看到变化的临界点,ease-out让动效结束时更柔和,符合“便签墙”的松弛感。

4.4 第四轮收敛:把代码“折叠”起来

最后一轮收敛,是把代码整理成可折叠的结构。不是重构,不是抽象,只是加注释和分区。比如:

// ========== 数据层 ========== let fragments = JSON.parse(localStorage.getItem('fragments') || '[]'); // ========== 渲染层 ========== function render() { ... } // ========== 交互层 ========== function addFragment(text) { ... } function randomReview() { ... }

这样做的好处是,当你过几天回来看这个原型时,能快速回忆起当时的思路。Vibe Coding 的产出往往是一次性的,但如果你不整理,连自己都看不懂,那就连“参考价值”都没了。折叠结构让代码变成一份可读的交互笔记,而不是一堆散乱的字符。

注意:这一步不要过度。我见过有人在原型阶段就搞模块化,把代码拆成十几个文件,结果改一个交互要跳五个文件。Vibe Coding 的代码应该是一个文件能装下的,超过五百行就说明你该进入正式开发阶段了。

5. 那些只有踩过才知道的坑

5.1 生成工具会“过度设计”你的简单需求

这是最常见也最隐蔽的坑。你说“做一个列表”,它给你一个带分页、排序、筛选、搜索的完整表格组件。你说“存本地”,它给你一个带版本迁移和加密的存储层。这些代码单独看都没问题,但放在一起就把一个下午能搞定的原型变成了三天的工程。

我的应对策略是:在提示里明确写“最简实现”。比如“用最简方式实现,不要分页,不要排序,不要错误处理,假设数据永远正确。”这句话能砍掉至少一半的生成代码。有人担心这样出来的代码“不健壮”,但原型阶段要的就是不健壮,健壮是正式开发的事。

5.2 氛围词会被工具“字面化”理解

我说“像便签墙一样”,工具真的给我生成了一个带砖墙纹理背景的页面。我说“轻快”,它给所有按钮加了弹跳动画。这些理解不能说错,但太字面了,反而破坏了氛围。

后来我学会了一个技巧:用“感觉词 + 反例”组合。比如“像便签墙一样,但不要纹理背景,不要拟物化,保持扁平。”这样工具就知道你要的是“便签墙的松散布局”,而不是“便签墙的视觉元素”。氛围词是给方向,反例是给边界,两者缺一不可。

5.3 本地存储的“隐式共享”问题

用localStorage存数据时,同一个浏览器下所有页面共享同一个存储空间。我同时开了两个标签页测试,一个标签页添加数据,另一个标签页看不到更新,因为另一个标签页的fragments变量还是旧值。这个问题在原型阶段很容易被忽略,但一旦你开始多标签测试,就会觉得“怎么数据丢了”。

解决办法很简单:每次渲染前重新从localStorage读一次,而不是只在初始化时读。这样虽然性能差一点,但原型阶段数据量小,完全无感。或者监听storage事件,但那个事件只在其他标签页修改时触发,自己修改自己不触发,逻辑更绕。我最后选了每次重读,一行代码解决。

5.4 移动端键盘弹出会顶飞布局

这个问题在桌面浏览器上永远测不出来。当输入框在页面底部时,手机键盘弹出会把整个页面往上顶,如果你的布局是fixed定位,输入框可能直接被键盘挡住。我试过用position: sticky和flex布局,最后发现最稳的方案是把输入框放在页面顶部,键盘弹出时页面不滚动,输入框始终可见。

这个坑让我意识到,Vibe Coding 的“氛围”必须包含设备维度。同一个交互,在桌面和手机上的感觉可能完全相反。所以我在氛围层描述里加了一句:“手机优先,桌面能用就行。”这句话一加,生成工具就会优先考虑移动端的布局和交互。

5.5 生成代码的“伪随机”陷阱

前面提到随机旋转角度的问题,其实还有一个更隐蔽的:伪随机数在短时间内连续调用会重复。Math.random()虽然看起来随机,但在某些浏览器实现里,连续调用的前几个值可能很接近。我连续添加十条碎片,前三条的旋转角度几乎一样,就是这个原因。

解决办法是用时间戳做种子,或者干脆从预设数组里随机取。我选了后者,因为预设数组还能控制视觉范围,避免出现旋转角度过大导致卡片看起来歪歪扭扭。这个经验告诉我,Vibe Coding 里的“随机”往往需要手动约束,不能完全交给Math.random()。

6. 从原型到可交付:什么时候该停止 Vibe Coding

6.1 三个信号说明你该进入正式开发了

Vibe Coding 不是终点,它只是起点。我总结了三信号,出现任何一个就说明该停下来了:

第一,你开始纠结变量命名和代码结构。这说明你的大脑已经切换到工程模式,继续用 Vibe Coding 只会让你烦躁。第二,你开始考虑多人协作和长期维护。原型代码是写给自己的,一旦要考虑别人能不能看懂,就需要正经的架构。第三,你开始处理边界情况和错误状态。Vibe Coding 假设一切顺利,但正式产品必须处理失败。

这三个信号出现时,不要犹豫,把原型代码当作交互规格说明书,重新用正式技术栈实现一遍。原型代码的价值不在于能跑,而在于它验证了感觉。感觉对了,重写一遍很快;感觉不对,重写多少遍都没用。

6.2 把原型当作“可交互的文档”

我现在的习惯是,每个 Vibe Coding 原型都会保留下来,但不再修改。它变成了一份可交互的文档,比任何文字描述都直观。当我要向别人解释“我想要这种感觉”时,直接打开原型让他点两下,比说十分钟都管用。

这份文档还有一个用处:记录决策过程。我会在代码顶部写一段注释,记录当时为什么这样设计、试过哪些方案、为什么放弃。比如“试过用卡片瀑布流,但滚动时太跳跃,改成单列列表后氛围更稳。”这些注释在正式开发时非常有价值,能避免重复踩坑。

6.3 一个反直觉的结论:Vibe Coding 的产出越“丑”越好

最后分享一个可能有点反直觉的体会:Vibe Coding 的代码越丑,说明你越专注于氛围。如果你生成出来的代码整洁、规范、有注释、有类型定义,那说明你把大量时间花在了代码本身上,而不是交互和感觉上。原型阶段的代码就应该是“能跑就行”的状态,丑一点没关系,因为它的使命是验证感觉,不是长期运行。

我见过有人把原型代码直接上线,结果三个月后自己都改不动。也见过有人把原型代码重构了三遍才敢给人看,结果感觉全没了。我的建议是:原型代码只对自己负责,感觉对了就赶紧进入正式开发,感觉不对就赶紧换方向。不要在原型阶段追求代码质量,那是对 Vibe Coding 最大的误解。

提示:如果你发现自己在一个原型上花了超过两天,大概率是方向错了。Vibe Coding 的节奏应该是半天出原型,一天调感觉,然后要么进入正式开发,要么放弃。超过两天还在调,说明这个“感觉”本身就不清晰。

7. 我个人的 Vibe Coding 检查清单

跑过几个项目之后,我整理了一份自己的检查清单。每次开始新的 Vibe Coding 之前,我会花五分钟过一遍,能省掉后面很多来回。

开始前:

  • 氛围层写了吗?三句话描述用起来的感觉。
  • 行为层写了吗?用户能做的三到五个核心操作。
  • 约束层写了吗?技术上的硬性限制,比如“纯前端”“手机优先”。
  • 写了至少三条“不要”吗?用来排除通用但不符合氛围的方案。

生成后:

  • 删掉所有不参与核心流程的代码了吗?
  • 关掉开发者工具,用手机连续操作十次了吗?
  • 核心交互有动效吗?动效时长在 150-250ms 之间吗?
  • 本地存储每次渲染前重读了吗?
  • 输入框在手机键盘弹出时可见吗?

收敛时:

  • 代码能折叠成三到四个区块吗?
  • 顶部注释记录了设计决策吗?
  • 出现“纠结命名”“考虑协作”“处理错误”这三个信号了吗?出现了就停。

这份清单不复杂,但每次过一遍,能避免 80% 的返工。Vibe Coding 的核心是保持氛围不被打断,而清单的作用就是在开始前把该想的想清楚,开始后就不用再想,只管感受。

最后说一句个人体会:Vibe Coding 最值钱的地方,不是它产出的代码,而是它让你在写代码之前先想清楚感觉。很多项目失败不是因为技术不行,而是因为一开始就没想清楚“这东西用起来应该是什么感觉”。Vibe Coding 强迫你把这个问题放在第一位,这本身就是一种很好的训练。至于代码,丑就丑吧,反正它只是感觉的临时容器。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询