我让AI写了3天代码,最后全删了——问题不在AI,在我自己

你有没有过这种体验:兴冲冲地打开Claude Code,噼里啪啦描述了一通需求,AI唰唰唰生成了几百行代码,你满意地点点头,继续加需求,AI继续生成……三天之后,你盯着屏幕上这坨互相矛盾、风格混乱、改一处崩三处的代码,默默按下了Ctrl+A,Delete。

恭喜你,你刚刚完成了一次教科书级别的”Vibe Coding”。

别不好意思承认——我们都干过。感觉自己在”驾驭AI”,其实只是在”遛AI”。AI跑得飞快,但方向全凭感觉,最后跑到了一个连你自己都不认识的地方。

翻车现场回放:Vibe Coding的三种死法

在正式聊解决方案之前,让我先帮你确认一下——你是不是已经踩过这些坑了。

死法一:架构漂移

你跟AI说”帮我写个用户管理模块”,AI写了。然后你说”再加个权限控制”,AI又写了。再然后你说”加个审计日志”——AI继续写。问题来了:这三个模块分别是AI在三个完全独立的上下文里写的,它们之间的数据流向、依赖关系、错误处理策略,全都是各写各的。

你以为你在搭乐高,其实你在叠积木。乐高有卡扣,积木只靠重力。

死法二:边界遗漏

你说”写一个文件上传功能”。AI给你写了,能跑。你开心了三秒钟,直到有人上传了一个2GB的文件,浏览器直接崩了。或者有人上传了一个叫../../../etc/passwd的文件。或者有人同时上传了100个文件。

AI不会主动替你想这些,因为你没说。你没说,不是因为你不知道,而是因为”随口说需求”的模式根本不鼓励你想这些。

死法三:风格精分

早上你让AI用函数式风格写,下午你换了个Prompt模板,AI开始用面向对象写。晚上你从网上抄了段Prompt,AI又换了一种架构模式。同一个项目里,三种编程范式和平共处,代码review的时候你自己都看不下去。

这不是AI精神分裂,是你的需求描述精神分裂。

Vibe Coding vs Spec驱动:两种AI编程模式对比

Spec是什么?不是文档,是施工图纸

说到这里,可能有人已经在想:”那我把需求写清楚不就行了?”

对,但”写清楚”这三个字,难度被严重低估了。

你觉得”写一个用户登录功能”已经很清楚了?来,我帮你展开一下:

  • 用户名还是邮箱登录?还是都支持?
  • 密码错误几次锁定?锁定多久?怎么解锁?
  • 要不要支持”记住我”?Token有效期多长?
  • 登录失败要不要记录IP?记录了干什么用?
  • Session管理用JWT还是服务端Session?为什么?
  • 并发登录怎么处理?踢掉旧设备还是允许多端?

一个”简单的”登录功能,背后至少有二三十个决策点。你不定,AI就替你定。AI替你定的结果,就是每次定的都不一样。

这就是Spec要解决的问题。

Spec不是需求文档——需求文档说的是”我想要什么”,Spec说的是”我们具体怎么做”。需求文档是甲方的愿望清单,Spec是工程师的施工图纸。

一个合格的Spec,包含四个核心要素:

1. 问题定义:我们到底在解决什么问题?

不是”做一个XX功能”,而是”用户在YY场景下遇到了ZZ困难,我们通过XX功能来解决”。这一步逼你想清楚Why,而不是直接跳到What。

2. 接口契约:模块之间怎么对话?

输入是什么格式?输出是什么格式?错误怎么返回?这不是AI该猜的,这是你该定的。

3. 验收标准:什么叫”做完了”?

不是”能跑就行”,而是具体的测试用例。输入A,期望输出B。边界条件C,期望行为D。这些写清楚了,AI才知道自己写的代码对不对。

4. 边界约束:什么不做?

这一条最容易被忽略,也最重要。明确告诉AI”这个版本不考虑XX”,比让AI自己猜你要不要XX,省下来的时间够你喝三杯咖啡。

实战对比:同一个需求,两种写法

来,我们用一个真实场景做个对比。

需求:给博客系统加一个评论功能。


Vibe Coding写法:

“帮我给博客加个评论功能,要支持回复,还要能点赞。”

AI收到后会开始干活。但它不知道:评论要不要审核?匿名能不能评论?点赞能不能取消?回复嵌套几层?评论删了,底下的回复怎么办?每一个没说清楚的地方,AI都会自己编一个答案。


Spec驱动写法:

## 问题定义
博客文章目前没有互动功能,读者无法反馈。
需要添加评论系统,提升读者参与度。

## 接口契约
POST /api/comments
  - body: { articleId: string, content: string, parentId?: string }
  - 返回: { id, content, author, createdAt, parentId }
  - 错误: 401(未登录), 400(内容为空/超过500字), 404(文章不存在)

GET /api/comments?articleId=xxx
  - 返回: 扁平列表,包含parentId字段,前端自行组装树形结构
  - 按创建时间正序排列

## 验收标准
- 登录用户可以对文章发表评论
- 评论支持一级回复(不支持嵌套回复)
- 评论内容限制500字,超出返回400
- 未登录用户只能查看,不能发表

## 边界约束(本版本不做)
- 不做点赞功能(下个版本)
- 不做评论审核(当前用户量不需要)
- 不做富文本,纯文本即可
- 不做评论编辑,只能删除

同样一个评论功能,第二种写法交给AI,出来的代码质量和第一种是天壤之别。不是因为AI变聪明了,而是因为你终于把话说明白了。

你的第一个Spec模板

别被上面的例子吓到——Spec不需要写成论文。这里给你一个最小可用版本的模板,复制粘贴就能用:

# [功能名称] Spec

## 背景
- 为什么需要这个功能?解决什么问题?

## 目标
- 这个功能做完后,用户能做什么之前做不了的事?

## 非目标(明确不做的)
- 本版本不包含什么?为什么不做?

## 接口定义
- 输入:什么格式?什么类型?
- 输出:什么格式?什么类型?
- 错误:有哪些错误情况?分别怎么处理?

## 测试用例
- 正常场景:输入X → 期望输出Y
- 边界场景:输入为空/超长/非法类型 → 期望行为
- 错误场景:依赖服务挂了 → 期望行为

## 已知约束
- 性能要求:响应时间、并发量
- 技术限制:必须用某个框架/库
- 兼容性:需要支持什么环境

你可能会说:”这不就是写技术方案吗?我以前也写啊。”

没错,Spec驱动开发并不是什么新发明。它本质上就是软件工程里”先设计后编码”的老规矩。只不过在AI编程时代,这个老规矩获得了一种新的生命力——因为AI是一个完美的”按图施工”选手。你给它清晰的图纸,它能交付惊人的效率;你不给图纸让它凭感觉来,它能制造惊人的混乱。

Spec驱动开发工作流:从模糊到精确

从Vibe到Spec:一个心态的转变

最后说一个容易被忽略的问题:为什么很多人明知道应该写Spec,但就是懒得写?

因为Vibe Coding太爽了。

打开编辑器,一句话甩出去,AI秒回代码,能跑!这种即时反馈带来的多巴胺,和刷短视频是同一种快感。你会上瘾的。而写Spec需要你停下来思考,需要你面对那些”我其实还没想清楚”的尴尬角落。这不爽,一点都不爽。

但你迟早要面对这些角落。区别只在于,你是在写Spec的时候面对,还是在第三次重写代码的时候面对。

前者花30分钟,后者花3天。

从Vibe到Spec,不是从”快”退化到”慢”,而是从”快速制造问题”进化到”快速解决问题”。

这不是倒退,是AI编程的成人礼。

写Prompt写得好,说明你会跟AI沟通。写Spec写得好,说明你会跟自己沟通——你真的想清楚了要什么、不要什么、为什么要、做到什么程度算完。

AI不会读心术,但它极其擅长读Spec。

把你脑子里那些模糊的”差不多就行”,翻译成清晰的”精确到此为止”——这才是AI编程时代最值钱的技能。


下次在打开Claude Code之前,先花10分钟写一份Spec。你会发现,AI编程最大的效率提升,不在Prompt工程里,在你落笔之前的那10分钟思考里。