Cursor + OpenSpec 开发工作流:从Vibe Coding到Spec-Driven Development的工程实践
引言:AI编程时代的困境与出路
过去一年,AI编程助手的能力突飞猛进。Cursor、Claude Code、GitHub Copilot 等工具让开发者能够以惊人的速度生成代码。然而,随着项目规模扩大,一种普遍存在的困境开始浮现:
5次对话后,AI还在跑偏需求。
需求散落在聊天记录里,再也找不到。
改完代码后,没人记得当初为什么要这么设计。
这种被称为"Vibe Coding"(凭感觉编程)的开发模式,虽然适合快速原型验证,但在企业级软件开发中,却引入了不可接受的风险-4。代码质量不可预测、需求追溯困难、团队协作混乱——这些问题正在困扰着越来越多的开发团队。
OpenSpec 正是为解决这些问题而生。它是一个轻量级的规范驱动开发(Spec-Driven Development, SDD)框架,与 Cursor 深度集成,通过"先写规范,再写代码"的工作流,让AI编程从不可预测的"聊天模式"转变为可预测的"工程模式"。
本文将系统性地介绍 Cursor + OpenSpec 的开发工作流,从安装配置到实际应用,帮助你在享受AI编程效率的同时,保证代码质量和团队协作的规范性。
一、Vibe Coding的痛点:为什么需要规范驱动开发?
1.1 Vibe Coding的真实困境
想象这样一个场景:
你在Cursor中告诉AI:"添加用户认证功能,支持邮箱登录和手机号登录"。
AI生成了一堆代码,但漏掉了密码加密;
你补充说:"需要密码加密";
AI加了加密,但又忘记加登录失败次数限制;
你又补充...如此循环5轮后,代码终于勉强能用,但谁也说不清最终实现了什么。
这就是Vibe Coding的典型困境-4:
| 痛点 | 具体表现 |
|---|---|
| 需求偏移 | AI对模糊指令的自由发挥,导致实现与预期不符 |
| 上下文丢失 | 需求只存在于聊天历史,无法复用和追溯 |
| 范围失控 | 没有明确边界,AI可能添加不需要的功能 |
| 审计困难 | 变更没有记录,不知道"为什么这样设计" |
1.2 Vibe Coding vs 规范驱动开发
| 维度 | Vibe Coding | 规范驱动开发 (SDD) |
|---|---|---|
| 开发方式 | 模糊提示 → AI生成代码 | 规范 → 审查 → AI实现 |
| 需求载体 | 聊天记录 | 结构化的spec文件 |
| 可追溯性 | 低 | 高,变更全流程可查 |
| 团队协作 | 困难,各自为战 | 容易,共享规范 |
| 适用范围 | 原型、个人项目 | 企业级、团队项目 |
1.3 OpenSpec的解决方案
OpenSpec 通过"提案-审查-实施-归档"的四阶段工作流,将AI编程从"凭感觉聊天"转变为"按规范开发"-4。其核心思想是:
在编写任何代码之前,先就"要构建什么"达成明确共识。
这种转变将AI助手从"随机建议的来源"转变为"执行锁定计划的可靠工程工具"-4。
二、OpenSpec核心概念与工作流
2.1 什么是OpenSpec?
OpenSpec是一个开源、轻量级的规范驱动开发框架,专为AI编程助手设计-1-2。它通过结构化的目录和文件,让AI和开发者在开始编码前就需求达成一致。
核心特点:
-
轻量化:无需API密钥,最小化配置
-
棕地优先:不仅适用于新项目,更擅长修改现有项目
-
AI原生:与Cursor等工具深度集成,支持slash命令
-
可审计:每个变更都有完整记录
2.2 核心目录结构
初始化OpenSpec后,会在项目根目录创建以下结构-8:
your-project/
├── openspec/
│ ├── config.yaml # 项目配置
│ ├── specs/ # 当前规范(已实现的功能)
│ │ └── [capability]/
│ │ └── spec.md
│ └── changes/ # 变更提案(待实现的功能)
│ └── [change-name]/
│ ├── proposal.md # 为什么改、改什么
│ ├── design.md # 技术设计(可选)
│ ├── tasks.md # 实现任务清单
│ └── specs/ # 规范增量(修改了什么)
│ └── [capability]/
│ └── spec.md
└── .cursor/
└── commands/ # Cursor斜杠命令
├── openspec-proposal.md
├── openspec-apply.md
└── openspec-archive.md
2.3 核心工件说明
| 工件 | 用途 | 关键内容 |
|---|---|---|
proposal.md |
变更提案 | Why(为什么改)、What Changes(改什么)、Impact(影响范围) |
spec.md |
需求规范 | 功能需求、场景描述、验收标准 |
design.md |
技术设计 | 架构决策、接口定义、关键技术选型 |
tasks.md |
任务清单 | 可执行的实现步骤,每步1-2小时 |
2.4 四阶段工作流
┌────────────────────┐
│ 1. 起草变更提案 │ ← 用自然语言描述需求,AI生成proposal、spec、tasks
└────────┬───────────┘
│
▼
┌────────────────────┐
│ 2. 审查与对齐 │ ← 人与AI迭代优化,直到达成共识
└────────┬───────────┘
│
▼
┌────────────────────┐
│ 3. AI驱动实施 │ ← AI按照tasks.md逐项实现代码
└────────┬───────────┘
│
▼
┌────────────────────┐
│ 4. 归档并更新规范 │ ← 将approved变更合并回specs,成为新的真相来源
└────────────────────┘
2.5 核心设计原则:Specs与Changes分离
OpenSpec将当前真相来源(specs/)与提议更新(changes/)分离-4-8:
-
specs/:已实现功能的稳定规范,AI参考的上下文
-
changes/:进行中的变更提案,每个变更独立文件夹
这种分离防止了上下文漂移和范围蔓延。类比Git:
-
specs/= master分支(稳定真相) -
changes/= 功能分支(隔离的更新)
三、Cursor + OpenSpec集成指南
3.1 前置要求
-
Node.js >= 20.19.0(执行
node --version检查) -
Cursor IDE(最新版本)
-
npm 或 pnpm
3.2 安装与初始化
步骤1:全局安装OpenSpec CLI
npm install -g @fission-ai/openspec@latest
验证安装:
openspec --version
步骤2:在项目中初始化OpenSpec
cd your-project
openspec init
初始化过程中:
-
系统会提示选择AI工具——选择"Cursor"
-
OpenSpec自动在
.cursor/commands/目录创建三个slash命令文件-7 -
创建
openspec/目录结构 -
生成
AGENTS.md指导文件
步骤3:重启Cursor
重启Cursor使slash命令生效。
3.3 Cursor中的Slash命令
OpenSpec会在Cursor中注册三个核心slash命令-1-5:
| 命令 | 用途 |
|---|---|
/openspec-proposal |
创建变更提案,生成proposal、spec、tasks |
/openspec-apply |
实施已批准的变更,按tasks逐项实现 |
/openspec-archive |
归档已完成变更,合并回主规范 |
3.4 可选:配置项目上下文
编辑openspec/config.yaml,补充项目背景,帮助AI生成更贴合项目的规范-8:
schema: spec-driven
context: |
项目:用户中心系统
技术栈:Go + Gin + GORM + MySQL + Redis
API规范:RESTful
Commit规范:Conventional Commits
rules:
proposal:
- 提案控制在500字以内
- 必须包含「非目标」章节
tasks:
- 每个任务不超过2小时
四、完整实战:厨房计时器应用
以构建一个厨房计时器Web应用为例,完整演示OpenSpec工作流。
4.1 需求描述
我们想构建一个简单的厨房计时器,要求:
-
提供1分钟、3分钟、5分钟按钮
-
大字体显示剩余时间
-
倒计时中再次点击按钮重置计时器
4.2 步骤1:创建变更提案
在Cursor的AI对话框中输入:
/openspec-proposal 创建一个厨房计时器UI
AI会自动完成以下工作-2:
-
在
openspec/changes/下创建create-ui文件夹 -
生成
proposal.md、tasks.md、spec.md等文件
生成的proposal.md:
# Proposal: create-ui
## Summary
Add a simple, highly visible kitchen timer UI for web browsers.
## Motivation
The project currently lacks any user interface. Implementing the timer UI is essential for delivering the core value proposition.
## Scope
- HTML, CSS, JS for timer UI
- 1/3/5 minute buttons
- Large countdown display
- Button press resets timer during countdown
生成的tasks.md:
# Tasks for create-ui
1. Scaffold html/, html/index.html, html/style.css, html/timer.js
2. Implement UI layout: buttons (1/3/5 min), large timer display
3. Implement timer logic in JS (countdown, reset on button press)
4. Style for visibility and usability (CSS)
5. Manual browser test: verify all scenarios
6. Add/validate spec.md for UI requirements
生成的spec.md:
# Spec: timer-ui
## ADDED Requirements
### Requirement: Timer UI for Kitchen Use
A simple, highly visible timer UI SHALL be provided in the browser for kitchen use.
#### Scenario: User starts timer
- User opens the app in a browser
- Sees buttons for 1, 3, and 5 minutes
- Presses a button; countdown starts from that time
- Remaining time is displayed in large font
#### Scenario: Timer reset
- During countdown, user presses a button
- Timer resets and starts new countdown
4.3 步骤2:审查与对齐
检查生成的三个文件,确保符合预期。如需调整,可以直接编辑文件,或在AI对话中提出修改。
例如,如果需要添加暂停功能:
请在spec.md中添加暂停/继续功能的验收标准
AI会自动更新规范文件。
4.4 步骤3:实施变更
规范确认后,执行实施:
/openspec-apply
AI会按照tasks.md逐项实现代码:
-
创建HTML结构
-
编写CSS样式
-
实现JavaScript计时器逻辑
-
添加重置功能
4.5 步骤4:归档变更
验证功能正常后,归档变更:
/openspec-archive
AI会将changes/create-ui/specs/中的增量合并到specs/目录,更新项目的"真相来源"。
五、进阶用法:自定义规范与团队协作
5.1 自定义Cursor AI规则
在Cursor中创建自定义AI Rule,可以精确控制代码生成规范-10。
步骤:
-
打开Cursor设置
-
找到"Rules for AI"
-
添加自定义规则,例如Flutter实体类生成规范:
当你生成Dart实体类时:
- 使用json_serializable注解
- 属性名使用驼峰命名
- 提供fromJson和toJson方法
- 导入utils/safe_convert.dart中的安全转换函数
5.2 使用project.md定义项目约定
openspec/project.md用于定义项目级惯例-3:
# Project Context
## Purpose
用户中心系统,提供用户注册、登录、个人资料管理功能。
## Tech Stack
- Backend: Go + Gin + GORM
- Database: MySQL + Redis
- Frontend: Vue 3 + TypeScript
- API: RESTful
## Code Conventions
- 使用go fmt格式化代码
- API错误码统一定义在errors.go
- 日志使用zap结构化日志
- 数据库操作必须在事务中完成
5.3 团队共享规范
团队多人开发时,共享两个文件即可实现统一标准-10:
-
Cursor Rules文件:定义代码风格和生成规则
-
spec.md模板:定义规范文件的编写标准
团队成员只需:
-
将OpenSpec初始化的
.cursor/和openspec/目录提交到Git -
各自执行
openspec init(或直接使用已提交的配置) -
AI生成代码时会自动遵循项目规范
5.4 与Git工作流结合
建议将OpenSpec变更与Git分支对应
-8
# 创建变更时同时创建分支
git checkout -b feature/add-user-auth
openspec new change add-user-auth
# 实施变更
/openspec-apply
# 归档后合并分支
git checkout main
git merge feature/add-user-auth
openspec archive add-user-auth
六、OpenSpec vs 其他工具
6.1 对比一览
| 工具 | 主要用例 | 变更管理方式 | 核心优势 |
|---|---|---|---|
| OpenSpec | 修改现有功能 (1→n) | specs与changes分离,功能文件夹集中管理 | 代码库演进清晰、跨规范更新友好 |
| spec-kit | 绿地项目 (0→1) | 每功能单独分支 | 从头定义新功能能力强 |
| Kiro | 新功能开发 | 更新分散到多个规范文件夹 | - |
| 无规范 | 非结构化任务 | 需求仅存在于聊天记录 | 快速原型,但不可预测 |
6.2 为什么选择OpenSpec?
OpenSpec的独特优势-4:
-
棕地优先:修改现有代码库时同样出色
-
集中变更:所有相关文件在同一文件夹,便于追踪
-
可审计差异:specs与changes分离,变更清晰可见
-
AI原生:原生支持Cursor slash命令
七、常见问题与最佳实践
7.1 常见问题
Q:使用OpenSpec会影响Cursor的原生能力吗?
A:不会。OpenSpec采用非侵入式设计,只增加slash命令,不修改Cursor任何原生功能-7。
Q:Slash命令不显示怎么办?
A:重启Cursor。Slash命令在IDE启动时加载-7。
Q:现有的代码库如何使用OpenSpec?
A:直接运行openspec init即可。OpenSpec是棕地优先设计,会尊重现有项目结构-4。
Q:任务粒度应该多大?
A:建议每个任务1-2小时可完成,便于分步实现和进度跟踪-8。
7.2 最佳实践建议
-
先写proposal再写代码:避免"想到哪写到哪",让AI有清晰上下文-8
-
善用context:在
config.yaml中写好技术栈和约束,减少AI猜测 -
任务粒度适中:tasks.md中每个任务建议1-2小时可完成
-
及时归档:变更完成后执行
openspec archive,保持changes目录清爽 -
与Git结合:变更名与分支名对应,如
feature/user-feedback-stats -
规范文件保持精简:每行规范都应指导决策,避免无意义的描述-4
八、实战案例:用OpenSpec生成标准化实体类
以下是一个更贴近实际开发的案例:用OpenSpec生成Flutter JSON实体类-10。
8.1 需求描述
团队需要统一生成Dart实体类的标准,确保:
-
每个字段都有类型注解
-
包含fromJson/toJson方法
-
使用安全转换函数处理空值
-
提供copyWith方法
8.2 创建规范文件
在openspec/specs/entity-generation/spec.md中定义规范:
# 实体类生成规范
## Requirement: JSON实体类生成
生成的实体类必须包含完整的JSON序列化能力。
#### Scenario: 用户提供JSON数据
- 用户粘贴JSON数据,指定类名
- AI生成对应的Dart实体类
- 类包含所有字段的类型定义
- 包含fromJson和toJson方法
- 使用safe_convert.dart中的安全转换函数
## Requirement: 代码风格统一
所有生成的实体类必须遵循统一风格。
#### Scenario: 命名规范
- 类名使用PascalCase
- 属性名使用camelCase
- JSON字段名使用snake_case自动映射
#### Scenario: 方法要求
- 提供copyWith方法
- 重写toString方法用于调试
- 实现==运算符和hashCode
8.3 使用效果
开发者只需在Cursor中输入:
根据以下JSON生成UserModel实体类:
{
"user_id": 1001,
"user_name": "张三",
"email": "zhangsan@example.com"
}
OpenSpec会自动:
-
读取entity-generation规范
-
按照团队约定生成代码
-
自动导入safe_convert工具类
生成的代码示例:
import 'package:project/utils/safe_convert.dart';
class UserModel {
final int userId;
final String userName;
final String email;
UserModel({
required this.userId,
required this.userName,
required this.email,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
userId: safeToInt(json['user_id']),
userName: safeToString(json['user_name']),
email: safeToString(json['email']),
);
}
Map<String, dynamic> toJson() {
return {
'user_id': userId,
'user_name': userName,
'email': email,
};
}
UserModel copyWith({int? userId, String? userName, String? email}) {
return UserModel(
userId: userId ?? this.userId,
userName: userName ?? this.userName,
email: email ?? this.email,
);
}
}
8.4 团队共享
只需将.cursor/rules/中的Rule文件和openspec/specs/entity-generation/spec.md提交到Git,团队成员即可获得完全一致的实体类生成能力-10。
九、总结与展望
9.1 核心收获
| 维度 | Vibe Coding | OpenSpec工作流 |
|---|---|---|
| 需求明确性 | 模糊、易变 | 结构化的spec文件 |
| 可追溯性 | 聊天记录 | 完整的变更历史 |
| 团队协作 | 各自为战 | 共享规范 |
| AI行为 | 不可预测 | 锁定意图,可预测 |
| 代码质量 | 依赖运气 | 规范约束 |
9.2 OpenSpec的核心价值
-
约束而非限制:OpenSpec不限制AI能力,而是为AI提供明确的上下文和约束,让AI发挥更稳定-4
-
从Vibe Coding到Engineering:将AI编程从"凭感觉"转变为"工程化"
-
可审计的变更:每个功能从提案到归档都有完整记录
-
团队协作的桥梁:规范的spec文件成为开发者和AI共同理解的"合同"
9.3 未来展望
随着AI编程能力的持续提升,规范驱动开发将成为企业级AI辅助编程的标准实践。OpenSpec这样的工具,正在帮助开发团队建立:
-
可复现的AI行为:同样的规范产生同样的代码
-
可审计的变更历史:知道"为什么改"和"改了什么"
-
可扩展的协作模式:新成员通过规范快速上手
从"Vibe Coding"到"Spec-Driven Development"的转变,不仅是工具的升级,更是工程理念的演进。当AI能够理解并遵循规范,开发者才能真正从重复劳动中解放出来,专注于更高价值的创造性工作。
十、快速上手指南
安装命令(2分钟上手)
# 1. 全局安装
npm install -g @fission-ai/openspec@latest
# 2. 项目初始化
cd your-project
openspec init
# 3. 选择Cursor,等待完成
# 4. 重启Cursor
# 5. 在AI对话框输入:
/openspec-proposal 你的第一个功能需求
OpenSpec GitHub仓库:github.com/Fission-AI/OpenSpec
Cursor官方文档:cursor.com/docs
欢迎在评论区分享你的OpenSpec使用体验!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)