ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

规格驱动开发实战:OpenSpec 与 AI 编码工具的高效协作

规格驱动开发实战:OpenSpec 与 AI 编码工具的高效协作 1. 规格驱动开发到底在解决什么问题第一次接触 OpenSpec 是在一个 Laravel 项目里。当时团队三个人后端接口改了三次前端每次都要重新对字段测试用例跟着改了两轮最后上线还是漏了一个状态码。复盘的时候大家一致认为不是谁不认真而是规格这个东西从来没有被当成一等公民对待过——它散落在需求文档、聊天记录、接口注释和某个人的脑子里。OpenSpec 这类规格驱动开发工具的核心思路就是把规格从附属品变成源头。你先写清楚系统应该做什么、输入输出是什么、边界条件怎么处理然后代码、测试、文档都从这份规格里长出来。听起来像是老生常谈的先设计后编码但真正落地时它和传统文档最大的区别在于规格是可执行的、可校验的、和代码同步演进的。我把它理解成给项目立一份会自己检查的合同。以前写接口文档写完就过期现在写规格规格本身就是校验依据。你改了实现但没改规格工具会提醒你不一致你改了规格但没改实现测试会挂掉。这种双向约束才是规格驱动开发真正的价值而不是又一份没人看的 Markdown。适合谁来用我的判断是三类人收益最明显一是多人协作的后端项目接口契约容易扯皮二是需要长期维护的老项目规格能当活文档用三是和 AI 编码工具配合的场景比如 Claude Code、Codex 这类规格能大幅降低它们自由发挥的概率。如果你是一个人写一次性脚本那确实没必要上这套。2. OpenSpec 的核心设计与选型考量2.1 为什么是规格优先而不是测试优先测试驱动开发TDD流行了很多年但我在实际项目里发现一个尴尬测试写的是怎么验证而不是要什么。当需求本身模糊时测试写得再全也是在错误的方向上狂奔。规格驱动把顺序调了一下——先定义要什么规格再定义怎么验证测试最后才是怎么实现代码。这个顺序调整带来的直接好处是沟通成本下降。产品、后端、前端、测试坐在一起对着规格文件讨论而不是对着各自的想象讨论。规格文件用的是接近自然语言的结构化描述非技术同学也能看懂这就把翻译损耗降到了最低。2.2 OpenSpec 的目录结构与组织逻辑OpenSpec 通常会在项目根目录下建立一个专门的规格目录按功能模块或领域拆分文件。我习惯的结构是这样的specs/ auth/ login.spec.md register.spec.md order/ create.spec.md cancel.spec.md shared/ error-codes.spec.md每个 spec 文件描述一个相对独立的能力单元。拆分的粒度很关键——太粗一个文件几百行没人愿意看太细文件之间引用关系复杂到爆炸。我的经验是一个 spec 文件对应一个用户能感知的完整动作比如登录是一个 spec刷新 token可以单独一个但校验密码格式这种就不该单独成文件它是登录规格里的一条规则。2.3 和 Claude Code、Codex 的配合逻辑现在很多人用 Claude Code 或 Codex 来辅助编码但直接让 AI 写代码有个通病它会猜你的意图猜错了你还得花时间 review 和纠正。规格驱动开发在这里的价值就体现出来了——你把 spec 文件喂给 AI它有了明确的约束生成代码的准确率会明显提升。我实测下来给 Claude Code 一份写清楚的 spec让它生成对应的 Laravel Controller 和测试一次通过率比只给一句帮我写个登录接口高得多。原因很简单spec 里已经定义了输入字段、校验规则、成功响应、失败响应、边界情况AI 不需要猜只需要翻译。提示喂给 AI 的 spec 最好控制在单个文件 200 行以内太长了 AI 容易丢细节。如果规格确实复杂拆成多个文件分次喂。3. 从零搭建一套可用的规格体系3.1 环境准备与工具安装先说基础环境。OpenSpec 本身是一套方法论加工具链落地时你需要的核心组件包括一个规格文件格式约定、一个校验工具、以及和现有技术栈的集成方式。以 Laravel 项目为例我通常会做这几件事第一步在项目根目录创建specs/目录并加一个README.md说明规格文件的编写规范。这个 README 很重要它是团队共识的载体新人进来先看这个。第二步安装校验工具。如果 OpenSpec 官方提供了 CLI直接通过包管理器安装如果没有用 Node.js 或 PHP 写一个简单的校验脚本也够用。校验的核心是检查 spec 文件的格式是否符合约定比如是否包含必需的章节、字段定义是否完整。第三步配置编辑器和 AI 工具的集成。VS Code 里可以配置 Claude Code 插件把specs/目录加入上下文Codex 那边则通过项目配置文件指定规格目录路径。# 以 Node 生态为例安装校验工具示意 npm install --save-dev openspec/cli # 初始化规格目录 npx openspec init # 校验所有规格文件 npx openspec validate specs/3.2 规格文件该写哪些内容这是最容易踩坑的地方。很多人第一次写 spec要么写成需求文档全是用户应该能……要么写成接口文档只有字段列表。我的经验是一份合格的 spec 应该包含五个部分背景与目标一两句话说明这个能力解决什么问题为什么需要它。这部分是给未来的自己和新人看的别省。输入定义所有输入字段的名称、类型、是否必填、校验规则、示例值。这里要写死不能有视情况而定。输出定义成功响应和各类失败响应的结构、状态码、错误信息格式。业务规则核心逻辑的文字描述包括边界条件和特殊处理。比如密码连续错误 5 次锁定 15 分钟这种。验收标准可执行的检查项通常直接对应测试用例。我拿登录功能举个例子spec 文件大概长这样# 登录规格 ## 背景 用户通过邮箱和密码换取访问令牌用于后续接口鉴权。 ## 输入 | 字段 | 类型 | 必填 | 校验规则 | |------|------|------|----------| | email | string | 是 | 合法邮箱格式最长 255 | | password | string | 是 | 长度 8-64至少含字母和数字 | ## 输出 - 成功200返回 { token, expires_at, user } - 参数错误422返回字段级错误信息 - 凭证错误401返回统一提示邮箱或密码错误 - 锁定423返回解锁时间 ## 业务规则 1. 连续 5 次密码错误账号锁定 15 分钟 2. 登录成功后重置错误计数 3. token 有效期 2 小时 ## 验收标准 - [ ] 正确凭证返回 200 和有效 token - [ ] 错误密码返回 401 且不泄露账号是否存在 - [ ] 第 6 次尝试返回 4233.3 规格与代码的同步机制写完 spec 只是开始难的是让它和代码保持同步。我的做法是在 CI 流程里加一道校验每次提交代码时检查改动的代码文件是否有对应的 spec 文件以及 spec 里的验收标准是否都有对应的测试。具体实现上可以在 spec 文件里加一个related_files字段列出这个规格对应的代码文件路径。CI 脚本读取这个字段如果代码改了但 spec 没改就给出警告。反过来如果 spec 改了但测试没更新测试覆盖率检查会暴露出来。这套机制不需要多复杂一个几十行的脚本就能跑起来。关键是让规格和代码不一致这件事变得可见而不是靠人自觉。4. 实操全流程一个 Laravel 接口的规格落地4.1 需求拆解到规格编写假设要做一个创建订单的接口。传统做法是产品给个需求后端直接开写。规格驱动的做法是先坐下来把 spec 写清楚。我会先问几个问题订单包含哪些商品信息库存不足怎么处理重复提交怎么办优惠券怎么算这些问题在写 spec 的时候必须回答而不是等到写代码时临时决定。拆解完之后spec 文件里会明确输入是商品 ID 列表和数量输出是订单号和总价业务规则包括库存校验、幂等处理、价格计算。每一条规则都要能对应到一段代码或一个测试。4.2 用 AI 工具生成骨架代码spec 写好后我会把它喂给 Claude Code让它生成 Controller、Service 和测试的骨架。提示词大概是这样的根据 specs/order/create.spec.md 生成 Laravel 代码 1. Controller 方法接收请求并调用 Service 2. Service 实现业务规则 3. 生成对应的 Feature 测试覆盖所有验收标准 4. 遵循项目现有的代码风格实测下来生成的代码大概能覆盖 70% 的工作量剩下的 30% 是项目特有的细节比如用了某个自定义的异常类、某个 trait。这部分需要人工调整但比从零写快太多了。4.3 参数计算与边界处理规格驱动开发里参数计算必须写清楚过程。比如订单总价的计算spec 里要写明总价 Σ(商品单价 × 数量) - 优惠金额 运费 优惠金额 min(优惠券面额, 商品小计) 运费 商品小计 99 ? 0 : 10这种明确的公式AI 生成代码时不会算错测试也能直接照着写。我见过太多项目因为满减怎么算这种问题扯皮其实写清楚就没事了。边界处理同理。库存为 0、数量为负、优惠券过期、订单金额为 0这些情况在 spec 里列出来代码里就不会漏。4.4 测试与规格的对应关系每个验收标准对应至少一个测试用例。我在 Laravel 里用 Pest 或 PHPUnit 写 Feature 测试测试方法名直接引用 spec 里的验收标准编号这样一眼就能看出哪个测试对应哪条规格。// 对应 create.spec.md 验收标准 2 it(库存不足时返回 422 且不创建订单, function () { // ... });这种对应关系的好处是当规格变更时你能快速定位到需要改的测试而不是全项目搜索。5. 常见问题与排查实录5.1 规格写得太细或太粗怎么办这是最高频的问题。写太细spec 变成伪代码维护成本高写太粗AI 和人都看不懂等于没写。我的判断标准是spec 应该描述做什么和什么算对不描述怎么做。比如密码用 bcrypt 加密属于实现细节不该写进 spec密码不能明文存储属于规格应该写。如果一条规则换了技术栈还成立它就是规格如果换了框架就不成立它就是实现。5.2 AI 生成的代码和规格不一致有时候 Claude Code 或 Codex 生成的代码会自作主张比如多加了一个字段、改了一个状态码。这时候不要直接改代码先检查 spec 是不是有歧义。大部分不一致都是因为 spec 里某句话可以有两种理解。如果 spec 没问题那就是 AI 的幻觉直接在提示词里强调严格遵循 spec不要添加未定义的字段和行为通常能解决。5.3 规格文件的版本管理spec 文件必须进 Git和代码一起管理。每次改 spec 都要有 commit message 说明改了什么、为什么改。我习惯在 spec 文件顶部加一个变更记录表日期变更内容变更人2024-01-15增加账号锁定规则张三2024-02-03token 有效期从 1 小时改为 2 小时李四这样回溯的时候一目了然。5.4 常见问题速查表问题排查思路解决方法校验工具报格式错误检查 spec 文件是否缺少必需章节对照模板补齐AI 生成代码偏离规格检查 spec 是否有歧义明确措辞消除二义性测试和规格对不上检查验收标准是否都写了测试补测试或删无效标准规格更新后代码没跟上检查 CI 校验是否生效修复校验脚本加警告团队不愿意写 spec检查 spec 是否太重简化模板先从小功能试点5.5 几个踩过的坑第一个坑是规格大爆炸。一开始热情高涨给每个功能都写详细 spec结果维护不过来最后全烂尾。后来改成只给核心流程写 spec边缘功能用简化模板才可持续。第二个坑是规格和代码两套真相。有人改了代码忘了改 spec过两周 spec 就没人信了。解决办法是把 spec 校验加进 CI让不一致变得可见。第三个坑是AI 依赖过度。有段时间我完全靠 AI 从 spec 生成代码结果生成了一堆能跑但风格不统一的代码。后来改成 AI 生成骨架人工统一风格质量才稳定下来。6. 和现有技术栈的集成细节6.1 Laravel 项目里的落地方式Laravel 本身有很好的测试和文档生态和规格驱动开发天然契合。我会把 spec 目录放在项目根目录然后在phpunit.xml里配置测试套件让 Feature 测试按 spec 模块分组。路由、Controller、Service 的分层保持不变spec 只是多了一层契约。FormRequest 的校验规则直接从 spec 的输入定义翻译过来Resource 的输出结构从 spec 的输出定义翻译过来。这样 spec 就成了单一真相来源。6.2 编辑器与 AI 工具配置VS Code 里我装了 Claude Code 插件把specs/目录加入工作区这样 AI 能直接读取规格文件。Codex 那边通过项目配置文件指定上下文目录。有一点要注意AI 工具的上下文窗口有限不要把整个specs/目录都塞进去只喂当前任务相关的 spec 文件。我一般会在提示词里明确指定参考 specs/order/create.spec.md。6.3 团队协作中的规格评审规格写完不能直接开写代码要有个简短的评审。我习惯拉一个 15 分钟的会产品、后端、测试一起过一遍 spec重点看业务规则和边界条件。评审通过后 spec 冻结改动要走变更流程。这个评审看起来增加了流程但实际上省掉了后面无数次的返工。我统计过一个项目加了规格评审后接口联调阶段的问题减少了大概六成。7. 我个人的一些实操体会用 OpenSpec 这套方法大概一年多了最大的感受是它逼着你在动手之前想清楚。以前写代码是边写边想现在写 spec 是想清楚再写虽然前期慢一点但后期返工少很多。另一个体会是规格驱动开发和 AI 编码工具是绝配。AI 擅长翻译明确的指令不擅长猜模糊的意图。spec 把意图变明确了AI 的价值就放大了。我现在的工作流基本是写 spec → AI 生成骨架 → 人工调整 → 测试验证 → 更新 spec。这个循环跑顺了效率提升很明显。最后分享一个小技巧spec 文件里的验收标准尽量写成可勾选的 checklist 格式。这样无论是人工 review 还是 AI 生成测试都能一条条对应不会漏。我试过把验收标准写成段落描述结果就是有人看漏、AI 也漏改成 checklist 之后好多了。这套方法不是银弹小项目、一次性脚本确实没必要。但只要项目有协作、有维护周期、有 AI 参与规格驱动开发带来的收益就远大于成本。
返回列表