Vibe Coding 到底是什么?从 Karpathy 一条推文说起
Karpathy 一条推文命名了 Vibe Coding:模型、工具、传播三要素在 2025 年到位,人用自然语言指挥并做方向判断与验收,AI 负责把方向变成能跑的代码。
本文是《Vibe Coding 实战系列》第 1 篇。
如果你关注 AI 编程,应该很难绕开 Vibe Coding 这个词。它的传播速度,几乎和当年 Low-Code 一样凶猛,但比 Low-Code 更容易让人困惑,因为它的名字里只有 vibe(氛围、感觉)和 coding(写代码)两个词,翻译成中文看着像是在开玩笑。
这篇文章将回答 Vibe Coding 的三个问题:
-
这个词从哪来?
-
它到底是什么?
-
它和已经火了好几年的「AI 写代码」有什么区别?
读完本文你就会知道为什么这个看似随意的命名,会在 2025 年引爆整个开发者社区。
一切都要从那条推文开始
时间回到 2025 年 2 月。Andrej Karpathy 在 X(原 Twitter)上发了一条看起来很随意的推文。要知道 Karpathy 可不是个普通人,他是 OpenAI 的创始成员之一、前特斯拉 AI 总监,也是深度学习领域最受欢迎的讲师之一。他随手写下的每一句话,几乎都会被开发者社区逐字解读。
那条推文原文是这样写的:
There’s a new kind of coding I call “vibe coding”, where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. It’s possible because the LLMs (e.g. Cursor Composer w Sonnet) are getting too good.
翻译过来是:
有一种新的编程方式,我称之为 “vibe coding”(氛围编程)。在这种方式里,你完全顺着自己的感觉走,拥抱指数级的变化,甚至忘了代码的存在。这之所以可能,是因为大语言模型(比如 Cursor Composer 搭配 Sonnet)已经强到离谱。
这条推文发出去之后,迅速在开发者圈层炸开。短短几天里,被海外科技媒体、播客、博客纷纷跟进报道,vibe coding 这个词也由此正式进入开发者的术语表。
国内也有大量转载与讨论。如果你现在去搜,能在腾讯云开发者社区、CSDN、头条等多个平台找到这条推文的中文转发与逐句解读(我在文末参考资料里列了几个原始链接,你可以自行核对)。
值得注意的是,半年后的 2025 年 8 月 25 日,Karpathy 又发了一条补充推文,专门讲了他自己这段时间 vibe coding 的心得体会。也就是说,这个词不是昙花一现的玩笑,而是被他本人在持续使用和修正的,这正是它区别于很多营销概念的关键。
Vibe Coding 到底是什么
vibe = 直觉、感觉、氛围;coding = 写代码。合在一起,字面意思就是凭感觉写代码,但这个翻译会误导人,让人感觉是说乱写代码。
其实更准确的拆解是这样的:
-
用自然语言指挥 AI:你不敲键盘写代码,而是用一句中文或英文告诉 AI,我想要什么。
-
AI 生成并迭代代码:AI 把你的自然语言翻译成可运行的代码,并按你的反馈持续修改。
-
人做方向判断与验收:你不再纠结语法细节,而是判断这版对不对、好不好、要不要再改。
关键词其实不是 coding,而是 vibe,它更多的强调的是一种指挥姿态:我们凭直觉给出开发方向,AI 负责把方向变成可运行的东西。代码本身在这个过程里反而退居幕后。
这一点很重要,也是它和让 AI 写代码最本质的区别。后者的重点还在代码上,AI 依旧是替你打字的工具,而 vibe coding 的重点落在了指挥上,AI 不再只是打字员,而是你的执行引擎,连读不读代码都变成可选的动作。
传统编码与 Vibe Coding 的工作流可以这样对比:
传统编码: 人 ──键盘──▶ 代码 ──▶ 运行
AI 助手: 人 ──键盘+Tab补全──▶ 代码 ──▶ 运行
Vibe Coding: 人 ──自然语言──▶ AI ──▶ 代码 ──▶ 运行
└──人凭感觉验收──┘注意在 Vibe Coding 工作流中,人退出了“写代码”这一环,进入“指挥+验收”这一环。这是范式级别的位移,而不是简单的工具升级。
为什么2025年才火
Vibe Coding 这个名字 2025 年才出现,但用自然语言生成代码这件事,在几年前就一直在讨论。可为什么偏偏是 2025 年初这个时间点引爆?
我认为是满足这一模式的前置条件都已经到位了:
-
模型到位。 2024 年下半年到 2025 年初,Claude 3.5 Sonnet、GPT-4o、Gemini 2.0 这一档模型陆续发布。它们的共同特征是:长上下文(几十万 token 不掉链子)、代码能力质变(不再写一段忘一段)、对模糊指令的容错大幅提升。这三点缺一不可,因为只要模型还会失忆或存在理解跑偏的问题,vibe coding 就只是个理想态。
-
工具到位。 模型再强,没有趁手的产品也用不起来。Cursor、Trae、Claude Code、Windsurf 这些工具在 2024–2025 年间陆续成熟,它们把自然语言→代码→运行这条链路打通成了真正的产品体验。我们不再需要手动复制粘贴,也不用配环境,只需要一句话吩咐下去,AI 直接在项目里改文件、跑测试。
-
KOL 加持。 同样的能力,Karpathy 一条推文的传播效率是普通博文的几百倍。这也是因为 Karpathy 在 AI 圈的可信度极高,他亲口命名并使用,等于是给这个概念加盖权威章,这也是它能在两周内从一条推文变成行业热词的直接原因。
所以, vibe coding 现在不再是被吹出来的概念,它是技术曲线跨越临界点后的自然产物。 毕竟,模型没到位的时候,怎么吹都吹不起来,等到位之后,即使没人吹也是易燃易爆品。
同义概念
vibe coding 这个词火了之后,有比较多的误解,其中,最常见的一种是:这不就是 Copilot 换个名字吗?。看似相近,其实差得很远。
| 概念 | 谁写代码 | 谁懂代码 | 典型工具 | 适合场景 |
|---|---|---|---|---|
| 传统编码 | 人 | 人 | VS Code、IDE | 任何项目 |
| AI 助手 | 人 + AI 补全 | 人 | GitHub Copilot | 提速,人仍是主导 |
| 低代码 | 拖拽 + 少量代码 | 半懂 | 钉钉低代码、Mendix | 内部系统、表单流程 |
| 无代码 | 拖拽 | 不懂 | Webflow、宜搭 | 简单建站、营销页 |
| Vibe Coding | AI 写 | 人懂方向、AI 懂细节 | Cursor、Trae | 原型、个人工具、迭代快的项目 |
总结下来就是:
-
Copilot 是翻译官,人还是主导者,AI 只在你写代码时把你的一些话转换成代码。
-
低代码/无代码是预制菜,满汉全席也只需要组合一下就能完成。
-
Vibe Coding 是请了团队,干啥都有细分方向的专家帮你做。
Show Me Code
Talk is Cheap,Show Me Code ,讲再多概念,不如我这里带你实践一次。
这里我用一句话让 AI 帮我生成了一个待办清单应用:
做一个待办清单网页,单文件 HTML,能添加、勾选完成、删除待办,底部显示总数和已完成数,配色用浅色 + 蓝色主色。
AI 生成的代码核心部分(节选关键 10 行,完整代码见文末附录):
function add(){
var t = inp.value.trim();
if(!t) return;
items.push({text:t, done:false});
inp.value=''; render();
}就这一句话,AI 给我返回了一个完整可用的单文件应用——含 HTML 结构、CSS 样式、JS 逻辑、初始示例数据。我把它直接在浏览器里打开,跑起来是这样的:

完整的可交互版本,我在博客附录中提供了(因为太小,没必要上传git)
整个过程的体验是这样的:
-
我没碰键盘写一行代码,全部由 AI 生成。
-
我只凭感觉判断:嗯,这样能用,配色也对,下一句改改就行。
-
想继续迭代也只需要再发一句话,比如加一个清空全部的按钮、待办按完成时间排序、改成深色模式,给出明确的指令,AI 都能照做。
这就是 vibe coding 的核心体验:你上升到了指挥官的位置,AI 在前面为你执行命令。代码不再是你的产出物,而是你和 AI 之间的中间语言,你甚至可以不读它。
谁适合、谁不适合
Vibe Coding 看起来很美,但它不是万能的。
适合用 Vibe Coding 的场景:
-
原型验证:想快速验证一个产品想法,不用纠结工程化。
-
个人小工具:自己用的脚本、内部小工具,能用就行。
-
教学与演示:讲一个概念,现场生成一个能跑的例子。
-
创意探索:试一个新交互、新算法,不在乎代码长什么样。
不太适合 Vibe Coding 的场景:
-
生产核心系统:金融交易、医疗、自动驾驶,这些系统出错的代价太高,AI 的凭感觉不能替代严谨审查。
-
合规严格的领域:审计、签名、加密,必须每一行都能解释清楚。
-
性能敏感的代码:热路径、底层优化,AI 还难稳定写出极致性能。
-
长生命周期维护:要维护十年的代码,可读性和稳定性比快更重要。
Vibe Coding 是加速器,不是替代品。
它能让你在合适的场景里快 10 倍,但不能让你在不合适的场景里更安全。
题外话
这篇只是开胃菜。vibe coding 这个话题,单讲概念其实讲不出多少东西,真正的价值在怎么用好它。
这个系列,我估摸着会写这些内容,如果想追更,不妨收藏一下咱的博客:
-
工具篇:Cursor、Trae、Claude Code、Windsurf 横向测评,帮你选趁手的那一个。
-
实战篇:从一句话生成应用,到长项目怎么不让 AI 失忆,再到项目超过 1 万行怎么工程化。
-
质量篇:vibe coding 写的代码敢不敢上线、要不要读懂、AI 会挖什么坑。
-
反思篇:会让程序员失业吗、从码农到指挥官的身份变化、AI 还干不了哪些活。
-
场景篇:非程序员怎么用它做工具、创业团队的真实成本收益、48 小时上线一个产品。
下一篇,我们会聊一个很多人会搞混的点:
《Vibe Coding ≠「让 AI 写代码」——一个被误解的概念》
最后留一个问题给你:
你最想用 Vibe Coding 做什么? 评论区告诉我,下一篇可能就拿你的需求做案例。
附录:完整代码
下面是上面那个待办清单应用的完整代码(单文件 HTML,复制保存为 .html 双击即可运行):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vibe Coding 第一课 · 待办清单</title>
<style>
:root{
--bg:#fafafa; --card:#ffffff; --text:#1f2329; --muted:#8a919e;
--border:#e5e6eb; --brand:#3370ff; --brand-soft:#e8f3ff;
--danger:#f5222d; --radius:10px;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);
font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;
min-height:100vh;display:flex;justify-content:center;padding:24px}
.app{width:100%;max-width:480px;background:var(--card);
border:1px solid var(--border);border-radius:16px;
box-shadow:0 6px 24px rgba(0,0,0,.04);overflow:hidden}
.app-header{padding:20px 22px 14px;border-bottom:1px solid var(--border)}
.app-header h1{margin:0 0 4px;font-size:18px;font-weight:600}
.app-header p{margin:0;font-size:12px;color:var(--muted)}
.input-row{display:flex;gap:8px;padding:14px 22px;border-bottom:1px solid var(--border)}
.input-row input{flex:1;padding:9px 12px;font-size:14px;border:1px solid var(--border);
border-radius:8px;outline:none;background:var(--bg)}
.input-row input:focus{border-color:var(--brand)}
.input-row button{padding:0 16px;font-size:14px;color:#fff;
background:var(--brand);border:none;border-radius:8px;cursor:pointer}
.input-row button:hover{filter:brightness(.95)}
ul{list-style:none;margin:0;padding:0}
li{display:flex;align-items:center;gap:10px;padding:12px 22px;
border-bottom:1px solid var(--border);font-size:14px}
li:last-child{border-bottom:none}
li.done span{text-decoration:line-through;color:var(--muted)}
li .checkbox{width:18px;height:18px;border:1.5px solid var(--border);border-radius:5px;
cursor:pointer;display:flex;align-items:center;justify-content:center;
color:#fff;font-size:12px;flex:none}
li.done .checkbox{background:var(--brand);border-color:var(--brand)}
li .del{margin-left:auto;color:var(--muted);cursor:pointer;font-size:12px;
border:none;background:transparent}
li .del:hover{color:var(--danger)}
.footer{padding:12px 22px;font-size:12px;color:var(--muted);
background:var(--brand-soft);display:flex;justify-content:space-between}
.empty{padding:32px 22px;text-align:center;color:var(--muted);font-size:13px}
</style>
</head>
<body>
<div class="app">
<div class="app-header">
<h1>我的待办清单</h1>
<p>用一句话生成的第一个 Vibe Coding 应用</p>
</div>
<div class="input-row">
<input id="inp" placeholder="输入待办,回车添加" />
<button id="add">添加</button>
</div>
<ul id="list"></ul>
<div class="empty" id="empty">还没有待办,加一条试试吧</div>
<div class="footer"><span id="count">0 项</span><span id="done">0 已完成</span></div>
</div>
<script>
(function(){
var items = [];
var inp = document.getElementById('inp');
var list = document.getElementById('list');
var addBtn = document.getElementById('add');
var empty = document.getElementById('empty');
var countEl = document.getElementById('count');
var doneEl = document.getElementById('done');
function render(){
list.innerHTML = '';
items.forEach(function(it, i){
var li = document.createElement('li');
if(it.done) li.className = 'done';
var cb = document.createElement('div');
cb.className = 'checkbox';
cb.textContent = it.done ? '✓' : '';
cb.onclick = function(){ items[i].done = !items[i].done; render(); };
var span = document.createElement('span');
span.textContent = it.text;
var del = document.createElement('button');
del.className = 'del'; del.textContent = '删除';
del.onclick = function(){ items.splice(i,1); render(); };
li.appendChild(cb); li.appendChild(span); li.appendChild(del);
list.appendChild(li);
});
empty.style.display = items.length ? 'none' : 'block';
var doneN = items.filter(function(x){return x.done;}).length;
countEl.textContent = items.length + ' 项';
doneEl.textContent = doneN + ' 已完成';
}
function add(){
var t = inp.value.trim();
if(!t) return;
items.push({text:t, done:false});
inp.value=''; render();
}
addBtn.onclick = add;
inp.addEventListener('keydown', function(e){ if(e.key==='Enter') add(); });
items = [
{text:'写完 W1 的开篇文', done:true},
{text:'跑通最小示例并截图', done:false},
{text:'准备 3 个备选标题', done:false}
];
render();
})();
</script>
</body>
</html>