别让 AI 写屎山代码!Vibe Coding 三步法:规划先行 + 胶水编程 + 自我进化
你用 AI 写过代码吗?大概率经历过这两种绝望:要么 AI 生成"幻觉代码"------看起来像那么回事,一跑就报错;要么是"屎山代码"------能跑,但乱得想改都不知道从哪下手。问题不在 AI,而在你怎么用它 。本文将介绍一套经过验证的 Vibe Coding 方法论:规划先行 → 胶水编程 → 自我进化,让你从"AI 代码受害者"变成"AI 协作高手"。
前置知识
- 有基本的编程经验(任何语言即可)
- 使用过 AI 编程工具(Cursor / Claude Code / GitHub Copilot 等)
- 了解前端基础概念(组件、状态管理)
一、AI 写代码的两个极端问题
1.1 幻觉代码 vs 屎山代码
arduino
┌──────────────────────────────────────────────────────────────────┐
│ AI 写代码的两个极端问题 │
│ │
│ 极端 1:幻觉代码 │
│ ├── 看起来像那么回事,一跑就报错 │
│ ├── API 不存在、参数编造、逻辑自相矛盾 │
│ └── 原因:AI "编"了它不真正理解的代码 │
│ │
│ 极端 2:屎山代码 │
│ ├── 能跑,但乱的想改都不知道从哪下手 │
│ ├── 单文件 2000 行、没有模块化、变量满天飞 │
│ └── 原因:没有规划,AI 想到哪写到哪,功能无限膨胀 │
└──────────────────────────────────────────────────────────────────┘
这两个问题的根源都是同一个:开发者没有给 AI 足够的约束和指引,直接让它"自由发挥"。
1.2 典型的错误姿势
diff
❌ 错误姿势:上来就让 AI 写代码
用户:帮我写一个 React 代办清单页面,支持新增、删除任务。
AI:好的!我来写一个完整的代办清单...
(AI 内心活动)
- 要不要本地存储?→ 加一个 localStorage 吧
- 要不要 API 远程存储?→ 再加一个 fetch 请求吧
- 要不要拖拽排序?→ 来一个拖拽库吧
- 要不要优先级标记?→ 加个颜色标签吧
- 要不要分类筛选?→ 加个 tab 切换吧
- ...
结果:一个简单的代办清单,变成了 2000 行的"全能怪兽"
这就是没有规划的后果:AI 会擅自扩展功能边界,把简单问题复杂化。
二、第一步:规划就是一切
2.1 核心原则
不要上来就让 AI 写代码。先强制它读懂你的技术栈和项目规划,让它"入职培训"后再干活。
这个原则的本质是:像管理新员工一样管理 AI。
bash
新员工入职流程:
第 1 天:阅读公司技术文档、了解业务流程
第 2 天:参加项目规划会,明确职责和边界
第 3 天:开始写代码
AI "入职"流程(应该也一样):
第 1 步:/init → 让 AI 了解技术栈、项目规范
第 2 步:输出规划文档(.md) → 明确功能边界、模块划分、数据结构
第 3 步:审核规划 → 确认无误后才开始编码
在 Claude Code 中,这个动作就是 /init ------ 初始化项目上下文,让 AI 先"读懂"你的项目。就像去阿里入职要先读 Java 员工手册一样。
2.2 正确姿势:先规划,再编码
以 React + Tailwind 实现代办清单为例,不要直接说"帮我写一个代办清单",而是先输出一份规划 Prompt:
markdown
遵守胶水编程思维:优先使用成熟方案,避免凭空造逻辑。
第一阶段:只做规划,禁止输出任何代码。
1. 确认技术栈:
React 19 + Tailwind CSS + useState
2. 梳理功能边界:
- 新增代办、删除代办、切换完成状态
- 不做本地持久化、筛选、拖拽功能
3. 拆分模块(乐高组件):
- 输入框组件(TodoInput)
- 代办条目组件(TodoItem)
- 列表容器组件(TodoList)
4. 定义数据流:
useState 存储 task 数组
数据结构:{ id, text, completed }
5. 输出这份完整规划,等待我确认无误后,再分段实现代码。
2.3 这份规划为什么有效?
| 规划要素 | 解决什么问题 |
|---|---|
| 技术栈确认 | 防止 AI 用错框架版本或引入不必要的依赖 |
| 功能边界 | 明确"做什么"和"不做做什么",防止功能无限膨胀 |
| 模块拆分 | 强制组件化,好读好维护(AI 生成的代码我们都要审核) |
| 数据结构定义 | 预先规定字段名和类型,从根源减少 AI 字段幻觉 |
| "禁止输出代码" | 强制 AI 先思考,避免边想边写的混乱 |
关键细节 :数据结构中的字段名必须由你来定。比如用
text还是用title,这不是 AI 该决定的事。如果让 AI 自由发挥,它可能这次用text,下次用title,再下次用content------三处不统一就是屎山的开端。
2.4 规划伴随整个开发周期
markdown
开发流程:
输出规划 → 审核规划 → 更新规划 → 确认后编码 → 审核 → 更新
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
第一版 发现遗漏 修正边界 分段实现 发现问题 迭代优化
规划文档 补充细节 确认无误 代码 修正 规划同步
这份规划文档(.md)将伴随项目的完整开发周期。在 Cursor / Claude Code 等工具中,这份规划会被自动带入每次对话的上下文中(通过 claude.md / .cursorrules 等机制),保持 AI 行为的一致性。
三、第二步:胶水编程思维
3.1 核心原则
能抄不写,能连不造。轮子别人造好,你只做胶水。
什么是"胶水编程"?用一个比喻来理解:
ini
传统编程(从零造零件):
我需要一辆车 → 自己造引擎、造轮胎、造底盘、造车身...
胶水编程(组装现成零件):
我需要一辆车 → 买引擎、买轮胎、买底盘、买车身 → 组装在一起
"胶水" = 组装时的螺丝、焊接、线路连接
"零件" = 社区中已经成熟、经过验证的开源组件
胶水本身不创造零件,只负责把现成零件黏在一起。你只写衔接、调用、流转的粘合代码,把各个模块联通。
3.2 为什么胶水编程能减少幻觉?
css
┌──────────────────────────────────────────────────────────────┐
│ 从零造零件 vs 胶水编程 │
│ │
│ 从零造零件(高幻觉风险): │
│ ├── AI 手写拖拽逻辑 → 坐标监听、排序算法、边界 case... │
│ ├── 边界情况多 → 幻觉 bug 概率极高 │
│ └── 代码难以维护 → 出了问题不知道改哪 │
│ │
│ 胶水编程(低幻觉风险): │
│ ├── 使用 react-beautiful-dnd → 社区验证千万次的成熟组件 │
│ ├── 你只写粘合代码 → 组件 A 的输出 → 组件 B 的输入 │
│ └── 出了问题 → 大概率是粘合层的问题,定位简单 │
└──────────────────────────────────────────────────────────────┘
核心逻辑:AI 生成的代码越少,产生幻觉和屎山的可能性就越低。让成熟的开源组件承担重活,AI 只负责"胶水"部分的少量代码。
3.3 正确姿势:拖拽排序功能的实现
同样是"给代办列表增加拖拽排序"这个需求,两种指令方式天差地别:
错误示范(从零造零件):
帮我写 React 代办清单的拖拽排序功能
AI 很可能凭空手写一套拖拽逻辑:自行实现坐标监听、排序算法、动画过渡...... 边界 case 极多,代码难维护。
正确示范(胶水编程):
markdown
遵守胶水编程原则:绝不从零自研底层逻辑,优先选择社区长期验证的成熟开源组件。
当前需求:给代办列表增加拖拽排序。
1. 先调研:React 生态成熟的拖拽库
→ 优先选用 @dnd-kit/core(react-beautiful-dnd 已停止维护)
2. 安装依赖:
pnpm add @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
3. 不要自己手写拖拽底层代码,只做粘合工作。
输出内容顺序:
- 安装依赖命令
- 把现有 TodoList 组件和 @dnd-kit 进行衔接
- 只写模块之间适配、数据流转的粘合代码
3.4 胶水编程的代码量对比
xml
从零实现拖拽排序: 胶水编程(使用 @dnd-kit):
┌────────────────────┐
┌────────────────────┐ │ 安装依赖:1 条命令 │
│ 坐标计算逻辑 │ │ │
│ 触摸/鼠标事件监听 │ │ 组件衔接:~20 行 │
│ 排序算法实现 │ │ <DndContext> │
│ 动画过渡效果 │ │ <SortableList> │
│ 边界 case 处理 │ │ <SortableItem>│
│ 移动端适配 │ │ </SortableList> │
│ ... │ │ </DndContext> │
│ │ │ │
│ ~300+ 行手写代码 │ │ ~20 行粘合代码 │
│ 高幻觉、难维护 │ │ 低幻觉、好维护 │
└────────────────────┘ └────────────────────┘
四、第三步:用元方法论让 AI 自我进化
4.1 核心思路
前两步(规划 + 胶水编程)解决了"怎么写靠谱代码"的问题。第三步要解决一个更高级的问题:如何让 AI 工具本身不断进化,越用越好?
┌──────────────────────────────────────────────────────────────┐
│ 元方法论:AI 自我进化闭环 │
│ │
│ Alpha 提示词 ──→ AI 执行 ──→ 生成结果 │
│ (怎么干活) │ │ │
│ │ ▼ │
│ │ Omega 提示词 │
│ │ (怎么评价) │
│ │ │ │
│ │ ▼ │
│ │ 打分 / 判断 / 反馈 │
│ │ │ │
│ └──────────┘ │
│ │ │
│ ▼ │
│ 更新 Alpha 提示词 │
│ (根据反馈优化规则) │
│ │ │
│ ▼ │
│ 更强的 Alpha ──→ 下一轮执行... │
└──────────────────────────────────────────────────────────────┘
4.2 Alpha 提示词 vs Omega 提示词
| 类型 | 职责 | 类比 |
|---|---|---|
| Alpha 提示词 | 定义"怎么干活"------规范、流程、约束 | 公司的操作手册 |
| Omega 提示词 | 定义"怎么评价"------打分标准、判断规则 | 公司的绩效考核标准 |
Alpha 告诉 AI 该做什么,Omega 告诉 AI 做得好不好。两者形成闭环,AI 系统就能不断自我优化。
4.3 在 Claude Code 中的实践
Claude Code 的记忆模块(claude.md)和 Harness 架构,天然支持这种元方法论:
markdown
claude.md(Alpha 提示词 - 怎么干活):
- 使用 React 19 + Tailwind CSS
- 遵守胶水编程原则
- 组件拆分粒度:单一职责
- 命名规范:PascalCase 组件名
Omega 评估(怎么评价):
- 代码是否通过了所有测试?
- 组件是否按规划文档拆分?
- 是否使用了成熟的开源方案而非从零手写?
- 代码行数是否在预期范围内?
随着项目推进,你可以根据 Omega 的评估结果,不断更新 claude.md 中的 Alpha 规则。比如:
- 发现 AI 总是忘记错误处理 → 在 Alpha 中增加"所有异步操作必须包含 try/catch"
- 发现 AI 生成的组件太大 → 在 Alpha 中增加"单个组件不超过 100 行"
- 发现 AI 总是手写工具函数 → 在 Alpha 中增加"优先使用 lodash"
这就是AI 系统的自我进化:不是换一个更强的模型,而是通过优化提示词规范,让同一个模型越用越好。
五、Vibe Coding 三步法全景图
vbnet
┌──────────────────────────────────────────────────────────────────────┐
│ Vibe Coding 三步法 │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Step 1: 规划先行(/init) │ │
│ │ │ │
│ │ 确认技术栈 → 梳理功能边界 → 拆分模块 → 定义数据结构 │ │
│ │ │ │
│ │ 产出:规划文档(.md) │ │
│ │ 原则:禁止输出代码,先思考 │ │
│ └──────────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ▼ 审核确认 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Step 2: 胶水编程 │ │
│ │ │ │
│ │ 能抄不写,能连不造 │ │
│ │ 优先使用社区验证的成熟组件 │ │
│ │ AI 只写粘合代码:模块衔接、数据流转 │ │
│ │ │ │
│ │ 原则:绝不从零自研底层逻辑 │ │
│ └──────────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ▼ 审核 + 反馈 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Step 3: 自我进化(Alpha + Omega) │ │
│ │ │ │
│ │ Alpha 提示词:定义怎么干活 │ │
│ │ Omega 提示词:定义怎么评价 │ │
│ │ 闭环:执行 → 评价 → 优化 Alpha → 再执行 │ │
│ │ │ │
│ │ 产出:越来越完善的 claude.md / .cursorrules │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
六、不同水平的 Vibe Coding 策略
| 水平 | 策略 | 建议 |
|---|---|---|
| 新手 | 自然语言编程 | 把 AI 当伙伴/助手,用自然语言描述需求,但一定要先规划 |
| 进阶 | 规划 + 胶水编程 | 能独立输出规划文档,引导 AI 使用成熟组件 |
| 高级 | 三步法完整闭环 | Alpha/Omega 提示词优化,claude.md 持续迭代 |
| 专家 | Harness 架构 | Memory + Tools + Rules + Loop 四层架构,AI 系统化进化 |
无论什么水平,第一步永远是规划。新手最容易犯的错误就是跳过规划直接让 AI 写代码。
七、Vibe Coding 与传统编程的对比
| 维度 | 传统编程 | Vibe Coding |
|---|---|---|
| 核心能力 | 写代码的能力 | 与 AI 协作的能力 |
| 思维方式 | "我该怎么实现?" | "我该怎么让 AI 帮我实现?" |
| 规划重要性 | 重要 | 极其重要(没有规划 AI 就会失控) |
| 代码审核 | 自己写的,熟悉 | AI 写的,必须逐行审核 |
| 迭代速度 | 较慢 | 极快(前提是方法正确) |
| 风险 | 能力不足导致 bug | AI 幻觉 + 功能膨胀导致屎山 |
八、知识图谱
kotlin
Vibe Coding 三步法知识体系
│
├── AI 写代码的两个问题
│ ├── 幻觉代码:看起来对,一跑就错
│ ├── 屎山代码:能跑,但乱得改不动
│ └── 根源:没有给 AI 足够的约束和指引
│
├── Step 1: 规划先行
│ ├── 核心原则:像管理新员工一样管理 AI
│ ├── /init → 让 AI "入职培训"
│ ├── 规划文档包含
│ │ ├── 技术栈确认
│ │ ├── 功能边界(做什么 / 不做什么)
│ │ ├── 模块拆分(乐高组件)
│ │ └── 数据结构定义(字段名由你定)
│ ├── "禁止输出代码"------强制先思考
│ └── 规划伴随整个开发周期
│
├── Step 2: 胶水编程
│ ├── 核心原则:能抄不写,能连不造
│ ├── 轮子别人造好,你只做胶水
│ ├── AI 生成的代码越少,幻觉概率越低
│ └── 正确指令:指定成熟组件 + 只写粘合代码
│
├── Step 3: 自我进化
│ ├── Alpha 提示词:怎么干活(claude.md)
│ ├── Omega 提示词:怎么评价
│ └── 闭环:执行 → 评价 → 优化 Alpha → 再执行
│
├── 工具支持
│ ├── Claude Code:/init + claude.md + 记忆模块
│ ├── Cursor:.cursorrules + Composer
│ └── Codex:类似上下文管理机制
│
└── 注意事项
├── react-beautiful-dnd 已停止维护,用 @dnd-kit
├── 数据结构字段名必须由开发者定义
├── 规划文档伴随整个项目周期
└── 无论什么水平,第一步永远是规划
总结
本文介绍了一套经过验证的 Vibe Coding 方法论,核心理念是:不是教你怎么写代码,而是教你怎么与 AI 协作写出靠谱的代码。
- 规划就是一切:不要上来就让 AI 写代码,先输出规划文档------技术栈、功能边界、模块拆分、数据结构,全部由你来定。这份规划就是 AI 的"员工手册"
- 胶水编程思维 :能抄不写,能连不造。让成熟的开源组件承担重活,AI 只写粘合代码。AI 写的代码越少,幻觉概率越低
- 自我进化闭环:Alpha 提示词定义"怎么干活",Omega 提示词定义"怎么评价",形成执行→评价→优化的闭环,让 AI 系统越用越好
记住:AI 是你的新同事,不是魔法棒。你需要像管理团队一样管理它------先培训(规划),再分配任务(胶水编程),最后复盘优化(自我进化)。这套方法论不仅适用于 React 代办清单,也适用于任何 AI 辅助编程场景。