OpenSpec 完整指南(三):实战技巧与最佳实践

· 阅读约 23 分钟

前两篇我们介绍了 OpenSpec 的核心概念和完整工作流。这一篇,我们来聊聊实战中的技巧、团队协作模式,以及 OpenSpec 与其他工具的对比。


实战场景

场景一:跨多个模块的功能变更

假设你要实现「用户可以导出自己的数据」功能,这涉及:

  • 用户模块:新增导出权限检查
  • 数据模块:新增数据聚合逻辑
  • API 模块:新增导出接口
  • 通知模块:导出完成后发送邮件

传统做法是在聊天中描述需求,AI 可能会遗漏某些模块。用 OpenSpec:

/openspec:proposal 用户数据导出功能,需要涉及用户权限、数据聚合、API 接口和邮件通知

AI 会创建一个变更,包含多个规格增量:

openspec/changes/user-data-export/
├── proposal.md
├── tasks.md
└── specs/
    ├── user/
    │   └── spec.md      # 权限相关增量
    ├── data/
    │   └── spec.md      # 数据聚合增量
    ├── api/
    │   └── spec.md      # 接口增量
    └── notification/
        └── spec.md      # 通知增量

好处:所有相关的规格变更都在一个地方,审查时一目了然。

场景二:修改现有功能的行为

你需要修改登录逻辑:从「密码错误 3 次锁定」改为「5 次锁定,且锁定时间从 30 分钟改为 15 分钟」。

/openspec:proposal 修改登录锁定策略:错误次数从 3 次改为 5 次,锁定时间从 30 分钟改为 15 分钟

AI 会生成 MODIFIED Requirements

# Delta for Auth

## MODIFIED Requirements

### Requirement: Account Lockout Policy
The system MUST lock an account after 5 consecutive failed login attempts.
The lockout duration MUST be 15 minutes.

#### Scenario: Account lockout trigger
- WHEN a user fails to login 5 times consecutively
- THEN the account is locked for 15 minutes
- AND subsequent login attempts are rejected with "Account locked" message

#### Scenario: Lockout expiration
- WHEN 15 minutes have passed since lockout
- THEN the user can attempt to login again
- AND the failure counter is reset

好处:修改的内容清晰可见,不会遗漏边界情况。

场景三:移除废弃功能

要移除旧的「短信验证码登录」功能:

/openspec:proposal 移除短信验证码登录功能,该功能已废弃
# Delta for Auth

## REMOVED Requirements

### Requirement: SMS OTP Login
This feature is deprecated due to:
- High SMS costs
- Security concerns with SMS interception
- Low usage rate (< 1% of logins)

Migration path:
- Existing users will be prompted to set up password or other 2FA methods
- SMS login option will be hidden from UI immediately
- Backend support will be removed after 30-day grace period

好处:移除功能的原因和迁移计划都有记录,方便后续追溯。


团队协作模式

模式一:规格先行的 Code Review

传统 Code Review 只看代码。用 OpenSpec 后,可以先 Review 规格:

  1. 开发者创建变更提案
  2. 团队 Review proposal.md 和规格增量
  3. 规格通过后再实现
  4. Code Review 时对照规格检查实现

好处:在写代码前发现需求问题,避免返工。

模式二:混合工具团队

团队成员可能用不同的 AI 工具:

  • Alice 用 Claude Code
  • Bob 用 Cursor
  • Carol 用 GitHub Copilot

OpenSpec 的规格文件是工具无关的 Markdown,所有人共享同一套规格。每个人用自己熟悉的工具,但产出的代码都遵循相同的规格。

# 有人换了工具?更新配置即可
openspec update

模式三:渐进式采用

不需要一次性给整个项目写规格。推荐的采用路径:

  1. 新功能先行:新功能用 OpenSpec 管理
  2. 逐步补充:修改旧功能时,顺便补充规格
  3. 关键模块优先:核心业务逻辑优先写规格
openspec/specs/
├── auth/           # 核心模块,完整规格
│   └── spec.md
├── payment/        # 核心模块,完整规格
│   └── spec.md
└── settings/       # 非核心,暂无规格

与其他工具的对比

vs. spec-kit

spec-kit 是另一个规格驱动开发工具。

特性OpenSpecspec-kit
适用场景0→1 和 1→n主要 0→1
变更追踪独立的 changes 文件夹
规格与变更分离
跨规格更新原生支持需要手动管理

选择建议

  • 新项目从零开始:两者都可以
  • 需要频繁修改现有功能:OpenSpec 更合适

vs. Kiro

Kiro 是 AWS 推出的 AI IDE,也有规格功能。

特性OpenSpecKiro
工具依赖无,支持多种 AI 工具绑定 Kiro IDE
变更组织每个功能一个文件夹分散在多个 spec 文件夹
功能追踪集中管理需要跨文件夹查看

选择建议

  • 已经在用 Kiro:可以继续用 Kiro 的规格功能
  • 团队用多种工具:OpenSpec 更灵活

vs. 无规格

没有规格时,AI 从模糊的提示词生成代码:

你:添加用户登录功能
AI:好的,我来实现...(可能遗漏 2FA、可能添加不需要的社交登录)

有规格时:

你:/openspec:proposal 添加用户登录功能
AI:创建规格...(明确列出需求和场景)
你:(审查规格,确认或修改)
AI:(按规格实现,不多不少)

进阶技巧

技巧一:善用 project.md

openspec/project.md 定义项目级别的约定,会影响所有变更:

# Project Context

## Tech Stack
- Backend: Node.js + Express + TypeScript
- Database: PostgreSQL with Prisma ORM
- Frontend: React + Next.js
- Testing: Jest + React Testing Library

## Conventions
- All API endpoints must return JSON
- Error responses must include error code and message
- All database operations must use transactions for writes
- Authentication uses JWT with 1-hour expiration

## Architecture
- Monorepo structure with packages/
- Shared types in packages/types
- API routes follow RESTful conventions

AI 在实现任务时会参考这些约定。

技巧二:规格模板

为常见的功能类型创建规格模板:

API 接口模板

### Requirement: <API Name>
The system SHALL provide a <METHOD> endpoint at <PATH>.

#### Scenario: Success response
- WHEN a valid request is received
- THEN return 200 with <response structure>

#### Scenario: Validation error
- WHEN request validation fails
- THEN return 400 with error details

#### Scenario: Authentication required
- WHEN request lacks valid authentication
- THEN return 401

#### Scenario: Authorization denied
- WHEN user lacks required permissions
- THEN return 403

技巧三:规格复用

如果多个变更涉及相同的模块,可以在规格中引用:

# Delta for Payment

## ADDED Requirements

### Requirement: Refund Processing
The system MUST support refund processing.
This requirement extends [Payment Processing](../../../specs/payment/spec.md#payment-processing).

#### Scenario: Full refund
...

技巧四:与 CI/CD 集成

在 CI 中验证规格格式:

# .github/workflows/ci.yml
- name: Validate OpenSpec
  run: |
    npm install -g @fission-ai/openspec
    openspec validate --all

技巧五:规格驱动的测试

规格中的 Scenario 可以直接映射到测试用例:

#### Scenario: OTP verification success
- WHEN a user submits a valid OTP within the time window
- THEN login is completed
- AND a session token is issued

对应的测试:

describe('OTP verification', () => {
  it('should complete login when valid OTP is submitted within time window', async () => {
    // WHEN
    const result = await verifyOTP(userId, validOTP);
    
    // THEN
    expect(result.success).toBe(true);
    expect(result.sessionToken).toBeDefined();
  });
});

常见问题

Q: 规格写得太细会不会限制 AI 的发挥?

不会。规格定义的是「要做什么」,不是「怎么做」。AI 在实现时仍有充分的自由度选择技术方案。

Q: 小功能也需要写规格吗?

看情况。简单的 bug 修复或样式调整不需要。但如果涉及行为变更,建议写规格。

Q: 规格和需求文档有什么区别?

规格更结构化、更精确。需求文档可能是「用户希望能导出数据」,规格是「系统 MUST 提供 /api/export 接口,返回 JSON 格式的用户数据」。

Q: 如何处理紧急修复?

可以先修复,后补规格。但建议在归档前补充规格,保持文档完整。


总结

OpenSpec 的核心价值:

  1. 共识先行:人和 AI 在写代码前对齐意图
  2. 变更可控:每个功能变更都有独立的提案和规格
  3. 工具无关:支持主流 AI 编程工具
  4. 适合演进:不只是 0→1,更适合 1→n

如果你正在用 AI 编程助手,但经常遇到「AI 不理解我的意图」「代码改来改去」的问题,不妨试试 OpenSpec。

npm install -g @fission-ai/openspec
cd your-project
openspec init

开始你的规格驱动开发之旅吧。


资源链接


本文是 OpenSpec 完整指南系列的第三篇:

评论