nkds

导航

 

MonkeyCode SDD 规范驱动开发:让 AI 写代码不再靠"盲敲"

告别"AI 盲猜"时代!MonkeyCode 的 SDD(Spec-Driven Development)规范驱动开发模式,让 AI 生成代码像工程师一样有章可循、质量可控。


🤔 传统 AI 编程的痛点

你是否遇到过这些场景?

场景一:
你: "帮我写一个用户登录接口"
AI: [生成了一段看起来能跑的代码]
你: "不对,我需要支持 OAuth2 登录"
AI: "好的,重新生成..." [又生成了新代码]
你: "还要加上限流和日志"
AI: "好的,再重新生成..."
结果:来回折腾了 10 轮,浪费了 1 小时 ❌

场景二:
你让 AI 写了一个模块,看起来没问题
上线后发现:
- 没做输入验证 → 安全漏洞
- 错误处理缺失 → 生产环境崩溃
- 日志不规范 → 排查问题困难
- 测试覆盖不足 → 改一处崩三处
结果:返工成本是开发的 5 倍 ❌

场景三:
团队成员各自用 AI 写代码
风格五花八门,质量参差不齐
新人看不懂,老人不想改
技术债务越堆越多
结果:维护成本直线上升 ❌

根本原因:传统 AI 编程缺乏"规范"!

AI 像一个聪明的实习生——能力很强,但如果你不给它明确的 Spec(规范文档),它只能靠"猜"。猜对了运气好,猜错了就是灾难。


💡 SDD 规范驱动开发是什么?

SDD = Spec-Driven Development(规范驱动开发)

┌─────────────────────────────────────────────────────┐
│                   SDD 工作流                         │
│                                                     │
│   ┌──────────┐    ┌───────────┐    ┌──────────┐    │
│   │ 编写 Spec │ → │ AI 按 Spec │ → │ 自动验证  │    │
│   │ 规范文档  │    │ 生成代码  │    │ 一致性检查 │    │
│   └──────────┘    └───────────┘    └──────────┘    │
│        ↑                                  │         │
│        │                                  ↓         │
│   ┌──────────┐                    ┌──────────┐      │
│   │ 需求分析  │                    │ 质量交付  │      │
│   └──────────┘                    └──────────┘      │
└─────────────────────────────────────────────────────┘

核心理念:

先写规范,再让 AI 执行。不是让 AI 猜你要什么,而是明确告诉 AI 你要什么。

Spec 文档长什么样?

## 用户认证模块 - 技术规范

### 1. 功能需求
- [REQ-001] 支持用户名/邮箱登录
- [REQ-002] 密码最少 8 位,需包含大小写字母和数字
- [REQ-003] 使用 JWT Token 认证,有效期 24 小时
- [REQ-004] 支持忘记密码(邮箱验证码重置)
- [REQ-005] 登录失败 5 次锁定 30 分钟

### 2. 安全要求
- [SEC-001] 密码必须 bcrypt 哈希存储(cost >= 12)
- [SEC-002] JWT Secret 从环境变量读取,禁止硬编码
- [SEC-003] API 限流:每 IP 每分钟最多 10 次
- [SEC-004] 必须通过 OWASP Top 10 安全检查
- [SEC-005] 敏感操作必须记录审计日志

### 3. 技术约束
- 后端框架:Python FastAPI
- 数据库:PostgreSQL 14+
- 缓存:Redis 7+
- 认证方式:JWT Bearer Token

### 4. 接口定义
POST /api/auth/login
Request:
  { "username": "string", "password": "string" }
Response (200):
  { "token": "jwt_string", "expires_in": 86400 }
Response (401):
  { "error": "INVALID_CREDENTIALS" }

### 5. 测试要求
- 单元测试覆盖率 ≥ 80%
- 必须包含正常流程和异常流程测试
- 必须模拟并发登录场景

🚀 MonkeyCode SDD 实战演示

第一步:初始化项目

monkeycode init

# 自动创建项目结构
# ├── .monkeycode/
# │   ├── config.yaml       # 项目配置
# │   └── specs/            # 规范文档目录
# ├── src/                  # 源代码目录
# └── tests/                # 测试目录

第二步:编写 Spec

# 创建认证模块的 Spec
cat > .monkeycode/specs/auth.md << 'EOF'
(上面的完整规范内容)
EOF

第三步:按 Spec 生成代码

# 方式一:CLI 命令
monkeycode gen --spec .monkeycode/specs/auth.md

# 方式二:Git 工作流(推荐)
git add .monkeycode/specs/auth.md
git commit -m "spec: 添加用户认证模块规范 @MonkeyCode 请按此规范实现"

# MonkeyCode 会自动:
# 1. 解析 Spec 文档
# 2. 理解功能需求和安全要求
# 3. 在隔离沙盒中生成代码
# 4. 运行安全扫描(MonkeyScan)
# 5. 生成单元测试
# 6. 提交 PR 等待 Review

第四步:查看生成的代码

# MonkeyCode 生成的代码示例
# src/auth/service.py

"""
用户认证服务模块
Spec: .monkeycode/specs/auth.md
Generated by: MonkeyCode SDD Engine
"""

import bcrypt
import jwt
from datetime import datetime, timedelta
from typing import Optional
from fastapi import HTTPException, status
from ..config import settings
from ..models import User
from ..repositories import UserRepository
from ..security import RateLimiter, AuditLogger


class AuthService:
    """用户认证服务 - 基于 SDD Spec 自动生成"""
    
    def __init__(
        self,
        user_repo: UserRepository,
        rate_limiter: RateLimiter,
        audit_logger: AuditLogger,
    ):
        self._repo = user_repo
        self._limiter = rate_limiter
        self._logger = audit_logger
    
    async def login(
        self, username: str, password: str, ip_address: str
    ) -> dict:
        """
        用户登录 [REQ-001]
        
        Args:
            username: 用户名或邮箱
            password: 明文密码
            ip_address: 客户端 IP
            
        Returns:
            包含 JWT token 的字典
            
        Raises:
            HTTPException: 认证失败时抛出
        """
        # [SEC-003] API 限流检查
        if not await self._limiter.allow(ip_address):
            raise HTTPException(
                status_code=status.HTTP_429_TOO_MANY_REQUESTS,
                detail="请求过于频繁,请稍后再试",
            )
        
        # 查询用户
        user = await self._repo.get_by_username(username)
        if not user:
            # [SEC-005] 审计日志
            await self._logger.log_failed_login(username, ip_address)
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="INVALID_CREDENTIALS",
            )
        
        # [REQ-005] 登录失败锁定检查
        if user.is_locked():
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="ACCOUNT_LOCKED",
            )
        
        # [SEC-001] 密码验证(bcrypt)
        if not bcrypt.checkpw(
            password.encode('utf-8'),
            user.password_hash.encode('utf-8')
        ):
            await self._record_failed_attempt(user, ip_address)
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="INVALID_CREDENTIALS",
            )
        
        # [REQ-003] JWT Token 生成
        token = self._generate_token(user)
        
        # [SEC-005] 成功登录审计
        await self._logger.log_successful_login(user.id, ip_address)
        
        return {
            "token": token,
            "token_type": "bearer",
            "expires_in": 86400,  # 24 小时
        }
    
    def _generate_token(self, user: User) -> str:
        """[SEC-002] JWT Token 生成"""
        payload = {
            "sub": str(user.id),
            "username": user.username,
            "exp": datetime.utcnow() + timedelta(hours=24),
            "iat": datetime.utcnow(),
        }
        return jwt.encode(
            payload,
            settings.JWT_SECRET,  # 从环境变量读取
            algorithm="HS256",
        )
    
    async def _record_failed_attempt(
        self, user: User, ip_address: str
    ) -> None:
        """记录失败的登录尝试"""
        await self._repo.increment_login_attempts(user.id)
        attempts = user.login_attempts + 1
        
        if attempts >= 5:  # [REQ-005]
            await self._repo.lock_user(user.id, minutes=30)
            await self._logger.log_account_locked(user.id, ip_address)

注意生成的代码特点:

  • ✅ 每个函数都有 Spec 引用注释 [REQ-xxx] / [SEC-xxx]
  • ✅ 所有 安全要求都已实现
  • ✅ 包含完整的 类型注解和文档字符串
  • 错误处理完善
  • 审计日志齐全

📊 SDD vs 传统 AI 编程对比

维度 传统 AI 编程 MonkeyCode SDD
需求理解 AI 靠上下文猜测 基于精确 Spec 文档
代码质量 不稳定,依赖 prompt 质量 稳定,符合规范标准
安全性 需要人工审查 自动通过 MonkeyScan 扫描
可追溯性 不知道为什么这样写 每个决策对应 Spec 条目
迭代效率 反复修改 prompt 修改 Spec 即可重新生成
团队协作 各写各的 统一规范,风格一致
测试覆盖 需要额外生成 按 Spec 自动生成测试用例
维护成本 高(代码难懂) 低(有规范文档)

效率提升数据

传统 AI 编程模式:
├─ Prompt 编写: 15 分钟
├─ AI 生成: 2 分钟
├─ 人工 Review: 20 分钟
├─ 发现问题: 10 分钟
├─ 修改 Prompt: 5 分钟
├─ 重新生成: 2 分钟
├─ 再次 Review: 15 分钟
└─ 总计: ~69 分钟(平均 3-5 轮迭代)

MonkeyCode SDD 模式:
├─ 编写 Spec: 20 分钟(一次性投入)
├─ AI 按 Spec 生成: 3 分钟
├─ 自动安全扫描: <1 秒
├─ 自动生成测试: 2 分钟
├─ 人工 Review: 5 分钟(只需确认符合 Spec)
└─ 总计: ~30 分钟(通常 1 轮即可)

效率提升: **56%+** 🔥
且 Spec 可复用,后续类似任务更快!

🛡️ SDD + 安全扫描的双重保障

MonkeyScan 如何与 SDD 协同工作

SDD Spec 定义安全要求
        ↓
   AI 生成代码(遵守 Spec)
        ↓
   MonkeyScan 自动扫描
        ↓
┌───────────────────────┐
│  扫描结果               │
├───────────────────────┤
│ ✅ SQL 注入防护: 通过   │
│ ✅ XSS 防护: 通过      │
│ ✅ CSRF 防护: 通过     │
│ ✅ 密码哈希存储: 通过   │
│ ⚠️ 缺少速率限制头: 已修复│
│ ✅ 审计日志: 通过      │
└───────────────────────┘
        ↓
   输出高质量、安全的代码

实际案例:

# Spec 要求 [SEC-003]: API 限流:每 IP 每分钟最多 10 次

# AI 初始生成(可能遗漏):
@app.post("/login")
async def login(request: Request):
    # ... 登录逻辑 ...
    pass
# MonkeyScan 检测到: ⚠️ 未发现速率限制机制

# MonkeyCode 自动修复后:
@app.post("/login")
async def login(
    request: Request,
    rate_limiter: RateLimiter = Depends(get_rate_limiter),
):
    client_ip = request.client.host
    if not await rate_limiter.allow(client_ip):  # ✅ 自动添加限流
        raise HTTPException(status_code=429, detail="Too many requests")
    # ... 登录逻辑 ...

📁 Spec 最佳实践

1. Spec 编写原则

原则 说明 示例
具体化 避免模糊表述 ❌ "性能要好" → ✅ "响应时间 < 200ms (P99)"
可验证 每个需求都能被测试 ❌ "界面美观" → ✅ "符合 Material Design 3 规范"
完整性 覆盖所有关键场景 包括正常流程、异常流程、边界条件
可追溯 每个需求有唯一编号 [REQ-001], [SEC-001]
层次分明 功能/安全/性能/运维 分开 便于不同角色关注不同部分

2. Spec 模板结构

# [模块名称] - 技术规范

## 1. 概述
[简要描述模块的职责和目标]

## 2. 功能需求
- [REQ-XXX] 具体功能描述
- ...

## 3. 安全要求
- [SEC-XXX] 具体安全要求
- ...

## 4. 性能要求
- [PERF-XXX] 具体性能指标
- ...

## 5. 技术约束
- 使用的框架/库版本
- 编码规范
- 命名约定

## 6. 接口定义
- API 签名
- 请求/响应格式
- 错误码定义

## 7. 测试要求
- 覆盖率目标
- 必须覆盖的场景
- 测试数据要求

3. 团队协作中的 Spec 管理

# Git 工作流中的 Spec 管理

# 1. 产品经理编写需求 Spec
git checkout -b spec/user-auth-requirements
# 编辑 specs/auth.md
git commit -m "spec: 添加认证模块需求规范"
git push origin spec/user-auth-requirements

# 2. 技术负责人补充技术 Spec
git checkout -n spec/user-auth-technical
# 补充安全要求、技术约束等
git commit -m "spec: 补充认证模块技术规范"
git push origin spec/user-auth-technical

# 3. 开发者触发 AI 实现
git checkout main
git merge spec/user-auth-technical
git commit -m "spec: 认证模块规范完成 @MonkeyCode 请按规范实现"

# 4. MonkeyCode 自动实现并提交 PR
# PR 中自动关联 Spec 条目

🔧 进阶技巧

技巧一:Spec 继承与复用

# .monkeycode/specs/base-security.yml
# 通用安全基线(所有模块继承)
security_baseline:
  owasp_top_10: must_pass
  sql_injection: prevention_required
  xss: csp_headers_required
  csrf: token_based
  authentication: jwt_bearer
  authorization: rbac
  rate_limiting: enabled
  audit_logging: sensitive_operations
  secret_management: env_vars_only

# .monkeycode/specs/auth.md
inherits: base-security.yml
# 只需定义认证模块特有的需求

技巧二:Spec 版本管理

# Spec 版本化
.monkeycode/specs/
├── v1.0/
│   └── auth.md          # 初始版本
├── v1.1/
│   └── auth.md          # 增加 OAuth2 支持
└── v2.0/
    └── auth.md          # 重构为微服务架构

# 查看 Spec 变更历史
monkeycode spec diff v1.0/auth.md v2.0/auth.md

# 按 Spec 版本重新生成代码
monkeycode gen --spec v2.0/auth.md --force

技巧三:多语言 Spec 支持

# MonkeyCode Spec 支持多种格式:

# 1. Markdown(推荐)✅
# specs/auth.md

# 2. YAML ✅
# specs/auth.yml

# 3. JSON ✅
# specs/auth.json

# 4. OpenAPI/Swagger ✅
# specs/auth.openapi.yaml

# 选择你最熟悉的格式!

❓ 常见问题 FAQ

Q1: 编写 Spec 不是更费时间吗?

A: 短期看是的,但长期收益巨大:

  • 第一次: 编写 Spec + 生成 ≈ 传统方式时间
  • 第二次及以后: 直接复用/微调 Spec,效率提升 60%+
  • 维护阶段: 有 Spec 文档,新人上手快,维护成本降低 50%

Q2: 我不会写 Spec 怎么办?

A:

  • MonkeyCode 提供 Spec 模板库,涵盖常见场景
  • 可以先用自然语言描述需求,让 AI 辅助生成 Spec
  • 提供交互式 Spec 向导,引导你逐步完善

Q3: SDD 适合哪些项目?

A: 特别适合:

  • 中大型项目(多人协作)
  • 安全敏感型项目(金融、医疗、政务)
  • 长期维护的项目(需要可追溯性)
  • 团队新人较多(需要规范化)

小型个人项目可以简化使用,不必写完整 Spec。

Q4: SDD 和 TDD(测试驱动开发)冲突吗?

A: 不冲突!两者互补:

  • TDD: 先写测试,再写实现(保证正确性)
  • SDD: 先写规范,再让 AI 实现(保证质量和一致性)
  • 最佳实践: SDD + TDD 结合 → Spec 定义需求和测试要求,TDD 验证实现

Q5: 其他 AI 工具也能做 SDD 吗?

A: 理论上可以(把 Spec 放进 prompt),但:

  • MonkeyCode 是原生 SDD 架构,不是事后补救
  • 内置 Spec 解析引擎,不是简单的文本拼接
  • 自动关联 Spec 条目和生成的代码
  • 自动验证 生成代码是否符合 Spec
  • 集成安全扫描,确保符合安全类 Spec 条目

🚀 开始使用 SDD

快速体验(3 步)

# 1. 安装
npm install -g @chaitin/monkeycode
# 或 VS Code 安装 MonkeyCode 插件

# 2. 初始化项目
mkdir my-project && cd my-project
monkeycode init

# 3. 编写你的第一个 Spec
cat > .monkeycode/specs/hello.md << 'EOF'
# Hello World API

## 功能需求
- [REQ-001] GET /api/hello 返回 {"message": "Hello World"}
- [REQ-002] 支持 name 参数自定义问候语

## 安全要求
- [SEC-001] 输入长度限制:name ≤ 100 字符
EOF

# 4. 生成代码
monkeycode gen --spec .monkeycode/specs/hello.md

# 完成!🎉

📚 学习资源

资源 链接
SDD 官方文档 https://docs.monkeycode.cn/sdd
Spec 模板库 https://github.com/chaitin/monkeycode-spec-templates
视频教程 https://space.bilibili.com/monkeycode
社区讨论 https://github.com/chaitin/monkeycode/discussions
问题反馈 https://github.com/chaitin/monkeycode/issues

💬 结语

SDD 不是增加负担,而是减少返工。

在 AI 编程时代,写得快的核心不是敲键盘的速度,而是需求的清晰度。SDD 规范驱动开发让你:

  • 一次说对 — 不再反复修改 prompt
  • 质量可控 — 代码符合预期标准
  • 安全内置 — 安全要求从一开始就满足
  • 团队协同 — 统一规范,降低沟通成本
  • 知识沉淀 — Spec 就是最好的技术文档

从今天开始,试试 MonkeyCode SDD —— 让 AI 写代码不再靠"盲敲"!


🔗 相关链接


本文由 MonkeyCode 团队原创,欢迎转载但请注明出处。如在使用过程中遇到任何问题,欢迎在 GitHub 提 Issue!

🎉 MonkeyCode SDD —— 规范驱动,质量可控,让 AI 成为靠谱的开发伙伴!

posted on 2026-07-06 11:41  MonkeyCode  阅读(22)  评论(0)    收藏  举报