☰
从氛围编程到TDD契约驱动:用Superpowers构建AI工程纪律闭环
2026/10/22 5:09:20 网站建设 项目流程

最近这半年,但凡深度用过AI编程助手的人,多半都听说过一个词:氛围编程(vibe coding)。我第一次看到这个词,正好在给一个“垮掉”的跨平台系统救火——代码能跑,没人知道为什么能跑,改一个字段炸三个模块。这一幕几乎是这个词的最好注解。后来我试着引入一套名为 Superpowers 的技能框架,用TDD契约驱动重新校准AI的出码节奏,再配合评审、回归、复盘形成一条AI工程纪律闭环,才慢慢把那种“氛围感”从项目里挤出去。这篇文章想把这条路径完整拆开,适合那些被AI代码雪崩坑过的小组、正打算把AI编程工具接入正式项目的团队,以及所有想从“让AI自由发挥”转向“让AI按契约交付”的开发者。

1. 氛围编程到底是怎么把项目搞崩的:三个前兆与一次翻车复盘

1.1 什么是氛围编程:不是偷懒,是反馈循环缺位

氛围编程这个说法最早是从社区里传开的,调侃的是一些开发者用AI写代码的方式:把一段模糊的想法丢给AI,AI生成一坨代码,人看都不看,跑不通就说“帮我修一下”,跑通了就继续下一个需求。整个过程很像“氛围感”这个词给人的印象——看起来有样子,实际上没有可验证的纹理。

很多人以为氛围编程的锅是“偷懒”,但偷懒只是表象。真正的核心问题在于:人类把自己从工程反馈循环里移除了。一个正常的开发循环应该是“需求理解→设计→实现→运行→观察→修正”,其中“观察运行结果并判断是否符合预期”这一环是人的核心职责。氛围编程把这个环节也交给了AI来想象,AI说“应该没问题”,人就说“好”。问题是,AI没有对业务目标的真实理解,它只是在优化“让你满意”这件事,而你给的反馈又总是不够具体。最后生成的代码看起来结构合理、注释齐全,实际上每一层都建立在未经确认的假设之上。

一旦这种状态持续几周,代码就变成了一个没有“真值来源”的黑盒系统。每个人都只能对着AI产出的表层现象猜细节,没有人能回答一个最基本的问题:这个行为当初是谁确认的、针对的是哪条需求。氛围编程真正可怕的地方,不是它让代码变得混乱,而是它让混乱变得不可追溯。

1.2 代码雪崩的三个前兆:快、空、乱

我复盘了自己和身边团队的经历,发现代码雪崩几乎不是在某个瞬间发生的,而是三个前兆凑齐之后的必然结果。

第一个前兆是“快”。AI的生成速度远快于人工审查速度,一次对话就能产出几百上千行代码。你让AI写一个登录模块,它可能顺手把权限中间件、用户表、验证码逻辑都写了。生成得越快,积累的未审阅代码就越多,后期的信任债务就越大。第二个前兆是“空”。需求没有结构化,入口只是一句“帮我做一个订单系统”。没有验收标准、没有优先级、没有边界描述。AI只能靠自己的世界知识去脑补业务规则,而业务规则恰恰是最不能被脑补的东西。第三个前兆是“乱”。修改请求是逐条追加的,“把税率改一下”“优惠券逻辑再调调”“最近订单报表不对”,每条指令都改变了系统的某个角落,但没有任何人追踪影响面。等到上下文滚动、窗口里的旧约束被遗忘,AI就会基于不完整的记忆继续行动。

这三个前兆凑齐之后,雪崩只是时间问题。注意,这里的“雪崩”往往不是编译错误,而是“改了A崩了B,修B又崩C”的连锁失效。它比编译错误更麻烦,因为反馈延迟很长,你可能在改完一周之后才发现线上数据不对。

1.3 一个典型的氛围编程翻车复盘

我用模拟项目X来还原这个过程。某团队需要给一个跨平台系统做订单计价模块,负责人让AI一次性生成价格累加、会员折扣、税费、优惠券、库存联动等全套代码。第一轮体验确实很爽,跑起来也有输出,还有很多AI自己附带的单元测试。第二轮,产品新增了一条规则:部分地区免税。AI改完税率之后,优惠券开始重复扣税;再去修优惠券,库存回滚又异常;接着修库存,历史订单报表里的字段又对不上了。团队最后花了三天定位,结论是70%的问题都指向一处——AI在无契约状态下反复猜“税额应该以哪个金额为基础”,并选择了多种隐含的假设,而且没有任何人审查过这些假设。

这场翻车的问题不在AI能力,而在于反馈循环里没有“真值来源”。如果一开始就把“税额基于折扣后的实付金额”写成断言测试,AI所有的自由发挥都会被拦截在合同检查点之外。这正是Superpowers这类技能框架试图解决的事:把约束前置,而不是等雪崩之后再去救火。

2. Superpowers技能框架的核心设计:为什么用“技能”取代“提示词”

2.1 技能(Skill)本质上是一个“可执行函数”

先说技能这个词。在Superpowers框架里,一个技能并不是一段普通提示词,而是一个预定义的工作流单元:它声明了什么时候触发、按什么顺序执行、每一步做什么、禁止做什么、最终交付什么。你可以把它理解成给AI编程行为装上了“函数定义”——有入参、有执行体、有返回值。

具体落地时,每个技能通常对应一个技能说明文件,我习惯称它为SKILL.md。这个文件用结构化文字描述技能的触发条件、工作步骤、输入要求和交付物标准。当AI检测到用户需求匹配某个技能时,它不再直接生成答案,而是先加载这个技能说明,按照里面固定的流程开始工作。TDD技能会要求“先列出测试清单,再写第一个失败测试,然后实现最小通过,最后重构”;探索类技能则会要求“用最快的速度写临时代码验证想法,禁止把实验产物混入主干”。这些指令不依赖用户临场发挥,它们被固化在流程里,成为AI和用户之间的公共约定。

为什么这比写一条更长的提示词靠谱?因为提示词是一次性的,靠记忆里的惯性执行;而技能是可复用、可版本化、可共享的。同一个技能库可以被多个项目、多个团队成员同时使用,等于把“优秀工程师的执行习惯”打包成了可装卸的模块。人不需要每次重复解释“要按测试驱动来”,技能框架已经把这个约定写死在流程里。

2.2 Superpowers框架为什么强调“预设工作流”

Superpowers叫“技能框架”,核心不是某一份技能文档写得漂亮,而是它把工程纪律拆成了若干可组合的单元:需求拆解、TDD、探索、重构、审查等。这些单元之间可以串联,也可以单独调用,但它们都有一个共同点——都在限制AI的自由度。

框架刻意让AI从“自由模式”进入“工作流模式”。大模型对普通提示的默认响应是“快思”——你说什么它马上回应,不会主动质疑,也不会先列一个执行计划。如果每个人都在通用对话窗口里问一句写一段,那产出就是零散的、缺乏纪律的。技能框架通过预设指令强制AI进入“慢想”模式:先理解任务边界,再拆解步骤,再逐项执行。这相当于给每个任务套上了一个执行模板,把决策压力从模型的随机生成转移到框架的结构约束上。

我在实际使用中体会最深的一点,就是框架不只是约束AI,也在约束我。以前我会忍不住打断AI说“顺便把这几个也改了”,技能框架会要求我把新需求单独拆成另一轮任务。这种双约束看起来降低了速度,实际上避免了大量返工,整体节奏反而稳了。

2.3 会话形态的变化:从“生成式”到“审批式”

没有框架的会话是典型的生成式:用户说“帮我写个登录模块”,AI噼里啪啦吐出一大坨代码,用户复制粘贴进项目就算完事。有框架的会话变成了审批式:用户说“为登录模块跑TDD技能”,AI先加载技能说明,然后列出测试清单给你确认,再逐项进入红绿循环。每完成一个测试,就停下来让你验收。

这个变化很关键。生成式会话里,人的角色是被动接收者;审批式会话里,人的角色是验收员。你不是在逐行读代码,而是在每个决策点上做语义判断——“这个测试对应了这条业务规则吗”“这个实现算是契约允许的最小范围吗”。输出被切成小且可验证的增量,任何错误都能被及时截停,而不是堆到最后一起爆。

有人可能会觉得审批式太慢,但仔细算一笔账:一次性生成一千行代码,审查需要一小时,出问题定位三小时;而十个增量各生成五十行,每次审查十分钟,总共也是一小时,但出问题时定位往往只需要几分钟。真正贵的不是审查时间,而是失控后的连带修复成本。

3. TDD契约驱动实战:三步建立AI协作的护栏

3.1 契约驱动:把需求变成机器可读的承诺

在软件工程里,契约是调用方与被调用方之间的协议:输入是什么、输出必须满足什么、副作用边界在哪里。放到AI协作场景里,契约之所以重要,有三个原因。

第一,模型没有长期记忆,它不会跟你吵“当初你明明说的是A”。只有把需求固化成机器可读的断言,才能对抗上下文滚动带来的遗忘。第二,模型天然倾向迎合用户,你说“差不多就行”,它绝对不会指出这里有个边界条件没处理。契约可以逼它正视那些不好看的角落。第三,模型不会主动反驳你的需求漏洞,但测试会。当你尝试把一个模糊需求翻译成断言时,你自己会先发现需求的自相矛盾之处。

所以我把TDD契约驱动理解为:先用测试定义行为的可验证边界,再让AI在这个边界内实现代码。这里的测试不是“证明代码能跑”的工具,而是“锁定需求承诺”的凭证。每一条测试都像一张合同里的条款,AI是乙方,必须在条款约束下交付。

3.2 TDD技能的红-绿-重构管线

TDD的红绿重构是经典三步,放进AI协作里依然成立,但每一步的参与方式有变化。我通常的流程是先让AI根据需求列出测试清单,然后由人确认或修改这份清单,确认之后才开始执行。

第一步是红灯:为一个明确行为写测试,预期失败。这个失败就是契约——代表“当前行为尚未满足需求”。第二步是绿灯:让AI写最小实现,只求通过当前测试,不扩展额外功能。第三步是重构:在测试保护下优化结构,确保行为不变。对AI来说,最常被跳过或者被搞砸的其实是第一步,因为模型天然想输出完整代码,而不想先输出一个注定失败的测试。

这中间有一个认知误区:很多人以为TDD技能的价值是“让AI生成测试代码”,其实它的价值是让“失败”成为流程的合法起点,让“通过”成为有依据的终点。没有这个红绿循环,AI的每一次输出都只是“猜了个答案”,有了它,AI的每一步都有可检验的凭证。

3.3 契约的三层护栏:签名、断言与不变量

我在实践中会把契约分成三个层级,每个层级对应不同的保护强度。

第一层是接口签名。函数名、参数类型、返回类型必须稳定,避免AI在实现过程中悄悄改签名来迎合调用方。接口签名就像一份合同的封面条款,只要封面写清楚了,后面的细则才能讨论。第二层是行为断言。核心业务逻辑的输入输出映射通过测试固定下来,比如“会员折扣必须在优惠券之前计算”“税费以折扣后的金额为基数”。这一层是最主要的保护,因为业务规则往往就藏在这些断言里。第三层是系统不变量。跨模块、跨事务的规则,比如“订单实付金额不能小于零”“库存扣减必须与支付成功在同一事务内完成”。不变量是最难被AI主动维护的,因为它通常不来自某个具体需求,而是来自系统整体的稳定性要求。

三层护栏不一定全部都用,但如果一个模块同时涉及接口变更、复杂业务逻辑和跨模块数据一致性,那么这三层缺一不可。每一层护栏都能在某个方向上把“氛围编程”的自由散漫挡在门外。

4. 从需求到重构:一次完整AI纪律闭环的落地实操

4.1 模拟项目X:先立需求与验收标准

理论讲完,落到键盘上。我还是用模拟项目X里的一个模块来做完整演示。需求描述很简单:某系统的订单报价模块,输入商品列表、会员等级、优惠券,输出订单总额。业务规则有三条:会员折扣在优惠券之前计算;税费只对折扣后的实付金额计算;优惠券满减金额不能使订单实付为负。

注意,第一步不是让AI写代码,而是把需求翻译成可执行的验收标准。我建议把每条业务规则拆成一个验收项,并写成“给定某某输入,期望某某输出”的句式。比如:给定普通会员和满减券,期望先算会员折扣再算满减;给定折扣后金额100元,税率10%,期望税费等于10元。这些验收标准就是后续测试清单的原料。

这个阶段最容易犯的错是把验收标准只写成自然语言丢给AI。自然语言对着AI说一百遍,不如一条断言来得有效。我在实操里会把验收标准内置进测试文件,让每个验收项对应至少一个测试函数。

4.2 红灯阶段:用失败的测试锁住行为

在确认需求之后,我让AI列出测试清单。一个合格的测试清单应该覆盖所有验收项,并且每条测试都有明确的业务断言。下面是一段典型的测试伪代码,实际项目里我会让AI用项目现有的测试框架来写:

def test_empty_items_should_raise(): with pytest.raises(ValueError): calculate_total([], member="normal", coupon=None) def test_member_discount_applied_before_coupon(): # 商品原价100,会员9折,满减券-5 # 期望:先折上折再满减 = 100*0.9 - 5 = 85 assert calculate_total([100], member="vip", coupon={"type": "full_reduction", "threshold": 50, "amount": 5}) == 85 def test_tax_based_on_discounted_amount(): # 折扣后金额100,税率0.1,期望税费10 assert calculate_tax(100, 0.1) == 10

这个阶段有一个值得强调的纪律:测试必须运行且失败,而且失败原因必须符合“行为尚未实现”,不能是语法错误或导入错误。如果测试连编译都过不了,那它就不是契约,而是一张废纸。

我在实操中会让AI先跑一遍测试,把失败信息贴在对话里给我看。这既能确认测试真的在检验业务行为,也能防止AI偷偷写一个永远通过的“空断言测试”。

4.3 绿灯阶段:只允许最小实现

红灯确认之后,进入绿灯阶段。流程是提交一个测试,让AI实现最小代码,运行测试,通过后再提交下一个测试。下面是配合上面测试的最小实现示例:

def calculate_total(items, member, coupon=None): if not items: raise ValueError("items must not be empty") subtotal = sum(items) if member == "vip": subtotal *= 0.9 if coupon and subtotal >= coupon["threshold"]: subtotal -= coupon["amount"] return max(subtotal, 0)

注意,这段代码只满足“会员折扣在优惠券之前”和“空列表抛异常”这两个契约,它没有包含税费逻辑。这套流程刻意不让AI一次性写完所有功能,就是为了把每次变更的影响半径限制在一个契约之内。

我在这个阶段最常见的失控场景是AI“顺便”加东西:它会顺手加一个日志、顺手抽象一个基类、甚至顺手修一个它自己发现的bug。我的经验是,尽早打断这种“顺手行为”,把它单独拆成另一轮任务,并且要求这个任务先写测试。任何不在当前契约范围内的变更,都可能是下一次雪崩的起点。

4.4 重构与回归:闭环的最后一关

所有契约都变绿之后,我还会再跑一次全量测试套件,确认彼此之间没有副作用,也就是“契约回归”。然后让AI以审查者身份检查代码,找出重复实现、隐藏依赖和不符合约定的命名。这个阶段AI经常能发现一些我在实现过程中忽略的细节,比如某个公共常量被魔法数字替代了,或者某个函数同时做了两件事。

AI的角色从“生产者”切换成“审查者”之后,我作为人的角色又变回了最终验收员。我会要求AI输出一份变更摘要,列清楚每个需求点对应哪个测试、哪段实现、影响了哪些模块。这份摘要不是写给我存档的,而是用来做语义评审的——我要看的是,某些未写进验收标准的隐含决策是否被AI悄悄做掉了。

复盘的时候我发现,这套闭环真正厉害的地方不是每一步都多完美,而是项目里始终存在可回滚的行为边界。无论AI怎么改,全量测试就是那条底线。跑不通就不能并主干,这个规则没有人能偷偷绕过。

5. 常见问题与实施经验:让AI工程纪律闭环长期稳定

5.1 高频问题速查表:遇到雪崩前兆怎么处理

落地过程中,我遇到过不少典型问题,也踩过一些坑。这里整理成一张速查表,方便对照处理。

现象常见原因处理方式
AI跳过测试直接给实现提示没有强制进入技能流程,模型默认走“快思”路径重开会话并加载TDD技能,把“先测试后实现”列为第一约定
测试很多但全是形式测试断言太弱,只检查非空或类型,不检查具体业务数值要求每个测试至少有一个业务断言,禁止仅检查“结果不为空”
实现过程中AI顺手改了一堆无关代码没控制变更范围,或者上下文里积累了太多旧指令每轮只允许一个测试对应一个实现,新需求必须拆成新任务
技能执行到一半行为飘移上下文太长,旧契约被后续对话稀释拆分任务,定期清空上下文,把关键契约写进独立的需求文档
测试先红了,但跑出来的失败原因完全不是业务期待前置条件没搭好,或者测试对象依赖了未初始化数据先跑通测试框架,再写业务测试,失败信息必须是“行为未实现”

5.2 纪律闭环持续有效的四个支点

在我维护的项目里,纪律闭环能持续运转,靠的是四个支点,缺一个都会慢慢打回原形。

第一个支点:契约先行。每条需求在进入编码之前都必须变成机器可执行的测试,不允许出现“测试还没写,但AI已经在写实现”的场景。第二个支点:最小粒度。一次只做一个测试,一次只让AI提交一个增量。没有这个限制,变更的爆炸半径迟早会失控。第三个支点:人的验收角色。纪律闭环并不要求人逐行读AI代码,但每个绿灯点都要求做语义评审,至少看一眼“这个测试是不是真的锁住了这条规则”。第四个支点:定期让AI输出变更摘要。把上下文里的隐含决策显性化,让每次修改都有据可查。

这四个支点本质上是一套减速机制。它的代价是每个环节没那么爽,但换来的是可预测的、可持续的交付节奏。

5.3 探索与交付要分开:什么时候可以暂时松绑

最后想聊聊“松绑”。很多人听说纪律闭环,容易走向另一个极端,把每一行代码都要求走严格流程。其实没必要。在探索性试验阶段——比如评估某个第三方库能不能满足需求、验证某种交互方案是否合理、测绘一个陌生系统的数据流向——完全可以用“探索技能”快速写临时代码,跑完就扔,不需要先写测试再做重构。

关键在于把探索和交付彻底隔离。探索阶段产生的代码一律不允许直接进入主干,必须经过重写,变成有契约约束的正式实现。我在一个项目里就吃过教训:为了省事,把一个探索用的临时脚本改了两行直接提交,结果其中隐藏了一个全局状态覆盖,两周后才在线上发现。从那以后,我的规则很明确——临时代码可以写得难看、可以不计较细节,但它的死期就是探索结束的那一刻。

写在最后

我自己从“氛围编程”转向这套纪律闭环的过程并不是一帆风顺。最开始我也觉得每轮只改一个测试太慢,明明可以让AI一把梭。但经历了模拟项目X的翻车,又硬着头皮跑了一段时间全流程之后,我逐渐意识到:AI编程真正让人上头的不是AI的“快”,而是那种“有人愿意替你兜底”的幻觉。纪律闭环做的恰恰是打碎这个幻觉,把每个决策都摆到台面上,让AI从猜答案的执行者变成按契约交付的协作者。这个方法不复杂,甚至看起来有点笨,但它稳。稳,在软件工程里就是我见过最强的东西。

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

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

立即咨询