ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

规约驱动开发实战:从OpenSpec到AI编程工具集成

规约驱动开发实战:从OpenSpec到AI编程工具集成 1. 重新理解“规约驱动”OpenSpec 到底在解决什么问题1.1 从测试驱动到规约驱动开发范式的一次重心迁移接触 OpenSpec 之前我先花了不少时间研究“规约驱动开发”Spec-Driven Development这个概念。圈子里一个常见的类比是测试驱动开发TDD把“测试”当作可执行的文档规约驱动开发则把“规约”Specification当作一切开发动作的源头。换句话说TDD 回答的是“代码怎么才算对”规约驱动回答的是“我们要做的到底是什么”。早期的 TDD 实践中我们通常先写一个失败测试然后写实现让测试通过。这套方法在逻辑清晰、模块边界明确的场景下非常好用。可一旦需求本身含糊——业务方说“这里要有一个权限控制”但没说清楚是页面级、接口级、还是数据行级——测试写出来也容易跑偏。测试约束的是实现约束不了需求本身的正确性。规约驱动的思路是先把需求用结构化、可校验的方式写成规约文件让规约先于代码存在。OpenSpec 正是这个思路的工具化实现。它不替代测试也不替代项目管理工具而是把“需求描述”从一个聊天记录里的口头约定变成一份可解析、可审查、可执行校验的 Markdown 文档。在这点上它其实更贴近“文档驱动开发”的现代版本只不过这份文档被拆成了固定的目录结构和字段格式人和 AI 都能读懂。1.2 OpenSpec 的核心价值让“需求”和“实现”之间不再靠猜我在实际项目里最大的感受是OpenSpec 解决的不是编码效率问题而是需求传递过程中的信息损耗问题。传统开发流程里产品经理讲一遍需求技术负责人转述一遍开发同学再理解一遍理解偏差几乎是必然的。有了规约文件之后这个链条变成了——需求被写成一份包含背景、目标、验收标准的结构化文档开发、测试、AI 编程助手都基于同一份文档工作。它还有一个容易被忽略的价值可追溯性。每一份规约文件都有明确的变更历史哪个需求在哪个版本被修改、验收标准为什么调整翻一下 Git 历史就清清楚楚。这比在飞书文档里翻聊天记录高效太多了。所以如果你想上手 OpenSpec首先要理解的不是它的命令行用法而是它的核心思想规约即单一事实来源Single Source of Truth。后面所有的功能——IDE 集成、AI 辅助编程、自动化校验——全是围绕这个思想展开的。2. 环境准备与基础工作流从零开始跑通 OpenSpec2.1 安装与初始化macOS 和 Node 环境下的实测记录先说明一个重要前提OpenSpec 目前主要通过 Homebrew 和 npm 两种方式分发。我在 macOS 上实测了最新版本安装命令如下# 方式一Homebrew推荐 macOS 用户使用 brew install openspec/openspec/openspec # 方式二npm适合 Node.js 环境已经就绪的场景 npm install -g openspec/cli # 验证安装是否成功 openspec --version如果安装顺利你会看到一个类似于0.x.x的版本号。截止我写这篇总结的时候Homebrew 渠道的更新速度通常比 npm 略快特别是 macOS 平台建议优先用 Homebrew。Windows 用户建议直接走 npm 或者 WSL官方对 Windows 原生支持不算特别积极这一点要有心理准备。初始化项目的命令很简单# 在项目根目录执行 openspec init执行之后OpenSpec 会在当前目录下生成一个openspec/文件夹里面包含specs/、changesets/、proposals/等子目录同时自动生成一个openspec.yaml或openspec.json配置文件。这个配置文件里定义了项目元信息、校验规则开关、以及 AI 辅助相关的配置项。注意openspec init默认不会覆盖已有目录如果你之前已经建过openspec/目录它会提示是否合并或跳过。建议初始化之前先提交一次 Git避免文件冲突时回滚麻烦。2.2 写第一份规约目录结构、字段约定和实际用例OpenSpec 的规约文件遵循一套约定俗成的结构。我在实际项目中写的最基础的一个例子是这样# 用户登录接口限流 ## 背景 当前登录接口无任何限流策略存在暴力破解风险。 需要在不影响正常用户体验的前提下对登录尝试进行频率限制。 ## 目标 - 单个 IP 每分钟登录失败次数不超过 5 次 - 超过阈值后该 IP 被锁定 15 分钟 - 正常用户成功率 95%不受影响 ## 需求 - 登录接口增加基于 IP 的计数器和时间窗口 - 失败次数达到阈值后返回 429 状态码 - 锁定状态需支持通过 Redis 缓存实现便于多实例共享 ## 验收标准 - 使用测试账号在 1 分钟内连续失败 6 次第 6 次请求返回 429 - 第 6 次请求后继续请求登录接口15 分钟内均返回 429 - 15 分钟后第 1 次登录请求可正常进行这份规约文件实际上就是一个需求文档的格式化版本。OpenSpec 的好处在于它会根据这个文件生成可追踪的校验条目。文件的基本约定是每个规约文件必须包含背景说明为什么做、目标说明做到什么程度、需求说明具体怎么做、验收标准说明怎么判断做完四大部分文件统一使用 Markdown 语法内部可以通过列表、表格、代码块自由扩展文件名使用短横线命名法比如api-rate-limit.md、user-auth-flow.md不要用空格和中文。写完规约后可以执行校验命令确认文件格式是否符合 OpenSpec 的约束# 校验当前项目所有规约文件的格式 openspec validate # 查看规约状态 openspec statusvalidate会帮你检查有没有语法层面的错误比如某个必要字段缺失、编号重复等。它会输出一个简单的报告告诉你哪些文件通过、哪些文件有问题、问题出在哪个字段里。这对团队协作特别有用——哪怕是不熟悉 OpenSpec 的新人只要照着报告改也能很快把格式写对。2.3 从规约到任务拆分OpenSpec 工作流的三个核心阶段OpenSpec 的工作流可以简单归纳为三个阶段起草规约、拆解任务、验收实现。第一个阶段是起草规约。新需求来了之后不要急着写代码先在openspec/specs/目录下建一个子目录比如openspec/specs/user-login-limit/然后在里面创建spec.md文件。按照上一节提到的四个部分把需求写清楚。这个阶段的核心原则是只描述要什么不描述怎么实现。很多同学第一次写规约的时候容易犯一个毛病——把技术方案写进需求里。比如直接写“用 Redis 的 INCR 命令实现计数器”这就把实现约束死了。正确写法是描述“系统需要限制单个 IP 的登录失败频率”至于用什么存储、什么命令留给后续技术选型去解决。第二阶段是拆解任务。规约文件写好之后OpenSpec 会为你提供一组任务tasks建议。你可以用openspec plan生成任务计划也可以手动在规约文件里通过“任务分解”字段来拆。例如## 任务分解 - [ ] 创建登录失败计数存储接口 - [ ] 实现登录接口接入限流中间件 - [ ] 编写限流策略的单元测试 - [ ] 编写 429 响应的集成测试每个任务对应一个可独立交付的代码变更联调时也可以按这个列表来逐项验收。第三个阶段是验收实现。代码写好之后回到规约文件把任务列表里的勾挨个打上去然后对照验收标准逐条验证。如果某条验收标准当时没考虑到比如“数据库主从延迟的情况下计数是否一致”那就补充进规约再做实现调整。整个过程是循环的但每次循环都基于格式化的文档而不是口头沟通。这套流程跑通之后你会发现一个很直观的变化开会讨论需求的时候大家不再依赖白板和便签直接把规约文件打开逐条过验收标准就够了。这在远程协作团队里尤其有用——异步沟通时每个人的讨论都有据可依。3. 在 Cursor 和 IDEA 里集成 OpenSpec实操记录3.1 让 Cursor 读懂你的规约目录关于 OpenSpec 和 AI 编程工具如何配合是社区里讨论最多的话题之一。我实际用下来最有效的用法是让 AI 编程助手以规约文件为上下文来生成代码而不是让 AI 自由发挥。先说 Cursor。Cursor 本身并不内置 OpenSpec 支持但你可以通过.cursorrules文件或项目提示词Project Prompt让它理解你的规约结构。我的做法是在项目根目录创建.cursorrules文件把以下规则放进去你是一个严格遵循规约驱动开发的工程师。 在开始编码之前必须阅读 openspec/specs/ 目录下对应的 spec.md 文件。 你的代码实现必须满足该文件中的「需求」和「验收标准」部分。 如果规约中的需求不明确先向用户提问澄清禁止猜测实现。 编码完成后对照验收标准逐条检查自己的实现并把结果输出给用户。这样配置之后Cursor 在进行代码生成时会优先检索openspec/specs/目录下的相关文件作为参考。配合 Cursor 的文件引用功能可以直接让 AI 读取某个具体的规约文件openspec/specs/user-login-limit/spec.md 请根据这份规约实现登录限流功能。实测下来相比不给任何上下文直接让 AI 写代码这种方式的代码贴合度要高很多。原因是AI 编程工具最怕的不是不会写代码而是“自由发挥”——它会在你没要求的地方做额外假设在关键约束上反而漏掉。规约文件本身就是一份约束集把它作为上下文相当于给 AI 戴上了缰绳。另一个实用技巧是把openspec的命令封装成 Cursor 的快捷指令。在 Cursor 里配置一个执行openspec validate的自定义命令每次 AI 改完代码就顺手跑一遍校验能避免很多低级格式错误。3.2 通过 CCGui 插件在 IDEA 里接入 OpenSpec如果团队里有同学主要用 JetBrains IDEA比如写 Java 或 Kotlin社区里有开源插件叫 CCGui可以通过它集成 OpenSpec 的核心能力。这个插件的思路是把规约管理做进 IDE 侧边栏让你不切终端就能执行常见的 OpenSpec 操作。CCGui 插件的接入步骤大致如下在 IDEA 的插件市场搜索“CCGui”安装后重启 IDE在项目设置里指定 OpenSpec 可执行文件的路径如果已经通过 Homebrew 安装通常路径是/opt/homebrew/bin/openspec打开 CCGui 工具窗口它会自动扫描项目中的openspec/目录把规约文件以树形结构展示出来右键某个规约文件可以直接执行validate、plan、status等命令也可以在编辑器和规约文件之间快速跳转。CCGui 本质上只是 OpenSpec 的命令行工具的图形化封装它不额外做代码生成。价值在于降低操作成本以及当你记住不命令参数的时候不需要去翻文档。但要注意第三方插件的功能往往落后于 CLI 版本遇到命令执行结果和命令行不一致的情况以命令行输出为准。3.3 IDE 集成之外规约驱动在 AI 辅助编程中的最佳实践工具层面的集成只是第一步真正的难点在于让团队成员改变编码习惯。我在实践过程中总结了三条经验第一条AI 生成的代码必须以规约为准以提示词为辅。不要直接对 AI 说“帮我写个限流功能”而是说“请阅读openspec/specs/user-login-limit/spec.md按照验收标准实现”。前者 AI 可能会用内存缓存来做计数后者 AI 会主动参考规约里“多实例共享”的需求选择 Redis 方案。差的不是 AI 的能力是它接收的信息。第二条规约也要进 Code Review。很多团队做 Review 只看代码 diff忽略需求文档的变更。但规约驱动开发里规约文件的变更恰恰是最需要 Review 的验收标准放宽了没有需求是否悄悄变了这些内容变化如果不审查代码实现就会慢慢偏离原始目标。我现在会专门要求团队把.md文件的变更也纳入 PR 审查范围。第三条不要为了规约而规约。不是所有需求都值得写成规约文件。简单到一句话能说清的 bug 修复、临时脚本、一次性数据迁移直接写代码就好。规约文件适合的是那些需要多人协作、有明确验收标准、周期较长的功能模块。一个判断标准是如果这个需求两周后你还会回头看它那就值得写规约。4. 与 Superpowers 等工具链的组合实践4.1 Superpowers 是什么它和 OpenSpec 怎么互补顺着热搜词里的“OpenSpec 怎么和 Superpowers 一起用”我也去实践了一下。Superpowers 是一套技能包/工作流增强工具核心能力是把复杂任务拆解为可复用的“技能”步骤再把多个技能串联成流水线。它和 OpenSpec 的定位并不冲突反而可以形成互补OpenSpec 负责定义“做什么”Superpowers 负责定义“怎么做”。打个比方OpenSpec 是产品需求文档Superpowers 是研发流程手册。前者描述目标和验收标准后者描述编码时应该遵循的步骤和模式。两者结合时一个规约文件被 OpenSpec 校验通过后Superpowers 可以把规约中的需求逐条翻译成具体的编码任务并按照预设的工程规范比如测试优先、目录结构约定、错误处理模式指导 AI 逐步实现。4.2 组合使用的完整流程从规约到代码生成的串联示例我这里分享一个我在示例项目中实际跑通的串联流程整个流程分四步。第一步先用 OpenSpec 写好规约并校验通过openspec init # 手动创建 openspec/specs/order-service/spec.md openspec validate第二步启动 Superpowers 的任务拆解功能。它支持多种 AI 后端我这边配置的是本地模型接口但无论接哪个模型核心动作都是让 Superpowers 读取 OpenSpec 生成的规约文件请基于 openspec/specs/order-service/spec.md 为每个「需求」条目生成对应的编码任务。 每个任务必须包含 - 涉及的文件路径 - 需要实现的函数/接口 - 对应的验收标准编号 - 测试策略Superpowers 会返回一个结构化任务清单类似这样需求条目涉及文件实现要点验收标准编号测试策略需求1创建订单接口api/order.go校验商品库存和价格AC-1、AC-2单元测试 API 集成测试需求2订单状态流转internal/order/state.go状态机严格单向流转AC-3状态机单元测试第三步把任务清单喂给 AI 编程助手逐步实现。这里有一个关键的技巧不要一次性把整个任务清单发给 AI而是一个任务一个任务地来。每完成一个任务就对照验收标准做一次本地验证。如果多个任务同时发给 AI它经常会在处理跨文件依赖时出现遗漏返工成本远高于逐个过。第四步全部实现后返回 OpenSpec 做最终校验openspec validate openspec status然后按照验收标准逐条跑测试、做 Code Review。整个流程跑下来我的体感是OpenSpec 管住了“需求不跑偏”Superpowers 管住了“实现有章法”AI 编程工具负责“把手写码的脏活累活干了”三者结合后效率和质量的提升不是叠加而是乘法级的。4.3 组合使用时的注意事项和配置建议这套组合虽然好用但配置上还是有几个坑值得提醒。第一版本兼容性。Superpowers 对 OpenSpec 规约文件的解析依赖文件格式的稳定性。如果你们团队里有人升级了 OpenSpec 且改了默认的目录结构Superpowers 可能会因为找不到spec.yml或某个固定字段而报错。建议在项目里锁版本比如在package.json或README里限定 OpenSpec 的版本。第二上下文窗口管理。把 OpenSpec 全套规约文件和 Superpowers 提示词一次性塞给 AI很容易触发上下文窗口超限。我的经验是只把与当前任务相关的规约片段作为上下文而不是把整个openspec/目录都交给 AI。第三明确职责边界。OpenSpec 负责需求层的校验Superpowers 负责任务执行层的编排不要让它们互相替代。有些同学会尝试在 Superpowers 的技能脚本里直接改 OpenSpec 的规约文件——我建议不要这么做。规约是需求层面的产物建议由人来修改和审核AI 修改需求总归有风险哪怕只是改错一个验收标准后果也可能很严重。5. 常见问题与排查经验实录5.1 安装、校验和集成过程中的高频问题速查表在实际使用 OpenSpec 的过程中我把遇到过的高频问题整理成了一张速查表都是实打实踩过的坑问题现象根因分析解决方案openspec: command not foundHomebrew 安装后 PATH 未刷新或 npm 全局 bin 目录不在 PATH 中macOS 执行eval $(/opt/homebrew/bin/brew shellenv)npm 用户确认 npm 全局 bin 路径已加入 shell 配置文件openspec validate报“字段 missing”规约文件缺少必要字段比如“背景”或“验收标准”按报错提示补齐字段字段名必须与模板完全一致注意大小写无法在 Cursor 中识别规约文件.cursorrules文件未生效或者没有在提示词中显式引用文件路径在 Cursor 设置里确认 Project Prompt 已加载用显式引用具体规约文件CCGui 插件显示 OpenSpec 命令执行失败插件配置的可执行文件路径错误或版本不兼容检查插件设置中的 openspec 路径切换到命令行执行以便定位具体报错openspec status命令执行缓慢项目目录太大规约文件数量过多在.gitignore中排除无关目录或按模块拆分多个规约子目录5.2 一个典型案例CocoaPods 依赖冲突引发的规约校验失败这个标题看起来有点奇怪——OpenSpec 和 CocoaPods 有什么关系实际上它们没关系我想说的是一个在 iOS 项目里遇到的麻烦安装 OpenSpec 的时候Homebrew 会自动检查它依赖的 Node.js 版本和 CocoaPods 的 Ruby 环境是否有冲突。我当时遇到的情况是执行brew install openspec报错提示 Node.js 版本不符合要求。排查后发现Homebrew 默认帮我安装了最新版 Node.js但项目里有个老旧的 CocoaPods 环境依赖旧版 Node。它们俩互相抢资源导致 OpenSpec 的 CLI 命令始终无法正常运行。解决方法也很直接用 Homebrew 的版本管理能力给 OpenSpec 单独指定 Node 版本同时用rbenv或者chruby管理项目里的 Ruby 环境把两者隔离开。这种“工具链相互打架”的问题在 macOS 开发环境里非常常见碰上之后最重要的是冷静排查先确认是 PATH 问题还是版本依赖问题再决定怎么隔离。5.3 几个通用的排查技巧遇到 OpenSpec 相关的问题我通常按下面的顺序排查第一先看命令行输出。OpenSpec 的 CLI 报错信息做得比较友好大多数情况会直接告诉你缺了什么、错在哪。遇到看不懂的错误码把它复制到 GitHub Issues 里搜一下往往能找到类似案例。第二确认配置文件。openspec init生成的配置文件不一定总适合你的项目结构。检查配置里有没有多余的路径映射或者缺少必要的模块声明。配置文件改动之后要重新执行openspec validate确认没问题再继续。第三把问题缩小到最小复现。如果规约文件很多且校验失败不要一个文件一个文件猜先备份目录然后逐步删减规约文件把问题范围缩到最小再针对可疑文件逐行检查。这套方法适合所有需要定位规则问题的场景。6. 实践心得与三个核心体会写这篇实践总结的过程中我又把从安装到集成的整条路径跑了一遍。踩过不少坑也有了一些比较稳固的心得。第一个体会是OpenSpec 真正改变的并不是编码方式而是需求流转方式。在一个团队里推行 OpenSpec 的时候最难的不是让大家学会写规约文件而是改变“拿到需求就写代码”的惯性。一旦团队真的接受了“先有可校验的规约再谈实现”这种节奏跨角色沟通的摩擦会肉眼可见地下降。第二个体会是工具选型不必一步到位。如果你是小团队、个人项目其实只需要 OpenSpec 命令行加一个 Git 仓库就足够跑起来了。等团队长大、需求变复杂再逐步接入 AI 编程工具、Superpowers 这些增强组件。我见过一些团队一开始就想把全套工具链搭齐结果光配置就折腾了两周最后什么都没跑起来。工具永远服务于流程而不是反过来。第三个体会是规约文件是一笔沉淀资产。在新人加入项目时让它读一遍 OpenSpec 规约目录比看一堆代码注释有用得多。规约文件会随着项目演进保留新增和变更记录这相当于一份“活文档”。比起那些写完就没人维护的 Wiki 页面规约文件的生命力要强得多。最后再分享一个小技巧如果团队里有远程协作的场景不妨把 OpenSpec 的openspec status输出接入到 CI 的构建日志里。这样每次提交代码之后团队成员都能直观看到规约覆盖率和校验结果让“规约先行”成为团队里看得见的默认动作。规约驱动开发这个方向本身就还在快速演进相关的工具链也日新月异保持好奇多动手试试你会找到最适合自己团队的那套打法的。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进