SDD 与超级个体:AI 时代的人机协作范式
最近在思考一个问题:AI 编程工具的真正价值是什么?不是"让机器替代人",而是让人工作在更高的抽象层次上。这个认知转变,带出了一系列关于人机协作、Agent 架构设计的思考。
一、从 Vibe Coding 到 SDD:一个被误解的问题
2024-2025 年,AI 编程助手的爆发带来了一个新词汇——Vibe Coding(基于感觉的编程)。开发者与 AI 对话,AI 即时生成代码,看起来效率惊人。
但这里有一个被普遍忽视的根本矛盾:
Vibe Coding 优化的是"个人编码效率",但工程的真正瓶颈是"团队协作效率"。
一个人写代码快 10 倍,但团队沟通成本不变,整体效率提升极为有限。更糟的是,Vibe Coding 在协作层面制造了新的麻烦:
- PM ↔ 研发:对话历史无法作为契约,验收时各执一词,“这不是我要的”
- 前端 ↔ 后端:各自 vibe,联调时才发现接口格式对不上,浪费 1-2 天
- 后端 ↔ 后端:订单服务调用
POST /inventory/deduct,库存服务只有PUT /stock/reduce,集成测试时 404
这些问题不是工具不够好,而是 Vibe Coding 从根本上缺少一样东西:共同语言。
AI 编程的演进链条
理解 SDD 的必要性,需要先看清 AI 编程工具的演进轨迹——这是一条"问题→解决方案→新问题"的链条:
| 阶段 | 核心问题 | 解决方案 | 遗留问题 |
|---|---|---|---|
| Vibe Coding | 推一步走一步,依赖大量人工精力 | 自动迭代循环(Ralph Loop) | 什么时候停下来? |
| 自动迭代 | 没有明确的完成标准 | 单元测试驱动(测试通过即完成,即 Ralph Loop:编译→测试→修复的自主迭代循环) | 如何生成有意义的测试? |
| 测试驱动 | AI 难以凭空生成有意义的测试 | 规范驱动(从需求生成测试) | 不适合多系统环境 |
| 单应用规范驱动 | 单应用视角,无法处理服务间协作 | 系统行为层(BDD) | 如何串联全流程? |
| BDD | 单独使用时各层独立,缺乏跨系统端到端串联 | 三层 Agent 架构 | — |
这个演进揭示了一个关键洞察:端到端是一个软件工程管理问题,不是纯粹的研发问题。只停留在研发领域(代码生成、测试生成),永远无法做到端到端。必须向上延伸到需求分析,向外扩展到多系统协作。
SDD 的本质:规范先行,协作优先
SDD 的核心逻辑:在写代码前,先用一种"AI 易读、人类可维护"的结构化语言定义系统的每一个细节。
规范驱动开发(Spec Driven Development,SDD)的核心不是"AI 写代码",而是在写代码之前,先用结构化的方式定义"系统应该做什么",让这份规范成为:
- 人类与 AI 之间的契约
- 代码实现的验收标准
- 团队协作的共同语言
这个思想并不新鲜。早在 2000 年代初,Kent Beck 提出 TDD(测试驱动开发)时就包含了"先定义预期,再实现代码"的核心。今天,这一思想在 AI 编程的语境下获得了新生——而且有了更丰富的工程含义。
类比:印刷术的发明不是让抄书匠失业,而是让知识的传播者从"复制者"升级为"创作者"。SDD 的意义与此相同——它不是让 AI 替代人,而是让人从低层级的编码工作中解放出来,去处理更高层的问题。
这就是"超级个体"的由来:不是一个人变得更聪明,而是一个人拥有了原本需要一个团队才能覆盖的能力边界。
超级个体:能力边界的重新定义
"超级个体"这个概念,值得在此多展开一些。
传统意义上,一个软件工程师的能力边界是清晰的:他擅长某个技术栈,熟悉某个业务领域,在团队中承担特定角色。跨越这个边界,需要学习、需要时间、需要经验积累——这是人类认知带宽的自然限制。
AI 工具的出现,并没有消除这个限制,但它大幅降低了跨越边界的摩擦成本。一个后端工程师,借助 AI,可以在不深入学习前端框架的情况下,产出质量可接受的 React 组件;一个研发,借助 AI,可以在不成为产品专家的情况下,将模糊的用户反馈转化为结构化的需求文档。
这不是"万能",而是**“够用”**——在特定场景下,AI 能把一个人的能力从"不会"提升到"够用",从"够用"提升到"熟练"。这个提升,在某些场景下足以让一个人独立完成原本需要 2-3 人协作的工作。
但超级个体的真正价值,不在于"一个人干多个人的活",而在于减少协作中的信息损耗。当一个人能同时理解产品意图、技术实现和测试验收,他就不需要在三个角色之间反复传递信息、对齐理解——而这种对齐成本,往往是团队效率的最大杀手。
SDD 正是超级个体的工程基础设施:它提供了一套结构化的语言(Gherkin、OpenAPI、Spec),让一个人能够在不同抽象层次之间自如切换,同时保持各层之间的一致性。没有这套基础设施,超级个体只是"一个人同时做多件事";有了它,才是"一个人在统一的认知框架下驱动多个层次的工作"。
二、正确的使用姿势:AI 代替已解决的问题
在讨论具体的使用姿势之前,需要建立一个核心认知框架:
软件工程效果 = 模型能力(基础) × 上下文质量(决定性因素)
其中,上下文包含领域知识、编码规范、历史经验——这些知识需要显性化。构建上下文是 AI 软件工程的核心活动。
这个公式揭示了一个常被忽视的事实:模型能力只是基础,真正决定输出质量的是上下文的丰富度和准确性。没有准确上下文的 AI,就像一个拥有超高智商但缺乏领域知识的新手——能快速学习,但容易犯错。
基于上述认知,AI 的正确使用姿势变得清晰:
不是让 AI 代替自己,而是让 AI 代替那些已经被解决的、重复的、昂贵的问题。
更进一步,有一个更激进但也更务实的原则:
凡是 AI 已能稳定胜任的,原则上都应优先交由 AI 完成。
这不是对 AI 的盲目信任,而是对人机协作效率的理性计算。当 AI 能够稳定、一致地完成某项任务时,继续由人工介入只会引入不必要的延迟和人为错误。人类的精力应该集中在那些真正需要判断力、创造力和跨领域整合的工作上——而不是与 AI 争夺那些它已然擅长的领域。
这里有一个关键区分:
| 类型 | 特征 | 应该由谁处理 |
|---|---|---|
| 已解决的问题 | 有明确答案、可重复执行、规则清晰 | AI |
| 新问题 | 边界模糊、需要判断、涉及权衡 | 人 |
AI 的价值在于稳定、一致地输出——它不会因为疲劳而出错,不会因为情绪而走神。当 AI 稳定地处理已知领域,人就可以把精力投入到拓展工作场域上,去解决那些还没有答案的问题。
这是一种正向循环:AI 处理旧问题 → 人解决新问题 → 新问题被解决后成为旧问题 → AI 接管 → 人继续探索更新的问题。
三、Spec 的理论根基:TDD 家族
SDD 的"规范先行"思想,有一套完整的理论谱系支撑——TDD 家族。理解这个谱系,才能理解 SDD 为什么有效,以及如何在不同层次上落地。
TDD 家族的分层体系
这四个方法论并非互斥,而是在不同抽象层次上相互补充:
1 | |
产物驱动:每层的输出是下一层的输入
这里有一个关键洞察,值得单独点出:TDD 家族的三层不只是"并列的方法论",而是一条产物驱动的流水线——每一层的输出文档,就是下一层的输入上下文。
这也是近两年不少 SDD 实践会采用的工作流:
1 | |
为什么 ATDD 和 BDD 都产出 Gherkin?
细心的读者可能注意到:ATDD 层和 BDD 层都产出"Gherkin(Given-When-Then 场景)",这有什么区别?
关键区别在于视角和抽象层次:
| 层级 | 视角 | Gherkin 描述的对象 | 主角是谁 |
|---|---|---|---|
| ATDD | 用户视角(黑盒) | 用户与系统的交互行为 | 用户 |
| BDD | 系统视角(白盒) | 系统内部各模块的协作行为 | 服务/模块 |
具体来说:
-
ATDD 层的 Gherkin(用户行为):描述的是用户故事,主角是"用户",关注的是"用户看到什么、做什么、得到什么"。PM 可以直接阅读并确认,不需要了解系统内部结构。
1
2
3
4
5# ATDD 层:用户行为 Gherkin
Scenario: 成功提交订单
Given 用户已登录,购物车中有商品
When 用户点击"提交订单"
Then 用户应该看到订单号 -
BDD 层的 Gherkin(系统行为):描述的是服务间协作,主角是"服务/模块",关注的是"哪个服务做什么、服务间如何协作"。需要了解系统的技术架构才能编写。
1
2
3
4
5# BDD 层:系统行为 Gherkin
Scenario: 订单服务调用库存扣减
Given 订单服务收到创建请求
When 调用库存服务的 POST /inventory/deduct 接口
Then 库存服务返回 200,库存数量减少
两者都使用 Gherkin 语法,但抽象层次不同——ATDD 是"黑盒视角"(用户不知道系统内部),BDD 是"白盒视角"(知道系统由哪些服务组成、如何协作)。这就是为什么它们需要分两个阶段、由不同角色的 Agent 来处理。
Augment Code 的研究将这一流程总结为五个阶段:Specify → Plan → Tasks → Implement → Debug,与上述三层有较强的对应关系。也有一些业界分析把 SDD 的重点概括为"将规划阶段(生成 spec)和实现阶段(生成代码)分离"——而分离的介质,就是这些层层传递的结构化文档。
这个机制的价值在于:每一层的产物都是对上一层意图的精确化和可验证化。用户故事 Gherkin 把模糊的 PRD 变成可确认的场景;系统行为 Gherkin 把单一的用户故事拆解为多个服务的职责边界;单元测试把系统行为变成可自动执行的验证。每一步都在减少歧义,每一步都在增加可验证性。
BDD 的核心创新在于:规范不仅是文档,还是可直接执行的测试。Gherkin 语法让 PM 能读懂、研发能执行、测试能自动化:
1 | |
这份 Gherkin 是 PM 与研发的共同契约:PM 可以直接阅读确认,研发以此为开发目标,测试将其转化为自动化用例。验收时,双方对着同一份文档检查,而不是各执一词。
四、企业级挑战:Spec 无法独立生成代码
理解了 TDD 家族之后,还需要面对一个现实:现有的 Spec 驱动工具(Spec-Kit、OpenSpec、Kiro 等)都有一个共同的隐含假设——
一个 Spec 对应一个应用。
但企业级开发的现实是:一个需求需要多个职责分明的应用协同完成。
以"用户下单后自动扣减库存"为例,这个看似简单的用户故事,实际上涉及一系列无法从 Spec 直接得出的决策:
| 问题 | 需要决策 |
|---|---|
| 谁负责扣减? | 订单服务同步调用?库存服务异步处理? |
| 失败怎么办? | 重试?补偿?人工处理? |
| 如何保证一致性? | 分布式事务?最终一致性? |
| 前端需要感知吗? | 立即反馈?后台通知? |
这些决策不是 Spec 能回答的,而是需要技术方案设计。这正是现有工具缺失的关键环节:
1 | |
存量知识:proposal 质量的天花板
在理解了"一个需求需要多个应用协同"这个挑战之后,还有一个更深层的问题值得正视:即使有了完整的 Spec 驱动流程,生成的 proposal 质量仍然受制于一个先决条件——知识库里的存量有多准确。
这里的"知识库"不局限于某种特定形式,可以是 project.md、AGENTS.md、service-catalog.yaml,也可以是 specs/ 目录下的历史规范——凡是 AI 在生成 proposal 之前会读取的上下文,都属于存量知识。
存量知识的作用链条是这样的:
1 | |
存量设计的偏差会在这条链条上逐级放大。如果 service-catalog.yaml 里记录的库存服务能力已经过时,AI 生成的 proposal 就会基于错误的前提做出功能归属判断;如果 specs/ 里的历史规范与代码实际行为不符,AI 生成的接口契约就会与现实脱节。这不是 AI 的问题,而是 GIGO(Garbage In, Garbage Out)在 AI 工程中的具体表现。
这个认知带来一个实践结论:在大规模工程开始之前,维护准确的存量知识,比优化 prompt 更重要。 存量知识是 proposal 质量的天花板——天花板不够高,再好的 AI 也只能在低处徘徊。
五、分层 Agent 架构:按工程流程拆分 SDD
解决上述矛盾的方案,是按 TDD 家族的层级关系拆分 Spec 驱动流程,每一层由专门的 Agent 负责。
三层 Agent 模型
flowchart TB
subgraph L1["🔍 PRD 分析 Agent(ATDD 层)"]
A1["输入:PRD 需求文档"]
A2["输出:用户行为 Gherkin(PM 可读可确认)"]
A3["价值:PM ↔ 研发的协作契约"]
A1 --> A2 --> A3
end
subgraph L2["🏗️ 技术方案设计 Agent(BDD + UTDD 层)"]
B1["输入:用户行为 Gherkin"]
B2["输出:接口契约 + 各应用系统行为 Gherkin + 任务分配清单"]
B3["价值:研发 ↔ 研发的协作规范"]
B1 --> B2 --> B3
end
subgraph L3["⚙️ 代码开发 Agent(执行层)"]
C1["输入:系统行为 Gherkin + 接口契约"]
C2["输出:可编译运行的代码 + 通过的单元测试"]
C3["模式:TDD 红绿重构循环,逐场景执行"]
C1 --> C2 --> C3
end
L1 -->|"用户行为 Gherkin"| L2
L2 -->|"系统行为 Gherkin + 接口契约"| L3
style L1 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style L2 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style L3 fill:#fff3e0,stroke:#ff9800,stroke-width:2px
关键洞察:Agent 不只是"代码生成器",更是"协作规范生成器"。分层架构的核心价值,是让团队在开发前就对齐预期,而不是在联调时才发现问题。
协作成本的前置解决
| 协作关系 | 问题根源 | 分层 Agent 的解决方案 |
|---|---|---|
| PM ↔ 研发 | 需求理解不一致 | PRD 分析 Agent 生成 Gherkin,双方共同确认 |
| 前端 ↔ 后端 | 接口定义不一致 | 技术方案 Agent 生成接口契约,开发前对齐 |
| 后端 ↔ 后端 | 服务协作不明确 | 技术方案 Agent 定义服务间协作规范 |
与其在联调时发现问题并返工,不如在开发前就通过 Spec 对齐预期。
端到端工程实践:从阶段到接口
理解了三层 Agent 模型之后,还需要一套具体的工程实践来支撑落地。以下是一个前后端端到端交付项目的完整工程流程。
四阶段交付流程
一个完整的端到端项目,通常经历四个阶段:
| 阶段 | 输入 | 产出 | 方式 |
|---|---|---|---|
| 阶段一:需求分析 | PRD + 历史需求 | 结构化需求文档 | AI 做结构化分析 → 人工确认修正 |
| 阶段二:UI 设计 | 需求文档 | UI 原型 | AI 生成 → Iteration 反馈迭代 |
| 阶段三:详细设计 | 需求 + UI 稿 | 接口契约 + 领域模型 + 数据模型 | AI 生成 → 人工评审关键决策 |
| 阶段四:代码生成(ATDD 驱动) | 设计文档 + 参考代码 | 可运行代码 + 测试用例 | 先测试(红灯)→ 代码(绿灯) |
这四个阶段与三层 Agent 架构高度对应:需求分析对应 PRD 分析 Agent,详细设计对应技术方案设计 Agent,代码生成对应代码开发 Agent。UI 设计作为前端专属阶段,在详细设计之前完成,为接口契约提供前端视角的输入。
小步快跑:接口级迭代循环
在代码生成阶段,坚持小步快跑的节奏——每一轮只实现一个接口,完成后才进入下一轮:
flowchart LR
START(["🚀 开始新接口"]) --> IMPL
IMPL["⚙️ 实现接口\n(含单元测试)"] --> TEST
TEST["🧪 测试验证\nRalph Loop 通过"] --> REVIEW
REVIEW["👀 Code Review\n人工审查"] --> CONFIRM
CONFIRM{"✅ 确认通过?"}
CONFIRM -->|"是"| NEXT["➡️ 进入下一个接口"]
CONFIRM -->|"否"| FIX["🔧 修复问题"]
FIX --> TEST
style START fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style IMPL fill:#e3f2fd,stroke:#2196f3
style TEST fill:#e3f2fd,stroke:#2196f3
style REVIEW fill:#fff3e0,stroke:#ff9800
style CONFIRM fill:#f3e5f5,stroke:#9c27b0
style NEXT fill:#e8f5e9,stroke:#4caf50
style FIX fill:#fce4ec,stroke:#e91e63
为什么要小步快跑? 每个接口都是一个可验证的交付单元。接口粒度的迭代让问题暴露得更早、修复成本更低,同时也让 Review 的认知负担保持在可控范围内——审查一个接口的实现,远比审查一个功能模块的全量代码更容易发现问题。
测试八问:接口级质量门禁
每个接口开发时,遵循测试八问作为质量门禁——这八个问题覆盖了接口可能遇到的所有典型场景,确保测试覆盖不留盲区:
| # | 问题 | 必须有测试覆盖 |
|---|---|---|
| 1 | 正常路径是否可走通? | 创建成功、查询有数据 |
| 2 | 必填参数缺失会如何? | 返回参数错误 |
| 3 | 参数格式错误会如何? | 类型不匹配、超长、负数 |
| 4 | 关联数据不存在会如何? | 父资源不存在时的处理 |
| 5 | 重复操作会如何? | 幂等性验证 |
| 6 | 边界值会如何? | 0、-1、空、最大值 |
| 7 | 状态流转是否正确? | 非法状态转换拒绝 |
| 8 | 并发操作会如何? | 同时操作不冲突 |
测试八问与 Ralph Loop 形成互补:Ralph Loop 保证"测试通过才算完成",测试八问保证"测试本身是有意义的"。没有测试八问的约束,AI 可能生成只覆盖正常路径的测试,让 Ralph Loop 在一个不完整的测试集上通过——这是一种更隐蔽的"偷懒"。
领域驱动分工与外部记忆
在团队协作层面,由领域资深工程师牵头,按以下顺序组织工作:
1 | |
纵横切分的含义:
- 纵切:按业务功能切分(订单、库存、支付各自独立)
- 横切:按技术层次切分(接口层、服务层、数据层分别实现)
两个维度的切分共同作用,确保每个 Agent 的单次任务粒度足够小,避免上下文过载——这是 AI 协作中最常见的失败模式之一。
基于文件的外部记忆是应对上下文限制的关键机制。在工作过程中,将关键决策、进度状态、接口契约持久化到文件系统,而不是依赖对话上下文:
| 场景 | 外部记忆的价值 |
|---|---|
| 快速恢复上下文 | 新开一个 Agent 会话时,读取文件即可还原工作状态 |
| 多人协作 | 不同开发者的 Agent 通过共享文件同步进度,避免重复工作 |
| 上下文超限 | 即使对话历史被截断,关键信息仍保存在文件中,不丢失 |
这正是本章目录约定的深层价值:.specs/ 目录不只是"规范存放处",更是团队协作的外部记忆载体——每个 Agent 的输出都写入文件,每个 Agent 的输入都从文件读取,上下文通过文件而非对话历史传递。
落地:数据流与目录约定
三层 Agent 之间通过约定好的目录结构传递数据,无需额外的编排层:
1 | |
其中,服务目录是技术方案设计 Agent 的核心依赖——它描述了当前环境有哪些服务可用,以及每个服务的能力边界,Agent 据此做出功能归属判断:
1 | |
这个约定的价值在于:Agent 之间通过文件系统解耦,每个 Agent 只需读取上一层的输出文件,写入自己的输出文件,无需了解其他 Agent 的内部实现。
工具链落地:OpenSpec 完整实操指南
理解了目录约定之后,一个自然的问题是:这些 Spec 文件由谁来管理?格式是否有要求?能否借助工具自动生成?
OpenSpec 可以看作这类规范管理工具中的一个轻量实现。它的核心理念与本文的 SDD 思想相当接近:在写代码之前,先让人类与 AI 就规范达成共识(align before code)。
OpenSpec 是一个轻量级的 SDD 工具链,通过标准化的目录结构和 CLI 命令,让开发者在写代码之前先与 AI 就需求规范达成共识。它解决了 AI 辅助编程中的三个核心问题:如何让 AI 理解项目上下文、如何规范需求描述格式、如何沉淀已实现的功能知识。OpenSpec 的核心机制包括项目知识库(project.md)、变更提案(proposal.md)、需求规范(spec.md)和实现任务清单(tasks.md),通过 init、new、apply、archive 四个核心命令,实现了从需求到代码的完整闭环。
更详细的实战教程:如果你希望了解 OpenSpec 的完整实操步骤(包括安装、初始化、核心概念详解、目录结构详解、完整工作流程等),请参考独立文章 OpenSpec 实战教程:从入门到精通,那里包含了从零开始使用 OpenSpec 的完整示例和最佳实践。
工具机制选择:Skills vs Slash Commands vs MCP vs Hooks
在构建 SDD 工作流时,一个关键问题是:生成脚手架、单元测试、集成测试、Mock、实现记忆等任务,应该使用哪种工具机制来实现?
这涉及 AI 编程工具生态中的四种核心机制:
| 机制 | 触发方式 | 典型用途 | 特点 |
|---|---|---|---|
| Skills | 自动激活(基于描述匹配) | 领域知识注入、工作流自动化 | 上下文感知,零摩擦触发 |
| Slash Commands | 手动调用 | 可重复工作流、参数化任务 | 显式控制,适合标准化流程 |
| MCP | 外部服务集成 | 数据库、API、文件系统访问 | 突破沙箱,连接真实世界 |
| Hooks | 事件驱动 | 质量门禁、自动化检查 | 在特定时机自动执行,不可绕过 |
核心决策框架
选择哪种机制,取决于三个维度:
- 触发模式:自动触发(Skills/Hooks)vs 手动触发(Slash Commands)
- 上下文需求:需要丰富上下文(Skills)vs 需要外部资源(MCP)
- 执行确定性:概率性输出(Skills 调用 LLM)vs 确定性执行(MCP/脚本)
flowchart TB
Q1{"需要自动触发?"}
Q2{"需要外部资源?<br/>(数据库/API/文件系统)"}
Q3{"需要概率性推理?<br/>(创意/判断/模糊匹配)"}
Q4{"需要在特定时机强制执行?"}
Q1 -->|"是"| Q3
Q1 -->|"否"| Q2
Q3 -->|"是"| SKILL["🎯 <b>Skills</b><br/>自动激活 + LLM 推理"]
Q3 -->|"否"| Q4
Q4 -->|"是"| HOOK["🔒 <b>Hooks</b><br/>事件驱动 + 强制执行"]
Q4 -->|"否"| SCRIPT["⚙️ <b>确定性脚本</b><br/>自动触发 + 精确执行"]
Q2 -->|"是"| MCP["🔌 <b>MCP</b><br/>外部服务集成"]
Q2 -->|"否"| SLASH["📝 <b>Slash Commands</b><br/>手动触发 + 可重复工作流"]
style SKILL fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style MCP fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style SLASH fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style HOOK fill:#fce4ec,stroke:#e91e63,stroke-width:2px
style SCRIPT fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
六项任务的具体分析
1. 生成脚手架 → Slash Command
- 理由:脚手架生成是显式触发的任务,需要用户指定项目名称、模板类型等参数,属于"可重复工作流"
- 实现:
/scaffold <template> <project-name>,支持参数化配置 - 为什么不选 Skill:脚手架生成不需要自动触发,用户明确知道何时需要创建新项目
2. 生成单元测试 → Skill
- 理由:单元测试生成是 TDD 工作流的自然组成部分,应该在检测到新代码或代码变更时自动激活
- 实现:Skill 描述包含"检测到新增函数/类时,自动生成对应的单元测试框架"
- 为什么不选 Slash Command:测试驱动开发的核心是"测试先行"或"测试同步",不应该要求用户手动触发
3. 生成集成测试 → Skill + MCP
- 理由:集成测试需要了解服务间依赖关系,可能需要访问服务目录、API 定义等外部资源
- 实现:Skill 负责推理"测试什么、如何测试",MCP 负责获取服务目录和接口定义
- 协作模式:Skill 调用 MCP 工具获取上下文,再基于上下文生成测试
4. 生成 Mock → Skill + 确定性脚本
- 理由:Mock 生成分为两个阶段:决策(哪些接口需要 Mock、返回什么数据)和执行(生成 Mock 文件)
- 实现:Skill 负责决策(概率性推理),脚本负责生成 Mock 文件(确定性执行)
- 原则:遵循"概率与确定性分离"原则——LLM 决定"What",脚本执行"How"
5. 实现记忆 → CLAUDE.md + PKB Skill
- 理由:记忆分为两类:持久化规范(存放在
CLAUDE.md/AGENTS.md)和动态知识(通过 PKB Skill 管理) - 实现:
CLAUDE.md:项目级规范,如编码风格、架构决策(极低频变更)- PKB Skill:管理个人/团队级的品味、规范、规则,支持冷热分层和自动归档
- 协作模式:CLAUDE.md 提供静态上下文,PKB Skill 提供动态知识注入
6. 特定代码生成 → 视情况而定
- 模板化代码(CRUD、DTO):确定性脚本,效率优先
- 业务逻辑代码:Skill,需要领域知识注入
- 涉及外部 API 的代码:Skill + MCP,需要获取 API 定义
SDD 工作流的 Skill 化架构
将上述决策应用到三层 Agent 架构:
1 | |
理论支撑:近两年的常见实践
这一决策框架,与近两年 AI 编程工具社区里常见的分工思路大体一致:
- Anthropic 官方文档:Skills 用于"上下文增强和自动触发",MCP 用于"外部服务集成",两者互补而非替代
- Claude Code 最佳实践:Write-Time Hooks(如 plankton)证明"强制执行"比"事后检查"更有效
- Cursor 社区:Slash Commands 适合"可重复的复杂工作流",Skills 适合"零摩擦的自动化"
核心洞察:机制选择不是"非此即彼",而是"各司其职"。正确的做法是:
- 让 Skills 处理"什么时候该做什么"(自动感知)
- 让 Slash Commands 处理"用户明确要求的重复任务"(显式控制)
- 让 MCP 处理"需要外部资源"(连接真实世界)
- 让 Hooks 处理"强制执行的质量门禁"(不可绕过)
代码开发层:Ralph Loop 防偷懒机制
我们正在进入这样一个时代:10 倍开发者(10x Developer)的核心技能不再是解决复杂 Bug 的能力,而是设计自动化测试体系与反馈循环的能力——这些机制能让模型的十六个并行实例替他们解决问题。
代码开发 Agent 面临一个特殊挑战:AI 模型在 TDD 场景下容易"偷懒"——声称"测试已通过"但实际没运行,或跳过 Red 阶段直接写实现。
解决方案是引入 Ralph Loop(由 Geoffrey Huntley 提出)——一种自主迭代机制:
1 | |
flowchart TD
START(["🚀 开始:Agent 接收场景任务"]) --> COMPILE
COMPILE["⚙️ 执行编译检查\nmvn compile"]
COMPILE -->|"编译失败 ❌"| FIX_COMPILE["🔧 修复编译错误"]
FIX_COMPILE --> COMPILE
COMPILE -->|"编译通过 ✅"| TEST
TEST["🧪 执行单元测试\nmvn test"]
TEST -->|"测试失败 ❌"| FIX_TEST["🔧 修复实现代码"]
FIX_TEST --> COMPILE
TEST -->|"测试通过 ✅"| LINT
LINT["📋 代码规范检查\ncheckstyle / spotbugs"]
LINT -->|"规范不符 ❌"| FIX_LINT["🔧 修复代码风格"]
FIX_LINT --> COMPILE
LINT -->|"规范通过 ✅"| DONE
DONE(["✅ 完成:所有检查通过\nAgent 声明本场景完成"])
style START fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style DONE fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style COMPILE fill:#e3f2fd,stroke:#2196f3
style TEST fill:#e3f2fd,stroke:#2196f3
style LINT fill:#e3f2fd,stroke:#2196f3
style FIX_COMPILE fill:#fff3e0,stroke:#ff9800
style FIX_TEST fill:#fff3e0,stroke:#ff9800
style FIX_LINT fill:#fff3e0,stroke:#ff9800
关键在于 Backpressure(反压)机制:用编译结果和测试结果验证 AI 的输出,防止自欺欺人。只有当所有检查都通过时,Agent 才能声明完成。
| 验证手段 | 作用 |
|---|---|
| 编译检查 | 语法正确性 |
| 单元测试 | 逻辑正确性 |
| 代码规范检查 | 代码质量 |
| 类型检查 | 契约一致性 |
这套机制的本质,是把"完成"的定义权从 AI 手中夺回来,交给客观的验证标准。
从源头约束:Shift Left 与 Write-Time Quality Gates
Ralph Loop 解决的是"生成后验证"的问题,但在 SDD 的多步骤流水线中,一个更深层的挑战是:迭代后半程的输出量太大,Code Review 压力过重。几百行 Spec 可能产生几千行代码,问题发现越晚,修复成本越高。
这个问题的解决思路是 Shift Left(左移)——将质量约束从 Review 阶段前移到代码生成阶段,甚至生成之前。
Plan/Spec Mode:生成前的意图对齐
Claude Code 的 Plan Mode(Shift+Tab 切换)提供了一个非破坏性的规划阶段:
- 只读探索:Plan Mode 下禁止写入文件,AI 只能读取代码、分析依赖、输出规划
- 意图显式化:人类确认规划无误后,再进入执行阶段
- 避免返工:在生成代码前对齐预期,而不是在 Review 时发现问题
OpenAI Codex 团队也在探索类似能力(GitHub Discussion #7355),核心设计问题是:模态 vs 非模态、持久化 vs 临时、访谈式 vs 自由形式。社区反馈强烈倾向于硬模态切换——明确的 Plan Mode 能提供安全感和可预测性。
Write-Time Quality Gates:写入时强制检查
plankton 项目(GitHub: alexfazio/plankton)将 Shift Left 推向极致:
“Code quality gate enforcement at write-time — The agent is blocked from proceeding until its output passes your checks”
其核心是 Claude Code Hooks 的三阶段流水线:
1 | |
关键机制:
- PreToolUse Hook:在工具调用前拦截,阻止不符合规范的代码写入磁盘
- Config Tamper-Proof:禁止 AI 修改 lint 配置来绕过检查
- Model Routing:简单问题用小模型,复杂问题用大模型,节省 Token
这套机制的价值在于行为塑造——AI 在生成代码时就知道约束存在,会主动避免违规,而不是生成后再被动修复。
分层 Agent 中的约束映射
将 Shift Left 思想应用到三层 Agent 架构:
| 层级 | 约束目标 | 机制 |
|---|---|---|
| PRD 分析 Agent | Gherkin 完整性 | Skill 约束:必须使用 Given-When-Then,覆盖正常+异常路径 |
| 技术方案 Agent | 架构合理性 | Skill 约束:明确服务边界、幂等性、失败策略 |
| 代码开发 Agent | 代码质量 | Write-Time Gates:编译检查 → 静态分析 → 单元测试 |
核心洞察:约束不是限制 AI 的能力,而是将人类的工程经验编码为可执行的质量门禁。与其在 Review 时反复指出同类问题,不如让 Skill 在生成时就避免这些问题。
这与 Ralph Loop 形成互补:
- Ralph Loop:生成后验证,确保输出正确
- Shift Left + Write-Time Gates:生成前/生成中约束,减少错误产生
两者结合,才能从根本上缓解 SDD 流水线后半程的 Review 压力。
六、上下文管理:Skills 渐进披露机制
分层 Agent 架构还需要解决一个技术层面的根本限制:LLM 的上下文窗口是有限的。
当 Agent 拥有大量 Skill(技能)时,会遇到一个矛盾:
- Skill 越多,Agent 能力越强
- 但把所有 Skill 的完整内容都加载进上下文,Token 消耗巨大,且注意力会被稀释(无关信息越多,模型对关键指令的遵循能力越弱)
这就是上下文拥挤问题(Context Crowding)。
解决方案:声明层 + 实现层的分离
聪明的做法是将 Agent 的能力库分为声明层和实现层,通过多趟调度实现按需加载:
这里还有一个更深层的协作原则值得强调:
对话优于僵硬指令,协作上下文优于单纯追求更强模型。Spec 的正确性,会直接影响项目成败。
这意味着:
- 对话优于指令:与其给 AI 一长串静态指令,不如通过多轮对话逐步澄清意图、修正理解。对话是动态的、可迭代的,能够暴露假设、消除歧义。
- 上下文优于模型:与其一味追求更强大的模型,不如投入在更精确的协作上下文(Spec)上。一个准确的 Spec 能让普通模型表现出色,而一个错误的 Spec 即使交给更强模型,也可能南辕北辙。
Spec 的正确性是项目的质量天花板——天花板不够高,再好的 AI 也只能在低处徘徊。
flowchart TB
L0["🗂️ <b>Level 0: 语义注册表</b><br/>Skill 名称 + 简短描述 + 参数 Schema<br/>Token 消耗:极低 | LLM 角色:Router"]
L1["📖 <b>Level 1: 渐进式加载器</b><br/>按需加载选中 Skill 的完整 Prompt/文档<br/>Token 消耗:中等 | LLM 角色:Planner"]
L2A["🤖 <b>Level 2A: LLM 生成</b><br/>非结构化、创意任务<br/>概率性输出"]
L2B["⚙️ <b>Level 2B: 确定性脚本</b><br/>结构化、逻辑严密任务<br/>精确执行,零概率误差"]
L0 -->|"路由选择"| L1
L1 -->|"执行决策"| L2A
L1 -->|"执行决策"| L2B
style L0 fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
style L1 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style L2A fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style L2B fill:#fff3e0,stroke:#ff9800,stroke-width:2px
关键洞察:LLM 不需要知道所有 Skill 的细节,只需要知道"有哪些 Skill 可用"(注册表)。一旦选定 Skill,再加载细节。这就像操作系统的动态链接库——程序启动时不加载所有库,只在调用时才链接。
在实践中,Skills 使用标准化的目录结构组织业务知识:
1 | |
这套机制的核心思想:不是一次性加载所有背景,而是按需分批加载。就像程序员需要时查阅文档,而不是先背诵所有文档一样。
为什么要引入确定性脚本(Script)?
这是架构中最精妙的一层。LLM 是概率模型,它的输出本质上是"最可能正确的答案",而不是"一定正确的答案"。对于精确计算、严格的格式转换、数据库查询、文件系统操作,让 LLM 去"模拟"这些操作,既昂贵又不可靠。
正确的做法是:LLM 决定调用哪个脚本,脚本负责精确执行。
| 维度 | LLM | 确定性脚本 |
|---|---|---|
| 擅长 | 意图理解、模糊处理、创意生成 | 精确计算、严格逻辑、一致输出 |
| 不擅长 | 精确计算、完全一致的重复输出 | 理解自然语言、处理歧义 |
LLM 是指挥官,Script 是工兵。不要让指挥官去挖战壕,也不要让工兵去制定战略。
七、三大设计原则
阅读说明:本章的三条原则聚焦于 Agent 架构设计层面——如何构建高效的 AI Agent 系统(上下文管理、概率与确定性分离、规范先行)。第九章的五条原则则聚焦于 SDD 工程实践层面——如何在团队中落地规范驱动开发(规范先行、分阶段验证、规范即上下文、警惕 Spec 瀑布、Bug 是 Spec 缺口)。两套原则视角不同、互为补充,共同构成 AI 时代人机协作的完整工程哲学。
从上述架构模式中,可以提炼出构建高效 AI Agent 的三条设计原则。
graph LR
P1["🎯 原则一<br/><b>上下文最小化</b><br/>Minimal Context Exposure<br/>摘要·索引·注册表作为入口<br/>细节按需披露"]
P2["⚖️ 原则二<br/><b>概率与确定性分离</b><br/>Probabilistic vs Deterministic<br/>LLM 负责意图与变化<br/>Script 负责精确与可靠"]
P3["📋 原则三<br/><b>规范先行</b><br/>Specification First<br/>Human 定义 What & Why<br/>AI 处理 How"]
P1 -->|"降低 Token 消耗<br/>提升注意力集中度"| P2
P2 -->|"LLM 调用 Script<br/>Function Call 机制"| P3
P3 -->|"规范驱动上下文<br/>最小化加载"| P1
style P1 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style P2 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style P3 fill:#fff3e0,stroke:#ff9800,stroke-width:2px
原则一:上下文最小化(Minimal Context Exposure)
“The model should only know what it needs to know to make the next immediate decision.”
永远不要把所有知识一次性灌输给 LLM。上下文是稀缺资源,过多的无关信息会产生两个副作用:
- Token 浪费:直接的成本问题
- 注意力稀释(Attention Dilution):LLM 的注意力机制会被无关内容分散,导致对核心指令的遵循能力下降
实践:使用摘要(Summary)、索引(Index)和注册表(Registry)作为入口,细节按需披露。
原则二:概率与确定性分离(Separation of Probabilistic and Deterministic Logic)
“Use LLMs for intent and variability; use Scripts for precision and reliability.”
实践:通过 Function Call(工具调用)机制实现——LLM 输出结构化的调用意图,运行时将其路由到对应的确定性代码。
原则三:规范先行(Specification First)
“Humans define the ‘What’ and ‘Why’; AI handles the ‘How’.”
这是对整篇文章人机协作哲学的技术化表达:
- Human:定义接口(Interface)、约束(Constraints)、验收标准(Acceptance Criteria)
- AI:填充实现细节(Implementation)
人类从"写代码(Coding)"升级为"设计系统(System Designing)“和"审查(Reviewing)”。这不是降低了人的价值,而是提升了人工作的抽象层次,让人能够统摄更大的系统复杂度。
八、完整案例演练:用户下单功能
理念最终要落地。以"用户下单"这个经典场景为例,走一遍三层 Agent 的完整流程。
flowchart LR
subgraph Input["📄 输入"]
PRD["PRD 需求文档\n用户下单功能"]
end
subgraph Step1["🔍 Step 1: PRD 分析 Agent"]
G1["生成用户行为 Gherkin\n成功下单 / 库存不足场景"]
PM["✅ PM 确认契约"]
G1 --> PM
end
subgraph Step2["🏗️ Step 2: 技术方案设计 Agent"]
SC["读取服务目录\norder-service / inventory-service"]
SG["生成系统行为 Gherkin\n× 各服务职责边界"]
TA["输出任务分配清单\n开发顺序建议"]
SC --> SG --> TA
end
subgraph Step3["⚙️ Step 3: 代码开发 Agent"]
RED["🔴 RED\n写失败测试"]
GREEN["🟢 GREEN\n最小实现通过"]
NEXT["➡️ 下一场景"]
RED --> GREEN --> NEXT --> RED
end
subgraph Output["✅ 输出"]
CODE["可编译代码\n+ 通过的单元测试"]
end
PRD --> G1
PM -->|"用户行为 Gherkin"| SC
TA -->|"系统行为 Gherkin\n+ 接口契约"| RED
NEXT -->|"所有场景完成"| CODE
style Input fill:#f5f5f5,stroke:#9e9e9e
style Step1 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style Step2 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style Step3 fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style Output fill:#fce4ec,stroke:#e91e63,stroke-width:2px
Step 1:PRD 分析 Agent → 用户行为 Gherkin
输入(.specs/prd/user-order.md):
1 | |
输出(.specs/user-behavior/user-order.feature):
1 | |
这份 Gherkin 是 PM 与研发的共同契约,PM 可以直接阅读确认,无需理解任何技术细节。
Step 2:技术方案设计 Agent → 系统行为 + 接口契约
Agent 读取服务目录,分析每个场景涉及的能力点,匹配到对应服务,然后输出:
功能归属判断:
| 用户行为步骤 | 匹配能力 | 归属服务 |
|---|---|---|
| “用户提交订单” | 订单创建 | order-service |
| “库存应该扣减” | 库存扣减 | inventory-service |
| “用户应该看到订单号” | 用户界面展示 | frontend-app |
输出:订单服务系统行为(.specs/system-behavior/order-service.feature):
1 | |
输出:任务分配清单(.specs/system-behavior/task-assignment.md):
| 服务 | 任务 | 依赖 |
|---|---|---|
| 库存服务 | 实现 POST /inventory/deduct |
无 |
| 订单服务 | 实现 POST /orders |
库存服务接口 |
| 前端 | 实现下单页面 | 订单服务接口 |
开发顺序建议:库存服务(无依赖)→ 订单服务 → 前端。
Step 3:代码开发 Agent → TDD 实现
Agent 按 Red-Green-Refactor 循环逐场景实现,Ralph Loop 在后台持续验证:
Round 1 - RED:先写失败的测试
1 | |
运行测试 → 编译失败,OrderService 不存在 ❌
Round 2 - GREEN:写最小实现,测试通过 ✅
Round 3:继续下一个场景,直到所有 Gherkin 场景都有对应的通过测试。
flowchart LR
subgraph TDD["🔄 TDD Red-Green-Refactor 循环"]
RED["🔴 RED\n先写失败的测试\n编译失败 / 断言失败"]
GREEN["🟢 GREEN\n写最小实现\n让测试通过"]
REFACTOR["🔵 REFACTOR\n重构代码\n保持测试通过"]
RED -->|"实现代码"| GREEN
GREEN -->|"优化结构"| REFACTOR
REFACTOR -->|"下一个场景"| RED
end
subgraph RALPH["🔁 Ralph Loop 外层保障"]
CHECK["编译 + 测试 + 规范检查\n全部通过才能退出"]
end
REFACTOR -->|"场景完成,进入验证"| CHECK
CHECK -->|"有失败 → 回到修复"| GREEN
CHECK -->|"全部通过 ✅"| NEXT["➡️ 下一个 Gherkin 场景"]
NEXT --> RED
style RED fill:#ffebee,stroke:#f44336,stroke-width:2px
style GREEN fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style REFACTOR fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style CHECK fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style NEXT fill:#f3e5f5,stroke:#9c27b0
整个过程中,Ralph Loop 持续运行编译和测试检查。只有当所有检查都通过时,Agent 才能退出循环,声明完成。
案例小结
这个案例展示了三层 Agent 的核心价值:
- PRD 分析 Agent:把模糊的需求文档转化为 PM 和研发都能确认的 Gherkin 契约
- 技术方案设计 Agent:把单一的用户故事拆解为多个服务的职责边界和协作规范
- 代码开发 Agent:在 Ralph Loop 的约束下,确保每一行代码都有对应的测试覆盖
三层之间通过文件系统传递数据,每一层的输出都是下一层的输入,形成一条从 PRD 到代码的完整流水线。
九、SDD 的五项核心原则
如果说第七章讨论的是 Agent 架构怎么设计,那么这里要收束的是 SDD 在工程实践中如何落地。下面五条原则更偏交付、协作与质量控制,而不是再重复一次前面的架构讨论。
原则一:规范先行,而非文档补写
"先定义预期,再实现代码"——不是写完代码后的文档补充,而是驱动实现的前置契约。
传统软件开发中,文档往往扮演着"事后说明"的角色:代码写完后,再补一份设计文档或接口说明。这种模式下,文档与代码脱节是常态,"文档过时"成为永恒的抱怨。
SDD 彻底反转这一顺序:
| 传统模式 | SDD 模式 |
|---|---|
| Code → Document → 维护时文档已过时 | Spec → Code → Spec 即验收标准 |
| 验收时各执一词 | 双方对着同一份 Gherkin 确认 |
| 接口变更靠口头同步 | 接口契约变更需更新 Spec |
规范先行的本质,是将"意图"从隐性的对话历史中提取出来,固化为可验证、可传递的结构化知识。 这正是 OpenSpec 工作流中 proposal.md → tasks.md → spec.md 的核心价值——在写第一行代码之前,人类与 AI 必须先就"要做什么"达成共识。
原则二:分阶段验证,拒绝模糊推进
每一层都有明确的完成标准和验证机制,拒绝"差不多行了"的模糊推进。
Vibe Coding 的最大风险在于进度幻觉——AI 声称"完成了",但实际上只是输出了看起来合理的代码,并未经过客观验证。SDD 通过分层验证机制解决这一问题:
1 | |
关键机制:
| 层级 | 验证手段 | 拒绝模糊的方式 |
|---|---|---|
| PRD 分析 | PM 人工审查 Gherkin | 未确认不进入下一层 |
| 技术方案 | 服务目录匹配 + 架构评审 | 功能归属不明确不分配任务 |
| 代码实现 | Ralph Loop 强制检查 | 编译/测试/规范任一失败即阻塞 |
这种**分阶段门控(Stage-Gate)**机制,将"完成"的定义权更多交给客观可验证的标准。实践里未必每个团队都会采用同样严格的门禁,但核心思想是一致的:不要让未经验证的产物一路向下游扩散。
原则三:规范即上下文,赋能多 AI 协同
Spec 不仅是人与 AI 的契约,更是多 Agent 协同的"共同语言"和上下文载体。
当多个 Agent 协作完成一个需求时,最大的挑战是上下文传递——如何让 Agent B 理解 Agent A 的输出,并在此基础上继续工作?
SDD 的解决方案是:让 Spec 成为上下文本身。
1 | |
规范作为上下文的三重价值:
- 契约价值:人与 AI 之间的承诺——“你按这个规范实现,我按这个规范验收”
- 验收价值:代码实现的客观标准——“测试通过即符合规范”
- 协作价值:团队共同语言——PM、研发、测试对着同一份文档工作
这也回到了文章开篇的主线:Vibe Coding 最大的问题不是代码写得快不快,而是缺少可共享、可传递、可验证的共同语言;Spec 的价值,恰恰在于把这种共同语言显式化。
原则四:警惕 Spec 瀑布,拒绝 Markdown 怪兽
规范是必要的,但过度的规范是负担。警惕 Spec 瀑布,不要制造 Markdown 怪兽。
SDD 强调"规范先行",但这不意味着要写无穷无尽的文档。实践中存在一个危险的陷阱:为了规范而规范,最终产生大量无人阅读、无人维护的 Markdown 文件,成为项目的累赘而非资产。
Spec 瀑布的表现:
| 反模式 | 症状 | 后果 |
|---|---|---|
| 过度设计 | 一个简单需求产出 50 页 Spec | 维护成本超过实现成本 |
| 文档膨胀 | 每个变更都要更新 5 个文件 | 开发者逃避更新,文档迅速过时 |
| 形式重于内容 | 追求完美的格式而非清晰的意图 | Spec 成了表演,而非协作工具 |
健康的 Spec 应该遵循"刚好足够"原则:
- 长度:能说明白即可,不追求篇幅
- 格式:工具可解析即可,不追求排版
- 维护:变更时顺手更新,不成为额外负担
记住:Spec 的价值在于减少沟通成本,而不是增加文档工作量。 当你发现写 Spec 的时间超过了写代码的时间,就是 Spec 瀑布的警告信号。
原则五:Bug 是 Spec 缺口,而非代码问题
很多值得长期修复的 Bug,最终都应该回到源头——在 Spec 文档中补上缺口。
传统观念认为 Bug 是代码写错了,但在 SDD 的视角下,Bug 的本质是 Spec 的缺口——要么是 Spec 没有覆盖这个场景,要么是 Spec 的描述不够精确,导致实现偏离了预期。
Bug 根因分析:
| Bug 类型 | 传统视角 | SDD 视角 |
|---|---|---|
| 边界条件未处理 | 代码遗漏 | Spec 未定义边界行为 |
| 异常流程报错 | 异常处理缺失 | Spec 未覆盖异常场景 |
| 功能与需求不符 | 实现错误 | Spec 描述模糊,理解有歧义 |
| 性能不达标 | 算法优化不足 | Spec 未定义性能验收标准 |
在源头闭合缺口意味着:
- 发现 Bug 时,先问 Spec:这个场景在 Spec 中有定义吗?定义清晰吗?
- 修复 Bug 时,先改 Spec:补充缺失的场景描述,明确预期行为
- 验证修复时,对照 Spec:确保实现与更新后的 Spec 一致
这不是在推卸代码质量的责任,而是尽量把质量保障左移到更便宜的阶段——越早发现问题,修复成本通常越低。
一个无法回写到 Spec 的 Bug 修复,往往还不算完整。 只有把缺口补回规范层,团队才更有机会避免它以别的形式再次出现。
把这五条放在一起看,它们更像一组彼此制衡的工程准则:
graph TB
P1["📋 原则一<br/>规范先行<br/>定义 What"]
P2["✅ 原则二<br/>分阶段验证<br/>确保 Quality"]
P3["🤝 原则三<br/>规范即上下文<br/>赋能 Collaboration"]
P4["⚠️ 原则四<br/>警惕 Spec 瀑布<br/>保持 Lightweight"]
P5["🐛 原则五<br/>Bug 是 Spec 缺口<br/>源头闭合"]
P1 -->|"驱动"| P2
P2 -->|"验证"| P3
P3 -->|"反馈"| P1
P1 -.->|"约束"| P4
P2 -.->|"约束"| P4
P3 -.->|"约束"| P4
P4 -->|"保障"| P5
style P1 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style P2 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style P3 fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style P4 fill:#fce4ec,stroke:#e91e63,stroke-width:2px
style P5 fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
- 规范先行回答了"做什么"
- 分阶段验证约束了"什么时候算完成"
- 规范即上下文支撑了"如何协作传递"
- 警惕 Spec 瀑布提醒我们不要把规范本身做成负担
- Bug 是 Spec 缺口则要求把经验真正沉淀回体系
它们共同指向一个更务实的目标:让规范既能驱动实现,又不反过来拖垮实现。
十、总结
这几个层次的思考,实际上是同一个核心洞见在不同尺度上的展开:
1 | |
graph TB
L1["🧠 哲学层<br/>人 → 高层决策 | AI → 低层执行"]
L2["❓ 问题层<br/>Vibe Coding 优化个人效率<br/>SDD 优化团队协作效率"]
L3["📐 方法论层<br/>已解决的问题 → AI<br/>新问题 → 人"]
L4["⚙️ 工程层<br/>PRD → 用户行为 Spec → 技术方案<br/>→ 系统行为 Spec → Code"]
L5["🏗️ 架构层<br/>注册表(路由)→ 按需加载(规划)<br/>→ 脚本(执行)"]
L6["🔧 实践层<br/>目录约定(解耦)→ Ralph Loop(防偷懒)<br/>→ 服务目录(归属判断)"]
L1 -->|"指导"| L2
L2 -->|"落地为"| L3
L3 -->|"实现于"| L4
L4 -->|"支撑于"| L5
L5 -->|"约束于"| L6
style L1 fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
style L2 fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
style L3 fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style L4 fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style L5 fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style L6 fill:#fce4ec,stroke:#e91e63,stroke-width:2px
AI 的演进方向,是从"生成器"转变为"调度器"和"决策器"。而人的演进方向,是从"操作员"晋升为"架构师"。
Vibe Coding 时代,我们关注"如何让 AI 更快地写出代码"。SDD 时代,我们关注"如何让团队更高效地协作"。理念落地的关键,是把三层 Agent 架构从概念变为可运行的实现——而这需要的不只是工具,更是一套工程约定。
这不是零和游戏,而是一场认知升维的协作。而这一切的核心,仍然是那个从 Kent Beck 时代就开始的理念:先定义预期,再实现代码。





