VibeCoding 大概是最近一年里开发者圈子里被玩得最狠的一个梗:有人说它是“让AI发电式写代码”,有人说它是“氛围编程”,还有人直接把它等同于“摸鱼新姿势”。我第一次刷到这个词的时候,心里想的是“这又是什么旧概念换了个新马甲”,但真正用它连续做完两个小项目之后,我的看法变了:这个词之所以火,是因为它戳中了一个真实现状——AI 编程已经不是少数人的玩具了,而是大部分人每天都在干的事。问题只在于,有人是在有章法地用,有人是在靠运气试。
我今天想聊的,不是怎么敲几个俏皮话让 AI 给你写个贪吃蛇,而是那些真正能提高产出、减少返工的习惯和做法。这些东西你在官方文档里很难看到,都是我一遍遍踩坑踩出来的。
1. VibeCoding 到底是什么,先别急着跟风
1.1 这个词怎么来的,大家为什么这么兴奋
VibeCoding 字面意思就是“跟着 vibe(氛围/感觉)编码”。最早火起来的时候,大家描述的场景是:你在编辑器里用自然语言描述需求,AI 一顿输出看起来能跑的代码,你复制进去跑一下,报错了再把报错丢回去,如此循环,直到功能看起来正常。
听起来很像“瞎猫碰死耗子”,但它能火,背后其实有个硬逻辑:过去写代码,你要先建立完整的心理模型,才能动手;现在有了强力的代码生成模型,你可以在边做边学的过程里,让 AI 帮你把“从想法到运行”之间的距离缩短到几分钟。原型验证、临时脚本、跨语言改写、补齐样板代码,这些都是 VibeCoding 真正的用武之地。
我看到很多人拿它玩梗,说“今天 vibe 到了,代码自己写完了”。但实际上,真正拿 AI 做正经项目的人,很少是纯靠感觉的。他们只是把控制方式从“手写每一行”变成了“把控方向、反馈纠偏”。这不是不写代码,而是换了一套工作逻辑。
1.2 我眼里的 VibeCoding:不是躺平,是换了个协作角色
我的比喻是:传统开发里,你是个纺织工,从棉线开始织布,每一步都亲自动手。而 AI 编程更像当导演,你面前站着一个效率极高、但特别容易加戏的演员。你说“这场戏要一个下雨天失恋的镜头”,它给你拍成科幻片也完全有可能。
所以 VibeCoding 的上手门槛确实低了,但“做好”的难度一点都不低。你需要的不是更少的思考,而是另一种思考:怎么表达需求,怎么判断产出,怎么把 AI 的幻觉拦在门外,怎么在它扯远的时候把它拉回来。
明确这些之后,下面要聊的每个习惯,本质上都是在做一件事:把“导演”这份工作干好。
2. 把 AI 变成结对伙伴:三个底层思维转变
2.1 从“问答案”到“给指令、看过程、提反馈”
最常见的低效用法,是把 AI 当成搜索引擎:“怎么用 Python 读 Excel?”得到一段代码,复制,跑,不行,继续问。这种方式不是不能用,但产出非常随机,因为它没有上下文。
真正高效的用法,是把它当成一个随时在待命的结对程序员。你要给的不是一个问题,而是一段带有明确意图的指令。比如你同样的需求可以这样描述:
在 src/excel_parser.py 里新增一个 parse_excel(path) 函数。 要求:用 pandas 读取第一个 sheet,返回所有行组成的 list[dict]; 列名如果有空格自动去掉;文件不存在时抛 FileNotFoundError; 不给这个函数加命令行入口。只用标准库和 pandas。对比一下就知道,后者不只是在“要代码”,而是在“派活”。它告诉了 AI 文件位置、函数签名、行为约定、边界条件、依赖限制。这样生成出来的代码,几乎不用改就能用,关键是它可预测。
2.2 把“一次性生成”改成“小步快走”
很多人在 AI 编程时犯的最大的错误,就是让 AI 一次性生成一个完整的模块、一个完整的接口、甚至一个完整项目,然后跑一下,面对二十个报错,再逐条贴回去修复。这个循环在项目小的时候还能忍,一旦文件多起来,AI 的上下文窗口会被一堆编译错误和半成品代码占满,改出来的东西往往是顾此失彼。
我现在习惯把一个大需求拆成几步:先让它搭骨架,再填血肉,最后做收尾。每一步开始前,都会明确这一步的完成标准和验收动作。比如做一个订单管理页面,我不会说“帮我写一个订单管理页面”,而是拆成:
- 把 mock 数据结构和接口类型定好
- 写好列表组件,跑通渲染
- 加搜索和分页
- 再处理空状态和错误状态
- 最后统一样式和交互
每跑通一步,就相当于锁定了一步的成果。后面出了问题,我也能一眼看出是哪一步引入的,返工成本立刻降下来了。
2.3 学会给 AI“定向投喂”上下文
你得接受一个现实:AI 模型本身再聪明,它默认也并不知道你的项目里有什么。你不告诉它你的实体类长什么样、你用的组件库是什么版本、你的代码风格如何,它就只能给你生成一套“标准的、普适的”代码,然后你的工作就是去改它,变成“适配项目的代码”。
所以我现在会把两三份材料当成“日常投喂包”:相关文件的路径和内容摘要、错误日志的关键片段、项目里已有的相似代码。尤其是“相似代码”,AI 看到你项目里已有的写法之后,生成的东西会贴合很多。这就好比你带新人,与其让他读一本通用教科书,不如直接拿一份老代码让他照着写。
3. 实战环境搭建:我用下来顺手的配置组合
3.1 编辑器、模型与工具链怎么搭配
AI 编程现在不是某一个工具一家独大的局面,而是一套组合拳。我的日常主力是编辑器里直接集成的 AI 助手——比如我常用的一款 AI Code Editor,配合一个主流的大语言模型跑日常编码,再用终端里另一个 CLI 工具做批量重构和跨文件改动。
几个我觉得很实用的搭配原则:
- 编辑器的 AI 助手负责“局部改动”:补函数、改逻辑、写测试,因为这部分需要看到当前文件内容。
- CLI 工具负责“全局任务”:比如全项目扫描 TODO、统一改命名风格、批量生成文档,因为它可以在项目根目录读取完整结构。
- 版本管理走 Git,而且我坚持每个由 AI 产生的有效改动单独提交。这样万一改坏了,我能精准回滚,而不是一锅端。
3.2 让 AI“记住”项目结构的两类资料文件
我自己体会很深的一件事:项目里的说明文件,不光是给人看的,更是给 AI 看的。很多仓库里 README 写得马马虎虎,自己看可能无所谓,但 AI 一读就会“理解跑偏”。
我现在会在项目根目录维护一份项目约定文档,里面包含:
| 条目 | 示例内容 |
|---|---|
| 技术栈 | React 18 + TypeScript + Vite,不用 Redux |
| 目录结构 | src/pages 放页面,src/components 放通用组件 |
| 代码风格 | 2 空格缩进;组件用函数式;props 用 interface |
| 关键依赖 | 不要引入新依赖,除非提前知会 |
| 测试要求 | 关键工具函数必须有小测试 |
是的,听起来有点“文档驱动开发”的意思,但这套东西最大的受益者其实是 AI。你只要在对话开头说一句“开发前先读一下项目约定文档”,AI 后面生成的东西就会长期稳定地贴着你项目的规范走。它省掉的返工,远远超过你维护这个文件花的时间。
3.3 何时让 AI 维护文档,何时自己动手
文档维护这件事我踩过坑:有一段时间我让 AI 自动为所有生成的函数补注释和文档字符串,结果代码注释密度上去了,但很多注释等于把代码翻译成英文讲了一遍,一点价值都没有。后来我做了调整:
- 公共 API、对外接口的注释,让 AI 根据代码自动生成,人工再抽查一遍关键点;
- 模块内部长函数的注释,不让 AI 硬写,而是要求它把逻辑拆小、用函数名表达意图;
- 项目文档里记录的“为什么这样做”的部分,永远我自己写,因为这些决策上下文是代码里看不出来的。
这个调参我调了大概两周,现在 AI 产出的注释质量明显干净了,而且代码可读性比之前还好。关键原则就一句话:AI 可以帮你“记录现状”,但替你做不了“判断取舍”。
4. 写 Prompt 和指令的实用模式:从新手到够用的三条路子
4.1 角色设定与约束描述:把 AI 拉进你的项目语境
很多人用 AI 写代码,第一句话就是“写个 XX”,好像对面是个算命先生。但同一个模型,你给它的上下文颗粒度不同,产出能差出一个量级。我现在会用一段“项目语境”开头,哪怕只是为了完成任务,这段话也值回它的字数。
我常用的开头模板是:
你是这个项目里的资深前端工程师。 项目用 React + TypeScript + Vite,组件库是 Ant Design。 现在我要在 pages/OrderList.tsx 里增加一个搜索框,要求: - 不改动任何其他文件 - 不引入新的依赖库 - 搜索走现有 API:/api/orders?keyword=xx - 沿用现有页面风格,不要额外写 CSS 完成后,先输出改动摘要,再给具体 diff。注意这里面的几个细节:指定“不改动任何其他文件”,是给 AI 划边界;指定“不要引入新依赖”,是挡掉它最喜欢干的“加个库”操作;要求“先输出改动摘要再给 diff”,是为了让你在合并之前能先判断它有没有跑偏。这套约束下来,AI 的收敛速度会快非常多。
4.2 任务拆解:把“大需求”切碎了再提交
如果你直接说“做一个博客系统”,AI 可能会眼前一亮给你生成一堆文件,但这个模式在真实项目里基本不可用,因为你的项目已经有自己的结构。更好的做法是把它拆成你能逐个验收的小任务。
比如:
- 先定义 Post 数据模型和示例数据。
- 实现文章列表页,从 JSON 文件读取数据。
- 实现文章详情页,定义好路由。
- 加一个简单的 Markdown 渲染。
- 最后做导航和整体布局。
每一轮任务,我都在对话开始时给它当前相关文件的路径,并且告诉它“上一步已经完成,现在基于当前这份代码继续加下一个功能”。这样 AI 不会反复在同一个问题上绕圈,也不容易把之前已完成的功能改坏。
4.3 用“编辑请求”和“审查请求”代替“再写一遍”
我发现很多人在 AI 改错了之后,习惯说“重新写一遍”,这其实是最容易踩雷的一句话。“重新写一遍”意味着从头生成,很可能把之前正确的部分也覆盖了。我现在更常说的是:
保留现有整体结构,只把 handleSubmit 函数改一下: - 加参数校验,空字符串直接 return - 提交失败时保留表单内容 - 不要改动其他函数把修改范围锁定到函数级,AI 的改动风险就小了很多。改完之后,我会再追加一个“审查请求”:
现在以 QA 视角审阅 handleSubmit 函数: 列出边界情况、潜在 bug、以及它和现有错误处理方式的冲突。 只输出问题清单,先不要改代码。这个习惯救过我太多次——AI 自己写的东西,自己审一遍,往往能发现那些我一眼扫过会忽略的问题。这相当于免费的初步 Code Review,虽然不能代替人工,但能把明显问题提前过滤掉。
5. 工程化护栏:让 AI 生成的代码提得动、改得动、烂不掉
5.1 测试先行:没有测试的 AI 代码等于裸奔
如果你只是拿 AI 写一次性脚本,测试可写可不写。但只要你打算把代码合进主分支,或者它会运行超过一周,那么测试就不是可选项了。我在用 AI 生成工具函数时,会直接让它先写测试用例,再写实现,或者两者一起生成。
这么做有几个实实在在的好处:第一,测试就是需求说明书,AI 在写测试的时候会倒逼你把边界情况想清楚;第二,测试能立刻验证 AI 的输出,而不是靠肉眼看了又看;第三,后面你让 AI 改这个函数的时候,因为测试还挂着,改错了会立刻爆红,不用等到上线才知道坏了。
我常用的命令是:
为 utils/date.ts 里的 formatDate 函数编写单元测试。 覆盖:正常格式化、非法输入返回空字符串、时区边界、12/24小时制。 写完测试后,如果实现不满足测试,再修改实现。这个“测试先行”的习惯,是我觉得从“AI 帮我写代码”到“AI 帮我写合格代码”之间的一道分水岭。
5.2 人工 Review 环节不能省:机器写的代码也要过脑子
我坚持一个原则:AI 生成代码,我可以省去打字的时间,但绝对省不掉理解的时间。凡是 AI 生成的、要进入主分支的代码,我都会花时间完整读一遍,并且读的时候带着明确的关注点。
我自己的 review 清单是这样的:
- 函数名和结构是否真的表达了意图,还是只是能跑?
- 有没有隐藏的副作用?比如它是不是悄悄改了全局变量、缓存、文件?
- 错误处理是否真实存在?还是把异常都吞了?
- 有没有硬编码?API 地址、密钥、魔法数字。
- 它引用的库是不是真的存在?版本对不对?
很多人以为 review 是浪费时间,但如果不在这一步花时间,后面花的时间只会更多。AI 生成的代码有个特点:看起来非常规矩,甚至比很多人手写的还格式化,但逻辑上偶尔会“认真的胡扯”。没有人工这条线,你就是在拿生产环境当测试环境。
5.3 代码健康度:识别烂摊子,及时重构
VibeCoding 最容易堆出来的一种代码,我管它叫“AI 饺子”:看起来皮光馅足,咬下去发现里面是一堆插件式补丁,逻辑绕来绕去。这种情况通常不是某一次生成的问题,而是多次累加的。
我会定期让 AI 做一次“代码健康度扫描”:
遍历 src/core 目录下的所有文件,找出明显的问题: - 重复逻辑超过两处的代码 - 过长函数(超过 50 行且分支过多) - 明显可以抽成公共函数的模式 - 命名混乱的变量 不要修复它们,只输出一份带文件和行号的清单。拿到清单之后,我会挑优先级最高的两三个,亲自确认需求后,再让 AI 针对性重构。这里有个很重要的经验:不要让 AI 在发现问题的同时顺手就重构,因为它经常会把“重构”做成“重写”,带来不必要的大范围改动。发现和修复这两件事要分开,发现可以全自动,修复必须带人工控制。
6. VibeCoding 翻车现场:四类常见事故与我的处理手段
6.1 幻觉依赖:AI 编了个不存在的 API
这是 AI 编程最经典的事故。你让它调用某个第三方库的方法,它振振有词地给你写出一个听起来特别合理的函数,你复制进去一跑,直接 ModuleNotFoundError 或者 TypeError。原因很简单:模型记住的是语料,不是运行环境,它在不确定的时候非常擅长“自信地编造”。
我的应对手段是三条:
- 凡是 AI 引用了我不确定的 API,我都会先让它在对话里给出引用依据,比如官方链接或版本号,再决定用不用。
- 凡是 AI 引入了一个新的第三方库,我需要它先说明这个库的用途、版本、和项目现有技术栈的兼容性。
- 最关键的一点:拿到 AI 给的代码后,先原地跑少量验证,再合入项目。验证成本再低,也比回头排查几小时强。
6.2 上下文漂移:改一处崩一片的连锁反应
还有一种高频事故:项目进行到中後期,AI 的上下文窗口里塞了太多历史对话,它已经忘了一开始定的协议。你让它改 A 模块,它顺手把 B 模块里它“认为不该存在”的东西改了,或者它按最新的对话理解,给你重写了之前已经验收过的逻辑。
我现在的做法是对对话进行“分段管理”:同一个功能的一条链跑到底,不穿插其他任务;一旦任务切换,开一个新对话,并且在新对话里重新贴一次项目约定文档和相关文件摘要,而不是依赖旧对话里的“记忆”。
如果项目里出现“改一处崩一片”的现象,我的第一反应不是继续在现有对话里修,而是开到新对话,用新的上下文重新描述现状和目标。很多时候,一个干净的新开场,比跟旧对话里的幻觉搏斗高效得多。
6.3 无限迭代:和 AI 在同一条错路上走到黑
AI 编程里最消耗耐心的场景,就是和它连续纠缠同一个错误,来回七八轮,每次它都给出“抱歉,之前的做法有误,我将修复”,然后给出一版新代码,结果要么是原点,要么是坑更深。这种时候你就要警惕了:你止损的速度,决定了这个项目的活路。
我的止损线是“三次”。同一个报错,让 AI 修三次还没好,我就停手。接下来我把代码缩到一个能复现问题的“最小示例”,重新开一个对话,把最小示例和完整报错贴进去。这个动作看着简单,但它强制把问题从“整个项目”收敛到“一个点”,AI 在这种条件下给出的解法往往立刻有效。
6.4 代码孤儿化:生成之后没人敢动
这是我最担心的一种情况,但很多人没意识到。当一个文件完完全全是 AI 生成的,而你自己再也没读过它,它就变成了“代码孤儿”。它能跑,但没人看得懂;任何小改动,你只能继续找 AI 做;AI 一换模型或上下文一清空,这代码就成了黑盒资产。
为了避免这种情况,我从一开始就要求 AI 生成“人类能读的代码”:命名要有语义、函数拆得小块、关键复杂逻辑必须附带一两行注释解释“为什么”。我也给自己定了规矩:AI 写完一个文件,我必须完整读一遍,即便当时觉得浪费时间也要读。这个习惯让我从“被 AI 牵着走”变成了“牵着 AI 走”,差别非常大。
7. 我自己沉淀下来的几个高频习惯
7.1 每天开工前先让 AI“复述”项目状态
这个习惯听起来有点怪,但我坚持了快半年,效果出奇的好。每天开工,我会在一个新对话里丢出几个关键文件,然后让 AI 描述一下“目前项目做到哪一步、代号用了什么、有什么已知限制”。它如果复述的和我预期的吻合,我就知道上下文没跑偏;它如果复述出一些我没写过的逻辑,我就立刻知道前一天的问题还有残留。
这个“复述确认”的过程成本很低,却能把一天的返工量降一大截。本质上,它是在给 AI 的上下文做体检。
7.2 用“伪代码+注释”当对话的锚点
现在我要 AI 做比较复杂的改动时,会先写下我要的逻辑,哪怕是用注释、伪代码、甚至中英混杂,然后把这段锚点一同发给它。比如,我想让 AI 实现一个带重试的网络请求:
伪代码: fetchUsers = 尝试最多3次 第1次失败 等待 1s + 随机抖动 再试 第2次失败 等待 2s 再试 第3次失败 返回错误提示给UI 要求:每次重试必须明显日志;错误对象要保留出错的status。这个习惯的好处是,AI 不会被模型自己脑补的逻辑带跑,它会严格按你的骨架填肉。我们目标是写代码,但真正的蓝图是由你来定的,AI 只是个执行者。
7.3 定期让 AI 做“反向 Review”
最后一个我特别喜欢的习惯:让 AI 扮演一个严格的外部评审,反向审视我的代码和习惯。我不只让它 review 单个文件,还会让它 review 一段技术方案、一组接口设计,甚至让它找“如果我是一个攻击者,这个接口哪里能捅出洞”。AI 不一定每一条都对,但它往往能提出很多人想当然忽略的视角。
我会要求这类 review 输出成三个栏目:
- 必须修的问题(含理由)
- 建议优化项(含成本收益)
- 可保持现状但我应该有意识的地方
这样一轮下来,项目里的“盲点清单”会非常清楚,我再决定哪些交给 AI 处理、哪些自己动手。
说回开头的话题,VibeCoding 确实可以被玩成摸鱼和玄学,但它同样可以被用成一套相当硬核的开发方法。差别不在于你用没用 AI,而在于你有没有建立起对应的习惯:给上下文、定边界、设验证、做 review、及时止损。这些习惯单独看都不新潮,但叠在一起,就是 AI 编程里真正拉开产出差距的地方。我到现在也会偶尔被 AI 生成的烂代码气到,但只要这套流程还立着,最后兜底的就永远是我自己,而不是那个概率模型。