上个周六早上,我干了件以前绝对不会干的事。在街角的咖啡店里,我把手机里两年没整理的两千多张照片交给一个AI辅助编程工具,全程自己没怎么写代码,主要精力都花在描述需求、追加条件、然后把报错信息原封不动贴回去。四十分钟后,一个批量归档脚本跑通了,照片按拍摄日期自动落进文件夹,截图、发票和无关杂物也被分开。发到朋友圈没人信。因为认识我的人都知道,我在半年前公开吐槽过vibe coding这种“氛围编程”,觉得它就是把代码质量扔进垃圾桶。现在回头想,真正的问题从来不在工具,而在于大多数人一开始就搞错了它是什么、应该用在哪儿、以及自己需要承担多少责任。
1. vibe coding到底是新概念,还是老问题的另一种解法
1.1 这个词是被一位大牛带火的
vibe coding这个词,最初是Andrej Karpathy在社交媒体上随口说出来的。大意是:你完全跟着感觉走,让AI写代码,遇到报错就复述给AI,甚至不懂代码也能推进。他原话里还有一句很戳人的表达:你不是在写代码,而是在“vibe”(氛围式地)确认一切正常。
这词一出来就炸了。程序员分两派:一派觉得这是未来——把想法讲清楚,让机器写代码,人类该去做更高层的设计;另一派觉得这是灾难——不懂原理的人堆出一堆能跑的垃圾,迟早要还债。
我的态度经历了一个从嘲讽到接受,再到认真研究的过程。半年前我在公司内部群里引用这个词是为了讽刺,后来自己接了个数据清洗的小活儿,第一次认真用AI生成完整脚本,才意识到:它解决的是一个非常古老的问题——程序员脑子里想的和手上键盘敲出来的之间,隔着一层巨大的翻译损耗。vibe coding真正改变的,是把这层翻译从“敲键盘”变成了“对着AI把需求说清楚”。
1.2 它不是“无脑写代码”,而是把分工挪了个位置
很多人对vibe coding最大的误解,是觉得使用者的状态是不看代码、不负责、纯靠感觉。我实际操作下来的感受是:它的确可以不看代码,但不代表不思考。它更像是一种新的分工方式。
传统的编程模式里,一个人要把脑中的方案翻译成语法正确的代码,再反复调试。vibe coding模式下,这个翻译过程被交给语言模型。人的工作变成了三件事:第一,说清楚到底要什么;第二,判断AI给的方案是否合理;第三,对结果进行验证和收口。
打个比方。以前写代码更像自己动手做家具:图纸在心里,每一刀自己裁。vibe coding更像你跟一个手艺还行的木工师傅描述需求:“我要一个能坐两到三人的电视柜,要白色,要有收纳。”师傅给你出第一版,你看了一眼说抽屉不够大,他说改就改。你不需要会刨木头,但你必须知道电视柜应该有几个抽屉、尺寸大概是多少、什么颜色的木头适合你家客厅。
这个转变很容易被低估。它意味着程序员的核心能力从“会写”变成了“会判断”。判断力的本质,是你对系统底层逻辑、性能边界和失败风险的理解。这恰恰不是消失了,而是变得更加重要。
2. 一次真实的vibe coding:我把“照片归档脚本”交给AI
2.1 从一句模糊需求到第一版可运行脚本
为了让这篇文章有可复现性,我用那天早上做照片归档的例子展示一下完整过程。
我最初给AI的需求描述是这样的:
我需要一个Python脚本,扫描某个文件夹里的所有照片,按拍摄日期排序归档到新目录,目录结构是“年/月”。如果照片没有EXIF数据,就用文件修改时间。需要输出一个统计报告,告诉我总共处理了多少张、其中多少张没有EXIF。
AI第一版很快就出来了,读了一遍逻辑上没大问题:用os.walk遍历、PIL读取EXIF、shutil.move移动文件。但手机里的照片很多是HEIC格式,PIL默认读不了,脚本跑一半直接报错。
我把报错信息完整贴回去,加了一句:“支持HEIC格式,转换不了就跳过并记录下来。”AI补了对pillow-heif的调用,还顺手加了异常处理模块。第二次跑,大部分照片正常归档,但手机截图被并入了普通照片,这不符合我的预期。我继续补约束:“截图和PDF文件不要按日期归档,放到单独的文件夹。”
就这样来回了三轮。最终脚本大概是这样的形态(简化版):
import os from PIL import Image from pillow_heif import register_heif_opener import exifread import shutil from collections import Counter register_heif_opener() SRC_DIR = "./phone_photos" DEST_DIR = "./sorted_photos" SKIP_EXT = {".jpg", ".png", ".jpeg", ".heic", ".heif"} TYPES = {".png": "screenshot", ".pdf": "document"} report = Counter() for root, dirs, files in os.walk(SRC_DIR): for name in files: ext = os.path.splitext(name)[1].lower() # 分类处理逻辑、EXIF读取、按年月归档 ...当然,这段代码远谈不上优雅,但完成任务的效率足够高。全程四十分钟里,我自己写的代码可能不到十行,其他时间都花在观察现象、分析报错、追加条件上。
2.2 返工两次才明白:vibe coding的重点不是生成,而是验收
第一次跑通时我其实挺兴奋的,但冷静下来复盘,发现整个过程中真正起决定作用的时刻,不是AI写出第一版代码的那一刻,而是我抛出问题的那些瞬间。
“这张照片为什么出现在2024512这样的文件夹里”这种糟糕的观察,和“截图应该走分类逻辑而不是时间归档逻辑”这种清晰的指令,带来的结果完全不同。AI生成代码的能力大家都差不多,但能不能把需求约束精确传达给模型,决定了你是在“高效率协作”还是在“无限返工”。
这给我的启发是:vibe coding对使用者的要求其实不低。你至少得能看懂报错信息,知道报错大致指向代码的哪一层;得能设计出一个最小的验证动作,确认修改是对的;还得在AI给出一个表面上没问题、实则隐含缺陷的方案时,具备怀疑的判断力。
我后来跟团队里的人开过一句玩笑:用vibe coding写脚本,就像带一个转正前的实习生写代码。它不是不提要求就能自动做好,而是你需要像真正的师傅一样,给边界、做验收、卡质量。
3. 什么项目能vibe、什么项目必须较真
3.1 先说结论:没有一个项目是纯vibe的,vibe是百分比
我很反感把项目一刀切分成“适合vibe coding”和“不适合vibe coding”。实际经验告诉我,更准确的说法是:不同项目里适合让AI自主发挥的比例完全不同。
我用一个表格来总结目前的判断依据:
| 项目类型 | 适合的vibe比例 | 原因 |
|---|---|---|
| 一次性数据处理脚本 | 很高(70%-80%) | 生命周期短,错误损失小 |
| 内部自动化工具 | 较高(50%-70%) | 可以容忍小缺陷,快速迭代 |
| 单元测试和测试桩生成 | 中高(50%-70%) | 模式比较固定,容易验收 |
| Web原型/前端页面 | 中等(40%-60%) | 视觉可快速验证,但交互逻辑可能藏坑 |
| 生产环境的核心API/业务逻辑 | 低(10%-30%) | 问题影响面大,错误会扩散 |
| 嵌入式驱动和硬件相关 | 很低(0%-20%) | 硬件行为不能靠猜,错误可能损坏设备 |
3.2 判断标准:失败成本、维护周期、黑盒风险
为什么我给出上面这些比例?核心其实是三个问题。
第一个问题是失败成本。一个照片归档脚本跑挂了,最坏的结果是文件移动错目录,还有机会补救。但一条交易流水处理逻辑如果被AI的错误判断绕过,那直接就是资金事故。失败成本越高,就越不该让AI承担核心决策。
第二个问题是维护周期。写一次再也不用改的脚本,让AI怎么写都行,你只要保证一次运行结果正确。但一个团队要长期维护的核心模块,代码的可读性、注释质量、设计模式、处理逻辑的清晰程度,直接决定了半年后接手的人的生活质量。这时候如果AI写出压缩饼干一样的代码,维护成本会暴涨。
第三个问题是黑盒风险。AI生成的代码有没有可能在没有报错的情况下默默做错事?当然有可能。比如一个数据去重脚本,AI用了一个冷门的第三方库,性能很差但输出正确;或者一段并发代码,逻辑上看起来没问题,却存在竞态条件。这些风险在纯脚本场景里你还能通过输出结果快速发现,在硬件交互、账务处理、安全加密等场景里,可能要等到线上出问题才会暴露。
3.3 嵌入式vibe coding:辅助可以,托管不行
这次搜vibe coding相关的热搜词时,我注意到“嵌入式vibe coding”被提到了不少。我在嵌入式开发上不算专家,但以前也做过不少单片机项目,最近还专门用AI辅助写过一小段STM32的传感器读取逻辑,体验可以分享一下。
嵌入式开发和web开发相比,最大的区别是:错误不只存在于代码逻辑层面,还存在于硬件行为层面。AI可以非常流畅地写出一个I2C外设的初始化代码,写得很自信,寄存器地址看起来也对,但芯片手册上的一行注记可能告诉你这个外设在上电后需要额外延时才能访问。AI不知道,它也没办法真机验证。所以嵌入式场景下把整个驱动“托管”给AI,风险非常高。
但这不是说嵌入式就不能用AI辅助。我实际有效的做法是:让AI做中层代码的翻译和拼接,而硬件相关的细节自己对照手册确认。比如我让AI根据我从芯片手册里摘出来的寄存器配置,生成对应的C语言初始化函数,它做得又快又好。再由我人工检查关键时序和硬件引脚定义。这个分工方式,可以把嵌入式开发的效率提升不少,同时保住安全性。
嵌入式的朋友们如果需要尝试vibe coding,建议秉持一个态度:AI能帮你写协议解析、状态机框架、测试工程这些“代码层面”的东西,但“硬件行为层面”的决策必须自己核实。
4. 让Codex这类工具真正出活的提示词与工作流
4.1 需求描述是vibe coding的“第一行代码”
很多人让AI写代码,就丢一句话:“帮我写一个爬虫。”然后抱怨AI写的什么东西,根本不能用。我用下来最大的心得是:需求描述的质量,基本决定了生成代码质量的上限。这玩意儿的价值,不亚于程序员自己写的那一行行代码。
我现在用的需求描述格式比较固定,几乎成了肌肉记忆:
- 背景与场景:这段代码要解决什么场景下的什么问题
- 输入与输出:输入是什么格式、来源在哪里、输出要达到什么结果
- 环境约束:用哪种语言、能不能引入第三方库、运行平台是什么
- 边界与异常:哪些情况不需要处理,哪些情况必须兜底
- 验收标准:我拿什么来判断这段代码是成功的
一个实际的例子,比如我要让AI写一个解析Nginx日志的脚本,我给的提示词大致是:
背景:我有一批Nginx access日志,需要分析其中响应时间超过3秒的请求,统计出Top20的最慢URL。 输入:日志文件路径,每行是标准Nginx combined格式,可能有前端负载均衡造成的重复日志。 输出:一个txt报告,每行是“URL 最大响应时间 平均响应时间 请求次数”,按最大响应时间降序。 环境:Python 3.10以上,建议用pandas尽可能不用其他重型依赖。 边界:日志中“-”表示的字段视为空值,不报错;如果日志格式不符合预期,跳过该行而不是崩溃。 验收:先处理样例文件,确认Top列表和用awk手工统计的结果吻合。
把这一大段话丢给AI,和丢一句“写个脚本分析慢请求”,结果差距是肉眼可见的。后面的几乎是可用代码,前面的经常需要来回拆补。
4.2 上下文投喂:一次只做一个功能模块
第二个心得是控制上下文范围。AI对话模型有一个特点:对话越长,它越容易丢失最早说过的话。这就导致一个经典翻车场景:你让AI写一个带缓存的服务,它写得很顺,十几轮迭代后加了一个新需求,它直接无视了之前约定的接口约束。
我现在的习惯是:一次对话只解决一个功能模块,不要试图在同一个对话里让AI完成整个项目的所有部分。如果一个任务确实需要分模块推进,那就先让AI给出整体模块划分,再针对每个模块新建对话。
还有一种情况,就是中途发现AI行为的“漂移”。比如我一开始规定过“不要用外部数据库”,第五轮后它引入了一个SQLite存储。遇到这种情况,光口头纠正还不够,我会翻出最开始对话里的那条约束,重新贴给它,并且补一句:“这是这次任务不可变更的约束,后续所有代码都要在此基础上设计。”效果要比说“你怎么又忘了”好得多。
4.3 先解释方案再生成代码:把AI当面试者,而不是工具人
这是我想重点推荐的一个小技巧。很多人和AI协作是直接下指令:“写一个函数,实现XX。”我的习惯是强制AI先解释它的思路:
先不要写代码。告诉我你打算分几步解决这个问题,每一步用到什么算法或数据结构,为什么这么设计。我确认方案合理之后,你再开始写。
别小看这一步。它能让代码生成的质量上一个台阶。因为语言模型在你要求它“解释设计”的时候,会主动构建一个更稳定的规划,然后在这个规划之上生成代码。直接跳进代码生成的路径,模型会倾向于“哪里不会点哪里”式地堆逻辑,容易陷入局部错误。
有一次,我让AI写一个带超时重试的HTTP请求库。如果你直接让它写代码,它通常会给一个最基本的try-except循环。但如果你先逼它讲思路,它会说到“指数退避”和“并发安全性”,等到它真的开始写的时候,代码也就是顺着思路展开的。这个差别,就是“面试者”和“工具人”的差别。
审核AI生成代码时,我还会让它自己列出三个潜在风险点。这个玩法很省心,因为模型既然能生成代码,它就大概率知道自己在哪里偷了懒。让它“自首”,有助于提前卡住隐藏问题。
5. 踩坑实录:AI编造API、行为漂移与隐性技术债
5.1 三个我实际遇过的典型坑
vibe coding远没有字面上那么轻松惬意,我在这条路上踩过的坑,整理出来大概能绕咖啡馆一圈。其中最典型、也最坑人的有三个。
第一个坑是AI“一本正经地编造API”。有一次我需要调用某个开发文档中并不存在的函数,AI居然给我写出了一段看起来非常合理、实际上完全无法编译的代码。我第一眼差点没发现,因为函数名拼写、参数风格都符合常规认知。直到本地IDE提示找不到这个符号,才意识到被“幻觉”给骗了。后来我专门问AI:“这个函数在哪个版本之后可用?有没有官方文档来源?”它开始支支吾吾,我才确认这函数根本不存在。这个教训是:AI生成的涉及第三方库或系统API的代码,一定要自己查官方文档验证,不能只看形式对不对。
第二个坑是长对话里的行为漂移。还是拿脚本举例。我一开始规定脚本不安装额外依赖,结果第四轮之后AI自作主张引用了某个包,说“这样可以更快”。在任务边界模糊时,这种自作主张经常发生。原因也很简单:模型在较长的上下文里会逐渐模糊历史约束,尤其是在你不断追加新需求时,早期约束会被挤到注意力边缘。解决方式上面提过:核心约束要么固定放在每轮消息的前面,要么中途重新贴一次,还要明确告诉AI这是不可变更的死约束。
第三个坑是隐性技术债。AI生成的代码往往“能跑”,但处理不了边界情况。比如写文件读取逻辑时,它不会主动考虑文件不存在、文件编码不一致、文件存在但为空的情况。我们需要花力气做“需求翻译”:把代码里的隐含假设全部变成显式条件。我的做法是在提示词里明确要求:“考虑所有可能失败的输入场景,一一给出兜底方案。”这样至少能在源头提高生成代码的健壮性。
5.2 我用来把关的“四道关”流程
踩坑踩多了,自然长了记性。现在我从AI那边拿到代码,不管再赶,都会走一遍“四道关”流程。可以理解为给vibe coding加的一层安全缓冲带。
第一道关:编译与静态检查。不管AI生成的代码是什么语言,先跑一遍编译或语法检查。能用linter就上linter,能用类型检查就上类型检查。大部分语法层面的幻觉和低级错误在这一关就被拦下了。
第二道关:人工diff Review。这一步不是让你从头到尾读一遍AI的全部代码,而是看diff。重点看新增代码的意图是否清晰、是否有意外的大规模改动、有没有引入额外的依赖或者删掉了什么关键逻辑。第一次用vibe coding的人很容易跳过这一步,这是最危险的习惯。AI写的代码,本质上是“另一个开发者”改动的代码,你让它在没有code review的情况下就进入生产环境,想想都可怕。
第三道关:边界测试。我给AI交代任务时,本来就会在验收标准里写几个关键场景,拿到代码后先跑这些场景。比如“文件名没有后缀”“目录不存在”“输入数据全为空”这些容易崩的边界情况。如果测试case没过,我可以把报错和测试数据一起贴回给AI,让它继续改。这一关能拦住大量运行时问题。
第四道关:小范围上线观察。一把代码丢进生产环境之前,先跑一个小批次或者找一个镜像场景验证。如果是脚本任务,就先用一个子集目录试跑;如果是服务,就灰度发布。宁可多花一步观察时间,也不要为“它看着没问题”付出代价。
这套流程听起来朴素,但它在vibe coding模式下非常重要。因为传统编程模式下,代码在你自己手里写出来,边写边理解;vibe coding模式下,代码像是一个“外包团队”交出来的结果,你天然缺少那种“身体记忆”。只有通过流程化验收,才能把质量关补回来。
6. 工具选型、成本与给不同阶段朋友的建议
6.1 我目前顺手的工作搭配
vibe coding不是一个单一工具的事,是一个工具组合的事。目前我身边常驻的AI辅助编程工具是这三类:
第一类是IDE内嵌的辅助编程,比如Cursor和GitHub Copilot。这类适合写代码过程中的补全、重命名、生成测试等效率型操作。它跟我的编辑器融为一体,不打断思路,适合在写代码的中途随时调用。
第二类是对话式CLI工具,比如OpenAI的Codex CLI这样的命令行智能体。这类工具的特点是能真实操作终端,跑命令、看报错、检查文件内容,甚至自己迭代修改代码。我比较喜欢让它在独立的临时目录里干活,把任务丢给它,让它自己去跑,最后把结果拿回来给我Review。它的好处是适合那种“完整任务”而非“零散补全”,比如我前文说的照片归档脚本,就是这种工具完成的。需要注意的是:CLI工具能执行命令,本身权限比较大,建议只在你明确可控的环境里使用,别让它裸奔在生产服务器上瞎折腾。
第三类是通用网页端对话模型,如ChatGPT、Claude。这类模型上下文窗口可以做很大,适合前期方案讨论、需求拆解、复杂知识问答。比如让模型解释一个陌生算法、帮我拆解一个不熟悉的协议格式,效果比较好。但它不直接接触我的代码库,所以我一般只借助它做构思和答疑。
这三类工具在流程上是有配合的:先用网页对话拆方案,再用CLI跑整个实现任务,最后在IDE里Review和调整。这个搭配用下来,效率提升比较明显,也不太会出现“东西写完了但本地跑不起来”的情况。
6.2 关于成本和个人账本
说到vibe coding,不可避免地会谈成本。现在主流AI辅助编程工具,有的是订阅制,有的按token计费,有的免费额度加付费档位。我的整体感受是:它很值,但你不能把所有任务都给它做。
我给自己定了一个粗粒度的成本判断逻辑:估算一个任务如果我手写要花多久,再对比AI辅助预计要花多久,同时考虑往返返工的损耗。凡是“五分钟能手写出来的简单函数”,我没必要折腾AI;凡是“要写几十行以上、模式固定、我需要查一堆文档”的任务,交给AI节省的时间非常可观。
长上下文也是成本里容易忽略的点。有些工具支持把整个仓库塞进上下文,但代价是token消耗大、响应变慢。我的做法是:只把当前任务相关的文件放进去。比如改一个API接口,就让AI只读接口定义文件和对应实现文件,而不是把整个工程都喂进去。这种精准投喂既能省钱,又能提高准确率。
6.3 给不同基础读者的建议
如果你是完全没写过代码的小白。vibe coding对你是双刃剑。好处是,可以用自然语言快速做出小的自动化工具,提升工作效率;坏处是,你很难判断AI给出的方案是否合理,出问题时也没有能力手修。我的建议是:从最轻量的脚本开始,比如批量重命名文件、整理表格数据的简单自动化任务,熟悉“描述→生成→报错→回填”这个循环。不要一上来就去生成一个复杂的全栈应用。
如果你是有经验的程序员。我建议你把vibe coding当成一个高效的“外包团队”。把需求文档写得更清楚一点,把验收标准定得更硬一点,把代码审查做得更细一点,它确实能让你在同样的时间里产出更多东西。但不要因为AI能写就放松对代码质量的底线。
如果你是带团队的负责人。我更建议你把它当作一个流程议题来管理。团队里哪些代码是AI生成的、哪些是人工精写的,需要在Review和文档里明确标记。把AI辅助的代码纳入和普通代码一致的测试、审查、发布流程。红线可以有两种:一种是“禁止让AI直接操作生产环境”,另一种是“核心模块的架构设计必须由人亲手完成”。有了明确红线,vibe coding才能真正成为生产力工具,而不是埋在工程里的隐患。
最后再分享一点个人体会。用AI辅助编程到现在,我越来越觉得它像是一种“上手门槛很低、精通门槛很高”的技能。你可以两分钟让AI写一个爬虫,但真正决定产出质量的,永远是你对目标的理解、对系统的判断、对质量的把控。那杯咖啡之后,我照着同样的方法又做了好几个工具,有顺手的也有翻车的。顺手的那些,大概率是我把需求描述得足够清楚;翻车的那些,几乎都是我自己偷懒、跳过了验收流程。所以别把vibe coding当成不用动脑的魔法,把它当成一个能力放大器。你自己的水平,决定了放大出来的是精品还是事故。