
拯救老项目!比Cursor更细、比spec-kit更轻:OpenSpec如何颠覆AI编程工作流? 原创
背景
在我借助AI进行开发的过程中,最常遇到的困扰并不是“AI写不出代码”,而是它写出的代码过于随意——有时误解了我的意图,有时给出的实现逻辑不够清晰,最终不得不由我逐一修正。
后来,我尝试过像 spec-kit、BMAD-METHOD 这类强调“规范驱动开发”的工具。理念虽好,实际使用起来却不够顺畅,而且它们更适用于从零启动的项目。但在公司实际环境中,大多数项目并非从头开始,更多场景是在现有代码基础上开发新功能或重构旧模块。
直到最近,我发现了一个更轻量、也更实用的新项目:OpenSpec。
相比 Cursor 的 Plan 模式,OpenSpec 更细致、结构更清晰;相比 spec-kit,它又轻得多,非常适合个人开发者和小团队使用。
与其他工具对比
工具 | 适用场景 | 特点 |
spec-kit | 从 0 到 1 的系统搭建 | 结构化强、上手复杂 |
BMAD-METHOD | 团队协作型 AI 项目 | 自动化程度高、学习曲线陡峭 |
OpenSpec | 已有项目的功能演进与维护 | 轻量、兼容性强、适合个体开发者 |
尤其在需要修改现有功能或触及多个模块规范时,OpenSpec 的变更分组与追溯机制非常实用。
工作流&核心理念
┌────────────────────┐
│ Draft Change │
│ Proposal │
└────────┬───────────┘
│ share intent with your AI
▼
┌────────────────────┐
│ Review & Align │
│ (edit specs/tasks) │◀──── feedback loop ──────┐
└────────┬───────────┘ │
│ approved plan │
▼ │
┌────────────────────┐ │
│ Implement Tasks │──────────────────────────┘
│ (AI writes code) │
└────────┬───────────┘
│ ship the change
▼
┌────────────────────┐
│ Archive & Update │
│ Specs (source) │
└────────────────────┘
OpenSpec 增加了一个规范驱动的工作流程。
你无需在聊天中解释某个功能,并希望 AI 能够正确理解,而是:
- 撰写(或让 AI 起草)提案。
- 共同审查并调整规范。
- 让 AI 实施已批准的计划。
- 将变更归档,以便更新你的项目规范。
其核心逻辑分为两部分:
- specs:记录当前的规范状态(项目规则、API 约束、模块定义等)
- changes:追踪每一次变更提案及其实施过程
AI 执行顺序
1. 读取 proposal.md
→ 理解"为什么要做"、"做什么"
2. 读取 design.md (如果存在)
→ 理解"如何做"、"技术决策"
→ 了解架构选择和权衡
3. 读取 tasks.md
→ 获取实现清单
4. 开始实现
→ 按照 design.md 中的决策编写代码
实操流程
OpenSpec 支持命令行和自然语言两种交互方式,并且支持多种ai coding 工具:
Tool |
Claude Code |
Cursor |
Factory Droid |
OpenCode |
Kilo Code |
Windsurf |
Codex |
GitHub Copilot |
Amazon Q Developer |
Auggie (Augment CLI) |
安装与初始化流程非常简洁:
npm install -g @fission-ai/openspec@latest
初始化你已有的项目,初始化过程中你可以选择你会使用的AI Coding 工具
cd your_project
openspec init
初始化后会生成以下结构:
openspec/
├── specs/ # 已经实现的功能或修改
├── changes/ # 正在开发的功能
├── AGENTS.md # AI 工作流指南(如何使用 OpenSpec)
└── project.md # 项目整体上下文(技术栈、规范)
其中project.md 的内容结构大致如下:
# [项目名] Context
## Purpose
[描述项目的目的和目标]
## Tech Stack
- [列出主要技术]
- [例如: TypeScript, React, Node.js]
## Project Conventions
### Code Style
[描述代码风格偏好、格式化规则和命名约定]
### Architecture Patterns
[记录架构决策和模式]
### Testing Strategy
[解释测试方法和要求]
### Git Workflow
[描述分支策略和提交约定]
## Domain Context
[添加 AI 助手需要理解的领域特定知识]
## Important Constraints
[列出任何技术、业务或法规约束]
## External Dependencies
[记录关键外部服务、API 或系统]
project.md 不应该包含:
- 详细的 API 文档(应该在 specs/ 中)
- 具体的实现细节(应该在代码中)
- 临时的开发笔记
- 个人偏好(除非是团队共识)
1. 完善项目文档project.md
Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions
接着AI 会按照OpenSpec guide 阅读当前repo structure, 并在openspec目录生成project.md。
新 AI 助手首次接入项目:
- 读取 openspec/project.md
- 了解项目背景和规范
- 准备好遵循一致的开发标准
2. 生成变更提案
我想增加一个api,用于导出RecommendRecord 成csv, 这个api 可以传餐厅id, 开始时间和结束时间,请使用OpenSpec 创建一个提案
或者使用命令行的方式:
/openspec:proposal 我想增加一个api,用于导出RecommendRecord 成csv, 这个api 可以传餐厅id, 开始时间和结束时间
在公司我一般会习惯拿着产品的需求功能文档,使用/openspec:proposal 帮我生成提案,防止我的表达不到位生成的提案不够精确。
它搭建了以下文件夹:
openspec/
└── changes/
└── add-recommend-record-export-api/
├── proposal.md # 变更提案:为什么做、做什么、影响范围
├── tasks.md # 实施清单:逐条可勾选的任务
└── specs/recommend-records/spec.md # 使用 ADDED/MODIFIED/REMOVED 标记
proposal.md 的内容结构如下:
## Why
导出推荐记录用于运营分析、质量评估与模型回放,目前缺少按商户与时间窗口导出的标准接口。
## What Changes
- 新增导出接口:GET /xx/v1/recommend_record/export,支持 CSV 下载
- 支持参数:merchant_id、start_time、end_time(ISO 8601)
- 内容字段:xx
- 大数据量下采用流式响应,避免内存峰值
## Impact
- Affected specs: recommend-records
- Affected code:
- xx
- xx
- xx
tasks.md 将整个开发工作拆分为多个 Phase,每个 Phase 包含若干可勾选的 checkbox 任务
## 1. Implementation
- [] 1.1 新增导出视图:注册到 `/xxx/v1/recommend_record/export`
- [] 1.2 服务层实现:按商户与时间窗口查询 RecommendRecord,并关联 ProcessRecord、CallRecord 获取 `seat_id`、`call_id`、`merchant_id`
- [] 1.3 CSV 生成:使用生成器流式写出,设置 `Content-Type: text/csv` 与 `Content-Disposition`
- [] 1.4 校验与错误处理:参数校验(必填/时间格式/范围),异常返回 400/500
- [ ] 1.5 单元测试:服务层查询和 CSV 行序列化;空结果与大数据量用例
- [ ] 1.6 API 测试:GET 成功/空数据/参数错误
## 2. Non-Goals
- [ ] 不实现 XLSX 导出(后续需要再提)
- [ ] 不新增鉴权机制(与当前工程一致,如后续需要单独提案)
## 3. Rollout
- [ ] 本地验证与示例导出
- [ ] 预发环境验证(大样本)
- [ ] 文档更新 README/变更日志
spec.md 记录功能的新增与改动
## ADDED Requirements
### Requirement: Export Recommend Records CSV
系统 SHALL 提供导出 RecommendRecord 的 CSV 接口,按商户与时间窗口过滤。
- Endpoint: `GET /xx/v1/recommend_record/export`
- Query 参数(必填)
- `merchant_id`: string,商户 ID
- `start_time`: string,ISO 8601(例如 `2025-01-01T00:00:00-05:00`)
- `end_time`: string,ISO 8601(例如 `2025-01-31T23:59:59-05:00`)
- 时间过滤:基于 RecommendRecord `created_at` 范围,包含端点时间
- 响应:`text/csv`,`Content-Disposition: attachment; filename="recommend_records_{merchant_id}_{start}_{end}.csv"`
- CSV 列(顺序固定):
- `recommend_id`
- `process_record_id`
- `call_id`
- `seat_id`
- `dish_id`
- `dish_name`
- `std_id`
- `std_name`
- `type`
- `confidence`
- `accept`
- `accept_time`
- `recommend_method`
- `created_at`
- 性能:当导出记录量较大时,系统 MUST 采用流式写出,避免一次性加载到内存
#### Scenario: 导出成功(有数据)
- WHEN 调用 `GET /xxx/v1/recommend_record/export?merchant_id=abc&start_time=2025-01-01T00:00:00-05:00&end_time=2025-01-02T00:00:00-05:00`
- THEN 返回 200,`Content-Type: text/csv`
- AND 响应包含表头与至少 1 行数据
- AND 首行表头与列顺序与规范一致
#### Scenario: 导出成功(无数据)
- WHEN 指定时间范围内无 RecommendRecord
- THEN 返回 200,`Content-Type: text/csv`
- AND CSV 仅包含表头,无数据行
#### Scenario: 参数缺失或格式错误
- WHEN 缺少 `merchant_id` 或 `start_time` 或 `end_time`
- OR `start_time`/`end_time` 不是有效的 ISO 8601
- THEN 返回 400,JSON 错误消息,指明无效参数
#### Scenario: 大数据量流式导出
- GIVEN 预置 > 100k 条记录在时间窗口内
- WHEN 触发导出
- THEN 服务端以流式方式写出 CSV(分块 flush/迭代生成)
- AND 不发生内存 OOM 或进程阻塞
当你对变更提案不够满意的时候,你可以继续和ai 交流直到你满意为止,比如:
你能给接口增加一个校验吗,开始和结束时间相差不能超过一周
AI更新了规范,反复修改,直到符合我的要求。
3. 执行任务
当一切都和AI以及团队成员对齐之后,就可以执行 openspec.apply 来执行任务,AI 会:
- 读取
proposal.md
、tasks.md
、design.md
- 读取
specs/skills/spec.md
的新增或者修改需求 - 按
tasks.md
顺序逐条实施 - 每完成一个 task 就勾选对应的 checkbox
当任务完整之后,我习惯使用另外的模型对这次新增的代码进行审核,并让当前的AI Coding 工具针对审核结果做针对性的修改
4. 归档任务
当所有任务都执行结束并测试通过之后,执行归档,以让AI 知道项目的演变路径
/openspec:archive
当这个命令执行完毕之后,会进行两步操作:
- 移动目录
# 从
openspec/changes/add-recommend-record-export-api/
# 移动到
openspec/changes/archive/2025-10-20-add-recommend-record-export-api/
- 合并spec.md: 将需求中的spec.md 合并到主的spec 目录下,spec 目录下永远代表系统的最新状态
# 合并到
openspec/specs
为什么要归档?
假设没有归档:
第1周: 你计划添加"用户登录"功能
→ 创建 changes/add-login/
→ 编写代码,测试,部署 ✅
第2周: 你计划添加"密码重置"功能
→ 创建 changes/add-password-reset/
→ 编写代码,测试,部署 ✅
第3周: 你计划添加"双因素认证"功能
→ 创建 changes/add-2fa/
→ 编写代码,测试,部署 ✅
现在的状态:
changes/
├── add-login/ ← 已上线3周,但还在"计划"文件夹
├── add-password-reset/ ← 已上线2周,但还在"计划"文件夹
└── add-2fa/ ← 已上线1周,但还在"计划"文件夹
specs/
└── auth/spec.md ← 3周前的旧规范,不包含任何新功能!
问题出现:
1. 新同事入职:
新同事: "我看了 specs/auth/spec.md,系统只有基础认证?"
你: "不不不,我们还有登录、密码重置、2FA..."
新同事: "可规范里没写啊?代码在哪?"
你: "呃...去 changes/ 目录找找..."
2. AI 助手困惑:
你: "帮我添加用户注销功能"
AI: [读取 specs/auth/spec.md]
"我看系统还没有登录功能,需要先实现登录吗?"
你: "不用!我们已经有登录了!"
AI: "可是规范里没有啊..."
当有了归档功能之后
第1周: 添加"用户登录"
→ 创建 changes/add-login/
→ 实现并部署
→ openspec archive add-login
specs/auth/spec.md 更新(包含登录需求)
移动到 archive/2025-10-01-add-login/
第2周: 添加"密码重置"
→ 创建 changes/add-password-reset/
→ 实现并部署
→ openspec archive add-password-reset
specs/auth/spec.md 更新(包含密码重置)
移动到 archive/2025-10-08-add-password-reset/
第3周: 添加"双因素认证"
→ 创建 changes/add-2fa/
→ 实现并部署
→ openspec archive add-2fa
specs/auth/spec.md 更新(包含2FA需求)
移动到 archive/2025-10-15-add-2fa/
现在的状态:
specs/
└── auth/spec.md ← 最新!包含所有已实现功能
changes/
└── (空的或只有进行中的工作)
archive/
├── 2025-10-01-add-login/
├── 2025-10-08-add-password-reset/
└── 2025-10-15-add-2fa/
这样带来的好处就是:
新同事入职:
新同事: "我看了 specs/auth/spec.md"
新同事: "明白了!系统有登录、密码重置、2FA,很完善!"
你: "对!规范就是现状,看规范就够了"
AI 助手准确理解
你: "帮我添加用户注销功能"
AI: [读取 specs/auth/spec.md]
"我看到系统已有登录功能,我会在登录流程基础上添加注销"
你: "完美!你理解得很对"
总结
OpenSpec 给我的最大启发是:
“AI 编程不只是写代码,更是定义规则、执行规范的过程。”
它让我重新理解了“AI 参与开发”的意义—— 从简单的任务执行,转变为 以规范为中心的智能协作。如果你正在用 AI 做项目维护或功能升级,强烈建议试试。
本文转载自AI 博物院 作者:longyunfeigu
