AI全栈开发实战:从vibe coding到SDD,构建稳定可靠的智能编程工作流
2026/9/7 2:12:55 网站建设 项目流程

1. 从vibe coding到SDD:AI全栈开发的模式进化

这两年我几乎每天都在跟AI编码工具打交道,从最早拿ChatGPT补几个函数,到后来直接用Cursor搓整个项目,再到现在的Agent式开发,最大的感受是:AI全栈开发这件事,真正的瓶颈从来不是模型能力,而是开发者的工作方式。

前阵子有个词特别火,叫vibe coding,大意是你只负责描述需求、让AI一路写下去,自己跟着感觉走。听起来很爽,但实际做过的都知道,小demo确实能冲,一旦项目超过三五百行,或者涉及数据库、权限、多个服务之间的交互,vibe coding翻车概率几乎接近100%。AI会在一半的时候忘了最初的约束,会把两个模块的接口写得对不上,会为了修一个bug把另一个功能改坏,而且你自己因为没深度参与,根本不知道从哪儿排查。

后来我逐渐转向一种更结构化的做法,圈内管它叫SDD,也就是Spec-Driven Development,需求驱动开发。核心思想很简单:先让AI帮你写清楚规格说明、接口定义、数据模型,把这些当成“合同”,再让AI基于合同写代码。这样即使中间换模型、换工具,代码的主干还是稳的。今天这篇就把我这套从vibe coding到SDD的完整打法拆开讲,包括工具链怎么搭、提示词怎么设计、Agent怎么控、测试怎么做,以及一堆踩坑记录。

不管你是刚接触AI编程的初学者,还是已经在团队里推广AI开发落地的人,这套方法论应该都能直接用上。

1.1 vibe coding为什么容易翻车

先聊聊vibe coding的典型翻车场景。我自己最早拿AI写过一个内部工具,需求就是“从Excel读取数据,做清洗,生成报表”。看着简单吧,但AI生成的代码在读取某些特殊格式的日期时直接报错,我让它修复,结果它把整个数据清洗逻辑重写了一遍,原来的去重逻辑全没了。来回折腾了十几轮,最后我自己动手半小时改完。

这个例子特别典型,暴露了vibe coding的三个核心问题:

第一,缺少稳定的需求锚点。边聊边写,AI的记忆窗口有限,聊到后面它自己都忘了最初的目标约束,代码逻辑自然容易漂移。

第二,没有接口契约约束。模块与模块之间靠AI“自觉”保持一致,这在大型项目里是不现实的,AI生成A模块时根本不知道B模块内部怎么实现。

第三,缺少可验证的验收标准。vibe coding通常没有明确的测试用例和验收清单,AI说“改好了”,但你没法快速确认“真的好”。

所以后来我做AI全栈开发,第一件事就是建立需求锚点,即把用户故事、功能需求、非功能约束,全部转成一份结构化的规格文档,再让AI在这个规格的“包围”下写代码。

1.2 SDD模式的核心流程

SDD模式说起来也不复杂,整个流程分四步:

  1. 需求拆解:把产品需求拆成用户可以感知的功能点,每个功能点写清楚输入、处理、输出。
  2. 规格生成:让AI根据功能点生成技术规格,包括数据模型、API接口、页面结构、异常处理方案。
  3. 代码生成:基于规格文档,让AI按模块逐个生成代码,每完成一个模块就跑通对应测试。
  4. 验证反馈:执行测试用例,收集失败信息,反馈给AI修复,修复后回归验证。

你会发现这里的关键不是AI能不能写代码,而是你有没有一套机制让AI的输出始终围绕规格展开。规格文档就是给AI套的“缰绳”,没有它,AI就是脱缰的野马。

实际落地的时候,我常用的做法是用Markdown写规格文档,然后把它放在项目的/spec目录下,每次让AI干活前,先把规格文档的关键段落喂给它,再给出当前任务。如果是用Cursor或者类似工具,可以直接用@spec/xxx.md的方式引用,这样AI每次都能读到最新的需求锚点。

1.3 模式对比:vibe coding、SDD与纯人工编码

我用一个表格直观展示这三者的差异,方便你按场景选:

维度vibe codingSDD模式纯人工编码
上手速度极快中等
需求变更应对容易失控灵活,改规格即可灵活但耗时
代码可维护性
适合项目规模小demo中大型项目视团队能力
对开发者要求懂基本架构思维

现在我的习惯是:小工具或者一次性脚本,直接vibe coding;但凡要上线、要维护、要多人协作的项目,一律SDD。把时间花在写规格上,看着是多了几步,实际是在给后面的开发省大麻烦。

2. 工具链选型与AI Infra基本盘

聊完开发模式,再说说工具链。AI全栈开发不是只有一个AI编程助手就完事,它实际上是一条完整链路:模型接入、上下文管理、代码生成、测试反馈、持续集成。这里每个环节都有对应的工具选型和配置要点,我自己前后折腾过好几套方案,踩了很多坑,挑重点讲。

2.1 模型接入层:litellm proxy的作用

先从模型接入说起。很多人的第一个问题是:我到底该用哪个大模型?答案不是固定的,今天可能GPT效果最好,明天可能Claude、Gemini或者国产模型追上来。你要做的是让团队能随时切换模型,且切换成本几乎为零。

这时候litellm proxy就派上用场了。它本质上是一个统一模型网关,你在服务端配好各种模型的API Key和基础地址,对外暴露一个标准的OpenAI兼容接口。这样你的AI应用、AI编程工具、Agent框架都只连litellm,由它去路由到底层模型。

我的配置习惯是,项目根目录放一个litellm_config.yaml,大致长这样:

model_list: - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-sonnet litellm_params: model: anthropic/claude-3-5-sonnet api_key: os.environ/ANTHROPIC_API_KEY - model_name: deepseek-chat litellm_params: model: deepseek/deepseek-chat api_key: os.environ/DEEPSEEK_API_KEY

然后启动服务:

litellm --config litellm_config.yaml --port 4000

之后再给AI编程工具或者自研应用配Base URL时,统一填http://localhost:4000。这样底层模型随便换,上层业务代码一行都不用改。

这个做法的价值在于:避免被单一模型绑死。模型这东西没有永远的王者,今天你发现某个模型在代码生成上不行,换个模型可能就好了,而litellm帮你把这个切换过程压缩到改几行配置。

2.2 后端集成:Spring AI还是自研Client

如果你做的是Java后端项目,会面临一个选择:用Spring AI还是自研一个简单的LLM Client?

Spring AI的优势是跟Spring生态无缝集成:它把ChatModel、EmbeddingModel、VectorStore都抽象成了Spring风格的Bean,配置走application.yml,跟你的业务代码放在同一个工程里。特别适合已经深度使用Spring Boot的团队,省去自己封装HTTP请求、JSON解析、流式响应的工夫。

但Spring AI也有个尴尬点:迭代太快,版本之间API变动不小,你网上搜到的教程大概率已经过时。而且它封装的抽象程度比较高,一旦你需要一些自定义的prompt逻辑或者复杂的函数调用流程,反而会觉得被框架限制。

我的建议是:如果项目本身就是Spring Boot,且AI调用只是业务里的一个环节,比如做一个知识库问答、内容生成功能,直接用Spring AI,效率很高。但如果你做的是一款以Agent为核心的AI原生应用,交互逻辑复杂,工具调用频繁,建议自己写一个轻量Client,维护成本反而更低。

简单的自研Client核心就两个能力:调用模型接口、处理流式响应。剩下的业务逻辑都能自己控制。我在一个小微服务里自己封装过,核心代码不到100行,包括请求构造、重试机制、超时控制、流式解析,够用且可控。

2.3 AI Infra的上下文管理与可观测性

最后一个绕不开的是AI Infra。这个概念听起来高大上,落到具体问题就是三件事:上下文管理、可观测性、成本控制。

上下文管理是目前AI应用最容易出问题的一环。模型上下文窗口再大也是有限的,你不能把整个项目的代码都塞进去。实际工程中要做分层:

  • 系统提示词:占少量token,定义角色和全局规则。
  • 任务相关上下文:动态选择,只放当前任务最相关的代码、文档、数据。
  • 工具返回结果:通过函数调用动态获取,用完即丢。

可观测性方面,我推荐至少记录三份日志:请求日志(每次调用的模型、token数、耗时)、输出日志(模型返回内容,便于回溯问题)、质量日志(用户反馈或自动评估的打分结果)。有了这三份日志,出问题时你才能快速定位是模型问题还是上下文问题。强烈建议团队从第一天就做这个埋点,等出问题再补就来不及了。

3. 提示词工程与上下文管理的实战细节

提示词是AI全栈开发绕不开的底层能力。网上讨论提示词的很多,但大多是教你怎么写“请帮我生成一个网站”这种一次性需求。真正做全栈开发的时候,提示词要承担的任务比这复杂得多。

3.1 提示词不是玄学,是需求文档

我发现很多开发者写提示词特别随意,比如“帮我写个用户登录功能”,AI吐出来的代码能用但很平庸,而且经常跟项目现有的风格、结构不一致。原因很简单:你把AI当成搜索引擎了,但它其实是你的结对编程搭档,你得把背景信息给它讲清楚。

我写的提示词一般包含五个部分:

  1. 角色定义:你是某项目的后端开发工程师,熟悉现有代码结构。
  2. 背景说明:项目用了什么技术栈、遵循什么架构规范。
  3. 任务描述:要做什么功能、验收标准是什么。
  4. 约束条件:不要改哪些文件、不要引入哪些依赖。
  5. 输出要求:只输出核心代码还是包含解释,是否附带测试用例。

举个例子,同样让AI写登录功能,我会这么写:

角色:你是本项目的后端工程师。 背景:项目使用Spring Boot 3.x + MyBatis-Plus,统一返回Result对象,异常由GlobalExceptionHandler处理。 任务:实现基于密文密码校验的登录接口,用户名为手机号,密码需先经过前端RSA加密,后端解密后校验。 约束:不要修改已有的UserMapper和RedisConfig,登录成功后颁发JWT token,有效期7天。 输出:提供Controller、Service、ServiceImpl代码,以及对应的单元测试。

你看,这样AI生成的代码基本可以直接用,不需要来回改。核心原因是信息密度高,AI不需要猜你的意图。

3.2 上下文窗口的预算分配策略

上下文管理是另一个容易被忽略的问题。模型上下文窗口是有限的,而且在长对话中,越靠前的信息被模型“注意”到的权重越低。我遇到过很多次,AI聊到后面突然不遵循最初的约束了,检查发现是上下文已满,早期信息被截断了。

我的做法是“分配上下文预算”:

  • 系统提示词占10%,保持稳定不随对话增长。
  • 规格文档占20%,作为核心参考,每次对话都带上,但只带与当前任务相关的片段。
  • 当前任务描述占10%,清晰明确。
  • 代码上下文占30%,只包含当前要改的文件和直接相关的依赖文件。
  • 历史对话占30%,只保留最近几轮,老的历史果断丢弃。

注意这里不是让你手动删聊天记录,而是利用工具和框架层面做裁剪。比如用SDD模式时,规格文档放固定位置,每次对话重新引用,而历史聊天内容只保留最近几轮。这样即使对话很长,关键约束也不会丢。

3.3 RAG与记忆管理:让AI记住项目全貌

单个提示词能携带的信息终究有限,当项目本身比较大时,RAG(检索增强生成)就变得重要了。你可以把项目的技术文档、接口文档、数据字典、历史决策记录都建到向量数据库里,AI在干活前先去检索相关知识,自动补全上下文。

我之前给一个中大型项目做过RAG实践:把项目的README、数据库ER图、接口文档、编码规范文档全部切片嵌入,存在本地向量库。AI编程工具通过插件自动检索,每次生成代码前先看一遍相关规范和数据定义。效果非常明显,生成的代码风格跟项目原有代码高度一致,不再出现“外来的和尚乱念经”的情况。

但RAG也不是银弹。检索到的内容可能不准确,或者与当前任务无关,反而干扰模型判断。我的经验是:检索结果不要一股脑全塞进上下文,而是让AI先判断检索结果的关联度,决定用还是不用。这一点可以在提示词里明确要求AI“只使用与任务直接相关的参考信息,忽略无关内容”。

4. 工作流编排与Agent设计的工程化思考

聊完提示词,接下来是Agent。AI Agent是现在最火的词,但很多人对Agent的理解还停留在“能让AI自己用工具”这个层面。实际上,要把Agent落地到一个可用的全栈项目,你需要考虑工作流编排、工具权限、失败恢复、成本控制等一系列问题。

4.1 从单轮到多步:Agent的基础架构

先聊聊Agent与普通Chat的区别。普通Chat是一次性问答,用户问一句AI答一句。Agent则是一个循环:接收任务、拆解计划、调用工具、观察结果、调整下一步。这个过程就是ReAct模式,Reasoning + Acting,推理和行动交替进行。

在工程实现上,一个Agent通常由几个模块组成:

  • 规划器(Planner):负责把大任务拆成小步骤。
  • 执行器(Executor):负责具体执行某一步,比如调用代码生成、执行Shell命令。
  • 工具集(Tools):Agent可以调用的外部能力集合。
  • 记忆模块(Memory):短期记忆保存当前任务上下文,长期记忆保存跨会话的经验。
  • 评估器(Evaluator):判断当前结果是否满足目标,决定是继续还是终止。

我用一个最简单的例子说明:让Agent“实现一个用户注册接口”。它可能会先拆成:查数据库表结构、设计接口参数、写Entity和Mapper、写Service逻辑、写Controller、写测试。每一步如果遇到问题,它会调整方案或者要求更多信息。

4.2 harness模式:给Agent套上安全护栏

Agent的能力越强,失控的风险也越大。我给Agent做过几次“放养”式实验:让它自己折腾一个任务,结果它在一个错误的方向上反复尝试,白白烧了几百次API调用。后来我学到了harness模式,简单说就是给Agent搭一个“工作框架”,在不剥夺Agent主动性的前提下,把它的行为约束在安全边界内。

具体来说,harness包含三层控制:

  1. 流程控制:定义Agent必须按照固定的步骤推进,不能跳过关键节点。
  2. 工具控制:定义Agent可以调用哪些工具,被禁止的操作直接不让调用。
  3. 校验控制:每一步的输出先过校验器,不通过则不进入下一步。

举个例子,Agent要执行Shell命令改代码,我的harness会要求:所有Shell命令必须先打印出来,经过人工确认或者通过安全策略匹配后才能执行。这样即使Agent的判断有误,你也能在最后一道防线拦住它。

这让我想到带孩子学骑车,你不是放任他自己乱闯,也不是一直扶着不让动,而是给他划定一个安全的练习场地,配上头盔护具,再放手让他骑。Agent开发也是同理,harness就是场地和护具。

4.3 工具调用与权限边界设计

Agent的能力边界本质上取决于它能调用哪些工具。工具给得多,Agent能干的事多,但风险也大。我的原则是最小权限原则:每个Agent只配它完成任务所需的最少工具。

比如一个文档总结Agent,只需要“读取文件”和“写总结”两个工具;一个代码开发Agent,可以给它“读文件”、“写文件”、“执行测试”三个工具,但不给它“执行部署”或者“修改生产环境数据库”的权限。这看起来是常识,但在实际配置的时候,很多人为了省事会一股脑把所有工具都给Agent,结果出事只是时间问题。

此外,工具调用的参数也需要做校验。举个例子,如果Agent有一个“执行任意SQL”的工具,那它可能在误操作下删掉整张表。我在设计类似工具时,会加入只读模式作为默认配置,只有在特定标志位打开时才允许写操作。这些细节看似简单,但能在关键时刻保住你的数据和系统。

5. AI生成代码的测试策略与质量保障

AI生成代码的效率确实高,但质量保障容易被人忽视。我见过不少团队,AI生成的代码merge上去就跑CI,CI过了就上线,直到线上出了事故才回去排查。AI全栈开发的落地,必须有完善的测试策略,否则就是给自己埋雷。

5.1 对AI生成的代码做代码审查

先明确一个观念:AI生成的代码和同事写的代码一样,必须经过代码审查才能合入主干。你不能因为代码是AI写的就放松标准,恰恰相反,AI生成的代码更需要仔细审查,因为它可能存在“看起来对、实际错”的隐蔽问题。

我做AI代码审查时重点看几个方面:

  • 边界条件:AI经常忽略空值、超长字符串、并发访问这些边界场景。
  • 安全漏洞:AI生成的代码可能存在SQL注入、越权访问、敏感信息泄露等隐患。
  • 性能问题:AI可能写出循环嵌套查询数据库的代码,在小数据量下没问题,一旦数据量上来就爆。
  • 语义一致性:AI可能实现了接口,但业务语义跟需求里描述的不一致,这是最容易忽略的。

我的习惯是:AI生成代码后,要求它自己先写一轮自测用例,然后我再抽查关键文件的review。不要全部交给AI审查,AI审查自己的代码就像让作者给自己的书挑错,效果有限。

5.2 用AI测试AI:自动化测试的落地实践

AI代码要测试,测试代码本身也可以用AI生成,这是一个很正向的循环。现在很多AI编程工具已经支持一键生成单元测试,但质量参差不齐。我的实践是:先让AI生成测试骨架,再人工补充关键断言。

比如你实现了一个复杂的价格计算函数,你可以让AI生成一组基础测试用例,然后你手动加上几个关键边界测试:零元订单、负数折扣、并发下单等。AI生成80%的测试框架,人补齐20%的关键场景,这是目前效率最高、质量也可控的组合。

另外,AI还能帮你做回归测试的筛选。当需求变更后,你可以让AI分析现有测试用例,标出哪些用例会受变更影响,需要优先回归。这个功能在测试用例数量庞大时特别好用,能省下不少排查时间。

5.3 CI/CD流水线中的人工卡点

最后聊CI/CD。在AI全栈开发的流水线里,我建议至少设置三个卡点:

  • 规范卡点:代码格式化、静态检查必须通过。
  • 测试卡点:单元测试覆盖率不达标不能合入。
  • 人工卡点:关键模块的代码review必须由人完成,不能只靠自动化。

很多团队听到“AI开发”就觉得人不用管了,全自动就好了。但以现在的工具成熟度来看,完全无人值守还太激进。我的建议是“人机协同”:AI干重活,人管方向和关键决策。把AI当作一个效率极高的初级工程师,你可以给它安排大量工作,但关键节点的把关必须自己来。

我实际跑过的一条流水线是这样的:AI生成代码 → 自动跑静态检查和单元测试 → 生成PR → AI自动修复简单问题 → 人工审查关键模块 → 通过后合并 → AI自动生成发布说明。整个过程虽然最后还是人点了一下确认,但实际花在等待和操作上的时间比传统方式缩短了70%以上。

6. 常见问题排查与避坑技巧

写了这么多实操,最后把我在AI全栈开发中遇到的常见问题做个整理。这些都是真实踩过的坑,每个问题后面附上我的排查思路和解决方案,当成一个速查表用就行。

6.1 让AI“记住”需求:上下文丢失问题

现象:对话进行到一半,AI突然不遵循最初的约束了,开始自由发挥。

原因:上下文窗口被占满,早期信息被挤出。另外也可能是因为你中途切换了话题,AI把注意力全放到新话题上。

排查思路:先检查当前对话轮次和tokens消耗,确认是不是超了窗口。再看你最新的指令是否明确要求AI继续遵循初始约束。

解决方式:核心信息写进系统提示词或单独的规格文档,不让它只存在于对话历史中。对话里每隔几轮就提醒一次关键约束。如果上下文确实太长,就开一个新对话,把规格文档和当前进度重新贴进去,而不是在一个对话里硬扛到底。

6.2 Agent循环调用的死锁问题

现象:Agent在一个错误的方向上反复尝试,明明前一步结果已经不对了,它还是继续往下走。

原因:Agent缺乏“反思”机制,没有停下来评估当前路径是否有效的环节。也可能是评估器设置的终止条件过于宽松。

排查思路:查看Agent的完整行为日志,观察它是否在重复执行相同操作。重点看每一次工具调用的返回结果有没有被正确消费。

解决方式:在设计Agent时加一个“最大尝试次数”,超过次数就终止并向用户求助。每次工具调用后都要有一个“结果评估”步骤。我发现一个很有效的做法是在提示词里明确写:“如果你连续两次得到相同错误结果,停下来,换一种思路,或者直接向用户说明情况。”

6.3 API调用成本失控

现象:一个看似简单的任务,AI来回调用几十次API,月底账单吓人。

原因:Agent没有对成本进行感知,大量调用集中在重复的无效请求上。比如说上下文里塞了大量无关信息,每次调用都要消耗大量tokens。

排查思路:检查可观测性面板里各个模型的调用次数和tokens消耗,定位到具体是哪个任务烧钱最厉害。

解决方式:给Agent设置调用预算上限,超出后必须人工介入。在Agent的设计中增加“批处理”能力,把能合并的请求合并,减少往返次数。优先使用性价比更高的模型处理常规任务,把贵模型留给复杂推理。最后就是做好上下文裁剪,别把所有历史都塞进去,每轮最多保留最近几条就好,这一条就能省不少钱。

6.4 模型幻觉导致的代码错误

现象:AI生成的代码引用了一个不存在的方法或依赖版本,看起来像真的,但一跑就报错。

原因:模型是根据概率生成文本,不是真的在编译器里跑了一遍,它可能“幻觉”出不存在的API。

排查思路:报错信息里如果出现“module not found”、“attribute error”,大概率就是幻觉。另一种情况是API确实存在,但版本不对,AI用了新版本的API而你项目引入的是旧版本依赖。

解决方式:让AI在生成代码时先查一下项目的依赖文件,确认版本再写代码。我建议把项目的pom.xmlrequirements.txt内容作为上下文的一部分给AI,让它知道当前环境的实际版本。另外在代码审查时,对AI引用的一切API都保留“它可能搞错了”的怀疑态度,查官方文档确认,特别是你不太熟的库。

6.5 提示词长度与成本平衡的实操笔记

最后再说一个大家都关心的小细节:提示词写太长,每次都花不少tokens,写太短,AI又答非所问。怎么平衡?

我的经验是建立一套提示词模板库。把项目里高频使用的提示词模板固化下来,比如“实现新接口”、“修复Bug”、“写单元测试”、“生成数据库迁移脚本”,每个模板都包含角色、背景、任务、约束、输出要求五个部分。用时只需要替换模板里的具体任务描述,其他部分保持不变。

这样做有两个好处:一是提示词质量稳定,不会因为每次临时写而质量忽高忽低;二是方便统计成本,因为模板部分是固定的,你只需要关注任务描述部分的token变化。

另外一个省钱技巧是:在对话中尽量使用“增量修改”而非“全量重写”。让AI只生成变更的部分,而不是每次把整个文件重新生成一遍。我见过很多人让AI改一行代码,AI把整个文件重写输出,这直接导致token消耗暴涨。在提示词里明确写“只输出修改的函数,保留原有代码结构”,能有效控制成本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询