OpenSpec完整落地指南:用规范驱动开发让AI编码助手按契约交付
【免费下载链接】OpenSpecSpec-driven development (SDD) for AI coding assistants.项目地址: https://gitcode.com/GitHub_Trending/op/OpenSpec
AI编码助手把"写代码"的门槛拉到了历史最低,却把"写对代码"的难度推向了新高:生成速度越快,代码与产品契约脱节得越快。OpenSpec正是为这个矛盾而生的规范驱动开发(SDD)工具——它把规范从"写完就没人看的文档",升级为"AI开工前必须读、改完后必须过的可执行契约"。本文用一支团队的实战过程,完整走一遍从初始化到并行协作的落地路径。
失控的AI编码助手:我们真正缺的是一份契约
先说一个我们真实遇到的场景。去年我们让AI助手参与一个CLI工具的重构,它确实快——两小时产出了过去两天的代码量。但review时我们发现:它"顺手"改了错误提示的措辞、绕过了既定的配置加载顺序,甚至把两个本应独立的模块耦合在了一起。更麻烦的是,这些行为差异没有任何测试能兜住,因为需求本身从来没有人以机器可读的形式写过。
问题不在AI,而在我们。团队里最不缺的就是文档:README、设计稿、会议纪要散落各处,但没有一份是"AI能读懂、能执行、能自检"的。传统文档是给人看的,AI读完靠猜;规范一旦缺失,AI只能在概率空间里自由发挥。
OpenSpec的答案很直接:把规范当作仓库里的一等公民。它提供一套标准目录、一组固定工件、一个校验器,让"需求-实现-验证"三者咬合在一起。AI编码助手在开工前先读取规范,改完代码跑一次校验,过不了就返工——规范第一次变成了可执行的东西,而不是墙上贴的标语。
核心机制拆解:一条从"为什么"到"怎么验"的工件链
为什么很多团队在规范一致性上反复栽跟头?因为他们把规范当成一个静态文件,而不是一条生产流水线。OpenSpec把一次变更拆成四个按序产出的工件,每一步都有明确的生成规则和依赖关系:
| 工件 | 回答的问题 | 产出物 |
|---|---|---|
| proposal | 为什么做、改什么 | proposal.md |
| specs | 系统应该做什么(行为契约) | specs/**/spec.md |
| design | 怎么做、关键技术决策 | design.md |
| tasks | 分几步做完、怎么验收 | tasks.md |
这四个工件不是约定俗成,而是由schemas/spec-driven/schema.yaml声明式定义的。想扩展?改配置即可,无需动解析核心:
artifacts: - id: proposal generates: proposal.md description: Initial proposal document outlining the change requires: [] - id: specs generates: "specs/**/*.md" description: Detailed specifications for the change requires: - proposal - id: design generates: design.md description: Technical design document with implementation details requires: - proposal - id: tasks generates: tasks.md description: Implementation checklist with trackable tasks requires: - specs - design这条链上有两条纪律最值得记住。第一,spec只写"外部可观察行为"——输入、输出、错误条件、场景,不写类名、框架选型和实现步骤。判据很简单:如果换一套实现、对外行为不变,那这段内容就不该进spec。第二,tasks必须可勾选、可验证,每条任务都自带验收方式(测试、命令或可观察行为),因为apply阶段就是靠- [ ]复选框追踪进度的。这两条纪律保证了"文档-代码-验收"从源头就不脱节。
落地第一步:初始化仓库与三层配置的要点
实际落地时,我们第一步是初始化。openspec init会生成标准目录骨架:
openspec/ ├── config.yaml # 行为策略与规则注入 ├── specs/ # 已确认的主规范库(单一事实来源) │ └── cli-change/spec.md └── changes/ # 进行中的变更提案 └── add-export-command/ ├── proposal.md ├── specs/ ├── design.md └── tasks.md初始化之后真正花时间的,是配置。openspec/config.yaml里有两块内容决定了AI的"行为底色":context注入技术栈、产品语言和跨平台约束;rules约束各工件内容的写作纪律:
context: | Tech stack: TypeScript, Node.js (≥20.19.0), ESM modules Package manager: pnpm Product language: - Write proposals and specs in user-facing product behavior language - Requirements should describe the observable behavior and product contract Cross-platform requirements: - Always use path.join() or path.resolve() - never hardcode slashes - Tests must use path.join() for expected path values rules: specs: - Prefer user-facing product behavior over internal implementation mechanics tasks: - Add Windows CI verification as a task when changes involve file paths这套配置的价值在于"改配置不改代码"。我们落地跨平台支持时,没有写任何平台判断逻辑,只是在 context 里声明了三条路径处理规则——之后AI生成的所有任务和spec都会自动带上Windows场景。验证严格度也在这里调:开发初期strict: false宽松放行,进入发布周期再收紧。配置驱动让治理策略可以按阶段演化,而不是固化在代码里。
跑通真实变更:从提案到归档的完整闭环
抽象讲完了,看一次真实变更怎么走。假设我们要给CLI加一个"导出数据"的能力,流程是这样。
第一步,写 proposal.md:一两句话讲清 Why,列出 What Changes,并声明它会新增或修改哪些能力(capability)。关键约束是:要么声明至少一个能力,要么显式设置skip_specs: true,否则openspec validate会直接拒绝——这从机制上杜绝了"没有行为变更却乱写规范"。
第二步,写 delta 规范。OpenSpec 用 ADDED / MODIFIED / REMOVED / RENAMED 四种增量操作表达对主规范库的修改,每个需求必须有 WHEN/THEN 场景,且场景必须用四层级标题:
## ADDED Requirements ### Requirement: User can export data The system SHALL allow users to export their data in CSV format. #### Scenario: Successful export - **WHEN** user clicks "Export" button - **THEN** system downloads a CSV file with all user data注意这套格式的用心之处:场景就是验收用例,spec写完等于测试用例集就绪。我们后来给关键spec做自动化时,几乎是把场景原样搬进了测试文件。
第三步,跑openspec validate做校验,然后让AI按 tasks.md 逐项实现并勾选进度。整个过程的状态,用openspec view一眼看全:
如图所示,仪表盘把规范数、需求数、进行中与已完成的变更、任务完成率全部可视化。对管理者来说,最大的价值不是那张图,而是"变更量=工作量"的可量化性——我们靠它把规范库的节奏和迭代计划对齐了。
最后一步是归档:openspec archive把通过验证的 delta 合并进主规范库,变更文件夹转入 archive,规范库随之演进。整个过程里,变更即文档、验收即场景,不需要任何人对着一张过期的设计文档开会。
并行开发不乱套:隔离、堆叠与增量验证
单条变更跑通不难,难的是十个人同时改同一个规范库。我们靠的是OpenSpec的三重设计。
🧩隔离。每个变更独立目录,互不干扰,谁也不会在合并前污染主规范库。并行开发从"抢占文件"变成了"各自提案"。
🧱堆叠。当多个变更确实触碰同一能力时,用轻量元数据表达先后关系:dependsOn声明必须先行落地的变更,provides/requires声明能力供需,openspec change graph输出依赖DAG并检测环,openspec change next给出当前可以开工的变更。这让我们能把一个大变更安全地拆成可逐个合并的切片。
⚡增量验证。openspec validate默认只校验变更涉及的 delta,而不是每次全量重扫整个规范库。当spec数量涨到几十个时,这个设计省下的时间非常可观。验证分两级:
| 检查层级 | 覆盖内容 | 建议启用时机 |
|---|---|---|
| 语法验证 | 格式是否符合schema、场景层级是否正确 | 每次提交前 |
| 语义验证 | delta是否完整、依赖是否有环、是否破坏既有规范 | 合并前 |
| 跨平台验证 | Windows路径场景、大小写敏感性 | 涉及文件路径时 |
这里也要提一句我们付过的代价:最初我们以为"AI写的规范不会错",结果parser对格式的挑剔远超预期——场景少打一个#就会静默失效。所以强烈建议把openspec validate挂进CI,而不是指望人眼。
复盘与边界:我们踩过的坑和不该用的场景
文章写到这里,如果只讲优点,那是误导。三个月实践下来,我们踩过三个实打实的坑。
第一个坑:把spec写成了实现细节。有同事把"内部工具函数命名"写进了需求,归档后主规范库被实现噪音污染,后续每次改动都束手束脚。记住判据:实现换了行为不变,就不该进spec。
第二个坑:为了过校验而发明需求。openspec validate拒绝零delta变更,有人就硬凑一条需求。这恰恰违背了工具的本意——纯重构、工具链调整,就该用skip_specs: true光明正大地跳过。
第三个坑:变更拆得太碎。堆叠机制给了我们安全感,于是有人把一个功能拆成七八个切片,每个切片都小到没有独立价值,依赖图反而变成了负担。合理的粒度是"每个切片都能单独合并且不破坏现有行为"。
所以,什么场景不该用OpenSpec?我们的判断是:一次性脚本、原型验证、不涉及行为契约的小项目,上这套流程是负收益。它最适合的,是契约密集型、多AI助手并行参与、需要长期演进的工程——在那里,规范的维护成本会被"少返工、少扯皮、少回归"成倍地赚回来。
说到底,OpenSpec放大的是纪律,不是替代纪律。它把"写规范"变成了AI和人都无法回避的环节,但规范的质量,仍然取决于团队的判断力。
给团队的最小可行试点
如果你看完觉得值得一试,别急着全量铺开,按三步走:
- 拉取项目并跑通本地初始化:
git clone https://gitcode.com/GitHub_Trending/op/OpenSpec,读一遍docs/下的入门文档和openspec/specs/里现成的规范,感受格式密度。 - 选一个真实的小能力做试点(比如给内部CLI加一条命令),完整走一遍 proposal → specs → tasks → validate → archive,全程控制在半天内。
- 把
openspec validate挂进CI,并约定"spec不过、PR不merge",再用两周观察返工率变化。
规范驱动开发的收益不是立竿见影的,但它的复利很稳:每一条被验证过的规范,都在替未来的每一次变更做担保。从今天写下的第一条proposal开始,你的AI助手就会从"自由发挥的代笔",变成"按契约交付的协作者"。
【免费下载链接】OpenSpecSpec-driven development (SDD) for AI coding assistants.项目地址: https://gitcode.com/GitHub_Trending/op/OpenSpec
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考