Skip to content

Vibe Coding 记录

"Vibe coding"是 2025 年 Andrej Karpathy 提出的一个说法,描述一种新的编程方式:用自然语言描述你想要什么,让 AI 生成代码,然后在完全理解或不完全理解生成的代码的情况下,继续用自然语言迭代修改。

围绕这个概念的分歧一直很大。有人把它视为新的生产力范式,也有人把它视为技术债务的加速器。两种判断都触及了一部分事实,但都不完整。


到底什么是 vibe coding

Karpathy 的原话大意是:"你完全沉浸在 vibe 中,拥抱大型语言模型,忘记代码的存在。" 他的意思是:你把注意力从"怎么写"转移到"要什么"——描述意图、审查输出、迭代修正——而不是逐行编写实现。

这不同于传统的 AI 辅助编程。Copilot 帮你写一行代码,你仍然在"编程"的范式内——你理解每一行,你只是省去了打字。Vibe coding 更进一步:你可能不完全理解 AI 生成的代码,但你通过观察行为(运行、测试、用户反馈)来判断它是否正确。

把它放到一个光谱上会更容易理解:

text
传统编程           AI 辅助编程           Vibe Coding              全自主 AI
   │                  │                     │                      │
 手写每一行       AI 补全代码          描述意图→AI生成         AI 自主决策
 完全理解实现     理解实现             可能不理解实现          完全黑盒
 调试=读代码      调试=读代码+AI帮助    调试=描述问题+AI修复    调试=AI自主修复

Vibe coding 处于这个光谱的第三阶段。它的核心不是"用 AI 写代码更快",而是"把认知负荷从实现细节转移到意图表达和结果验证"。


为什么 vibe coding 现在才出现

三个条件同时满足才让 vibe coding 成为可能:

  1. 模型能力达到了"可用的代码生成"阈值。Claude 4、GPT-4-level 的模型在大多数常见编程任务上能生成可通过简单验证的代码。不是完美,但可用。

  2. 迭代成本降到了口语对话级别。以前你需要重写 prompt、等待几分钟、查看结果。现在你可以在对话中连续追问"这里不对,改成用 A 而不是 B"——交互成本接近和一个 junior 开发者 pair programming。

  3. 验证手段成熟了。TypeScript 的类型系统、自动化测试、preview/热重载——这些基础设施让"不读代码就能验证行为"成为可能。如果每次生成代码后你都必须逐行 review 才能确认正确性,vibe coding 就做不到——验证成本超过了编写成本。


vibe coding 改变了什么

1. 从"写代码"到"描述行为"

传统编程的心智模式:我想实现功能 X → 我理解 X 的实现原理 → 我逐行写出实现 → 我测试验证。

Vibe coding 的心智模式:我想实现功能 X → 我用自然语言描述 X 的预期行为 → AI 生成实现 → 我验证行为是否符合预期 → 不符合则用自然语言描述差异。

关键差异在第二步:你不一定需要"理解实现原理"才能完成功能。你可以通过描述想要的结果和约束条件来驱动开发。

这不意味着理解不重要,而是理解的时机后移了。在传统编程中,理解往往发生在编码之前;在 vibe coding 里,可以在看到生成结果之后再补理解,或者只在出现问题时才深入追溯。

2. 从"debug 代码"到"debug 行为"

传统 debug:看错误信息 → 看代码 → 分析逻辑 → 定位 bug → 修改代码。

Vibe coding 的 debug:看错误信息 → 把错误信息复制给 AI → AI 分析并给出修复 → 应用修复 → 验证。

表面上看,vibe coding 的 debug 更快。但潜在风险是:你缺少了"分析逻辑"这一步建立的对代码的深层理解。当 bug 是系统性的(不是某个地方的 typo,而是整体架构的假设错误),vibe coding 的 debug 方式会反复撞墙——AI 在不断修补症状而非修复根因,你也因为没理解代码而无法指出根因。

3. 从"架构设计"到"意图约束"

一个架构设计通常需要考虑:模块划分、依赖方向、数据流、错误处理策略、性能边界。在 vibe coding 中,这些需要在 prompt 中显式表达——AI 不会自己在生成代码时替你考虑架构。

这意味着 vibe coding 实际上提高了架构思考的重要性,而不是降低了。因为 AI 会服从你的 prompt,但不会质疑你的 prompt。如果你描述了一个"把所有状态放在全局变量"的方案,AI 会忠实地实现它——不会提醒你"这样在并发场景下会出问题"。

prompt 的质量直接决定了生成代码的架构质量。用了模糊的 prompt 得到的代码可以 work,但架构大概率是错的——没有错误边界、没有模块分离、状态随处散落。


vibe coding 的正确使用场景

不是所有开发任务都适合 vibe coding。判断标准:任务的理解成本和验证成本的比例。

适合 vibe coding

  • CRUD 页面和表单:模式固定,验证简单(页面是否渲染正确、表单能否提交)
  • 工具脚本:一次性使用,正确性要求低,验证成本低(跑一下看结果对不对)
  • 样板代码:配置文件、类型定义、数据转换——重复性高、无创新性
  • UI 原型:快速出界面,视觉验证即可,不需要追求代码质量
  • 已知问题域的变体:你做过类似的,知道正确答案长什么样,只是不想再写一遍

不适合 vibe coding

  • 核心算法和数据结构:理解错误会导致全系统问题,需要精确推理而非模式匹配
  • 安全关键代码:认证、授权、加密——必须逐行理解,不能依赖 AI 的"看起来对"
  • 跨多模块的状态管理:涉及复杂的数据流和副作用管理,AI 能处理局部但不能主动发现全局不一致
  • 性能敏感的代码:AI 生成的代码通常是"正确但不高效"的版本。高性能场景需要理解 CPU cache、内存布局、GC 行为——这些都是 AI 当前不擅长的
  • 调试系统性问题:不是某个函数有 bug,而是整个架构假设有误——AI 擅长修复局部代码,不擅长质疑架构前提

判断标准

一个比较实用的 heuristics 是:如果一个任务可以用 3 句话说清楚,而且验证结果只需要看一眼或跑一个测试,那它通常适合 vibe coding。

如果你需要 10 句话才能描述清楚,或者验证结果需要半小时的调试和分析——那就自己写。


vibe coding 的真正风险

风险 1:理解债务

如果你用 vibe coding 写了 10000 行代码但只理解了其中 20%,你就欠了 8000 行的"理解债务"。这笔债务在你需要修改核心逻辑、排查生产事故、或者对系统做架构升级时一次性到期。

理解债务和金融债务一样:适量的债务是杠杆(快速交付),过量的债务会导致破产(系统不可维护)。

风险 2:调试能力退化

vibe coding 让你不再需要"通过阅读代码推断行为"的能力。但这项能力就是调试的本质——当 AI 无法帮你时,你需要自己能做。越少练习,退化越快。

风险 3:架构的温水煮青蛙

AI 生成的代码通常遵循"局部最优"——单个函数写得不错,函数之间怎么配合不管。当你 vibe coding 10 个功能,每个都在其局部 prompt 下运作良好,但它们之间的交互可能已经形成了全局的反模式:循环依赖、不一致的错误处理、散落的全局状态。这些问题不会在单个功能的验证中出现,只会在系统运行一段时间后以"莫名其妙的 bug"形式爆发。

风险 4:所有权感的缺失

传统编程中,你花 4 小时写了一个模块——你是它的作者,你为它负责,你愿意花时间改进它。Vibe coding 中,你在 30 分钟内"生成"了同样的模块——它是 AI 的产物,它在心理上不属于你。当一个 bug 出现时,你的第一反应是"让 AI 修"而不是"我来看看到底怎么回事"。

所有权感的缺失不会在单个功能上体现——它会在系统的长期维护质量上体现。


vibe coding 的工程策略

这些风险并不构成“不用 vibe coding”的结论,它们只是说明需要明确使用边界和治理方式。

策略 1:分层使用

把系统分为三层,每层用不同的编程方式:

  • 核心层(infrastructure):自己写,逐行理解。这包括认证、数据模型、核心业务逻辑、模块间的接口约定。这是系统的"骨架"——骨架必须可靠。
  • 功能层(features):vibe coding + 人工 review。AI 生成 CRUD 页面、表格、表单、简单交互。但生成后必须走过一遍代码确认关键路径正确。
  • 样板层(boilerplate):纯 vibe coding。配置文件、类型定义、工具函数、测试 stub。

分层的边界在代码审查时是可见的——骨架代码在 PR 中被标记为"需要至少 2 人仔细 review",样板代码可以"看一眼通过"。

策略 2:Prompt 即文档

把 prompt 当作是代码的 specification。一个好的 vibe coding prompt 包含:

  1. 上下文:当前系统的技术栈、相关模块、已有的类型和接口
  2. 输入/输出:这个功能接收什么、返回什么
  3. 约束条件:性能要求、错误处理策略、边界情况
  4. 反例:明确说出"不要做什么"——比如"不要引入新的依赖""不要使用全局状态""错误要向上抛,不要内部吞掉"

prompt 本身应该被 version control——它不是临时对话,是代码的 specification。一个好的 prompt 可以在 2 周后回答"这个功能当初是为什么这么设计的"。

策略 3:硬性验证门

Vibe coding 生成的代码必须通过硬性验证门才能合并:

  • 类型检查:TypeScript strict mode,零错误
  • Lint:自动化的代码风格检查
  • 测试:至少覆盖 happy path + 一个出错路径
  • 行为验证:在本地或 staging 环境实际运行,观察是否符合预期

这些验证门都是自动化的——不需要你读代码就能判断代码质量。如果 AI 生成的代码通过了所有这些门,它大概率是一个合格的实现。如果没通过,把错误信息喂给 AI 让它修正。

策略 4:定期回溯理解

每 vibe coding 完成一个功能模块后,花 15-30 分钟回溯理解生成的代码。不看具体实现细节,而是搞清楚:

  • 这个模块和其他模块的交互方式
  • 数据流的关键路径
  • 错误处理的策略
  • 有哪些假设(assumptions)——如果这些假设被打破,哪里会出错

这不是 code review(逐行检查),而是 architecture review(结构理解)。目的是把"理解债务"在它小的时候还掉,而不是让它累积到系统级的规模。


几个判断

1. Vibe coding 不是编程的替代品,是编程的新分工。

它没有让"编程"消失——它把编程工作分解为"意图表达"和"实现生成"两个阶段。前者仍然需要工程判断、架构思维、领域知识;后者被 AI 加速了。认为 vibe coding = "不需要会编程就能写代码",和认为自动驾驶 = "不需要会开车"一样——在当前阶段过于乐观。

2. Vibe coding 对 Senior 和 Junior 的影响完全不同。

Senior 开发者已经具备了"判断生成的代码是否正确"的能力。他们可以通过快速的视觉扫描 + 测试验证来判断 AI 的输出质量。Vibe coding 对他们是纯粹的效率提升。

Junior 开发者还没有这个判断力。他们无法区分"功能上能跑通"和"实现上是对的"。在 Junior 手中,vibe coding 容易退化为 cargo cult programming——不断 prompt 直到输出看起来能工作,但不理解为什么能工作、有哪些边界条件会 break。

这对 Junior 的成长是一个陷阱:他们可以快速交付功能(看起来生产力很高),但没有积累真正的排查和设计能力。

3. "我完全理解生成的代码"和"我能写出同样的代码"是两回事。

很多人读 AI 生成的代码时感觉"我能理解",但这不等于"我会写"。理解他人写的代码比从零写起容易很多——因为读代码是识别模式,写代码是构建模式。Vibe coding 大量训练了"识别模式"的能力,但几乎没有训练"构建模式"的能力。

长期完全依赖 vibe coding 的开发者,最后能识别所有常见的代码模式,但在面对"没有现成模式能解决的新问题"时会束手无策。

4. Vibe coding 对代码质量的影响是 U 形的。

  • 不用 vibe coding:质量高,但交付慢
  • 不加约束地使用 vibe coding:质量最差——能跑通但架构混乱、难以维护
  • 有策略地使用 vibe coding(分层 + prompt 文档化 + 验证门 + 回溯理解):质量接近手写,交付速度快 2-5x

最终状态不是"要不要用 vibe coding",而是"多快能到达 U 形右端"。

5. 2026 年还不尝试 vibe coding 的团队,在交付速度上会被拉开。

但"尝试"不等于"全盘采用"。从一个非关键模块开始(内部工具、管理后台的某个页面),建立自己的 vibe coding 策略,然后在验证有效后扩展到更多场景。这和任何新技术引入的方式一样——试点、验证、推广。激进采用和完全拒绝都是错的。


一个完整的工作流示例

假设你要在 React 项目中实现一个"带有搜索和分页的数据表格"组件。以下是 vibe coding 的完整工作流:

第一轮:建立骨架

Prompt:

html
我正在开发一个 React 18 + TypeScript + Tailwind CSS 的管理后台。

需要实现一个可复用的 DataTable 组件,功能包括:
- 列配置(哪些列显示、列的 label、自定义渲染函数)
- 搜索(顶部搜索框,输入后 300ms debounce 触发过滤)
- 分页(底部页码,每页 20 条,支持切换每页条数)
- 排序(点击列头切换升序/降序)

约束:
- 使用 React hooks,不要引入新的依赖
- 状态管理用 useReducer,不要用 Redux
- 搜索和排序在客户端完成(数据已全量加载)
- 类型安全,所有 props 有完整 TypeScript 类型
- 不要使用 any 类型
- 分页组件独立为一个子组件

已有的类型:
type Column<T> = {
  key: keyof T;
  label: string;
  sortable?: boolean;
  render?: (value: T[keyof T], row: T) => React.ReactNode;
};

接口设计我希望是这样:
<DataTable<T> columns={Column<T>[]} data={T[]} pageSize?: number />

AI 生成后:得到一个包含 DataTable.tsxPagination.tsxSearchBar.tsx 三个文件的组件。TypeScript 编译无错误。

第二轮:修复边界情况

验证发现:空数组时表格显示"没有数据"的文字但没有样式。搜索框中输入不存在的关键词后表格空白但分页仍然显示"第 1 页/共 10 页"——分页没有根据过滤结果更新。

Prompt:

text
两个问题:
1. data 为空时,表格区域只显示纯文字"没有数据"。改为显示一个居中的空状态组件,包含一个图标和文字。
2. 搜索过滤后,总条数应该更新为过滤后的条数,分页组件应该反映这个变化。当前分页仍然显示原始数据的总页数。

修复这两点,不要改动其他功能。

第三轮:性能优化 + review

自己检查后发现:搜索过滤在每次输入时遍历整个 data 数组做 filter。如果 data 有 10000 条,每次输入都会触发 O(N) 过滤。但 debounce 已经做了,所以不会每次 keystroke 都执行——不过 filter 本身可以优化。

另外分页的页码渲染:当前实现是 Array.from({ length: totalPages }, (_, i) => ...) ——当总页数为 1000 时,会渲染 1000 个 button。应该改为只渲染当前页附近的页码 + 首尾页。

Prompt:

text
两个优化:
1. 搜索过滤逻辑:用 useMemo 缓存过滤结果,依赖 data 和 searchQuery。避免在每次 render 时重新过滤。
2. 分页组件:当前所有页码都渲染。总页数 > 7 时,改为省略号模式:"1 ... 4 5 6 ... 100"。只渲染当前页 ±2 的页码 + 首尾页。

第四轮:最终 review + 合并

最终得到的代码约 250 行(三个文件),TypeScript strict 零错误,Eslint 零 warning。关键路径(搜索 + 分页 + 排序的交互)手动验证通过,边界情况(空数据、单页、大量页码)验证通过。

时间对比

  • 如果纯手写:3-4 小时(设计接口、写实现、写类型、调试边界情况)
  • Vibe coding:约 45 分钟(写 prompt 5 分钟 + AI 生成 10 秒 + 验证 10 分钟 + 2 轮迭代修复 20 分钟)

这不是"完全不读代码"的 vibe coding——每轮生成后都做了 review,关键逻辑(分页的省略号算法、过滤的 useMemo 依赖)是自己确认过的。这就是"有策略的 vibe coding"的实际形态:AI 写代码,你做架构决策、审查输出、验证行为。


工具差异:不是所有 AI 编程工具都适合 vibe coding

不同工具对 vibe coding 的适用性不同,核心差异在"上下文范围"和"交互模式":

工具类型代表产品适合场景vibe coding 适用性
Inline completionGitHub Copilot, Supermaven逐行补全低——只能帮你写代码,不能帮你"生成功能"
Chat sidepanelCopilot Chat, Claude.ai对话生成一段代码中——需要手动复制粘贴,上下文在对话窗口和 IDE 之间割裂
Agent 模式Claude Code, Cursor Agent, Windsurf自主读代码、写代码、跑命令高——AI 可以直接操作文件系统,迭代成本最低
全自主 AgentDevin, FactoryAI 独立完成整个 issue极高但风险最大——你只看到结果看不到过程

Agent 模式是 vibe coding 最自然的落地形式——AI 能读你的代码库(理解上下文)、写文件(生成代码)、跑命令(验证)——你只需要描述意图和审查结果。但 Agent 模式也放大了 vibe coding 的风险:AI 可以修改多个文件,可能在你没注意到的地方引入跨模块的不一致。

工具选择的工程落点:

  • Agent 模式:更适合功能层和样板层(分层策略里的 feature 和 boilerplate)
  • Inline completion:更适合核心层(infrastructure),仍以人工实现为主,AI 补全为辅
  • 代码合并:AI 生成的代码仍然需要经过 PR review

扩展问题

Q1: Vibe coding 和传统 AI 辅助编程的边界在哪里?

边界在"理解责任"的转移。传统 AI 辅助编程中,你理解每一行代码,AI 只是帮你写得更快。Vibe coding 中,你可能不理解某些生成的代码,你把正确性的验证从"理解代码逻辑"转移到了"观察行为结果"。

这个边界不是二值的——是一个梯度。在一个功能中,你可能 vibe coding 了 80% 的代码(CRUD 逻辑、样式、样板)但手动写了 20%(关键状态转换、错误处理)。边界在哪里取决于"如果这段代码有问题,后果有多严重"。

Q2: Vibe coding 对代码审查(Code Review)流程的影响?

Vibe coding 让 code review 变得更重要但也更难。更重要是因为生成的代码需要人工验证。更难是因为 reviewer 不能假设"作者理解这段代码的设计意图"——作者可能只是 prompt 到能跑通为止。

对 review 流程的三个影响:

  1. PR description 必须包含 prompt 上下文:原始 prompt 是什么、做了哪些迭代修改。reviewer 需要知道"作者想要什么"才能判断"代码是否正确地实现了它"。
  2. Review 重点从"代码风格"转向"架构正确性":AI 生成的代码通常在风格上是干净的(格式、命名、简单逻辑)。reviewer 应重点关注模块间的交互、数据流、错误处理——这是 AI 最薄弱的环节。
  3. Vibe coded 的 PR 需要更严格的验证门:类型检查、测试覆盖率、手动行为验证——在 review 之前必须通过。不能依赖 reviewer 来发现所有问题。

Q3: 如果一个团队中部分人 vibe coding、部分人传统编程,会产生什么协作问题?

最直接的问题:PR review 的质量和速度不对称。Vibe coding 的人提交 PR 更快(AI 写代码),但 reviewer(尤其是传统编程的 reviewer)需要花更多时间理解代码——因为代码不是作者写的,作者的 context 更少。

解决方案:

  1. Reviewer 应该 review 行为而非实现:确认 prompt 描述的需求被满足,而不是逐行推理代码逻辑。
  2. Vibe coding 的作者必须在 PR description 中写清楚:prompt 上下文、生成后的修改、已知的限制——弥补"作者 context 不足"的 gap。
  3. 对 vibe coded 代码设定更高的自动化验证要求:减少 reviewer 手动验证的负担。

Q4: Vibe coding 对技术写作(文档、设计文档)有什么影响?

正面:写文档的效率提升——AI 可以根据代码生成文档初稿,你只需要修正和补充。设计文档中 boilerplate 的部分(项目背景、技术栈说明)可以直接 vibe。

负面:设计文档的"思考过程"可能被跳过。传统写设计文档的过程本身就是思考的过程——你在写"为什么选 A 而不是 B"的时候,实际上在梳理和验证设计决策。如果你 vibe 了设计文档,你可能跳过了这个思考过程,导致决策没有经过充分审视。

比较稳妥的方式是:用 vibe coding 生成文档的形式结构,但决策内容仍由人工完成。

Q5: 3 年后的 vibe coding 会是什么样?

三个可能的演进方向:

  1. 更深的上下文理解:AI 不只是看到当前文件,而是理解整个代码库的架构、约定和历史决策。生成代码时会自动遵循项目中已建立的模式。
  2. 测试驱动的 vibe coding:你描述验收条件(而不是实现细节),AI 生成代码并通过这些测试。验证从"观察行为"变为"通过自动化测试"。
  3. 多步自主开发:AI 不只是生成一个文件,而是创建一个 branch、生成多个文件、跑测试、提交 PR、根据 review 意见修改——完成一个完整的开发循环。

但根本性的限制不会变:AI 能生成代码,但不能替你承担"这段代码在生产中出问题"的责任。 只要这个责任还在开发者身上,vibe coding 就需要人来判断、验证、决策。