AI编码不可控?用OpenSpec规格驱动工作流实现需求到任务的落地
2026/9/13 20:41:30 网站建设 项目流程

过去一年我用 AI 写代码的方式和很多人一样:把需求往对话框里一贴,然后等着看 diff。直到有次它自作主张把整个支付模块的目录结构都重写了,我才真正意识到问题根源不在代码,而在需求——需求描述得越模糊,AI 就越敢自由发挥。后来我切换到 OpenSpec 这套规格驱动的工作流,把“给 AI 的一句模糊需求”换成“先写规格、再让 AI 按任务清单逐项执行”,返工率肉眼可见地降了下来。这篇文章就是一份写给普通开发者的 OpenSpec 操作手册,从安装初始化,到和 Cursor、IDEA、Superpower 配合使用的完整过程都会讲到,适合正在被 AI 编码“不可控”折腾的人参考。

1. 没有 OpenSpec 的时候,AI 编码到底卡在哪

1.1 对话式编码的三个老毛病

先说结论:没有 OpenSpec 的时候,AI 编码最大的问题从来不是“AI 不会写代码”,而是“AI 在正确理解需求之前就开始写代码了”。

第一个老毛病是需求漂移。你一开始说“优化登录流程”,聊了二十轮之后,AI 可能已经自己去研究单点登录了。这不是它笨,而是对话上下文天然有“近因效应”,越靠后的消息权重越高,早期那个精准的需求很容易被后续讨论覆盖掉。你真正想要的稳定边界,在纯对话里根本固定不住。

第二个老毛病是隐含假设。人脑里装着一堆“常识”,比如“登录流程要处理密码错误提示”“删除操作需要二次确认”“金额计算要考虑精度”,这些你不会逐字打给 AI,但你会默认它懂。问题是它又不是你肚子里的蛔虫,你没说它就不一定做,于是它交出来的东西总在某个角落和你的预期差一截。

第三个老毛病是无法复现。纯对话没有状态、没有版本、没有持久化,你关掉窗口第二天继续,所有约束条件都得重新说一遍。万一 AI 当时理解偏了,你还没留记录,那就只能从头再来。

1.2 规格驱动到底改变了什么

OpenSpec 解决的思路很直白:把“聊天记录”这种临时性载体,换成“规格文件”这种结构化、可版本化、可验收的载体。

维度传统对话式规格驱动式
需求载体聊天记录,会漂移规格文件,固定成文
执行方式AI 自由发挥按任务列表逐项执行
进度追踪只能靠人脑记任务状态可查可更新
团队协作个人经验,难传递共享文档,可评审
返工成本高,经常推翻重来低,改完规格再重跑

我自己的体会是:写代码的人,角色从“指挥 AI 干活”变成了“定义验收标准、审核 AI 是否达标”。听起来更麻烦,但这恰恰是可控性所在。

2. OpenSpec 的工作方式:先懂三条核心概念

2.1 Spec 文件到底长什么样

OpenSpec 的核心产物是一个个规格文件。不同版本生成的文件结构会略有差异,但核心都会包含三个区块:Context(上下文背景)、Requirements(需求清单)、Tasks(任务列表)。

简化看,一个规格文件大概是这种形态:

# 功能:用户登录 ## Context - 当前系统没有登录能力,所有请求都是匿名访问 - 需要支持邮箱 + 密码登录 - 安全要求:密码必须加密存储,登录失败不能暴露用户是否存在 ## Requirements - R1:用户可以用邮箱和密码登录 - R2:登录成功后返回 token,前端保存并附带在后续请求中 - R3:连续 5 次密码错误需要锁定账号 15 分钟 ## Tasks - [ ] T1:创建 users 表和密码哈希字段 - [ ] T2:实现 POST /api/login 接口 - [ ] T3:实现密码错误次数记录和账号锁定逻辑 - [ ] T4:编写登录接口的单元测试

Context 是给 AI 补背景知识的,避免它瞎猜;Requirements 是验收标准,每一条都能明确判断“做没做到”;Tasks 是给 AI 的执行清单,一次只做一件事。

2.2 从需求到任务列表的拆解逻辑

我见过很多人把 Requirements 和 Tasks 混在一起写,这是最常见的误区。Requirements 是“要达成什么”,Tasks 是“要做什么动作”。前者偏结果,后者偏过程。

以登录功能为例:

  • Requirement 是“登录成功后返回 token”,这是一个结果,你无法直接让 AI 去实现一句话,它得先知道要查数据库、校验密码、生成 token。
  • Task 则是“实现 POST /api/login 接口”“增加密码校验工具函数”“生成 JWT 并返回”这类动作,每一条都能对应一次代码变更。

拆解时我遵循两个原则:第一,单个任务要小到可以被独立验证;第二,任务的顺序要尽量让每个中间状态都能编译通过。比如先建表、再写接口、再补测试,而不是让 AI 一次性把整个功能全写完再给你看效果。

顺便说一句,让 AI 参与拆解任务本身是好事,但拆完你必须自己审一遍。AI 擅长把大需求拆成可执行步骤,但它不理解你的项目长期演进方向,有些它觉得“没必要”的边界情况恰恰是你要保护的地方。

2.3 状态与变更管理怎么跟踪

OpenSpec 和普通文档最大的区别,是任务状态可以跟着开发进度实时更新。一个任务从 open 到 in_progress 再到 done,每步都有迹可循。

实际操作里,我会把规格文件提交进 Git 仓库,和代码一起管理。需求变更时,流程不是直接告诉 AI“改成这样”,而是先改规格里的 Requirements,再改 Tasks,最后再让 AI 去动代码。

这么做的好处是:规格文件成了项目里最权威的“意图记录”。代码可能被重构、被删掉,但规格一直保留着当初为什么这么做的原因。几个月后有人问起某个模块的设计初衷,直接把当时的 spec 翻出来就行,比翻聊天记录靠谱一万倍。

3. 安装与初始化:Mac 和命令行快速上手

3.1 安装 OpenSpec 的三条路

在 Mac 上安装 OpenSpec,我试过两种比较省事的方式。第一种是 Homebrew:

brew install openspec

如果你的 brew 仓库里还没有这个包,或者你想锁定某个特定版本,就直接去 GitHub Releases 页面下载对应架构的二进制。这里需要留意的是 Apple Silicon 和 Intel 芯片的运行文件不通用,下载前先确认架构:

uname -m # arm64 或者 x86_64

下载完解压后,把可执行文件扔到 PATH 目录里就行。装好之后验证一下:

openspec --version

如果之前装过旧版本,建议看看新版发布说明,有几个版本的目录结构和命令名称做过调整,升级后老的规格目录可能需要迁移。

3.2 初始化项目:一次 init 搞定

进入项目根目录,执行:

openspec init

初始化完成后,项目里会出现一个专门的规格目录(不同版本可能叫 specs 或 openspec,以实际生成为准)。这个目录建议在一开始就提交到 Git,并且让团队所有人共用同一份。

初始化的时候它会问你几个问题,比如“是否把规格目录加入 .gitignore”“默认的规格作者是谁”之类,按实际情况回答就行。我推荐不要把规格目录忽略掉,因为规格和代码一样是需要版本管理的。

3.3 从创建一个最小规格到跑通全流程

创建一个新规格,命令大致是这样的:

openspec create user-login

这个命令会生成一个规格目录和初始的 spec 文件。打开文件,你会看到刚才说的 Context、Requirements、Tasks 三段框架,往里填内容就行。

填完后,用openspec list可以查看当前项目里有哪些规格,用openspec show user-login可以查看某个规格的详细内容和任务状态。当一个规格里的所有任务都完成时,把整体状态标记为完成,这个功能就走完了整个生命周期。

不同版本对子命令的命名可能有差异,第一次用的时候先跑一下:

openspec --help

把支持的命令看一遍,再开始干活。别照着老教程敲,不然容易卡在第一步。

4. 在 Cursor 和 IDEA 里使用 OpenSpec 的姿势

4.1 Cursor 下最顺手的用法

Cursor 这类 AI 编辑器最大的特点是能直接读项目文件,所以 OpenSpec 的规格文件天然就能被它感知到。但“能感知”和“会主动遵守”是两回事,你需要在会话开始时把规格文件的路径和当前任务明确告诉它。

我现在的做法是,在项目根目录放一个简短的规则文件,里面写上:

在修改代码前,先检查 openspec 目录下是否有与本次需求相关的规格文件。 如果有,严格按规格中的 Requirements 和 Tasks 执行。 每次只完成当前指定的 Task,完成后更新任务状态。

这样每次打开新会话,AI 都会自动去读规格目录。然后我在对话里再补一句“当前任务是 user-login 的 T2,实现 POST /api/login 接口”,它就能准确锁定范围和验收标准。

一个很容易忽略的细节:一次只给一个任务。如果你把 T1 到 T4 全贴在对话里,AI 大概率会一口气全部实现,一旦中途理解偏了,四个任务全错,回头改的代价非常大。

4.2 IDEA 里通过外部工具集成

在 IDEA 里,我试过两种集成方式。第一种最轻量:直接用 IDEA 内置的终端跑openspec命令,完全没问题,但每次敲命令有点繁琐。

第二种是把 OpenSpec 配成 IDEA 的外部工具,这样可以在工具栏里一键执行常用操作。路径是:

Settings -> Tools -> External Tools -> 添加新工具

按下面的示例配置一个“OpenSpec List”:

  • Name:OpenSpec List
  • Program:openspec
  • Arguments:list
  • Working directory:$ProjectFileDir$

配置好之后,点工具栏按钮就能快速列出所有规格。同样的方式可以配出openspec showopenspec create等常用命令。

有些 IDEA 插件(比如社区里基于 CCGui 做的 OpenSpec 集成插件)会把规格文件、任务状态、命令操作图形化,鼠标点击就能切换任务状态。原理其实就是把上面的外部工具操作包装成了 UI,不值得为了某个插件折腾太久,重点还是把 CLI 用熟。如果插件能帮你快速浏览规格内容,那它最大的价值是让你在写代码之前先看到需求边界,而不是等代码写完才发现偏了。

4.3 让 AI 会话正确读取规格文件的几个技巧

经验之谈,有四个技巧能大幅提升 AI 遵守规格的概率:

第一,只喂当前相关的内容。别把整个 openspec 目录全塞给 AI,它看完容易混乱。当前任务涉及哪个规格,就只贴哪个规格的内容。

第二,把验收标准放在任务描述的旁边。AI 在执行时,眼睛能看到“我怎么做完了”和“我怎么判断做完了”这两件事,完成质量会高很多。只给任务不给验收标准,它就会按自己的标准来。

第三,让 AI 在修改代码前先输出“执行计划”。不要一上来就写代码,先让它用自己的话复述一遍任务要求、涉及文件、影响范围,确认无误再动手。这一步能过滤掉一大半理解偏差。

第四,用 Git diff 做范围监督。每次 AI 改完,你都要看它动了哪些文件。如果它改动了规格里没有提及的文件,就要追问原因。管住两次,它就会收敛到规格范围内。

5. 把 OpenSpec 和 Superpower 组合起来用

5.1 Superpower 解决的是“怎么做”的问题

OpenSpec 做的是“定义任务”,但它没有规定“AI 执行任务时应该遵循什么方法”。比如同样是实现一个接口,AI 是直接写代码然后把测试扔给你,还是会先写失败测试再实现、最后重构?这两种路径的质量完全不同。Superpower(我理解为一套给 AI 编码代理准备的技能包)解决的就是后者。

打个比方:OpenSpec 是施工图纸,Superpower 是施工工艺规范。图纸告诉你要盖一栋什么楼,工艺规范告诉工人混凝土怎么配比、钢筋怎么绑扎、验收怎么进行。

Superpower 里通常会内置规划、测试驱动开发、调试、代码审查等一系列技能。AI 面对不同任务类型,可以按对应技能的方法论执行,而不是永远用同一种“直接开写”的粗暴方式。

5.2 一条规格从任务到技能执行的完整链路

把两个工具组合起来,我常用的链路是这样的:

有序列表:

  1. 先用openspec create创建规格,把 Context、Requirements、Tasks 写清楚。
  2. 在 AI 会话里指定当前任务,并告诉它“用 Superpower 里对应的技能来执行”。
  3. 如果任务是实现一个新功能,要求 AI 遵循 TDD 技能:先写测试,再实现,再重构。
  4. 如果任务是修复一个 bug,要求 AI 走调试技能:先复现,再定位,再修,再验证。
  5. 任务完成后,让 AI 更新规格里的任务状态,然后再进行下一个任务。

这套链路最大的优势是:任务边界由 OpenSpec 控制,执行质量由 Superpower 控制。两者各管一件事,不重叠也不冲突。

5.3 一个可以直接抄的提示词模板

如果嫌每次打字麻烦,我把我现在用的提示词结构分享出来。不一定非要原样复制,但骨架是经过多次实测沉淀下来的:

当前项目:<项目名称> 规格文件:openspec/<feature-name>/spec.md 当前任务:<Tasks 中的某一条> 执行要求: 1. 先阅读规格文件中的 Context 和 Requirements,确认你理解任务目标。 2. 按照 Superpower 的 <具体技能名> 流程执行本任务。 3. 只修改与当前任务直接相关的文件。 4. 完成后,更新规格文件中该任务的完成状态。 5. 提交前,用一句话说明你做了什么、改了哪些文件。

这个模板里最关键的是第 3 条“只修改与当前任务直接相关的文件”,我加进去之后,AI 乱动无关代码的次数明显减少。

6. 实测下来踩过的坑和我现在的推荐流程

6.1 规格写多大才算合适

刚开始用 OpenSpec 时,我犯过一个典型错误:把规格写得特别大,一个 spec 恨不得装下整个模块的所有功能。结果 AI 执行到第三个任务时,前面几个任务的状态都乱了,我根本分不清哪些做了哪些没做。

后来我总结出的判断标准很简单:

  • 一个规格对应一次可交付的功能增量,而不是一个完整的模块。
  • 规格里的任务列表超过 10 条就要考虑拆分。
  • 单个任务如果涉及 5 个以上文件的改动,说明任务拆得不够细。

宁可多建几个规格,也不要硬塞一个巨型规格。“做登录”可以算独立规格,“做用户中心”就不要设计成一次规格,拆成资料修改、头像上传、密码找回,每个都单独走一遍流程,状态管理才清晰。

6.2 AI 不按规格执行的纠正方法

再好的工具也架不住 AI 偶尔跑偏。遇到这种情况,我的处理顺序是:

第一步,先停,不让它继续往下写。只要 AI 改动了规格范围之外的东西,立刻打断,问清楚改动原因。

第二步,把规格文件中当前任务的原文贴回去,让它重新读一遍,然后用自己的话复述。

第三步,如果复述还有偏差,说明 Context 部分没写清楚,回去补 Context,而不是继续在对话里来回解释。对话解释只能救这一次,补充 Context 能救之后所有会话。

第四步,对比 Git diff,把规格外的改动 revert 掉,让 AI 重新做。

这个过程里最反直觉的一点是:AI 跑偏之后,修正的重点不是“骂它”,而是“检查规格是不是有歧义”。我见过太多人在对话里反复纠正同一件事,却从来不回头改规格。结果换一个新的 AI 会话,同样的问题又来一遍。规格文件才是那个能跨会话复用的记忆。

6.3 我现在的日常推荐工作流

用了大半年之后,我现在的流程基本稳定成了这样:

有序列表:

  1. 拿到新需求,先在项目里openspec create建一个规格。
  2. 花十几分钟把 Context、Requirements、Tasks 写完,磨刀不误砍柴工。
  3. 把规格文件发到 AI 会话,让它先复述任务理解,确认无误。
  4. 按任务列表逐项执行,每完成一个任务就更新一次状态。
  5. 全部任务完成后,做一次整体评审,重点看验收标准是否全部满足。
  6. 规格和代码一起提交,作为项目的长期文档存留。

最后再分享一个小细节:每次开始新一天的开发前,我会先跑一遍openspec list看看所有规格的状态,快速确认昨天做到哪了、今天还有哪些没完成。这个习惯让我很少再出现“开了几个会话之后忘了需求”的情况。

如果你现在还在用纯对话方式指挥 AI 写代码,强烈建议试一下 OpenSpec 这套流程。刚开始可能觉得多了一步写规格的动作很麻烦,但一旦你经历过“AI 大规模返工”“需求被 AI 悄悄改掉”“重开会话后需求忘光”这些事,就会明白这一步节省的时间远比花费的多。工具本身不复杂,真正值钱的是“先定义清楚再动手”这个习惯。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询