🔥 AI 写代码总翻车?这套实战方法论救了我

🔥 AI 写代码总翻车?这套实战方法论救了我

摘要 :让 AI 写代码,要么"幻觉代码"一跑就炸,要么"屎山代码"能跑但改不动。本文是我学习 vibe-coding-cn 开源教程后的个人实践总结 + 踩坑复盘 ,包含 3 个真实项目的对比实验。不是教你写代码,是教你怎么指挥 AI 写出靠谱的代码
📌 透明声明 :本文方法论框架参考了 vibe-coding-cn 开源教程,但所有实战案例、踩坑记录、对比实验均为个人独立实践。对原教程的部分观点,我也提出了不同看法。


📌 前言:我被 AI 坑了三次

第一次 :让 Claude 写一个 React 待办清单。我说 帮我写一个 react 待办清单页面,它噼里啪啦生成了 500 行单文件代码,titletext 字段混着用,能跑,但改不动。

第二次 :让 AI 写一个 Node.js 爬虫。它凭空捏造了一个 axios.getHTML() 方法------根本不存在的 API。我花了 20 分钟 debug 才发现是幻觉。

第三次:做一个电商后台,AI 自己设计了一套权限系统。上线后发现跟公司现有的 SSO 完全对不上,推倒重来。

三次翻车,三个不同的坑:屎山、幻觉、重复造轮子

后来我系统学了一套方法论,重新用正确姿势做了一遍,效果天差地别。这篇文章就是我的踩坑复盘 + 实战总结


🎯 本文适合谁

  • ✅ 想用 AI 辅助编程但总踩坑的开发者
  • ✅ 听过 Vibe Coding 但不知道怎么落地的同学
  • ✅ 用 Cursor / Claude Code / Codex CLI 但效率不高的老手
  • ✅ 想建立一套可复用的 AI 编程工作流的团队

🧠 第一章:搞清底层逻辑再动手

1.1 什么是 Vibe Coding

Vibe Coding = 用自然语言驱动,让 AI 生成大部分代码的开发方式。

由计算机科学家 Andrej Karpathy 首次提出。核心主张:先沉浸式做出能跑的东西。

但问题是 ------"能跑"和"能维护"是两码事。Karpathy 自己也说了,这是适合原型和一次性项目的玩法。如果你想做长期维护的项目,需要一套工程方法论来约束 AI。

1.2 我踩坑后总结的三条铁律

在学任何具体方法之前,先记住这三条,否则你永远在重复踩坑:

铁律 为什么
🛡️ AI 不能自证正确 永远不要让 AI 自己确认自己的输出。凡是能被测试、类型、schema 校验的规则,都应变成机器门禁
🧩 能复用时不重造 高阶形态不是从零生成代码,而是把已有成熟能力编排成业务系统
📋 先规划再编码 不上来就写代码,先强制 AI 读懂你的技术栈和项目规划

1.3 人机分工:谁干什么

很多人的误区是"让 AI 干所有事"。正确的分工是:

text 复制代码
你负责:描述意图 → 设定约束 → 验证结果 → 做决策
AI 负责:理解上下文 → 生成计划 → 修改文件 → 整理证据
机器门禁:拦截幻觉 → 拦截糊弄 → 拦截越界 → 强制执行规范

💡 我的实测体会:把 AI 当成一个"能力很强但需要明确指令的新员工"。你不会让新来的员工直接干活,得让它先熟悉业务流程。AI 也一样------先让它读懂你的项目,再让它动手。


📐 第二章:先规划,再编码------我的 TodoList 实战

2.1 需求

用 React + TailwindCSS 实现一个任务清单页面,支持:

  • ✅ 新增待办
  • ✅ 删除待办
  • ✅ 切换完成状态
  • ✅ 拖拽排序

2.2 ❌ 错误示范(我的第一次翻车)

直接说:

text 复制代码
帮我写一个 React 待办清单页面,支持新增、删除任务。

后果

  • AI 把所有逻辑堆在一个 500 行的 App.jsx
  • 字段名 title / text / name 混着用
  • 拖拽功能凭空手写一套坐标监听 + 排序算法
  • 想改功能?无从下手

2.3 ✅ 正确示范(先规划,再编码)

第一步:强制规划,禁止输出代码

text 复制代码
遵守胶水编程思维:优先使用成熟方案,避免凭空造逻辑。
第一个阶段:只做规划,禁止输出任何代码。

1. 确定技术栈:
   React 19 + TailwindCSS + useState

2. 梳理功能边界:
   - 新增待办、删除待办、切换完成状态
   - 不做本地持久化、筛选功能
   - 拖拽排序使用成熟库

3. 拆分模块(乐高组件):
   - TaskInput:输入框组件
   - TaskItem:单条待办组件
   - TaskList:列表容器组件

4. 定义数据流:
   useState 存储 tasks 数组
   数据结构:{ id, text, completed }

5. 输出完整规划,等待确认后再分段实现代码。

💡 背后逻辑

  • 先划定边界 → 防止 AI 擅自加功能(我的第一次翻车就是没做这步)
  • 强制模块拆分 → 好读好维护
  • 预定义数据结构 → 从根源减少字段幻觉(text 不能让 AI 自己决定叫 title 还是 name
  • 规划文档伴随整个项目周期

2.4 第二步:胶水编程------拖拽排序

现在要加拖拽排序功能。

❌ 错误指令

text 复制代码
帮我写 React 待办清单的拖拽排序功能

AI 很可能凭空手写一套拖拽逻辑,case 覆盖不全,bug 满天飞。

✅ 正确指令(遵守胶水原则)

text 复制代码
当前需求:给待办列表增加拖拽排序。
遵守胶水编程原则:绝不从零自研底层逻辑,
优先选择社区长期验证的成熟开源组件。

1. 先调研:React 生态成熟的拖拽库
2. 不要自己手写拖拽底层代码,只做粘合工作
3. 输出顺序:安装依赖命令 → 衔接现有组件 → 只写适配代码

AI 的调研结论

react-beautiful-dnd 已被 Atlassian 弃用,且不兼容 React 19。 选用社区维护的 fork @hello-pangea/dnd,API 完全一致,支持 React 19。

这就是胶水编程的精髓:不是自己造拖拽引擎,而是把成熟的拖拽库"粘"到现有组件上。

2.5 完整代码(可直接运行)

目录结构

text 复制代码
todolist/
├── src/
│   ├── App.jsx              # 主容器,状态管理
│   ├── components/
│   │   ├── TaskInput.jsx    # 输入框组件
│   │   ├── TaskItem.jsx     # 单条待办(含拖拽)
│   │   └── TaskList.jsx     # 列表容器(含 DragDropContext)
│   ├── index.css            # TailwindCSS 入口
│   └── main.jsx             # 应用入口
├── package.json
└── vite.config.js

App.jsx ------ 状态管理中枢

jsx 复制代码
import { useState } from 'react'
import TaskInput from './components/TaskInput'
import TaskList from './components/TaskList'

function App() {
  const [tasks, setTasks] = useState([])

  // 新增:预定义数据结构 { id, text, completed }
  const handleAdd = (text) => {
    setTasks((prev) => [
      ...prev,
      { id: Date.now(), text, completed: false },
    ])
  }

  const handleToggle = (id) => {
    setTasks((prev) =>
      prev.map((task) =>
        task.id === id ? { ...task, completed: !task.completed } : task
      )
    )
  }

  const handleDelete = (id) => {
    setTasks((prev) => prev.filter((task) => task.id !== id))
  }

  // 拖拽结束:数组重排(只做胶水,不做底层拖拽逻辑)
  const handleDragEnd = (result) => {
    if (!result.destination) return
    const startIndex = result.source.index
    const endIndex = result.destination.index
    if (startIndex === endIndex) return
    setTasks((prev) => {
      const next = Array.from(prev)
      const [moved] = next.splice(startIndex, 1)
      next.splice(endIndex, 0, moved)
      return next
    })
  }

  const completedCount = tasks.filter((t) => t.completed).length

  return (
    <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 py-12 px-4">
      <div className="max-w-xl mx-auto">
        <div className="text-center mb-8">
          <h1 className="text-4xl font-bold text-gray-800 mb-2">📝 待办清单</h1>
          <p className="text-gray-500">共 {tasks.length} 项 · 已完成 {completedCount} 项</p>
        </div>
        <div className="bg-white rounded-2xl shadow-xl p-6">
          <TaskInput onAdd={handleAdd} />
          <TaskList
            tasks={tasks}
            onToggle={handleToggle}
            onDelete={handleDelete}
            onDragEnd={handleDragEnd}
          />
        </div>
      </div>
    </div>
  )
}

export default App

TaskInput.jsx ------ 输入框组件

jsx 复制代码
import { useState } from 'react'

function TaskInput({ onAdd }) {
  const [text, setText] = useState('')

  const handleSubmit = (e) => {
    e.preventDefault()
    const trimmed = text.trim()
    if (!trimmed) return
    onAdd(trimmed)
    setText('')
  }

  return (
    <form onSubmit={handleSubmit} className="flex gap-2 mb-6">
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="添加新待办..."
        className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
      />
      <button
        type="submit"
        className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors font-medium"
      >
        添加
      </button>
    </form>
  )
}

export default TaskInput

TaskItem.jsx ------ 胶水粘合拖拽库

jsx 复制代码
import { Draggable } from '@hello-pangea/dnd'

function TaskItem({ task, index, onToggle, onDelete }) {
  return (
    <Draggable draggableId={String(task.id)} index={index}>
      {(provided) => (
        <li
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          className="flex items-center gap-3 px-4 py-3 bg-white rounded-lg shadow-sm border border-gray-100 group cursor-grab active:cursor-grabbing hover:shadow-md transition-shadow"
        >
          <input
            type="checkbox"
            checked={task.completed}
            onChange={() => onToggle(task.id)}
            className="w-5 h-5 text-blue-500 rounded focus:ring-2 focus:ring-blue-300 cursor-pointer"
          />
          <span className={`flex-1 text-gray-700 ${task.completed ? 'line-through text-gray-400' : ''}`}>
            {task.text}
          </span>
          <button
            onClick={() => onDelete(task.id)}
            className="text-red-400 hover:text-red-600 opacity-0 group-hover:opacity-100 transition-opacity text-sm px-2 py-1 rounded hover:bg-red-50"
          >
            删除
          </button>
        </li>
      )}
    </Draggable>
  )
}

export default TaskItem

TaskList.jsx ------ 列表容器

jsx 复制代码
import { DragDropContext, Droppable } from '@hello-pangea/dnd'
import TaskItem from './TaskItem'

function TaskList({ tasks, onToggle, onDelete, onDragEnd }) {
  if (tasks.length === 0) {
    return (
      <div className="text-center py-12 text-gray-400">
        <p className="text-lg">暂无待办事项</p>
        <p className="text-sm mt-1">添加一个开始你的任务吧!</p>
      </div>
    )
  }

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="task-list">
        {(provided) => (
          <ul ref={provided.innerRef} {...provided.droppableProps} className="space-y-2">
            {tasks.map((task, index) => (
              <TaskItem
                key={task.id}
                task={task}
                index={index}
                onToggle={onToggle}
                onDelete={onDelete}
              />
            ))}
            {provided.placeholder}
          </ul>
        )}
      </Droppable>
    </DragDropContext>
  )
}

export default TaskList

🎯 注意看 :我们没有写任何拖拽底层逻辑,只是把 @hello-pangea/dnd<Draggable> 组件"粘"到了 <TaskItem> 上。每个组件只做一件事,总共 4 个文件,每个都不超过 60 行。这就是胶水代码------短、薄、清晰、可删除。


🧬 第三章:胶水编程------从"实现者"到"整合者"

3.1 我的第二次翻车:凭空造 API

让 AI 写爬虫时,它生成了 axios.getHTML() 这种根本不存在的方法。为什么?因为我让它"从零实现",它就真的从零编了一个。

后来我学到一个原则:能抄不写,能连不造

text 复制代码
传统编程:人写代码
Vibe Coding:AI 写代码,人审代码
胶水编程:  AI 连接成熟模块,人审连接

3.2 胶水原则(刻进 DNA)

原则 解释
成熟方案优于自研实现 别人踩过的坑,你不用再踩一遍
官方能力优于私有轮子 官方维护 = 长期稳定
复用优于重写 重写 = 重新引入所有 bug
编排优于重造 用 A 的输出喂给 B,比自己造 C 强
可替换优于强绑定 今天用的库,明天可能弃维护
偏离必须说明 想自研?先写清楚为什么不用现成的

3.3 决策顺序(实战 checklist)

每次拿到一个需求,按这个顺序走:

  1. 🔍 先搜索:有没有官方能力、平台能力、成熟开源库?
  2. 📊 再评估:维护状态、许可证、文档质量、生产案例
  3. 🔗 再连接:只写胶水代码,把成熟模块粘在一起
  4. 再验证:测试、类型、schema、CI 全覆盖
  5. 🔄 留后路:替换路径、回滚方案

3.4 我的第三次翻车:重复造轮子

做电商后台时,AI 自己设计了一套权限系统。上线后发现跟公司现有的 SSO 完全对不上。

正确做法:先问 AI "有没有成熟的认证方案",它会告诉你 Auth0、Firebase Auth、Keycloak 这些。你只需要写胶水代码,把认证结果接入你的业务用户体系。

💡 胶水编程的精髓:轮子别人造好,为我所用;你只做胶水;胶水不生产零件,只联通零件。

3.5 对胶水编程的批判性思考

胶水编程不是万能的。我在实践中发现了几个局限性

  1. 过度依赖外部库的风险 :如果上游库突然弃维护(比如 react-beautiful-dnd),你得紧急迁移。所以胶水层要做好隔离,别让第三方 API 渗透到核心业务模型里。

  2. "成熟方案"的判断标准因场景而异:一个库有 10K star 就算成熟吗?不一定。要看它是否被真实生产环境使用、是否有活跃维护、是否与你的技术栈兼容。

  3. AI 有时候比你更懂"有什么轮子" :这是好事也是坏事------好在它能帮你发现你不知道的工具,坏在它可能推荐一个看起来活跃但实际有严重 bug 的库。所以评估环节不能跳过


🛠️ 第四章:真实项目对比------TodoList vs 爬虫 vs 后台

我把三个项目的经验放在一起对比,让你直观看到方法论的威力:

维度 ❌ 无规划(翻车) ✅ 有规划(成功)
TodoList 500 行单文件,字段混乱 4 个组件,每个 < 60 行
爬虫 凭空捏造 axios.getHTML() playwright + 胶水代码
电商后台 自研权限系统,与 SSO 不兼容 用 Keycloak + 适配层

关键差异 :不是 AI 能力的问题,是你给 AI 的指令质量的问题。


🐞 第五章:避坑指南------8 条入门铁律

踩过的坑,总结成铁律,建议打印贴墙上:

# 铁律 为什么
1 先定义问题,再让 AI 写代码 问题不清,代码必乱
2 先让 AI 给计划,再让 AI 执行 计划是约束 AI 的缰绳
3 每一步都要能验证 "看起来对" ≠ 真的对
4 频繁提交 Git 每次进展都是可回滚的检查点
5 让文档持续更新 README、AGENTS、progress.md 不能断
6 不相信 AI 的口头保证 只相信测试输出、CI 状态、可审查 diff
7 重要规范必须代码化 能写成 lint/test/schema 的,就别只写自然语言
8 不符合规范必须失败 靠人记住提醒 AI = 迟早忘

5.1 Debug 最小化

当 AI 生成的代码出错时,不要把整个项目丢给它。正确的做法:

text 复制代码
预期行为:点击"添加"按钮后,新任务出现在列表末尾
实际行为:点击后列表没有变化
最小复现:只贴 TaskInput.jsx 和 App.jsx 的相关代码

只给预期、实际和最小复现,AI 的修复准确率会大幅提升。

5.2 隔离审查

重要产出必须隔离审查 ------这是我认为整套方法论中最重要的一条:

新开一个会话,明确告诉审查 AI: "上一轮结果不可信,不能沿用结论,必须重新阅读原始资料,用事实和测试判断是否成立。"

为什么? 因为 AI 有"自偏好"------它倾向于认为自己的输出是正确的。同一个上下文里让它自我审查,等于让考生自己改卷子。

AI 负责生成候选解,隔离上下文负责审查,事实与验证负责裁决。


🔮 第六章:进阶------让 AI 帮你优化提示词

这一章分享一个我实测有效的进阶技巧:用 AI 优化你给 AI 的指令

6.1 实战案例:从"能用"到"好用"

我最初的规划 prompt 是这样的:

text 复制代码
帮我做一个 React 待办清单,用 TailwindCSS。

然后我让另一个 AI(或同一个 AI 的新会话)帮我优化这个 prompt:

text 复制代码
我有一个给 AI 的指令,用来生成 React 待办清单。
请帮我优化这个指令,让它:
1. 更具体,减少 AI 自由发挥的空间
2. 包含明确的验收标准
3. 强制模块化拆分
4. 预定义数据结构,减少字段幻觉

原始指令:帮我做一个 React 待办清单,用 TailwindCSS。

优化后的 prompt 就是前面第二章的那个强制规划版本------效果天差地别。

6.2 递归优化(元方法论)

这个思路可以继续递归:

text 复制代码
1. 用 AI 生成初始 prompt(v1)
2. 用另一个 AI 优化这个 prompt,得到 v2
3. 用 v2 生成更好的代码
4. 把代码中的问题反馈回去,再次优化 prompt
5. 循环,直到效果稳定

💡 我的体会:这个方法在复杂项目中特别有效。一个经过 3 轮优化的 prompt,生成代码的一次通过率从 40% 提升到了 80%+。但要注意,不要过度优化------有时候一个简单直接的指令就够了。

6.3 局限性

  • 递归优化需要额外的时间成本,小项目不划算
  • 优化后的 prompt 可能过拟合于特定场景,换个项目又得重新来
  • 本质上是在弥补当前模型的不足------当模型足够强时,这些技巧可能不再需要

📊 第七章:工具清单速查

⚠️ 以下工具推荐基于 2026 年 7 月的实测体验,AI 工具迭代很快,请以实际使用为准。

AI CLI 选择

工具 特点 推荐指数
Claude Code 终端原生,深度思考能力强 ⭐⭐⭐⭐⭐
Codex CLI OpenAI 官方,代码生成质量高 ⭐⭐⭐⭐⭐
Cursor IDE 集成,上手简单 ⭐⭐⭐⭐
Gemini CLI 免费额度,适合脚本和文档 ⭐⭐⭐
Kimi / 通义千问 国产模型,中文友好 ⭐⭐⭐

提升提示词效果的技巧

text 复制代码
// 触发深度思考(Claude Code)
think < think hard < think harder < ultrathink

// 万能后缀
"慢慢想,不着急,重要的是严格按我说的做,执行完美。
如果我表达不够精确请提问。"

上下文管理

  • 经常用 /clear/compact 清理上下文
  • /rewind 回滚到之前状态
  • 每完成一步就 /new 新建聊天,避免上下文污染

💡 总结:从"让 AI 写代码"到"指挥 AI 交付产品"

阶段 ❌ 新兵做法 ✅ 正确做法
拿到需求 直接让 AI 写代码 先规划、定边界、拆模块
技术选型 AI 说啥用啥 先调研成熟能力,用胶水粘合
写代码 一个文件 500 行 模块化,每块只做一件事
出了 bug 把整个项目丢给 AI 预期 + 实际 + 最小复现
代码审查 自己看一遍就完事 隔离会话,AI 审 AI
交付 跑起来就行 测试 + CI + Git + 文档

记住一句话

🎯 Vibe Coding 不是把代码外包给 AI,而是一套工程协作方式。人负责目标和验收,AI 负责执行和放大,机器门禁负责兜底。


🔗 参考资料


💬 交流讨论

你在用 AI 写代码时踩过哪些坑?有什么独门技巧?欢迎在评论区分享!

如果这篇文章对你有帮助,点个赞👍 收藏⭐ 关注👆,后续会更新更多 Vibe Coding 实战玩法:

  • 📦 如何用 Vibe Coding 快速搭建全栈项目
  • 🤖 Claude Code 自定义 Skill 实战
  • 🔄 用递归优化让 AI 自己改进自己的提示词

觉得有用?点个赞👍收藏⭐关注👆,下次更新更多 AI 编程玩法!

相关推荐
风栖柳白杨1 小时前
【面试】AI算法工程师_空白自测版本
人工智能·算法·面试
默大老板是在下1 小时前
信息深度加工框架:如何把“看过”变成“能调用”
人工智能
隔窗听雨眠1 小时前
AI Agent可观测性:破解多步推理黑盒
人工智能
延凡科技1 小时前
智慧燃气解决方案:管道煤气监管应用管理系统(三维GIS+IoT+大数据落地实战)
大数据·人工智能·科技·物联网·安全
水如烟1 小时前
孤能子视角:梁文锋的场,一个量化交易者的本能
人工智能
计育韬1 小时前
KimiK3一条龙从建模到3D打印,实现复旦大学老校门手办制作(榫卯结构拆件
人工智能
qq_454245031 小时前
ClineRule系统提示词
人工智能·架构
研☆香1 小时前
怎样利用AI工具,搭配制作网页
人工智能
ARM|X86+FPGA工业主板厂家2 小时前
AI视觉跟随运动控制实战|RK3588 NPU检测+FPGA EtherCAT多轴联动精准跟随方案,适用于半导体视觉对位等
人工智能·fpga开发·硬件工程·ethercat·实时系统