Spec First, Code Second: 用 OpenSpec 约束 AI coding assistant
背景:Prompt 工程的尽头是什么
用 AI coding assistant 写代码有一段时间了,最大的感受不是它不会写代码,而是它太容易跑偏。
一个典型场景:
我:帮我加个深色模式
AI:好的,我来实现...
(5分钟后)
AI:已完成以下改动:
1. 添加了 dark-mode class
2. 修改了 index.css
3. 添加了 theme.js然后我发现它改了全局样式,把亮色主题搞崩了。更要命的是,它没有保存用户的 theme preference 到 localStorage,下次访问还是默认亮色。
这不是 AI 的问题。是我给的指令太模糊。“加个深色模式” 这种描述,对人类来说歧义太多,AI coding assistant 只能靠猜。
Prompt 工程的尽头,不是更好的 Prompt,而是结构化的需求文档。
OpenSpec 的核心思路
OpenSpec 的思路很直接:在让 AI 写代码之前,先让它确认「我们要做什么」。
它的工作流:
# 1. 初始化项目
openspec init
# 2. 提出需求
/opsx:propose add-dark-mode
# 3. AI 会创建这样的目录结构
openspec/changes/add-dark-mode/
├── proposal.md # 为什么做这个改动
├── specs/ # 需求细节和场景
├── design.md # 技术方案
└── tasks.md # 实施清单这比你想象的轻量。不是传统的规格文档,不是 UML 图,是几个 Markdown 文件。
但关键是:在 AI 动手之前,你和 AI 都在这几个文件上达成一致了。
实际体验
我用一个真实场景测试:给一个 React 项目加汇率转换功能。
You: /opsx:propose add-currency-converter
AI: Created openspec/changes/add-currency-converter/
✓ proposal.md — 动机是用户需要多币种显示
✓ specs/ — 包含 5 个 user story,覆盖正常路径和边界情况
✓ design.md — 用 useCurrency hook 方案,不引入新状态管理
✓ tasks.md — 分解为 8 个可检查的任务项
Ready for implementation!打开 proposal.md 看看:
## 为什么做这个
用户在跨境交易场景下需要快速换算汇率。
## 成功标准
- 支持 USD/EUR/CNY 三种货币
- 实时汇率(用 exchangerate-api.com 免费 tier)
- 换算结果保留 2 位小数然后 specs/ 目录下有具体的 user story:
## Scenario 1: 基础换算
Given 用户在交易页面
When 用户选择 "100 USD" 转换为 "EUR"
Then 显示 "€92.35"(假设汇率 1 USD = 0.9235 EUR)这就是关键:不是让 AI 猜我要什么,而是我告诉它要什么,它用结构化格式确认,双方在同一个页面上再动手。
为什么这个模式比 Pure Prompt Engineering 有效
1. 消除上下文丢失
传统 Prompt Engineering 的问题:对话历史越来越长,AI 开始遗忘早期确定的决策。
OpenSpec 的 spec 文件是持久化的,你改了 design.md,AI 下次对话还记得。不依赖上下文窗口。
2. 强制「需求澄清」这一步
人写代码之前会想清楚要做什么,但用 AI coding assistant 的时候太容易直接问「帮我加个功能」然后期待好的结果。
OpenSpec 强制你先输出 proposal.md,这个过程本身就是思考。
3. 可审计的决策历史
openspec/changes/ 目录下保存了所有的变更记录。每个功能都有:为什么要做、具体规格、技术方案、实施清单。
openspec/changes/
├── 2025-01-15-add-dark-mode/
├── 2025-02-20-currency-converter/
└── archive/ # 已完成归档当产品说「这个功能当时怎么设计的」,你有文档可查。
与传统开发流程的对比
| 传统开发 | Prompt Engineering | OpenSpec | |
|---|---|---|---|
| 需求确认 | PRD / 需求文档 | 靠 Prompt 描述 | 结构化 Spec 文件 |
| 变更追踪 | Git commit message | 散落在对话里 | 每个变更独立目录 |
| AI 跑偏风险 | 低(人写代码) | 高 | 低(动手前确认) |
| 上下文丢失 | 无 | 严重(长对话) | 无(文件持久化) |
| 学习成本 | 高(完整开发流程) | 低 | 低(4 个 Markdown) |
支持的工具
OpenSpec 不是绑定某个特定 AI coding assistant 的工具。它通过 slash commands 接入,支持 25+ 主流 AI 编程工具:
- Claude Code
- GitHub Copilot
- Cursor
- Windsurf
- 等等
适合谁
OpenSpec 最适合的场景:
- 中型以上功能开发:不是「帮我改个 typo」这种,而是需要多个文件改动的功能
- 团队协作:Spec 文件可以在 team 内共享,确保大家和 AI 对需求的理解一致
- 长期维护的项目:有结构化的决策记录,后期回头看知道当时为什么这么设计
对于简单的一次性改动,OpenSpec 可能过度。但当你发现 AI coding assistant 经常「做了不是你想做的事」,这通常不是 AI 的问题,是需求定义环节就有问题。
快速开始
# 需要 Node.js 20.19.0+
npm install -g @fission-ai/openspec@latest
cd your-project
openspec init
# 告诉 AI:/opsx:propose <你要做什么>完整文档在 OpenSpec GitHub。
总结
OpenSpec 不是另一个「AI 编程框架」,它是一个轻量约束层。核心价值:在 AI 动手之前,强迫你把需求想清楚并写下来。
这比任何高级 Prompt 模板都有效。因为好的输出来自清晰的需求,而不是华丽的措辞。