
1. 从“AI代码失控”说起为什么我最终走向了OpenSpec先聊个事儿。过去半年我一直在重度使用各类AI辅助编程工具代码生成确实快但项目复杂度一旦上来问题就跟着来了——AI经常会“自作主张”地改掉不该改的逻辑或者在一堆互相耦合的模块里东一榔头西一棒子。最崩溃的一次我让它修一个登录态的bug它顺手把接口超时时间从10秒改成了3秒还自我感觉良好地加了个注释“优化用户体验”。项目是我自己的倒还好要是团队协作这种不可控比没有AI还可怕。后来我意识到问题不出在AI模型上而是出在“需求传递”这件事上。你用一段自然语言描述你想干什么AI就敢直接撸代码中间没有任何“评审”环节。这就像你让一个刚入职的实习生去重构核心模块只丢给他一句“把性能优化一下”他能不闯祸吗OpenSpec就是在这个背景下被我捡起来的。它不是一个编程语言也不是一个框架而是一套面向AI辅助开发流程的规格说明规范Spec-Driven Development。简单说它是把“需求怎么描述、任务怎么拆解、验收标准怎么定义”这套流程标准化让AI照着明确的规格去干活让人在关键节点做评审。用了一阵子之后我的项目返工率明显降下来了团队协作也舒服很多。这篇文章不打算写什么高大上的理念就从一个实际使用者的角度讲讲OpenSpec怎么落地、怎么和AI Agent配合、踩过哪些坑以及它到底适合什么样的团队和个人。2. 核心概念拆解OpenSpec到底是怎么工作的2.1 一套“面向变更”的规格体系OpenSpec的第一性原则是规格不是写给代码库看的而是写给“变更”看的。这与传统的API文档或者架构文档完全不同。传统文档描述的是“系统长什么样”——有哪些模块、接口、数据表。而OpenSpec描述的是“这次变更要做什么”——改哪个功能、加哪个字段、影响哪条链路。每一份OpenSpec文件都以一次具体的变更change为单位是面向变更的规格。好处是显而易见的。代码库是持续演进的传统文档非常容易过时因为没人愿意为一个已经稳定的系统反复维护文档。而变更导向的规格描述的是“此刻要解决的一个具体问题”生命周期从创建到完成通常只有几天。这就大幅降低了维护成本也让AI能精准地围绕变更来生成代码而不是在大而全的文档里“大海捞针”。2.2 三个关键的规格文件proposal、tasks、analysis每份OpenSpec变更里有三个文件是灵魂它们各自承担不同的职责文件职责必须回答的问题proposal.md变更提案这次改什么为什么改不删什么tasks.md任务拆解拆成哪几步每一步的验收标准是什么analysis.md设计分析有哪些备选方案选了哪个为什么刚开始用的时候我也不理解觉得一个需求写三个文件不是更慢吗但用久了我发现这三个文件正好对应了评审的三个层次proposal回答“做不做”这是方向问题。analysis回答“怎么做”这是设计问题。tasks回答“分几步做”这是执行问题。AI Agent每走一步都拿tasks里的验收标准自我检查人每过一个阶段拿proposal和analysis检查方向有没有偏。这样层层设卡失控的概率自然就低了。2.3 “麻雀虽小”的CLI工具OpenSpec附带一个轻量级CLI工具用来做规格文件的脚手架生成、结构校验、变更状态管理等。它不做代码分析、不连接AI、不管版本发布——只专心把“规格文件”这摊事理顺。CLI的设计有一个很有意思的原则可自举self-bootstrapping。也就是说这个CLI最早期的版本是OpenSpec自己用自己写出来的。鸡生蛋蛋生鸡但确实证明了这套规范在真实项目中能跑通。我当时看到这个设计反而更愿意相信它不是纸上谈兵。3. 完整实操从零到一跑通一次变更接下来是最重要的部分。我带你把一次完整的OpenSpec流程走一遍包含目录初始化、提案编写、任务拆解、Agent执行和人工评审。3.1 环境准备与项目初始化OpenSpec基于Node.js所以第一步是确保机器上有Node.js环境。建议版本不低于18实测在20 LTS上运行最稳。# 在项目根目录执行初始化 npx openspec/clilatest init这个命令会帮你在当前仓库里生成一个openspec/目录结构大致是openspec/ ├── project.md # 项目级背景信息用于给AI提供上下文 └── changes/ └── 2025-05-01-add-user-login/ # 每次变更是独立目录 ├── proposal.md ├── tasks.md └── analysis.md初始化之后建议第一件事就是把openspec/project.md认真写好因为AI Agent的执行质量很大程度依赖这个背景文件。我见过太多人忽略这个文件直接用默认模板结果AI产出明显“失忆”——写着写着就忘了项目的前置约束和既有设计。3.2 编写proposal.md明确边界比明确内容更重要proposal是整个变更的出发点。在OpenSpec里proposal会强制要求你写清楚两个方向新增add与不变preserve。我写一个实际例子。假设这是一个电商项目需要给订单系统增加“拆单”能力## Why 用户在一个店铺下了多件商品分属不同仓库目前只能整体发货。 当部分商品缺货时整个订单都被卡住。 ## What Changes - ADD: 订单拆分子表 order_splits - ADD: 按仓库拆单的后台服务逻辑 - ADD: 拆单结果对用户可见的通知文案 ## What Doesnt Change - PRESERVE: 原订单主表结构不做迁移 - PRESERVE: 支付结算仍以原订单号为单位 - PRESERVE: 未拆单历史订单不受影响你看第三节“What Doesnt Change”特别关键。AI执行过程中经常“用力过猛”把不该碰的东西顺手碰了。有了这一节AI能减少很多误操作。我习惯上会把“What Doesnt Change”写得比“What Changes”还细因为对AI来说划定禁区比划定作业区更重要。3.3 编写tasks.md把变量变成可验证的清单tasks文件是给AI Agent的“分步执行清单”。这里有一个核心原则每个task必须有可验证的验收标准而不是“完成某某逻辑”。还是用拆单的例子## Task 1创建 order_splits 表结构 - [ ] 新增 order_splits 表字段包含id, order_id, warehouse_id, status, created_at - [ ] 通过 sqlite3 执行 PRAGMA foreign_key_list(order_splits) 能查到 order_id 的外键约束 - [ ] 无数据库迁移工具时保留建表SQL在 db/migrations/20250501_create_order_splits.sql ## Task 2实现按仓库拆单服务 - [ ] 服务函数 splitOrder(orderId) 能按仓库编码聚合订单商品 - [ ] 拆单完成后原订单状态更新为 SPLITTED - [ ] 生成拆单结果事件写入 order_split_events 表注意几个小细节每个task的验收标准里必须出现可操作的方式比如执行某个能跑通的命令或者验证某个表结构。task粒度要控制在1-2小时能完成的范围。太粗的taskAI执行容易失控。如果Agent是Claude Code这类能自动执行命令的工具tasks里的验证步骤会被它自动跑掉所以写清“验证方式”等于白送它一段安全网。3.4 引入AI Agent执行任务环境备好、规格写好之后就可以让AI进场了。以Claude Code为例我们通常会在项目里配置一个自定义命令比如claude -p 执行 openspec/changes/2025-05-01-add-user-login/ 下的所有任务逐个完成并用命令验证完成后报告每个task的状态执行过程中有几个体验上的建议让Agent逐条执行不要一次把整个spec全丢给它然后等一个大结果。逐条执行时它能参照上一个任务的验证结果调整下一步的动作成功率更高。失败不可怕可怕的是失败不反馈。有时Agent执行一个命令失败后会尝试绕过或重试这种时候需要你在prompt里加上“任务失败时输出具体错误信息并停止不要尝试自行修改spec”。如果你还没用上规划类的Agent也可以只把OpenSpec作为“需求梳理工具”在需求阶段生成spec后再拿给任何一代代码生成工具让它们照着写——虽然效果会比Agent自动执行差一点但也比直接用自然语言描述需求强得多。3.5 人工评审这个环节不能省OpenSpec定义了“执行-验证-更新spec”的闭环。每当Agent完成一批task建议人工做一次评审重点看代码是否真的只动了proposal里“What Changes”提到的范围是否有未经过讨论的“顺手优化”是否所有验证命令的输出都符合预期tasks.md里已完成的task是否被正确勾选状态同步。评审完之后把评审结论写回proposal文件。这样整条变更链路上什么时候执行、什么时候review、中间改了什么都留痕可追溯。4. 工具链与命令参考OpenSpec CLI常用操作一览这里我把CLI常用命令做成一个速查表方便大家实际使用时翻查。命令作用说明npx openspec/clilatest init初始化目录在项目根目录生成openspec/npx openspec/clilatest new 变更名创建新change生成proposal.md/tasks.md/analysis.md模板npx openspec/clilatest validate校验spec格式检查markdown结构是否完整、必填项是否缺失npx openspec/clilatest list列出所有变更展示当前待处理/进行中/已完成列表npx openspec/clilatest archive 变更名归档变更完成后归档从活动列表移出npx openspec/clilatest plan生成执行计划将tasks转换成Agent可读执行序列绝大多数情况下我常用的只有new和validate。validate是个不错的“守门员”——提交前跑一下能避免很多因为格式不完整导致的Agent理解偏差。有一点要老实话讲OpenSpec CLI目前还在快速迭代阶段命令偶尔有小变更。如果哪天命令对不上别慌执行CLI的--help查看最新提示即可核心目录结构和管理逻辑是稳定的。5. 踩坑实录真实使用中遇到的典型问题5.1 问题一proposal写得太粗AI在没有边界的情况下自由发挥这是最普遍的问题。很多人习惯性地把proposal写得像是“需求文档摘要”比如“优化订单查询性能提升用户体验”然后让Agent去干。结果AI根据自己的“理解”改了索引、改了缓存策略甚至改了接口返回结构然后又引发了一连串连锁反应。我的解法写proposal时给自己定一个三问测试——如果AI只看proposal一个小时之后它能清楚地回答以下三个问题吗改什么、怎么改、不碰什么如果不能proposal就不合格。宁可多花20分钟把proposal写透也不要省这个时间留给后面三天返工。5.2 问题二tasks粒度太粗验证步骤难以执行有时因为偷懒task会写成“实现一个配置中心”或者“优化登录流程”完全没法验证。这种task对AI的约束力非常弱AI很容易用它的“默认套路”把事情混过去。我的解法验证标准必须具体到命令级别。举一个正面模板- [ ] 执行 npm run test:unit -- --grep splitOrder 返回 pass - [ ] 执行 curl localhost:3000/api/order/100/split 返回 HTTP 200 且响应体包含 split_ids验证标准足够具体之后Agent不管是用什么路径实现最终都得收敛到你定义的验收条件上。5.3 问题三把OpenSpec当成银弹忽略了人的作用OpenSpec是个规范不是魔法。我见过最快的翻车是一个人把所有活都交给Agent自己完全不看spec不做review然后期望Agent产生完全正确的结果。实际上OpenSpec适合的场景是人和AI协作它的价值是让人的评审点更前置、更结构化、更高效但它不能替代review。你说“让它自己跑跑完我看结果”这不叫协作这叫盲试。5.4 问题四为跑流程而跑流程spec写完再也不更新OpenSpec文件的“活性”是它真正的价值所在。如果你写完proposal就不再回头翻它那就只是一个形式主义的产物。按我的习惯每一次重要的代码评审前都先把对应的spec翻开更新一次代码哪部分和spec有偏差当场改spec或改代码取舍分明。6. 哪些场景真正适合OpenSpec最后聊一聊使用边界。个人体会OpenSpec在下面这几类场景里收益最大第一你正在用AI Agent写核心业务代码但心情天天像坐过山车——上次生成的功能不对下次又好了没有任何确定性。这时候OpenSpec等于给AI装了一个锚。第二你们团队在做小步快跑式Feature开发需求变化频繁但又不想牺牲架构稳定性。OpenSpec变更导向的粒度天然适配这种短周期迭代。第三你负责向团队交付AI辅助开发的流程和规范。它不是个人玩具而是一套能让团队里每个人都按同一套标准写Prompt和描述需求的约定。反过来场景不合适的时候硬上OpenSpec也难受极小型Demo项目代码量几百行没必要引入spec。目标模糊、探索性很强的研究项目需求每天都在变连proposal的“What Changes”都写不清。完全不使用AI辅助编程的团队——虽然OpenSpec本身有文档价值但收益会打个折扣。7. 从OpenSpec延伸出去规格驱动开发是一种可以复制的方法论用OpenSpec一阵子之后我做了一个调整把它的核心思路抽出来用到了那些不直接使用OpenSpec的项目里。方法很简单核心两条原则一、任何一次代码变更开工之前先写“与之对应”的验收清单。不用非得放进openspec目录写在Pull Request描述里也行。关键是这个清单不是给AI看的是给你自己看的。写完清单再动手你写出的代码完成度、边界感都会明显变好。二、把“不做什么”写进需求文档。这项习惯完全是从OpenSpec的proposal里学到的。绝大多数需求讨论里人们只讨论“要做什么”很少有人谈“维持什么、不碰什么”。一旦把后者也写出来很多理解偏差和过度设计能直接消弭于开工之前。如果你对这套思路感兴趣再往前走一步还可以看OWASP的Security Assurance 规范threat modeling 前置思路、Gherkin类的BDD实践验收标准的表达方式以及部分团队在用的ADRArchitecture Decision Records——它们和OpenSpec的analysis文件在“记录设计决策原因”上是同一个思路。Spec Runner这类自动化工具未来大概率会进一步把“规格-验证-代码检查”串成流水线。OpenSpec现在做的是“规格落地”但它可信的地方在于终端目标不是锁死一套格式而是一种真正能把AI和人的意图对齐的工作方式。我个人在实际使用中的体会是OpenSpec最大的价值不是工具本身而是它逼迫你重新思考“什么叫把需求说清楚”。过去跟同事沟通需求我们常常默认彼此理解一致然后一起被AI的“自由发挥”打脸。现在多了一道写spec的工序虽然前面慢了一点后面反而稳得多。如果你正好也被AI生成的“自信但错误”的代码折磨过不妨花一天时间把OpenSpec跑通试试。先从一个最小变更开始别贪大跑通一次完整的“写spec——Agent执行——人工review”闭环你会回来感谢自己的。