
“vibe coding 一时爽维护火葬场”。这句话我过去几个月体会得淋漓尽致。用自然语言让模型帮我写功能十分钟能出一个能跑的版本那种“人机合一”的流畅感确实容易上瘾。但等代码量堆到几千行、组件之间开始互相牵扯、改一个前端弹窗能把后端接口带崩的时候我才意识到vibe coding 总是失控问题多半不在模型而是我根本没搞懂工程化到底在解决什么问题。这个认知是被一个 24.5 万星的开源仓库点醒的。不是模型不行是我缺了它沉淀下来的那一整套系统设计思维。如果你也在 vibe coding 的爽感和失控之间反复横跳这篇内容应该能帮你少走几个月弯路。我会从症状聊到病根再把我实际用下来的六条“反失控”经验完整分享出来全程可操作。1. vibe coding 的爽与失控是同一枚硬币的两面1.1 从“一句话生成功能”到“三小时修 bug”的真实体验先说说我自己的真实经历。上个月我想给一个内部工具加一个数据导出功能对着模型说了一句“加个按钮点击后把当前表格导出成 Excel”三十秒不到代码出来了点击、下载、打开文件内容完全正确。那一刻真的觉得编程已经死了人人都是产品经理。这种体验在最初两周特别上瘾。新功能一个接一个加UI 调得飞快接口也能自动拼出来。我当时甚至觉得以后写代码根本不需要再“设计”什么了想到什么直接让模型生成就好。但问题在第三周集中爆发。先是导出的 Excel 里日期格式和旧文件对不上我让模型改结果它把生成 Excel 的库换掉了旧文件的样式全部失效。接着是权限校验逻辑模型“贴心”地加了一层缓存结果管理员的权限变更要等十分钟才生效。最崩溃的一次我只是想加一个空状态提示模型却把整个数据请求的链路重写了线上直接报 500。我统计过那段时间我花在“让模型理解我以前写了什么”上的时间比它帮我写新功能的时间还多。后来我翻 Git 提交记录发现项目在两周内新增了 4000 多行代码但真正被保留下来、没有返工的只有不到三分之一。1.2 失控的三层表现代码、依赖、需求这不是个例。我观察过团队里其他喜欢 vibe coding 的同事失控几乎都沿着同一条路径发生。第一层是代码失控。AI 生成的代码风格不稳定同一类工具函数可能同时存在三个版本命名一会儿用 camelCase 一会儿用 snake_case。最麻烦的是它倾向于“一次性生成一大坨”而不是像有经验的工程师那样小步拆分。你很难从几百行的函数里定位到底是哪一段逻辑出了问题。第二层是依赖失控。模型会为了一个小功能引入一个很大的库。我之前遇到过为了让一个字符串格式化功能更“优雅”它偷偷装了一个包结果这个包和项目原本的 lodash 版本冲突整个构建直接挂掉。这种依赖层面的问题最难排查因为错误信息往往出现在完全不相干的模块里。第三层是需求失控。这是最隐蔽的。当项目里没有清晰的 TODO、没有设计文档、没有验收标准时vibe coding 很快就会“自作主张”。模型会基于它对“一个导出功能应该长什么样”的概率理解去填充你没说的细节。而这些细节十有八九不是你真正想要的。于是你和模型之间会陷入“改了又改、越改越乱”的循环。这三层失控叠加起来就形成一个观感vibe coding 只在两种情况下好用——代码量极小的一次性脚本或者你对整个系统已经有了极其清晰的边界把控。2. 病根不在模型到底在哪2.1 模型的本质是“概率逼近”不是“工程承诺”很多人把失控的锅甩给模型能力说“要是有了更强的模型这些问题就自动消失了”。这话我不同意。从原理上看Transformer 这类模型做的事情是基于海量代码学习词汇和结构之间的概率关系然后在你给出一段 prompt 时预测最可能的下一段 token。它本质上是一个“概率逼近器”它在做的不是“保证这个功能在工程上正确”而是“这段代码在统计意义上最像人类程序员会写的代码”。这就意味着模型输出的代码是在“很多网友公开代码”的平均水平附近浮动。它擅长那些网上有大量样本的、约定俗成的写法但一旦你的项目有独特的业务规则、特有的历史包袱、微妙的边界条件模型就开始“凭感觉编”。它不知道你三个月前为了兼容某个旧系统做了什么妥协它也不知道你现在的生产环境上有哪些暗坑。所以模型不是不够聪明而是它没有一个“像你一样理解项目”的入口。你给它的上下文越少它越只能靠通用经验来猜。猜中的概率在你项目复杂度上升后会急剧下降。2.2 vibe coding 最大的误区把临时方案当长期架构我反思自己失控的根源是一个错误的心态把“能跑”当成了“做完了”。Vibe coding 天然鼓励快速产出这本身没错。原型验证阶段、黑客松项目、个人小工具快速跑通比设计方案重要得多。但问题是很多人直接把这个节奏带进了长期项目。前端框架随便选后端结构不划分异常处理全部靠模型自动生成数据库表设计完全交给模型的“感觉”。结果就是项目第一次能跑时看起来一切正常。但从第二次改动开始你就要为当初省的每一步设计买单。改一个字段要连带改十个文件因为当初没有做参数收敛加一个接口要复制三段几乎一样的鉴权代码因为当初没有做中间件抽象出了一个线上 bug要沿着五六层嵌套函数一层一层往里钻因为当初没有做模块边界。说白了vibe coding 失控的病根是你把“临时方案”当成了“最终架构”。模型只是忠实地执行了你的这个错误决策。它不会主动说“这个设计只能支撑三天”。2.3 “模型”在不同领域从来都不是银弹还有一个认知偏差值得点一下。“模型”这个词本身有太多含义。机器学习里有 Transformer 模型、扩散模型、世界模型工程上有电机模型、温控系统的 FOPDT 模型管理上有最大覆盖模型。这些“模型”都是对现实某种程度的抽象和简化从来没有任何一个模型是“完整”的。当你在 vibe coding 时使用“模型”你用的其实是一个经过压缩的、平均化的“程序员行为模型”。它对你项目的理解远不如你对它的理解那么完整。所以指望模型自动搞定架构、自动管理依赖、自动判断业务边界本来就超出了它作为“模型”的物理上限。想明白这一点你就不再跟模型较劲了。你要做的是把自己变成一个能补全模型短板的人你负责给系统画边界、定规则、控依赖模型负责在边界内高效生成。换句话说控制权必须在人手里。3. 24.5 万星仓库的启示系统化思维才是解药3.1 超高星仓库里藏着的不是代码是“反脆弱”的工程经验那个点醒我的 24.5 万星仓库名字我就不具体点了主题是“系统设计入门”System Design Primer。这类仓库能拿到这么多 Star不是因为里面的代码多炫酷而是它把软件工程里那些“看不见摸不着但决定项目生死”的东西整理成了一套可以学习的方法论。我翻它目录时的第一感受是它讲的全都是 vibe coding 最不爱讲的“硬知识”——容量估算、一致性哈希、分布式事务、缓存策略、API 设计、数据库选型。这些东西在你写 CRUD 的时候好像都用不上但你的项目一旦开始承担真实流量、真实业务、真实迭代每一项都是决定你能不能“睡得着觉”的关键。我当时就明白了一个道理高 Star 仓库的本质是大量从业者用血泪换取的经验凝练。它能获得几十万人的认可说明这些工程实践不是少数人的教条而是被反复验证过的“避坑指南”。Vibe coding 爽归爽但它恰恰绕过了所有这些经验。你把工程上的“边界约束”全丢掉只让模型自由发挥那失控就是必然的而不是偶然的。3.2 从仓库结构里反推出的“反失控”方法论我把这个仓库的目录结构反复读了几遍发现它本质上是一个“多层防御体系”每一层都在回答一个具体问题每一层都在压缩后续出错的概率。第一层是概念层先把术语和原理讲透。这对应到你做项目就是要在动代码之前先想清楚“这个系统到底有几部分、每部分的职责是什么”。第二层是设计层容量怎么估算、数据怎么存储、服务怎么拆分。这对应着你画架构图、设计数据模型、约定接口契约的过程。第三层是实现层缓存怎么用、消息队列怎么接、异常怎么处理。这对应到你写具体业务代码时要遵循的那些规范。第四层是运维层监控、日志、告警、回滚。这对应到项目上线后的可观测性。每多一层的约束系统就更稳一分。反观 vibe coding它的问题是直接跳过了前三层从“实现层”开始而且实现层也没有任何团队约定。你让一个模型去写它不了解业务背景的代码然后期望它能自动形成架构、自动做好边界、自动防御未来可能出现的风险这等于你把方向盘、油门、刹车全交给了一个刚拿到驾照的新手。所以那个 24.5 万星仓库真正教会我的不是某个具体技术而是一种“分层设防”的思维方式。Vibe coding 可以用但它必须被装进这套防御体系里而不是独立存在。3.3 为什么这么多人需要“把病根说透”再往深一层想这类仓库能火到 24.5 万星本身就说明了一个问题——行业中“会写代码但不理解系统”的人太多了。以前我们要独立负责一个模块得从前端写到后端再写数据库脚本跑通了还要看看日志。这个过程倒逼你必须理解系统是怎么串起来的。但现在有了 AI 辅助编程很多基础薄弱的开发者可以直接跳过“理解完整链路”这一步让模型把代码全部生成出来。这不是否定 AI 辅助编程的价值而是说如果你没有系统思维作为底盘AI 帮你写的每一行代码都可能是在给未来埋雷。24.5 万星仓库本质上在做的就是把这些“病根”掰开揉碎讲清楚。它告诉你不要等到系统崩了才去补系统设计不要等到代码改不动了才想去理清架构更不要以为把一句话需求丢给模型就真的能拿到一个可以长期维护的系统。4. 实操落地六条“反失控”实践4.1 划定边界原型可以 vibe生产必须收敛我实践下来最有效的一条是把项目分成两种状态“原型态”和“生产态”。原型态的定位是验证想法。这时候随便让模型发挥代码多乱都无所谓只要能快速验证“这个功能用户认不认可”“这个交互顺不顺畅”。我自己做原型时甚至不建 Git 仓库写废了就删掉重来。但一旦决定要把原型固化成正式功能就必须切换成“生产态”。这意味着 style 上要有规范结构上要有分层数据上要有校验异常上要有兜底。这个切换动作必须由人来触发不能由模型自动完成。我现在的做法是当一次 vibe coding 的产出要进入主分支时强制自己先做一轮“契约审查”把模型生成的代码里不符合当前项目约定的地方全部改掉。这就像写文章初稿可以意识流但定稿必须经过修改。Vibe coding 负责给你一个足够好的初稿你负责把初稿改成能拿得出手的定稿。两者都不该缺席。4.2 全局上下文用全局 md 文档给 AI 立规矩模型之所以“失控”很多时候不是它不会写而是它不知道你的规则。我现在的做法是在项目根目录维护一个AGENTS.md或CLAUDE.md这样的全局说明文档把项目的技术栈、目录结构、命名规范、常用模式、禁忌事项全部写进去。举例来说我在一个 Node.js 项目里写的是# 项目约定 - 技术栈Express 4 MySQL 8禁止引入 Mongoose 或 TypeORM。 - 目录结构路由放在 src/routes业务逻辑放 src/services数据库操作放 src/repositories。 - 命名规范文件名小写中划线常量 UPPER_SNAKE_CASE函数名动宾短语。 - 错误处理所有 service 层错误必须转成 AppError禁止直接 throw new Error。 - 时间字段统一使用 UTC 存储返回给前端之前再转本地时区。 - 鉴权方式使用项目现有的 jwt 中间件禁止另起一套 session。每次让模型生成代码之前我都会在 prompt 里附上这份文档的地址或者直接把关键部分贴进对话。效果立竿见影模型输出风格立刻就能对齐项目返工率至少降了一半。很多人忽略了这个“给模型喂规则”的过程总觉得模型应该自己会。但它真的不会。你不说清楚它就只能靠猜。全局 md 文档就相当于给 vibe coding 立了一份“基本法”让它在你画的圈里跳舞。4.3 系统设计思维先画图再写码哪怕只画三分钟我以前的习惯是拿到需求就开写写完再想架构。现在我会强迫自己先花三分钟画一张粗糙的图哪怕是手写几个方块都行。这个动作的目的是把“系统的边界”在脑子里显性化。画图的时候要想清楚几个问题入口是谁、出口是谁、需要哪些数据、数据存在哪、谁调用谁、谁不能调用谁。这几个点一旦明确再让模型去生成代码你就可以把上下文描述得很具体。我之前让模型写代码总是失控后来发现是因为我自己都没想清楚边界模型自然只能瞎猜。举一个实际例子有一次我要加一个“批量导入用户”的功能。以前我直接说“帮我实现批量导入”模型会给你写一个全流程上传、解析、校验、落库、返回结果。听起来很好但它会把解析逻辑和落库逻辑混在一起还会自动处理重复数据这正是我不想要的。现在我画完图之后prompt 会变成“只实现 CSV 解析模块入参是文件路径返回结构化的行数据数组不包含去重逻辑校验逻辑交给上一层 service 处理。”模型立刻就能写出一个边界清晰、好测试、好复用的模块。这不是说模型变聪明了而是我作为人的部分变靠谱了。我把复杂度挡在了自己这一侧模型只需要在一个很小的上下文里完成任务出错的概率自然就低了。4.4 代码仓库卫生Git 管理是最后一道保险Vibe coding 的另一个隐患是“没有存档点”。你让模型改了一版代码跑起来看着没问题但三天后发现少了一个边界处理而你根本找不到上一版是怎么写的。所以我现在的铁律是所有项目一律纳入 Git 管理哪怕只是临时原型。具体操作上我推荐做到三点。第一每次让模型做一次完整的代码变更前先打一个提交点。这样万一改坏了一条git checkout .就能回到安全状态。第二遇到“模型越改越乱”的情况直接用git log找到能跑的版本。这个命令就是你的后悔药。第三多用分支。我不会直接在 master 上让模型改东西而是开一个feature/xxx分支等确认没问题再合并。有同事问我说“git 回退会不会把新功能也搞丢”这里要澄清一下git revert是产生一个新的提交来抵消旧提交历史不会丢git reset才是把 HEAD 指到旧提交有丢失新提交的风险。你用git revert做回退其实是最安全的。Git 这块不需要多高深掌握clone、add、commit、push、log、revert这六个命令就足够给 vibe coding 上一道保险了。我个人还会用 GitHub/Gitee 这类代码托管平台的“私有仓库”作为云端备份。本地改乱了大不了从远端重新拉一份。这跟仓库出入库管理的思路一样入库存的是稳定版出库的修改随时可以被回滚。代码这种资产也需要一套“出入库”流程。4.5 依赖管理别让 AI 帮你“随便装包”模型在生成代码时最不拿手的就是依赖治理。它经常会因为觉得“用某个库更方便”就直接在代码里引入新依赖但它不知道这个库的维护状态、许可证、体积、和你现有依赖是否冲突。我之前在 Java 项目里被坑过一次模型为了解析一个 JSON 字段引入了某个小众库结果它传递依赖里包含一个旧版本的日志组件直接压过了项目里原本的 slf4j 绑定导致日志神秘丢失。排查了整整两天才定位根源。从此以后我定了一条规矩模型生成代码时默认只允许使用项目里已有的依赖非要引入新包必须由我手动评估后再加。如果你是 Java 后端Maven 仓库管理尤其要小心。建议在settings.xml里把国内镜像配好比如阿里云仓库既能加速下载也方便统一管理仓库源。配置方式大致是这样mirrors mirror idaliyun/id mirrorOfcentral/mirrorOf nameAliyun Central Mirror/name urlhttps://maven.aliyun.com/repository/public/url /mirror /mirrors配置多个镜像时要注意mirrorOf的匹配规则。如果你把所有仓库都*匹配到同一个镜像某些私服或者特殊仓库里的内部包可能就拉不到了。我的建议是中央仓库走国内镜像私服用自己的地址用逗号分隔匹配规则。核心原则是依赖的加载路径必须可控、可追溯、可重复这一点恰恰是 vibe code 最不关心的。4.6 测试与回归唯一能拉住失控列车的手刹最后一条也是最难坚持的一条给关键路径写测试。很多人觉得 vibe coding 就是图快再写测试不是更慢了吗但我的实测结论正好相反没有测试的项目改一次崩一次每个功能都要手工回归有测试的项目模型改完代码你只需跑一遍测试就知道有没有破坏旧功能反而省时间。我不建议一上来就追求什么 100% 覆盖率那对 vibe coding 项目来说不现实。我的做法是挑出项目里最核心、最容易出问题的三条路径比如登录鉴权、支付流程、数据导入导出给它们各写一个端到端测试。这三条路径稳了项目的底就不会漏。模型生成代码之后我会先跑一轮已有的测试如果变红就让模型去看测试失败的信息自己修。这个过程非常有价值因为它就像给模型加了一个“即时反馈器”让它不会再靠猜去写代码而是以“让测试通过”为目标。测试就是你和模型之间最客观的验收标准。5. 常见问题与排查经验5.1 典型失控症状与对应解法速查我把自己和团队成员踩过的坑整理成一张表方便你按图索骥。失控症状病根解决手段模型改 A 功能导致 B 功能挂掉缺少测试与模块边界给关键路径补端到端测试拆分模块明确每个模块的对外接口同一个功能出现多套实现缺少全局上下文约束在 AGENTS.md 里写明“统一使用哪个工具函数”并在 prompt 里强调代码能跑但看不懂改不动函数过长、职责混乱要求模型将函数拆成小函数每个函数只做一件事附上注释依赖包冲突构建失败模型擅自引入新库默认禁止新增依赖新增必须由人工评估越改越乱无法回退没有存档点每次让模型改代码前先 git commit用 revert 而非 reset模型自作主张加需求Prompt 里需求不明确写出明确的验收标准列出“不要做什么”这张表不是标准答案但大概率覆盖了你大多数失控场景。核心思路就一句话出了问题先去查“是不是人这边少了约束”而不是急着换更强的模型。5.2 我在实际使用中的几个私藏技巧第一个技巧让模型先“说方案”再“写代码”。我以前总是一上来就让模型直接生成完整代码现在我会先让它给我一个实现方案的简要描述我来判断这个方案会不会引入新依赖、会不会破坏现有结构。方案不对就继续磨方案对了再让它落代码。这就像一个简单的可行性审查能把 80% 的方向性错误消灭在生成之前。第二个技巧用“负面清单”来约束模型。很多人给模型的指令全是“要做什么”但我发现“不要做什么”往往更关键。比如“不要修改 existing 函数”“不要加缓存”“不要做去重”“不要自动处理错误直接抛给上层”。这些负面约束能极大压缩模型的“自由发挥空间”失控概率直线下降。第三个技巧定期做“代码走查”每天抽半小时翻一遍模型当天生成的代码。不用真的一行一行读重点是看目录结构有没有长歪、有没有多出不认识的依赖、有没有复制粘贴的重复代码。半小时的走查能避免未来八小时的重构。我的经验是vibe coding 的失控都不是突然发生的它是每天都在“多一点点”地发生。你只要每天花半小时踩住刹车车就翻不了。第四个技巧遇到反复改不好的问题别在一个对话里死磕。模型在长对话里会逐渐丢失早期的上下文尤其是上下文窗口被塞满之后表现会明显下滑。我现在的做法是一个功能如果来回改了四五轮还没收敛就新建一个对话把需求、相关代码路径、测试结果打包重新喂一遍。很多时候换个“状态”就解决了旧对话里积累的混乱反而会成为干扰。5.3 为什么我不再抱怨模型而是调整自己的工作流我经常看到有人在社区吐槽“这模型怎么这么蠢让它改个 bug 越改越多”。如果放在半年前我也会加入吐槽。但现在我会先问自己一个问题我有没有把这个 bug 的完整背景、复现步骤、以及与上下文的关系讲清楚大多数情况下答案是没有。我只给了模型一句“修一下这个 bug”然后期望它像读心术一样理解我项目里错综复杂的依赖和业务逻辑。这不叫 vibe coding这叫“许愿 coding”。调整工作流之后我发现自己跟模型之间的配合明显顺畅了。我不再指望模型比我更懂我的项目而是把它当成一个执行力很强但需要明确指令的伙伴。我负责判断方向、设定边界、验收结果它负责在边界内高效输出。这个转变本质上就是把系统设计思维重新请回来只不过实现系统设计的方式从“手写所有代码”变成了“手动设定规则、让模型填充代码”。6. 个人经验给同样在失控边缘的你的几点真心话如果你现在正处于“vibe coding 一时爽项目维护火葬场”的阶段我想说问题不在你用的模型强不强也不在你天赋够不够而在于你还没有把工程化的护栏装进你的工作流里。我现在的状态是vibe coding 依然在用而且用得很频繁但我会用全局文档给它立规矩用 Git 给它存档用测试给它兜底用系统设计给它画边界。模型负责速度我负责方向。这个组合到目前为止是我试过的最稳定的方式。最后分享一个小技巧下次让模型生成代码之前你只加上一句话——“请先查看项目根目录的 AGENTS.md 和现有代码风格严格遵循项目已有约定不要引入新的依赖不要修改与本次需求无关的文件。”就这一句话能让你的 vibe coding 体验发生质的改变。去试试看然后告诉我效果如何。