氛围编程(Vibe Coding)的真相以及为什么要警惕氛围编程

小麦2025年07月02日2018 字

给氛围编程泼一盆冰水,聊聊我对氛围编程的观察和思考。

引言

氛围编程(Vibe Coding)是 2025 年最热门的编程概念之一,由 OpenAI 联合创始人、前特斯拉 AI 负责人 Andrej Karpathy 提出。这种编程方式强调 "完全沉浸在氛围中,拥抱技术的指数级发展,并忘记代码的存在"。

氛围编程的定义

不同人对于氛围编程的定义和实践并不相同,不过大致可以分为以下两类:

  • 保守派:认为主要通过聊天,但需要进行代码审查的模式属于氛围编程
  • 激进派:认为完全依赖 AI、不进行代码审查的纯聊天模式属于氛围编程

无论定义如何,氛围编程的核心特征都是通过自然语言对话让 AI 生成可用代码,或是完成一个软件功能。

实际操作中,我更多属于保守派,即在严格限定的范围内,通过 Vibe Coding 让 AI 独立完成一个不太重要的模块,但人写起来要花一些功夫。

氛围编程要解决的问题

氛围编程解决两大问题:效率和门槛。

首先,它将开发者从繁杂的代码逻辑和 bug 中解放出来,更关注程序的运行结果,可以说是结果驱动开发。

其次,氛围编程可以实现快速验证想法,几乎抹平了编程门槛,让人人都能参与进来。

错误的期盼

许多人将氛围编程视为解决所有软件开发问题的万能解药,期望通过它跳过传统的编程学习过程,实现 “弯道超车”,本质上是在用 AI 生成的代码来掩盖自身技术能力的缺陷,认为掌握氛围编程就能快速开发出成功的产品。

但是,真实情况往往会比想象中的更复杂,一个成功的产品需要的不仅仅是代码,还需要优秀架构设计、用户体验以及市场验证等

从 MVP 过渡到生产级的鸿沟

"AI is like having a very eager junior developer on your team" an idea well illustrated in this illustration by Forrest Brazeal

生产级应用和 MVP 应用的差异是巨大的。

在代码量级上,MVP 通常几千行,而生产级通常都在数十万行以上。要维护好一个数十万行代码的 codebase 并非易事,在处理大规模代码库时,AI 往往难以理解复杂的代码结构和依赖关系,产生大量的冗余代码。

一个常见的错误论断是:我功能实现出来了,代码烂不烂其实不重要。这里的错误在于,只考虑到眼前的成果,而忽视了阶段性成果到最终价值的转换其实还有很大的 gap。这就像爬山,爬过一个小坡,前方还有一万个陡坡在等着。古人早就说:“不识庐山真面目,只缘身在此山中。”

另外,生产级应用非常强调通过工程化手段,来提升稳定性和可维护性,对于不同的场景,要有针对性的解决方案。比如同样是大促秒杀,淘宝和京东的做法会很不一样,氛围编程大概率想不出来也写不出来以前没有见过的方案

几个需要警惕的问题

1. 此氛围非彼氛围

那些声称通过氛围编程提效数十倍、以一敌百的成功案例背后,往往隐含了以下事实:

  • 使用者本身就是资深工程师,具备快速调试和问题解决的能力。
  • 项目复杂度相对较低(多为原型或小工具)。

当自我陶醉在氛围编程的成就中时,不妨想想此氛围是不是彼氛围。

2. 简单问题复杂化

氛围编程通过不断的迭代和纠错来解决问题,但这种机制容易将简单问题复杂化。

举一个例子:

我有一个卡片列表 cards,帮我实现一个 React 卡片瀑布流组件,它能始终占满屏幕宽度,并自动计算列数。

宇宙最强编程模型 Claude Sonnet 4 给出的实现包含复杂的 hooks 计算逻辑:

import React, { useState, useEffect, useRef } from 'react';
const WaterfallCards = ({ cards }) => {
const containerRef = useRef(null);
const [columns, setColumns] = useState(3); // 默认3列
const [positions, setPositions] = useState([]);
const [containerHeight, setContainerHeight] = useState(0);
const cardWidth = 300; // 卡片固定宽度
const gap = 16; // 卡片间距
// 计算列数
const calculateColumns = () => {
if (!containerRef.current) return;
const containerWidth = containerRef.current.offsetWidth;
const cols = Math.floor((containerWidth + gap) / (cardWidth + gap));
setColumns(Math.max(1, cols)); // 至少1列
};
// 计算卡片位置
const calculatePositions = () => {
if (columns === 0) return;
const columnHeights = new Array(columns).fill(0);
const newPositions = [];
cards.forEach((card, index) => {
// 找到高度最小的列
const minHeightIndex = columnHeights.indexOf(Math.min(...columnHeights));
// 计算位置
const x = minHeightIndex * (cardWidth + gap);
const y = columnHeights[minHeightIndex];
newPositions.push({ x, y });
// 更新该列高度(假设每个卡片高度为200px + gap)
columnHeights[minHeightIndex] += (card.height || 200) + gap;
});
setPositions(newPositions);
setContainerHeight(Math.max(...columnHeights));
};
// 监听窗口大小变化
useEffect(() => {
calculateColumns();
window.addEventListener('resize', calculateColumns);
return () => window.removeEventListener('resize', calculateColumns);
}, []);
// 重新计算位置
useEffect(() => {
calculatePositions();
}, [cards, columns]);
return (
<div
ref={containerRef}
style={{
position: 'relative',
width: '100%',
height: containerHeight,
padding: `${gap}px`,
boxSizing: 'border-box'
}}
>
{cards.map((card, index) => (
<div
key={card.id || index}
style={{
position: 'absolute',
left: positions[index]?.x || 0,
top: positions[index]?.y || 0,
width: cardWidth,
height: card.height || 200,
backgroundColor: '#fff',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
padding: '16px',
boxSizing: 'border-box',
transition: 'all 0.3s ease'
}}
>
{/* 卡片内容 */}
<div>{card.title}</div>
<div>{card.content}</div>
</div>
))}
</div>
);
};
export default WaterfallCards;

但实际上经验丰富的老登只需要一行代码就可以了:

<div className="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-4">

假设氛围编程的使用者并不知道有 CSS Grid 布局这个东西,那么极有可能写不出来这样的代码。因此基础学习和通识教育依然是重要的。

3. 不可忽视的沉默成本

氛围编程可以在短时间之内生成数千甚至上万行代码,随着代码量的增长,技术债务的影响会呈指数级增长。开发者对技术债务做出的妥协(不重构、不优化),在未来会通过改造成本成倍返还,直到难以通过有限的精力维系下去,然后推翻重做。

激进的氛围编程恰恰是妥协到底,缺乏系统性的质量控制机制,开发者对代码毫无理解,重构会变得非常困难。也并没有有效的方法论来规避客观的技术债务问题。

一个经典论断是:维护不下去那就重来,反正不缺 tokens。这里的错误在于,没有几个项目禁得起重来,能重来的项目也不缺那些 tokens 花掉的钱。

4. 敬畏软件工程

几十年来,软件工程一直在讲模块化设计、关注点分离、单一职责、开闭原则、分层结构、领域驱动、代码重构。这些方法论无一不是在为一个成功的产品打好地基,俗话说地基不稳地动山摇。

软件系统的复杂性是客观存在的,不会因为开发工具的改进而消失。经典的软件工程方法论提供了管理复杂性的有效手段。

当前阶段的氛围编程,似乎屏蔽了软件工程的实践细节,但是这些方法往往需要精心选择、相互配合才能发挥价值。专注局部功能的实现,缺乏对整体系统思考和设计的氛围编程,还没有解决软件工程已经解决的种种难题

小结一下

氛围编程作为一种新兴的编程方式,它降低了编程门槛,提高了开发效率,让更多人能够参与到软件开发中来。但是,我们依然必须清醒地认识到其局限性和适用边界,同时小心沉默成本,敬畏软件工程。

本文为「捣鼓键盘的小麦」原创文章,转载请联系微信:Micoozlee

评论

你需要先登录才能发表评论
加载中...
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有