找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1454

积分

0

好友

188

主题
发表于 昨天 09:10 | 查看: 5| 回复: 0

2024年,当 Andrej Karpathy 抛出 “Vibe Coding” 一词时,整个开发者社区既兴奋又惶恐。兴奋的是:任何人只要会描述需求,AI 就能把可运行的代码“震”出来;惶恐的是:当代码的生产速度超过人类理解速度,软件项目就变成了“黑箱沼泽”

Vibe Coding 的核心缺陷不是 AI 能力不足,而是开发流程仍停留在“人 <-> 模型”的无结构对话。聊天记录不是需求文档,LLM 的上下文窗口记不住三天前的决策,代码注释也不会自动同步变更理由。

二、Spec Coding:让AI从“聊出来”到“写出来”

Spec Coding(规范驱动开发) 不是新鲜的理论——它在传统工程中叫“契约优先”或“规范先行”。但 OpenSpec 让它首次适配 AI 时代的协作粒度

  1. 人负责定义“要什么”和“为什么”,将隐性知识显性化为规范文档
  2. AI 负责实现“怎么做”,并且每一步都与规范文档双向绑定。
  3. 规范文档随代码演进,每次变更都是对规范的增量修正,而非全量重写。

Spec Coding ≠ Waterfall:它不是要求你在写代码前写完数百页规格书,而是将每一次“变更”打包成一个自包含的规范单元,让 AI在理解现状的基础上,精确修改指定部分

三、OpenSpec是什么?——为AI时代的迭代而生的“规范操作系统”

OpenSpec 是由 Fission AI 团队发起、开源社区驱动的规范驱动开发工作流框架。2026年1月发布的 v1.0.0 版本是一次彻底重构,其核心定位是:棕地优先(Brownfield-first)

棕地优先——不假设你从空项目开始,专门解决已有数十万行代码、复杂依赖、历史债务的“真实项目”的规范管理问题。

3.1 不是另一个“文档生成器”

工具 定位 与 AI 的关系
Swagger/OpenAPI API 描述格式 被动阅读
Cucumber 可执行需求 需人工编写 Gherkin
OpenSpec AI 协作工作流 AI 主动遵循,自动维护

OpenSpec 不生产代码,它生产 AI 执行代码变更时所必须遵守的“契约”

四、OpenSpec 1.0 核心设计理念

4.1 规范即源码(Spec as Code)

OpenSpec 将所有规范文件纳入 Git 管理,与代码同源、同版本、同评审。项目根目录下会出现:

openspec/
├── specs/              # 系统当前能力的权威描述(只读)
│   ├── task/          # 任务模块规范
│   ├── settings/      # 设置模块规范
│   └── sync/          # 同步模块规范
└── changes/           # 进行中的变更
    ├── room-migration/  # 迁移到 Room 数据库
    └── dark-theme/      # 深色主题

4.2 产物依赖图(Artifact Graph),而不是线性流程

v1.0 最大的架构革新是用图取代流水线。每个变更(Change)包含四个标准产物,它们之间存在逻辑依赖

proposal (根)   ← 为什么要做?价值、范围、放弃方案
    ├── specs    ← 对 specs/ 的增量修改(用 ## ADDED 标记)
    ├── design   ← 技术选型、接口定义、数据模型
    └── tasks    ← 实现步骤(依赖 specs + design)

AI 通过 openspec status 查询当前产物状态图(BLOCKED / READY / DONE),自动选择下一步可执行的动作。这意味着:

  • 开发者可以随时回退到 proposal 修改需求,依赖它的 specs/design 会自动变为 BLOCKED
  • 开发者可以跳过部分产物(如直接写 tasks)但系统会警告缺少依赖

4.3 增量规范(Delta Spec)

这是 OpenSpec 解决“规范漂移”的核心设计。变更目录下的 specs 文件不是全量覆盖,而是用语义标记记录变化,比如下述代码变更记录:

# specs/task/spec.md(在 changes/room-migration/ 目录下)

## 现有能力(来自主规范)
- 使用 SharedPreferences 存储任务列表
- 支持增删改查,但查询效率低
- 无事务支持

## ADDED 能力
- 使用 Room 作为本地持久化方案
- 支持异步查询(Flow/协程)
- 定义 Task 实体、TaskDao、TaskDatabase

## MODIFIED 能力
- 【变更】任务查询方式:从直接读取 SP 改为 Flow 流式查询
- 【理由】提升 UI 响应性,自动数据更新

当变更归档时(/opsx:sync),OpenSpec解析这些标记,精确合并到主规范目录,而不是粗暴覆盖。每一次规范变更都成为可审计的 diff

五、OpenSpec 最新命令体系

命令 作用 对应产物 典型场景
/opsx:explore 零成本预研,不生成任何文件 评估多个技术方案、讨论可行性
/opsx:new <name> 创建变更脚手架 proposal 模板 开始一个新功能
/opsx:ff Fast-Forward,按依赖图生成全部产物 proposal+specs+design+tasks 需求明确,一步到位
/opsx:continue 一次生成一个“READY”状态的产物 单个产物 边想边写,逐步完善
/opsx:apply 按 tasks.md 实施代码变更 代码 AI 写代码的主阶段
/opsx:verify 检查代码与 specs 的一致性 验证报告 代码审查前自检
/opsx:sync 将 delta specs 合并入主规范 主规范更新 功能完成,知识沉淀
/opsx:archive 归档变更目录 移入 archive/ 生命周期结束
/opsx:onboard 15 分钟交互式教学 新成员、新项目初始化

六、原理深潜:OpenSpec 如何“驯服”AI?

6.1 规范注入(Spec Injection)

OpenSpec 不依赖任何专有 API 或模型微调,它的“魔法”本质是动态提示词工程

以 Claude Code 为例,openspec init 会生成:

.claude/
├── commands/
│   └── openspec/
│       ├── apply.md
│       └── ff.md
├── AGENTS.md
└── CLAUDE.md

.claude/AGENTS.md 是核心:

<!-- OPENSPEC:START -->
# OpenSpec 工作规范
当用户请求中包含以下关键词时,你必须首先加载本规范并执行 `openspec status`:
- “提案”、“变更”、“规范”、“规划”
- 任何涉及新增功能或修改 API 的请求
- 需要生成多文件的任务

执行流程:
1. 如果用户提供了变更名称,执行 `openspec status <name>`;
2. 根据产物状态图确定下一个可执行的 OPSX 命令;
3. 严禁绕过 OpenSpec 直接修改 `openspec/specs/` 下的文件;
4. 代码生成必须严格参照 `changes/<name>/tasks.md` 的勾选框。
<!-- OPENSPEC:END -->

Claude Code每次启动都会读取该文件,将 OpenSpec 规则注入系统提示词。当用户提到“迁移到 Room”,AI主动查询当前变更状态,并建议执行 /opsx:ff/opsx:continue

6.2 动态指令组装

三层架构

  1. 上下文层openspec/config.yaml,记录项目技术栈、测试框架、代码规范链接等。
    project:
      language: kotlin
      framework: android-jetpack
      android:
        min_sdk: 24
        target_sdk: 34
        compose: true
      test: junit4
    agents:
      allowed_models: [claude-3.7, gemini-2.0]
  2. 规则层openspec/rules/,产物级别的约束描述(如“specs 必须包含验收标准”)。
  3. 模板层openspec/templates/,各产物的 Markdown 结构。

当 AI 执行 /opsx:ff 时,CLI 实时读取三层配置,动态拼装提示词。这意味着开发者修改 config.yaml 后,所有后续生成的 design.md 都会自动适配 Android Compose + Room,无需人工同步。

6.3 产物状态机(Artifact State Machine)

这是 OpenSpec 1.0 能让 AI自我驱动的底层机制。

stateDiagram-v2
    
  • --> PROPOSAL: /opsx:new     PROPOSAL --> READY: proposal.md 写完成     READY --> SPECS_BLOCKED: 依赖 proposal     SPECS_BLOCKED --> SPECS_READY: /opsx:continue     SPECS_READY --> DESIGN_BLOCKED: 依赖 specs     DESIGN_BLOCKED --> DESIGN_READY: /opsx:continue     DESIGN_READY --> TASKS_BLOCKED: 依赖 design     TASKS_BLOCKED --> TASKS_READY: /opsx:continue     TASKS_READY --> IMPLEMENTING: /opsx:apply     IMPLEMENTING --> VERIFYING: /opsx:verify     VERIFYING -->
  • : /opsx:sync & /opsx:archive
  • AI 通过 openspec status 获取当前状态,用户只需说“继续”,AI 会自动选择正确的 /opsx:continue 路径,依次生成 specs → design → tasks。整个过程无需人类记住十几条命令的精确顺序

    七、实战:从 Vibe 到 Spec,一次 Android 数据层重构的完整转型

    7.1 初始状态

    TaskViewModel.kt

    class TaskViewModel : ViewModel() {
        private val prefs = PreferenceManager.getDefaultSharedPreferences(getApplication())
        private val _tasks = MutableLiveData<List<String>>()
        val tasks: LiveData<List<String>> = _tasks
    
        fun loadTasks() {
            val json = prefs.getString("tasks", "[]")
            val type = object : TypeToken<List<String>>() {}.type
            val list: List<String> = Gson().fromJson(json, type) ?: emptyList()
            _tasks.value = list
        }
    
        fun addTask(title: String) {
            val current = _tasks.value?.toMutableList() ?: mutableListOf()
            current.add(title)
            saveTasks(current)
        }
    
        private fun saveTasks(tasks: List<String>) {
            val json = Gson().toJson(tasks)
            prefs.edit().putString("tasks", json).apply()
            _tasks.value = tasks
        }
    }

    痛点

    • 数据逻辑与 ViewModel 高度耦合;
    • 无 Repository 模式,难以测试;
    • 存储使用 SharedPreferences,不适合复杂数据;
    • 无异步支持,可能阻塞主线程;
    • 无任何文档,新成员只能读代码猜意图。

    7.2 引入 OpenSpec,建立规范基线

    # 1. 安装最新版 OpenSpec
    npm install -g @fission-ai/openspec@latest
    
    # 2. 进入 Android 项目根目录
    cd App
    openspec init --tools claude
    
    # 3. 创建规范基线(挖掘现有代码意图)
    openspec baseline --auto

    openspec baseline 是逆向工程命令。它会扫描代码库,生成一份初始的 specs 目录,描述“当前系统已实现的能力”。

    openspec/specs/task/spec.md
    ├── 数据存储:SharedPreferences + JSON 序列化
    ├── 数据查询:同步阻塞方式,通过 LiveData 发布
    ├── 数据操作:增、删、改、查
    └── 缺陷:无事务支持,查询效率低,无法响应式更新

    此刻,项目的“原理过程”从散落的代码,集中到了 specs/。如果你想深入学习类似架构规范,可以到 技术文档 板块探索更多内容。

    7.3 发起变更:重构数据层为 Room

    /opsx:new room-migration

    AI 自动生成 changes/room-migration/proposal.md我们只需补充“为什么要重构”

    ## 问题陈述
    当前数据存储存在以下问题:
    1. 数据与 UI 逻辑耦合在 ViewModel,违背单一职责;
    2. SharedPreferences 不适合结构化数据,且查询全量反序列化效率低;
    3. 无法实现数据变化自动推送至 UI;
    4. 无法进行单元测试。
    
    ## 目标架构
    采用 Android 官方推荐的架构分层:
    - **数据层**:Room Entity + Dao + Database
    - **仓库层**:TaskRepository(屏蔽数据源细节)
    - **ViewModel**:依赖仓库,通过 Flow 接收数据
    
    ## 放弃方案
    - 使用 SQLiteOpenHelper + ContentProvider:模板代码过多,维护成本高
    - 使用 Realm:社区活跃度下降,Kotlin 支持较弱

    7.4 Fast-Forward 生成完整规划

    /opsx:ff

    AI 读取 proposal、读取现有代码、参考 config.yaml(Kotlin + Compose + Room),自动生成

    design.md(节选)

    // 实体定义
    @Entity(tableName = "tasks")
    data class TaskEntity(
        @PrimaryKey(autoGenerate = true)
        val id: Int = 0,
        val title: String,
        val isCompleted: Boolean = false,
        val createdAt: Long = System.currentTimeMillis()
    )
    
    // 数据访问对象
    @Dao
    interface TaskDao {
        @Query("SELECT * FROM tasks ORDER BY createdAt DESC")
        fun getAllTasks(): Flow<List<TaskEntity>>
    
        @Insert
        suspend fun insert(task: TaskEntity)
    
        @Update
        suspend fun update(task: TaskEntity)
    
        @Delete
        suspend fun delete(task: TaskEntity)
    }
    
    // 数据库
    @Database(entities = [TaskEntity::class], version = 1)
    abstract class TaskDatabase : RoomDatabase() {
        abstract fun taskDao(): TaskDao
    }
    
    // 仓库接口与实现
    interface TaskRepository {
        fun observeTasks(): Flow<List<Task>>
        suspend fun addTask(title: String)
        suspend fun toggleTask(id: Int)
    }
    
    class TaskRepositoryImpl(
        private val taskDao: TaskDao,
        private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
    ) : TaskRepository {
        override fun observeTasks(): Flow<List<Task>> =
            taskDao.getAllTasks().flowOn(ioDispatcher).map { entities ->
                entities.map { it.toDomain() }
            }
    
        override suspend fun addTask(title: String) {
            withContext(ioDispatcher) {
                taskDao.insert(TaskEntity(title = title))
            }
        }
        // ...
    }

    tasks.md(带依赖关系)

    • T1: 添加 Room 依赖(build.gradle.kts) ⚠️ 依赖:无
    • T2: 创建 TaskEntity、TaskDao、TaskDatabase ⚠️ 依赖:T1
    • T3: 实现 TaskRepository 接口及 Room 实现 ⚠️ 依赖:T2
    • T4: 重构 TaskViewModel,注入 TaskRepository ⚠️ 依赖:T3
    • T5: 更新 Compose UI 以适配 Flow ⚠️ 依赖:T4
    • T6: 编写单元测试(使用 TestDispatcher) ⚠️ 依赖:T3

    7.5 实施变更与增量规范

    /opsx:apply

    AI 按 tasks.md 顺序生成代码。关键差异:AI不会直接修改 openspec/specs/,而是在 changes/room-migration/specs/ 下生成增量规范文件

    changes/room-migration/specs/task/spec.md

    ## MODIFIED 架构描述
    - 旧:ViewModel 直接操作 SharedPreferences
    - 新:引入数据层(Room)+ 仓库层(TaskRepository)
    
    ## ADDED 组件
    - TaskEntity: 数据库实体
    - TaskDao: 数据访问接口
    - TaskDatabase: Room 数据库实例
    - TaskRepository: 定义任务操作契约
    - TaskRepositoryImpl: 基于 Room 的实现
    
    ## ADDED 能力
    - 异步任务存储(协程+Flow)
    - 响应式 UI 更新(collectAsState)
    - 单元测试支持(使用 Room 内存数据库)

    7.6 验证、同步、归档

    /opsx:verify   # AI 检查代码是否实现了上述增量规范
    /opsx:sync     # 将 delta 规范合并至主规范目录
    /opsx:archive  # 变更移入 archive/

    新成员加入项目时只需要:

    1. 阅读 openspec/specs/task/spec.md,即可了解系统当前确切的数据层设计;
    2. 执行 /opsx:onboard,AI 会用 15 分钟带他走完一次完整的规范变更流程(例如“添加任务截止时间字段”)。

    这就是从 Vibe 到 Spec 的转型——从依赖“人肉记忆”到依赖“代码与规范同源”

    八、横向对比:OpenSpec vs 其他规范驱动工具

    维度 OpenSpec v1.0 Spec Kit 传统 TDD
    规范存储 Git 内 openspec/,与代码同源 Git 内 spec/ 测试用例
    变更粒度 功能级变更(对应一个 change 目录) 模块级规范 方法级
    AI 适配 原生支持(规范注入+产物状态机) 需手动配置提示词
    棕地支持 ⭐⭐⭐⭐(自动基线+增量合并) ⭐⭐(需手动编写) ⭐⭐⭐(重构时可加)
    多人协作 变更隔离,类似 Git 分支 直接改主规范,易冲突 代码冲突
    学习曲线 15 分钟(/opsx:onboard 2 小时(多阶段) 低(但仅限测试)

    结论

    • 新项目、架构从 0 开始:Spec Kit 更轻量,快速建立规范骨架。
    • 已有项目、日常迭代、多人团队OpenSpec 是务实的选择,它的变更隔离和增量合并机制在真实开发中几乎是刚需。尤其是在处理复杂的 Android/iOS 项目时,这种结构化的变更管理尤为重要。

    九、结语:Spec Coding 不是回归瀑布,而是驾驭 Vibe

    2026 年的今天,没有任何人怀疑 AI 生成代码的能力。问题已经变成:我们如何与一个拥有高水平编码能力、但从不主动问“为什么”的同事协作?

    OpenSpec 给出的答案不是“禁止 Vibe Coding”——实际上,/opsx:explore 正是为快速原型、技术探索保留的自由地带。它的核心主张是:

    让每一次“写代码”都有据可循,让每一次“改需求”都可追溯,让团队的集体智慧沉淀在规范里,而不是聊天记录里。

    从 Vibe 到 Spec,不是用文档淹没创造力,而是用轻量的约束换取长期的可维护性。这也符合 云栈社区 倡导的“高质量知识沉淀与协作”的理念。




    上一篇:从51单片机到STM32:一位老鸟对HAL库与寄存器学习的杂谈
    下一篇:OpenClaw真实应用案例开源项目盘点:30+场景助你提升信息收集与自动化生产力
    您需要登录后才可以回帖 登录 | 立即注册

    手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

    GMT+8, 2026-2-25 10:43 , Processed in 0.597411 second(s), 41 queries , Gzip On.

    Powered by Discuz! X3.5

    © 2025-2026 云栈社区.

    快速回复 返回顶部 返回列表