AI编程失控?一文讲透SDD规范驱动开发的核心逻辑与实践指南

发布时间:2026/9/7 8:55:01
AI编程失控?一文讲透SDD规范驱动开发的核心逻辑与实践指南 过去两年AI 编程工具从“写个 demo”一路渗透进了生产环境行业里出现了两种极端感受一边是“vibe coding”信徒用自然语言快速堆出整条业务线另一边是技术负责人看着每天激增的 PR 数量和越来越不可控的回归私下吐槽“这玩意儿根本没法长期共事”。我自己两边都踩过。用 AI 写代码大半年之后我越来越确认一件事AI 写代码的瓶颈从来不在模型本身而在我们交给它的任务边界到底写没写清楚。于是我开始认真研究和实践最近被反复提到的 SDDSpecification-Driven Development规范驱动开发也就是大家常说的“文档先行”开发方法论。这篇想把 SDD 背后的东西讲透它到底要解决什么问题、那一套三级分类框架怎么理解、以小团队为单位落地时有哪些可以直接抄的步骤以及那些只有真踩过坑才知道的红线。1. 从 vibe coding 到失控边缘AI 写代码真正的瓶颈在哪先聊一个大家都有体感的场景。你让 AI 做一个“带用户登录和支付的后台管理系统”它前三轮生成得像模像样到第四轮开始加一些你没要求的模块第五轮把原有的某个接口改坏了你再让它修它又为了修这个接口把另一个功能“顺带”调整了。整个过程看起来很快但代码库越来越像一个“谁都不完全认识”的陌生项目。这不是 AI 变笨了而是我们一直在用错误的方式使用它。从工程角度看当前 AI 编码工具更像是“超强转换器”而不是“审慎架构师”。它的强项是在给定清晰上下文、明确改动范围和可验证目标时快速生成高质量实现弱项是在信息不足时它会用“高置信度的编造”来补全缺口——也就是我们常说的幻觉。落到具体开发流程里这种弱项会被放大成三种问题。第一全局上下文记忆有限。模型不能像人一样把整个代码库都装进脑子上下文窗口再大也有上限而且中间的任何偏差都会在后续代码里连锁放大。第二它倾向于在缺失约束的地方走“最常见路径”结果就是代码风格、架构取舍、边界处理全凭概率不一定适合你的系统。第三它几乎没有“取舍意识”。遇到需要权衡的方案比如用缓存还是不用、要不要引入中间表它会选一个看似合理但不一定正确的默认值。所以结论很朴素AI 不是不能写代码而是它需要一个足够好的“任务委托说明书”。类比一下你雇了一位能力很强的外包工程师但你给他的需求只有一句话“做个商城”。他大概率会按自己的理解把不该做的也做了、该确认的也没确认。等项目交付你发现结构、技术栈、交互全都不是你要的。AI 也一样它比普通人更“听话”但前提是你得把话说清楚。这个观察正是 SDD 整个方法论的出发点。2. SDD 的核心逻辑文档不是“副产品”而是给 AI 的委托合同很多人听到“文档先行”这四个字第一反应是“又要写文档了”。这种条件反射很合理毕竟传统软件工程里我们被文档坑过太多次——写了没人看、看了不更新、更新了也没法保证和代码一致。但 SDD 里的“文档”不是那种流程文档它的定位更像一份委托合同。合同里写清楚背景、范围、验收标准、边界条件唯一的目标是让对方不需要二次脑补就能开始干活。传统开发流程通常是“需求 → 设计 → 编码 → 文档”文档是编码的副产品写不写看心情。SDD 把顺序倒过来先写规范让规范成为主导产物代码反而是由规范驱动出来的结果。对于一个项目最重要的资产从“代码库”变成“规范库”。为什么这样做对 AI 开发特别关键因为 AI 编码工具面临的困境是它无法像人类同事那样靠长期参与同一个项目来积累隐性知识。人看一个老模块能通过会议、闲聊、历史记忆补全上下文AI 没有这些它看到的只是你扔给它的那一堆文件和 prompt。如果你的 prompt 里只说“帮我加一个导出功能”它就只能从代码库里“猜”导出格式、权限逻辑、字段含义猜出来的结果大概率和你预期不一致。SDD 的解法是主动替 AI 把上下文补齐。先把功能的行为写清楚再把它拆成足够小的执行单元每个单元都带有背景、目标、改动范围、验收标准甚至正反例。这样 AI 在开工时拿到的是一份结构化的、自包含的说明而不是一句模棱两可的指令。你可能想问这不就是把需求文档写得更细了吗为什么非要叫 SDD区别在于一个关键点普通需求文档是写给“人”的默认人会做合理推断SDD 的规范是写给“执行者”的——很多时候执行者就是 AI Agent——它会严格执行字面的每一条规则所以规范里写的每个词都会被当成约束来对待。写得好输出的可预测性就高写得不严谨AI 就会在某个意想不到的地方放飞自我。所以 SDD 真正解决的问题不是“写文档”而是“用规范把编码过程的随机性压到最低”。文档在这里变成了一条精细控制的通道AI 在里面执行而不是让它在一个大草地上乱跑。3. 三级分类框架拆解宏观、中观、微观三层规范怎么分工SDD 经常被吐槽的地方是“文档太重”。一个功能从想法到落地如果要把所有细节一次性写清楚往往几百行都挡不住。这不仅消耗精力对 AI 也不是好事——长文档塞进上下文窗口前面的约束可能到后面就“忘”了。ThoughtWorks 的杰出工程师 Birgitta Böckeler 在探讨 AI 辅助开发时提出的三级分类框架正好解决了这个问题。它的核心思想是不要用一份文档承载所有内容而是把规范拆成三个粒度层级各自服务于不同的目的和读者。层级中文定位主要读者解决的问题典型内容载体变更频率第一级宏观规范系统级架构师、技术负责人、AI Agent 的“背景知识”定义系统边界、架构约束、领域语言系统架构说明、模块地图、接口协议、核心数据模型低频随架构演进变化第二级中观规范功能级产品、开发、测试、AI Agent 的“行为契约”描述用户可感知的功能行为和交互流程用户故事、用例流程、验收标准、核心规则中频随功能迭代变化第三级微观规范任务级AI Agent、执行者定义一个具体编码任务的完整上下文任务描述、目标、改动范围、正反例、边界高频每个任务都写三层之间的关系是逐层细化的。宏观规范负责“锁住大方向”让 AI 在理解模块定位时不会跑偏中观规范负责“说清行为”把用户能感知的事情定下来微观规范负责“限定实现”让一次编码操作有非常明确的验收标准。宏观写得再好也不能直接拿去给 AI 写代码因为粒度太粗微观写得再细如果没有宏观兜底也可能和整个系统的架构风格冲突。有人可能觉得宏观规范有点“空”。但实际用下来它特别重要。比如你让 AI 改订单模块如果宏观规范里明确指出“订单状态由状态机管理禁止在业务代码里直接写 UPDATE 语句”AI 在生成实现时就不会绕过状态机去改库表。这种约束在传统开发里写在架构评审里就够了但在 AI 开发里你不写进规范它就不知道。宏观规范的另一个作用是统一领域术语。让 AI 知道系统里统一说“订单支付时间”而不是“下单时间”、“付款时间”混着用生成的代码和注释也会更一致。中观规范则是最像“产品需求文档”的部分但它有一个明显特点每一条规则都必须可验证。不是“用户会收到通知”而是“当订单在待支付状态超过 30 分钟时系统生成一条提醒记录并通过短信通道发送”。这一层输出的是“行为契约”它回答的是“系统在这个场景下应该怎么做”而不是“底层代码怎么实现”。微观规范是 AI 真正直接执行的“任务卡”。传统开发里同样的信息通过 Jira 工单来传但工单通常不够细。SDD 的要求是一个任务的微观规范需要做到“新接手的人不翻代码库也知道要改哪几个文件、改完怎么验证”。对 AI 来说尤其如此因为它的上下文窗口有限如果还要花大量时间去探索代码库很可能会在探索过程中被无关信息干扰或者干脆因为路径太深而放弃。把相关文件路径、预期行为、验收标准全写在任务卡里效率差异是肉眼可见的。4. 落地实践文档先行的六步实践指南附一个完整订单提醒案例框架听起来很有道理但落到具体团队里怎么开始我把实践过程梳理成了六个步骤。这套“六步实践指南”不要求团队一开始就做到完美只要按顺序执行就能逐步感受到 SDD 带来的变化。4.1 六步流程总览第一步定界。先用宏观规范把项目边界和架构约束定下来相当于给所有后续任务画一条“不能越过的红线”。第二步拆行为。把产品需求转化成中观规范写出用户可感知的行为流程和可验证的验收标准。第三步原子化。把中观规范拆成一个个能独立开发、独立验证的微观任务每个任务形成一张“任务卡”。第四步交付执行。把任务卡交给 AI Agent 或人类开发者执行按任务卡实现并运行相关测试。第五步验证回归。用自动化测试、代码评审和人工演示三种方式确认结果符合验收标准。第六步回流沉淀。任何最终代码行为与规范不一致时必须回头更新对应的规范文档保证规范永远是最新的事实源。这六步里最容易被忽略的是第六步。很多人把规范写完、代码跑通就觉得结束了结果规范慢慢和代码脱离关系后面再想用 SDD 就难了。规范一旦失真就会变成一个负担AI 读它反而会被误导。4.2 一个完整案例逾期订单自动提醒功能为了让流程更具体我拿最近一个实际场景举例在订单管理平台里增加“逾期订单自动提醒”功能。假设这是一个 B 端订单系统技术栈是 Spring Boot MySQL Redis 消息队列。宏观规范层面我们需要先确认三件事第一订单模块是独立服务订单状态变化只能通过状态机不允许直接改库第二定时任务模块独立部署通过消息队列与订单服务解耦第三通知模块支持短信和站内信两种渠道且所有发送记录都要存审计日志。这些约束不需要每张任务卡重复写但它们会作为模板在后续每张卡里作为“公共背景”被引用。中观规范层面我们把功能行为定义清楚当订单在“待支付”状态停留超过 30 分钟系统自动生成一条逾期提醒记录当停留超过 24 小时再次生成提醒并通过短信发给顾客同时给商家推一条待办事项。提醒最多触发 3 次每次间隔 24 小时。任何已支付或已取消的订单不参与本轮提醒。同时还要明确边界本功能不处理退款申请不修改订单金额不提供手动触发入口。有了前两层就可以把任务切成原子化的微观规范。比如拆成三张任务卡任务卡一在订单服务中新增“查询所有待支付超过 N 分钟的订单”接口入参为时间阈值返回订单 ID 列表分页大小 500。验收标准给定 1 笔 35 分钟前创建的待支付订单和 1 笔 10 分钟前创建的待支付订单只返回前者已支付订单即使超时也不返回。任务卡二在定时任务模块新增一个每 5 分钟执行一次的扫描任务调用上述接口并通过消息队列发送提醒事件。任务卡三在通知模块新增提醒事件的消费逻辑按订单 ID 查重若 24 小时内已发送过同一类型提醒则跳过发送短信和站内信并写入审计日志。你看这三张任务卡每张都包含背景、目标、改动范围和验收标准。哪怕 AI 完全没有这个项目的记忆只凭任务卡上的信息也能以较高精度完成实现而不是靠“猜”。这正是微观规范最核心的价值。实际执行时我会把这些任务卡喂给支持代码库上下文的 AI Agent让它一次性完成实现和基础测试。如果一个任务卡太大、验收项超过五条就说明原子化得还不够需要继续拆。一个良好的微观任务验收标准应该在 3 到 5 条之间这样它的执行确定性最高。5. 边界与踩坑规范过重、误写实现、以及三条自救原则SDD 不是银弹实践过程中最容易踩的坑我基本都踩了一遍。列出来供大家避雷。第一个坑是规范过重。一听到“文档先行”就恨不得把每个按钮的颜色都写进规范里结果规范文档越来越厚到最后连人都不愿意读AI 更是被一堆无关上下文干扰。解决方案是“分层控制”加“粒度控制”宏观和中观规范可以由团队成员共同维护允许相对完整微观规范必须短小精悍一般控制在 15 到 20 行以内超了就该拆。第二个坑是把规范写成了实现伪代码。有些团队在微观规范里写“用 Redis HyperLogLog 实现去重”“通过 for 循环遍历列表”这实际上是替 AI 做实现了。SDD 的核心原则是规范只定义“做什么”和“怎么验收”不定义“怎么做”。一旦你开始规定实现细节就失去了发挥 AI 能力的机会而且还给自己增加了维护成本。我常用的判断标准是如果 AI 按规范写出来后和你预期的实现方式不一样但验收测试都能过那这份规范就是好规范如果你发现它换个实现方式你就接受不了那说明规范里少了一条约束而不是该去规定具体写法。第三个坑是只管生成、不管回归。我见过一些团队把 AI 生成的代码 review 完就上线结果过了两周某个功能因为隐性依赖的模块被改动而出了问题。SDD 模式下规范虽然写清楚了行为但不能保证 AI 生成的代码在所有边界场景下都和系统其他部分完全兼容。所以必须保留自动化测试防线同时在做行为变更时把“影响面描述”也写进中观规范里。比如提醒功能会不会影响订单查询接口的性能会不会重复发送给同一用户这些都在验收标准里明确掉。基于这些教训我总结出三条自救原则平时用来自检。第一条如果 AI 开始“自由发挥”了先别怪 AI回去看规范。说明规范里的约束和边界写得不够给它的任务范围太宽了。第二条如果 AI 读不懂规范大概率不是模型问题而是规范太长或太模糊。试着把任务卡缩短、把验收标准拆细。第三条如果代码评审总在盯着 AI 生成的实现说明规范没立住。你可以把 review 的重心从“代码层面挑毛病”转到“验收测试是否覆盖到规范里的每条规则”这样效率更高也不会陷入 AI 代码风格的争执。我个人在实际项目里的体感是SDD 的收益不是立竿见影的。前两三个迭代会觉得写规范的时间变长了但一旦任务卡模板稳定下来AI 生成的代码一次通过率会明显提高需要人工介入的几率也大幅下降。最爽的一刻是把一张写清楚的微观任务卡丢给 Agent执行完跑测试一次全绿——那种感觉比亲手写代码还有成就感。如果你团队现在正处于“AI 生成代码一时爽维护起来火葬场”的阶段SDD 值得花两周时间试一下。先从一个小模块开始把宏观边界画好把行为拆清楚把任务卡写细跑完一个完整迭代再回头看你大概率也会认同规范的每一分投入最后都会在更可控的代码上连本带利地还回来。

相关新闻