从Vibe Coding到Spec Coding:一套可落地的AI-SDD企业级研发工程框架

写在前面

2025年,Andrej Karpathy提出"Vibe Coding"时,描述的是一种近乎直觉的编程方式:用自然语言描述意图,AI直接生成代码,开发者只需"感受"结果并不断调整。这种方式在原型阶段确实快得惊人------我见过有人一个下午就用AI搓出了一个完整的管理后台。

但当你试图把它搬到团队协作和生产环境 时,问题很快浮现:代码风格混乱、边界条件遗漏、架构漂移,以及那个被反复提及的 "90天墙" ------三个月后,代码库变成了一团没人敢动、难以理解和维护的代码。

Spec Coding 正是为了解决这些问题而生的

一句话概括:在让AI写代码之前,先用结构化文档(Spec)把"要做什么、怎么做、有什么约束"说清楚,然后AI围绕这份文档编码。

本文记录了我从踩坑规范驱动工具,到最终沉淀出一套可落地、可复制的AI-SDD企业级研发工程框架的完整历程。如果你也在"AI工具明明很强但就是用不好"的困境中挣扎,希望能给你一些启发。

一、为什么开源SDD工具还不够?

1.1 Spec Kit与OpenSpec:两种思路

目前主流的开源SDD框架主要有两个:

Spec Kit(GitHub出品,28K+ Star) 走的是"重流程、强规范"路线。它定义了从Constitution(宪章)→ Specify(规范)→ Plan(计划)→ Tasks(任务)→ Implement(实施)的五个固定阶段,每个阶段对应一个命令,必须按顺序执行。

OpenSpec 则相反,走的是"轻量、灵活"路线,通过Delta机制只记录变更操作本身,不存储完整的未来状态,更适合存量项目迭代。

它们解决的是 "规范化"问题------让AI的输出不再天马行空。但腾讯后端团队的技术负责人rickyshou在用了三个月Speckit后选择放弃,他的总结非常到位:

"Speckit的规范流程在企业需求的'千层套路'、海量代码面前显得理想化,上下文窗口频繁爆满 让复杂任务半途而废,每次做类似需求还是要花同样的时间因为知识全在人脑里。"

1.2 三个核心痛点

结合腾讯团队的实践和我自己的踩坑经历,开源SDD工具在企业场景下主要有三个问题:

痛点 具体表现
上下文窗口爆满 Spec Kit要求一次性加载全部规范,复杂项目轻松撑爆AI上下文
知识不沉淀 这次做登录花2小时,下次做支付花2小时,知识全在人脑里,无法复用
流程太死 5阶段流程是线性的,但企业需求是动态的、会反复的,越规范越难应对变化

那怎么办?放弃SDD吗?

不。rickyshou的解决方案给了我很大启发:从"规范驱动"升级为"上下文工程 + 复合工程" ------让AI在正确的时刻拿到正确的信息,让知识持续沉淀、复用。

下面就是我基于这个思路,结合前后端分离、反向同步、模式沉淀等实践,沉淀出的一套完整框架。

二、AI-SDD工程框架:核心设计

2.1 三条铁律

在展开具体设计之前,先明确三条不可妥协的铁律:

铁律一:No Spec, No Code ------没有文档,不准写代码。AI在没有约束的情况下生成代码,其试错成本远高于你写几行规范的时间。

铁律二:Spec is Truth ------当文档和代码冲突时,错的一定是代码。Spec是唯一的权威来源。

铁律三:Reverse Sync(反向同步) ------发现Bug或需求变更时,先修文档,再修代码。如果每次都直接改代码,Spec会迅速腐烂,失去对AI的约束能力。

改一行Spec的成本,远低于改一百行代码。

2.2 目录结构:前后端分离 + 资产独立

这是整套框架的物理基础。每个Feature都是一个独立的原子单元,自带完整上下文。

text

复制代码
期次-2026-07-月报功能/                     # 项目根目录
├── 00-项目总览/                           # 📋 全局资产(所有Feature共享)
│   ├── CONSTITUTION.md                   # 全局宪法(技术栈、命名、异常码)
│   ├── PROJECT_GRAPH.md                  # 依赖图谱与状态看板
│   ├── PATTERNS/                         # 🧠 经验模式库(只增不减)
│   │   ├── README.md                     # 模式索引
│   │   └── auth-pattern.md               # 用户认证模式(含踩坑记录)
│   └── RULES/
│       └── conflict-resolution.md        # 代码与Spec冲突裁决规则
│
└── Feature-001-用户登录/                  # 🎯 第一个功能特性
    ├── _shared/                          # 🔗 前后端共享资产
    │   ├── API_CONTRACT.yaml             # OpenAPI 契约(唯一事实源)
    │   └── business-rules.md             # 通用业务规则
    ├── backend/                          # 🟦 后端专属目录
    │   ├── REQ.md                        # 后端需求
    │   ├── prototypes/                   # 后端逻辑图
    │   │   ├── sequence-login.png
    │   │   └── db-schema.png
    │   └── TASK.md                       # 原子任务(流程、产出、验收)
    └── frontend/                         # 🟩 前端专属目录
        ├── REQ.md                        # 前端需求
        ├── prototypes/                   # UI设计稿
        │   ├── ui-login.png
        │   └── ui-error-state.png
        └── TASK.md                       # 原子任务(流程、产出、验收)

这个结构解决了什么?

  • 前后端真正并行API_CONTRACT.yaml作为唯一锚点,后端AI据此实现真实接口,前端AI据此生成TypeScript类型和Mock数据。两者可同时开工,互不阻塞。

  • 上下文精准控制 :每个Feature的TASK.md自带"上下文加载清单",AI只加载当前任务必需的5~7个文件,Token消耗降低约60%。

  • 知识持续沉淀PATTERNS/目录只增不减,每个Feature完成后AI自动总结可复用模式。

2.3 核心文件示例

全局宪法:CONSTITUTION.md

markdown

复制代码
# 项目全局宪法

## 1. 技术栈强制规范
- **后端框架**: Spring Boot 3.2.5 (Java 17)
- **ORM**: MyBatis-Plus 3.5.5
- **数据库**: MySQL 8.0,字符集 utf8mb4
- **缓存**: Redis 7.0
- **JWT**: jjwt-api 0.11.5
- **前端框架**: Vue 3.4 + TypeScript + Vite
- **UI组件库**: Element Plus

## 2. 命名铁律
- **Java类**: 驼峰命名 (如 `UserController`)
- **数据库表**: 小写+下划线 (如 `sys_user`)
- **接口路径**: 复数名词,如 `/api/v1/users`

## 3. 异常码区间
| 区间 | 含义 |
| :--- | :--- |
| 1000-1999 | 参数校验错误 |
| 2000-2999 | 认证授权错误 |
| 3000-3999 | 业务逻辑冲突 |
| 5000-5999 | 系统内部错误 |

## 4. 强制约束
- 所有后端接口必须包含 Swagger 注解
- 所有写操作必须加 `@Transactional`
- **本宪法优先级高于任何口头约定**
接口契约:API_CONTRACT.yaml

yaml

复制代码
openapi: 3.0.3
info:
  title: 用户认证API
  version: 1.0.0
paths:
  /api/v1/auth/login:
    post:
      summary: 用户登录
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - phone
                - password
              properties:
                phone:
                  type: string
                  pattern: '^1[3-9]\d{9}$'
                  description: 手机号(11位)
                password:
                  type: string
                  minLength: 6
                  maxLength: 20
      responses:
        '200':
          description: 登录成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                    example: 0
                  data:
                    type: object
                    properties:
                      accessToken:
                        type: string
                      userId:
                        type: integer
后端原子任务:backend/TASK.md

markdown

复制代码
# 原子任务:后端 - 用户登录接口

## 📝 变更履历
| 日期 | 版本 | 变更摘要 | 作者 |
| :--- | :--- | :--- | :--- |
| 2026-06-29 | v1.0 | 初始创建 | 架构师 |

## 1. 上下文加载清单(AI开发前必须逐项读取)
- [ ] `../../00-项目总览/CONSTITUTION.md`
- [ ] `../../00-项目总览/PROJECT_GRAPH.md`
- [ ] `../_shared/API_CONTRACT.yaml`(最高优先级)
- [ ] `../_shared/business-rules.md`
- [ ] `./REQ.md`

## 2. 产出物清单(AI完成后填写)
| 类型 | 预期路径 | 实际生成路径 | 状态 |
| :--- | :--- | :--- | :--- |
| Controller | `src/.../AuthController.java` | ___________ | ⬜ |
| Service | `src/.../AuthService.java` | ___________ | ⬜ |
| ServiceImpl | `src/.../AuthServiceImpl.java` | ___________ | ⬜ |
| DTO | `src/.../LoginReq.java` | ___________ | ⬜ |
| 单元测试 | `src/test/.../AuthControllerTest.java` | ___________ | ⬜ |

## 3. 验收标准(AC)
- [ ] AC-01: 接口响应时间 < 200ms
- [ ] AC-02: 单元测试覆盖率 ≥ 90%
- [ ] AC-03: 集成测试通过(含Redis模拟)

## 4. 开发完成签名
> **签名**: __________ | **日期**: __________
经验模式沉淀:PATTERNS/auth-pattern.md

markdown

复制代码
# P-001: 用户认证与JWT生成模式

## 1. 适用场景
- 新项目需要用户登录功能
- 需要生成包含用户信息的Token

## 2. 技术栈锁定
- Spring Boot 3.2 + jjwt-api 0.11.5
- 密钥存储于环境变量 `JWT_SECRET`

## 3. 核心实现片段
```java
public String generateToken(Long userId, String role) {
    return Jwts.builder()
        .setSubject(userId.toString())
        .claim("role", role)
        .setIssuedAt(new Date())
        .setExpiration(new Date(System.currentTimeMillis() + 7200000))
        .signWith(getSignKey(), SignatureAlgorithm.HS256)
        .compact();
}

4. 踩坑记录(⚠️ 必读)

  • 坑点 : 未在拦截器中处理 ExpiredJwtException,导致返回HTTP 500

  • 解决: 全局异常处理器增加统一捕获,返回HTTP 401

  • 坑点: Redis连接超时未处理,导致登录接口熔断

  • 解决 : 增加 @Retryable 重试机制,并降级为"允许登录但不计数"

5. 复用Checklist

  • 修改 JWT_SECRET 环境变量

  • 调整 setExpiration 过期时长

  • 确认Redis连接池配置

text

复制代码
### 2.4 冲突裁决规则

当代码与Spec冲突时,AI不能“瞎猜”。我们设计了**三级裁决机制**:

| 级别 | 场景 | 处理方式 |
| :--- | :--- | :--- |
| **L1 - 明确冲突** | Spec有明确定义,代码违反 | AI**立即修正代码**,无需人工 |
| **L2 - Spec缺陷** | Spec定义不清或自相矛盾 | AI**暂停并提问**,不得自行脑补 |
| **L3 - 环境不可行** | Spec方案在当前环境不可行 | AI**升级至架构评审** |

将此规则写入 `RULES/conflict-resolution.md`,AI每次开发前自动加载。

## 三、实战:在Qcoder/Trae中落地

有了设计,接下来是如何在工具中跑起来。核心策略是:

> **“宪法进规则(Rules),流程进技能(Skills),数据放项目”**

### 3.1 文件放哪里?

| 内容类型 | 存放位置 | 说明 |
| :--- | :--- | :--- |
| `CONSTITUTION.md`、`PROJECT_GRAPH.md`、`PATTERNS/` | 项目目录 `期次-xxx/00-项目总览/` | 数据资产,AI按需读取 |
| 各Feature的 `REQ.md`、`TASK.md`、`API_CONTRACT.yaml` | 项目目录 `Feature-xxx/` | 原子任务数据 |
| 核心宪法与裁决规则摘要 | Qcoder: `.qoder/rules/`<br>Trae: `.trae/rules/` | **始终生效**的刚性约束 |
| 后端/前端开发流程 | Qcoder: `.lingma/skills/`<br>Trae: `.trae/skills/` | **按需加载**的标准化流程 |

### 3.2 Rules配置(始终生效)

**Qcoder**: 保存为 `.qoder/rules/constitution-rule.md`
**Trae**: 保存为 `.trae/rules/constitution-rule.md`,并在界面中设为“Always Apply”

```markdown
---
ruleType: always-apply
---

# 项目核心宪法与冲突裁决规则(AI必须无条件遵守)

## 1. 核心原则
- **反向同步铁律**: 代码与Spec冲突时,**必须先更新Spec,再修改代码**
- **Spec是唯一事实源**: 当文档和代码冲突时,错的一定是代码

## 2. 冲突裁决规则
- L1 - 明确冲突: Spec有定义,代码违反 → 立即修正代码
- L2 - Spec缺陷: Spec不清或矛盾 → 暂停,提交裁决
- L3 - 环境不可行: Spec方案不可行 → 升级至架构评审

## 3. 规则优先级
1. 本规则文件(最高优先级)
2. 项目中的 `CONSTITUTION.md`
3. 口头或对话中的临时指令

3.3 Skills配置(按需加载)

Qcoder : 存放在 .lingma/skills/feature-backend-dev/SKILL.md

Trae : 存放在 .trae/skills/feature-backend-dev/SKILL.md

yaml

复制代码
---
name: feature-backend-dev
description: 基于Feature目录的后端原子任务开发
version: 4.0.0
---

# 角色定位
你是资深后端开发工程师,严格遵循反向同步原则。

# 强制前置流程
当用户指派你开发某个Feature的后端时:
1. 定位到 `Feature-XXX/backend/` 目录
2. 读取 `TASK.md` 中的“上下文加载清单”
3. 按清单逐项加载所有Spec文件
4. 检查 `PROJECT_GRAPH.md` 中的上游依赖状态
5. 若发现Spec冲突,按冲突裁决规则处理

# 核心开发
- 100%匹配 `API_CONTRACT.yaml` 实现接口
- 严格遵循 `CONSTITUTION.md` 命名规范
- 完成后运行单元测试,确保所有AC通过

# 强制后置流程(反向同步 + 知识沉淀)
1. 填写 `TASK.md` 中的产出物清单和签名
2. 若有偏离Spec的调整,先回写Spec文件
3. 更新 `PROJECT_GRAPH.md` 状态为 `✅ 已完成`
4. 检查是否有可复用逻辑,若有则沉淀到 `PATTERNS/`

3.4 在Qcoder/Trae中的实际使用

单兵作战(你一个人干前后端)

  1. 输入:@feature-backend-dev 开发 Feature-001 用户登录

  2. AI按流程读文件、写后端代码、更新状态

  3. 后端完成后,输入:@feature-frontend-dev 开发 Feature-001 用户登录

  4. AI读取同一个 API_CONTRACT.yaml 生成前端页面和Mock数据

团队并行(前后端同时开发)

  • 后端会话:@feature-backend-dev 开发 Feature-001

  • 前端会话:@feature-frontend-dev 开发 Feature-001

  • 两个AI同时读取 API_CONTRACT.yaml,后端写真实接口,前端生成Mock数据,互不阻塞

需求变更(反向同步实战)

  • 你在后端会话中说:"登录接口入参加上 Integer age,且必须 ≥ 18岁"

  • 后端AI自动执行:

    1. 修改 API_CONTRACT.yaml(加age字段和校验)

    2. 修改 TASK.md(更新变更履历)

    3. 修改 PROJECT_GRAPH.md(将前端任务状态回退为"待回归")

  • 前端AI下次启动时重新读取契约,自动感知到age字段的新增

四、这套框架解决了什么?

4.1 与开源工具的对比

对比维度 Spec Kit / OpenSpec 本套AI-SDD框架
上下文管理 全量加载,容易爆满 原子任务按需加载,精准控制
前后端协作 未做角色分离 API契约锚定,Mock驱动并行
需求变更 流程僵化,变更成本高 反向同步铁律:先改Spec再改代码
知识沉淀 仅保留Spec文件 模式库(PATTERNS)+ 踩坑记录
冲突处理 无明确规则 三级裁决机制,有法可依
工具适配 绑定特定命令链 通用Markdown + Skill,适配多工具

4.2 精准命中三大痛点

腾讯团队放弃Speckit的原因 本框架的解法
上下文频繁爆满,复杂任务半途而废 原子任务按需加载,每个任务仅5~7个文件,永不爆满
知识不沉淀,每次做类似需求同样耗时 PATTERNS/模式库强制沉淀,下次自动复用+避坑
流程太死,应对不了动态变化 Skill流程灵活可控,反向同步机制专门应对变更

五、总结

这套框架的定位是:

"一套面向AI原生团队的、基于规范驱动的、包含多个可复用模式的企业级研发工程框架。"

它不是最重的方案,也不是最轻的,而是在团队协作性知识复用性流程灵活性 三者之间找到了最佳平衡点的生产级AI研发基座

核心理念可以浓缩为一句话

让AI在正确的时刻拿到正确的信息,让知识持续沉淀、持续复用。

如果你正在从"Vibe Coding"走向"Spec Coding"的路上,希望这套框架能帮你少走一些弯路。


框架还在持续演进中,欢迎在评论区交流你的实践经验和改进建议。
项目下载地址https://gitee.com/windfullsheng/my-sdd

https://github.com/windfallsheng/my-sdd

相关资源