ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vibe Coding与智能体驱动全栈开发:SDD规格驱动实战指南

Vibe Coding与智能体驱动全栈开发:SDD规格驱动实战指南 1. 从“写代码”到“描述意图”Vibe Coding 到底改变了什么第一次听到 Vibe Coding 这个词是在一个做独立开发的朋友群里。有人甩了张截图说自己花了一个下午靠“跟 AI 聊天”把一个带用户登录、数据看板、支付回调的全栈小工具跑通了代码量不到两百行而且他本人已经快两年没正经写过前端。群里当时就炸了一半人觉得他在吹牛另一半人默默去试了。我自己试下来的结论是Vibe Coding 不是“AI 帮你补全代码”这么简单它真正改变的是开发者的工作重心——从“逐行实现逻辑”转移到“描述清楚意图、约束好边界、验证产出结果”。这个转变听起来轻飘飘实际落地时坑非常多。很多人第一次尝试就翻车不是因为模型不行而是因为脑子里还是“我要写一个函数”的思维而不是“我要一个满足某某条件的行为”。所以这篇内容我想聊的是把 Vibe Coding 和全栈开发、智能体Agent驱动、工程化这几件事串起来之后一套能真正跑起来的开发范式。它适合几类人一是想用 AI 提效但总感觉“差点意思”的全栈开发者二是正在搭智能体应用、需要把 LLM 能力接进真实业务系统的工程师三是对 SDDSpec-Driven Development规格驱动开发这类新提法好奇、想知道它到底是不是换皮概念的人。我会尽量把“为什么这么设计”讲透而不是只丢一堆提示词模板给你抄。先说清楚一个前提Vibe Coding 的核心不是“ vibe ”感觉而是“把感觉翻译成可验证的规格”。你越是能把模糊需求拆成明确的输入、输出、约束和验收标准AI 产出的代码就越稳。这一点和传统工程里的需求评审本质一样只是执行者从人变成了智能体反馈循环从“天”缩短到“分钟”。2. 智能体驱动开发与传统 AI 辅助编码的本质差异2.1 补全式辅助的天花板在哪里大多数人最早接触的 AI 编码是 IDE 里的补全你写个函数名它猜你想干嘛给你补一段。这种方式在“局部、模式化、上下文清晰”的场景下非常好用比如写个 CRUD、解析个 JSON、拼个 SQL。但一旦任务跨越多个文件、涉及状态管理、需要前后端约定接口补全式辅助就开始力不从心。原因很直接补全模型看到的是光标附近的局部上下文它不知道你的数据库 schema 长什么样不知道前端路由怎么配更不知道你团队约定的错误码规范。你让它补一个 API 调用它可能给你编一个看起来合理但根本不存在的字段名。这不是模型笨是信息不够。我踩过最典型的一个坑让补全工具写一个“根据用户 ID 查订单列表”的后端接口它刷刷刷写完了字段名用的是userId而我数据库里是user_id前端约定传的是uid。三个地方三种命名跑起来直接 500。这种错误补全工具自己发现不了因为它压根没看到全局。2.2 智能体为什么能跨过这道坎智能体和补全工具最大的区别是它有行动能力。它可以主动去读你的项目文件、查数据库 schema、跑测试、看报错、然后根据结果调整。这就把一个“单次预测”变成了“感知—决策—行动—验证”的闭环。举个具体例子。同样是“加一个订单查询接口”一个配置好的智能体拿到任务后会做这几件事先扫描项目目录识别出这是 Express Prisma 的技术栈读schema.prisma拿到真实的字段名找到现有的路由文件模仿已有的错误处理中间件写法写完代码后自己跑一遍npm run build和已有的测试用例如果报错读报错信息再改。整个过程你只需要在关键节点确认一下。这个差异带来的效率提升不是线性的。补全工具帮你省的是“打字时间”智能体帮你省的是“上下文切换和验证时间”。后者在复杂项目里往往占大头。2.3 一个对比表看清两者边界维度补全式辅助智能体驱动上下文范围光标附近数百行整个项目 外部工具能否执行命令否是读文件、跑测试、调 API错误处理依赖人发现自主读报错并重试适合任务局部、模式化跨文件、多步骤、需验证人的角色逐行审查定义规格 验收结果典型翻车点字段名/接口不一致规格模糊导致方向跑偏看懂这张表你就明白为什么“智能体驱动”不是营销词。它对应的是真实的能力边界变化。但也要注意最后一行智能体最大的风险从“写错代码”变成了“理解错需求”。规格没定清楚它跑得越快偏得越远。3. SDD 规格驱动把“感觉”翻译成智能体能执行的契约3.1 为什么提示词工程不够用了很多人做 Vibe Coding 的第一反应是去收集“神级提示词”。我早期也这么干存了一堆模板结果发现换个项目就不灵。问题在于提示词是一次性、无状态的而真实开发是多轮、有状态的。你今天让 AI 写了个登录接口明天让它加个“记住我”功能它根本不知道昨天那个接口长什么样除非你每次把全部上下文重新喂一遍。SDD 的思路就是解决这个不靠临时提示词而是维护一份结构化的规格文档作为人和智能体之间的契约。这份规格不是给人看的 PRD 那种长篇大论而是精确到智能体能直接执行的粒度。3.2 一份可执行的规格长什么样我现在的习惯是每个功能模块维护一个spec.md结构大致是这样## 功能用户订单列表查询 ### 输入 - 请求GET /api/orders?uid{uid}page{page}size{size} - uid: string, 必填, 用户唯一标识 - page: number, 可选, 默认 1 - size: number, 可选, 默认 20, 最大 100 ### 输出 - 成功: { code: 0, data: { list: Order[], total: number } } - 失败: { code: 非0, msg: string } ### 约束 - 数据库表: orders, 字段 user_id 对应入参 uid - 只返回 status ! deleted 的记录 - 按 created_at 倒序 - 需要鉴权从 JWT 中取 uid忽略入参中的 uid防越权 ### 验收标准 - 传入不存在的 uid 返回空列表而非报错 - page 超过总页数返回空列表 - size 超过 100 时按 100 处理这份规格的价值在于智能体读完它不需要猜任何东西。字段名、边界条件、安全约束全在里面。而且它是可版本控制的改了哪里一目了然出问题能回溯。3.3 规格和代码谁先谁后这里有个反直觉的点。传统开发是“先写代码文档后补”SDD 是“先写规格代码由智能体生成”。但规格不是凭空写的我通常的做法是先和智能体对话让它帮我一起把规格理清楚。比如我会说“我要做一个订单查询接口技术栈是 Express Prisma你先别写代码先帮我列一份规格包括输入输出、边界条件、安全约束。” 智能体会反问我一些问题比如“要不要分页”“要不要鉴权”“软删除怎么处理”。这一轮对话下来规格就成型了。然后我再让它基于规格生成代码。这个顺序很关键。如果直接让它写代码它会默认一堆你没想过的假设先写规格等于逼着双方把假设摆到台面上。4. 全栈场景下的智能体编排前后端如何不打架4.1 单智能体做全栈的局限理论上你可以用一个智能体搞定前后端。实践中我试过问题出在上下文污染。前端关心的是组件状态、路由、样式后端关心的是数据校验、事务、鉴权。当这些信息全塞进一个上下文窗口智能体很容易把两边的关注点混在一起写出“前端直接拼 SQL”这种离谱代码。更现实的问题是 token 消耗。一个中等规模的全栈项目把所有文件读一遍可能就几万 token 了每轮对话都带着成本和延迟都受不了。4.2 多智能体分工的三种编排模式我现在常用的是多智能体分工主要有三种编排方式各有适用场景模式一串行流水线。规格智能体先产出接口契约后端智能体按契约实现 API前端智能体按契约实现调用。适合接口边界清晰的项目。优点是职责分明缺点是前端要等后端定完契约才能动。模式二契约先行 并行。先由一个“架构智能体”产出 OpenAPI 或 TypeScript 类型定义前后端智能体拿着同一份契约并行开发。这是我现在最常用的因为契约一旦定死两边互不干扰最后联调时接口对得上。模式三主从协调。一个“协调智能体”负责任务拆解和进度管理下面挂若干“执行智能体”。适合大型、多模块项目但协调逻辑本身很复杂小项目用不上容易过度工程。4.3 契约文件是整个编排的枢纽不管用哪种模式契约文件都是核心。我一般用 TypeScript 的types.ts或者 OpenAPI 的 yaml 作为唯一真相源。前端智能体读它生成 API 调用层和类型后端智能体读它生成路由和校验逻辑。这里有个实操细节契约文件要足够具体不能只写data: object。我见过太多项目契约写得含糊结果前端以为data是数组后端返回的是对象联调时才发现。我的做法是让智能体在生成契约时把每个字段的类型、是否可选、示例值都写全宁可啰嗦。// contracts/order.ts export interface OrderItem { id: string; // 订单ID如 ord_123 userId: string; // 用户ID amount: number; // 金额单位分 status: pending | paid | shipped | deleted; createdAt: string; // ISO 8601 } export interface OrderListResp { code: number; data: { list: OrderItem[]; total: number; }; }这份契约一旦定下来前后端智能体各自开工最后拼起来基本不会有类型层面的冲突。剩下的就是业务逻辑的验证。5. 让智能体自己跑起来工具链与执行环境搭建5.1 智能体需要哪些“手脚”一个只会聊天的智能体做不了 Vibe Coding它必须能操作真实环境。核心能力包括读写文件、执行 shell 命令、调用 HTTP 接口、查询数据库、跑测试。这些能力通常通过“工具Tool”的形式挂载给智能体。不同平台的实现方式不一样。有的平台内置了文件系统和终端工具你开箱即用有的需要你自己写工具函数再注册进去。我个人的经验是优先用平台内置的工具因为它们的权限管理和错误处理通常更成熟自己写的工具很容易在边界情况上翻车。5.2 执行环境必须隔离这是我最想强调的一点。让智能体直接在你的开发机上跑命令风险极高。它可能误删文件、改错配置、甚至把测试数据写进生产库。我现在的标准做法是每个任务跑在一个独立的容器或沙箱里挂载项目代码的副本网络访问按需开放。具体配置上我会限制几件事文件系统只挂载项目目录不挂载家目录数据库连接指向本地测试库绝不连生产网络只允许访问必要的包管理源和 API。这些限制看起来麻烦但能避免 90% 的“智能体闯祸”场景。5.3 一个最小可用的执行循环抛开具体平台一个智能体驱动的开发循环大致是这样读取规格文件理解任务扫描项目结构识别技术栈和现有约定生成或修改代码执行构建/测试命令读取输出判断是否通过不通过则回到第 3 步通过则输出变更摘要这个循环里第 4 步是灵魂。没有验证的智能体就是“盲写”有了验证它才能自我纠错。我实测下来加上构建和测试验证后智能体一次通过率能从 40% 左右提升到 75% 以上剩下的 25% 通常需要人介入调整规格。6. 实测中那些规格没写清楚导致的翻车6.1 边界条件永远是重灾区规格里最容易漏的是边界条件。我让智能体写过一个“根据关键词搜索商品”的接口规格里只写了“返回匹配的商品列表”。结果它实现出来关键词为空时返回全部商品关键词超长时直接拼进 SQL 导致性能问题特殊字符没转义。后来我在规格里补了一段### 边界条件 - 关键词为空或纯空格返回空列表不查库 - 关键词长度 50截断到 50 - 关键词含 SQL 特殊字符使用参数化查询禁止字符串拼接 - 结果超过 100 条只返回前 100 条并标记 hasMore补完之后重新生成问题全没了。这件事让我意识到智能体不会主动帮你考虑边界它只会实现你写出来的东西。规格的完备性直接决定产出的健壮性。6.2 安全约束必须显式声明另一个大坑是安全。智能体默认假设“调用方是善意的”。比如它生成的查询接口很可能直接信任入参里的uid而不去校验这个 uid 是不是当前登录用户的。这就是典型的越权漏洞。我的做法是在规格里专门开一节“安全约束”把鉴权、越权、注入、限流这些写清楚。比如### 安全约束 - 所有涉及用户数据的接口uid 必须从 JWT 解析忽略请求体/查询参数中的 uid - 所有数据库查询使用参数化禁止拼接 - 单 IP 每分钟限流 60 次 - 敏感字段如手机号返回时脱敏这些约束写进去之后智能体生成的代码会主动加上对应的中间件和校验逻辑。不写它就当没这回事。6.3 依赖版本冲突的排查链路有一次智能体生成的代码本地跑不起来报了一堆 peer dependency 冲突。我当时的排查过程是这样的先看报错信息发现是某个 UI 库要求的 React 版本和项目里的不一致然后让智能体读package.json确认版本它建议升级 React但升级后另一个库又不兼容最后我手动锁定了 React 版本让智能体改用兼容的 UI 库版本。这个过程暴露了一个问题智能体对依赖生态的“时效性”认知可能滞后。它训练数据里的版本组合可能和当前最新版本有冲突。所以涉及依赖升级时我现在的习惯是让它先跑npm ls看清楚依赖树再决定怎么改而不是直接改package.json然后祈祷。7. 把 Vibe Coding 接进真实工程流程的几个硬约束7.1 代码审查不能省智能体生成的代码我坚持逐行审查尤其是涉及数据库、鉴权、支付的部分。原因很简单它写得越流畅你越容易放松警惕。我见过智能体生成的支付回调逻辑看起来完美但漏了签名验证直接就是个漏洞。审查的重点我一般放在三处一是安全相关鉴权、校验、脱敏二是边界处理空值、超限、异常三是和现有代码的一致性命名、错误码、日志格式。这三点过了基本就稳了。7.2 测试是智能体的“验收官”前面提到测试在智能体循环里的作用。这里补充一点测试用例本身也应该由规格驱动。我会在规格里写清楚验收标准然后让智能体根据验收标准生成测试用例再让另一轮智能体去实现代码让测试通过。这样测试和实现是解耦的避免了“自己写测试自己通过”的假象。实测下来这种“测试先行”的智能体流程产出的代码质量明显高于“直接写实现”。因为测试用例把规格里的验收标准固化下来了实现智能体有了明确的靶子。7.3 版本控制和回滚策略智能体一次可能改十几个文件如果不用版本控制出问题很难回滚。我的做法是每个智能体任务开一个独立分支任务完成后人工审查再合并。这样即使智能体改崩了直接丢弃分支就行不影响主干。另外我会让智能体在每次任务结束时输出一份变更摘要说明改了哪些文件、为什么改、有没有未解决的问题。这份摘要比 git diff 更易读审查时能快速抓住重点。8. 我踩过的三个印象最深的坑8.1 规格太粗智能体自由发挥早期我图省事规格就写一句话“做一个用户注册功能。” 结果智能体给我生成了一个包含邮箱验证、手机验证、第三方登录、密码强度校验的完整系统代码量巨大还引入了三个我没听说过的依赖。我要的只是一个简单的邮箱密码注册。这个坑的教训是规格的粒度要匹配你的真实需求。你写一句话智能体就按它的“最佳实践”发挥而它的最佳实践未必是你的最佳实践。后来我学乖了规格里明确写“不需要邮箱验证、不需要第三方登录、密码只要求长度大于 8”。8.2 上下文太长导致“失忆”有一次做一个中等项目我把所有相关文件都塞进上下文想让智能体“全面了解”。结果它反而开始胡言乱语把不同模块的逻辑混在一起。后来查资料才明白上下文过长时模型对中间部分的注意力会下降也就是所谓的“lost in the middle”。解决办法是按需加载上下文。不要一次性喂所有文件而是让智能体自己决定读哪些。比如给它一个“读文件”的工具让它先看目录结构再按需读取。这样既省 token又避免信息过载。8.3 过度信任智能体的“自信”智能体有个特点它说“已完成”的时候语气非常肯定哪怕实际上没跑通。我有次让它改一个 bug它说改好了我直接提交结果 CI 挂了。后来我养成习惯任何智能体的产出必须经过构建和测试验证才算数。它说完成不算测试通过才算。这个习惯救了我很多次。现在我的流程里智能体改完代码后必须自己跑一遍build和test把输出贴出来我才认。9. 关于这套范式我现在的真实看法用了一年多 Vibe Coding 加智能体驱动这套东西我的感受是它确实把开发效率拉高了一个台阶但前提是你愿意在规格和验证上花功夫。那些觉得“AI 写代码不靠谱”的人很多是跳过了规格直接让 AI 写然后被坑了那些觉得“AI 无所不能”的人往往是没做验证就上线迟早出事。我现在的日常是需求来了先和智能体对话理规格规格定稿后让它生成代码和测试跑通后我逐行审查安全和边界最后合并。整个流程里我花在“写代码”上的时间少了大概六成但花在“想清楚要什么”和“验证对不对”上的时间多了。总体是划算的因为想清楚和验证本来就是开发里最该花时间的部分只是以前被写代码的体力活掩盖了。如果你刚开始尝试我的建议是从一个小功能开始完整走一遍“规格—生成—验证—审查”的流程别一上来就搞大项目。走通一遍之后你会对智能体的能力边界有真实的感知也就知道哪些活能交给它哪些必须自己盯。最后一个实操小技巧给智能体准备一份project-context.md里面写清楚项目的技术栈、目录约定、命名规范、常用命令。每次开新任务时让它先读这份文件能省掉大量重复解释产出的一致性也会好很多。这份文件我维护了半年现在基本成了项目的“智能体入职手册”。
返回列表