ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

告别 Vibe Coding:Java 开发者用 OpenSpec 规范驱动开发,让 AI 写出生产级代码的实战指南

告别 Vibe Coding:Java 开发者用 OpenSpec 规范驱动开发,让 AI 写出生产级代码的实战指南 1. 为什么 Java 团队的 AI 编码会失控从 Vibe Coding 到规范驱动开发Vibe Coding 这个词在 2025 年被反复提起说的其实是一个很具体的现象你把一句需求丢给 AI它噼里啪啦生成几百行代码编译能过、单测能跑但改到第三轮就彻底失控——方法越加越多参数越传越乱最后你只能删掉重写。我在一个 Spring Boot 项目里就踩过这个坑让 AI 加一个订单超时自动取消的功能第一版它写了个定时任务第二版我让它支持配置化它把定时任务改成了事件监听第三版我让它加幂等它又在监听里塞了个 Redis 锁三轮下来 Service 层多了四个互相调用的类没人说得清调用链。这不是模型不行是上下文太模糊。AI 在 Vibe Coding 模式下靠猜来填充你没说清楚的细节猜你的异常处理风格、猜你的分层边界、猜你的幂等语义。猜对了是运气猜错了就是幻觉而幻觉在 Java 这种强类型、重分层的工程里会被放大成不可维护的债务。规范驱动开发Spec-Driven DevelopmentSDD就是针对这个问题的解法。它的核心主张只有一句先让 AI 写规范再让 AI 写代码。规范是人和 AI 之间的契约把做什么、为什么做、验收标准是什么提前钉死AI 按图索骥不靠猜。对 Java 开发者来说这套思路其实不陌生——你写 Spring 时习惯先定 Interface 再写实现SDD 只是把契约的载体从 Java Interface 换成了 Markdown 规范读它的对象从人变成了 AI核心思路一模一样。写过严格接口设计文档的人上手 SDD 反而最快。OpenSpec 是 Fission-AI 开源的 SDD 框架专为 Claude Code 这类 AI 编程助手设计把每个开发任务拆成 Proposal提案→ Spec规范→ Design技术设计→ Tasks任务分解→ 实现 → Archive归档六个阶段用/opsx:propose、/opsx:apply、/opsx:archive三个命令控制完整生命周期。它解决的问题不是让 AI 写得更快而是让 AI 写得可审计、可回归、可交接。这篇文章面向 Java 团队从需求描述一路走到生产级代码给出可复制的 OpenSpec 配置模板、AI 提示词结构和代码质量验证动作。2. TaoToken 前置准备给 OpenSpec 工作流接上稳定的模型通道OpenSpec 本身是工作流框架它不提供模型能力真正干活的是背后的 AI 编程助手。Java 团队常见的组合是 Claude Code 或 Cline 这类支持自定义 Base URL 的客户端接一个稳定的模型通道。我实测下来把模型通道统一到 TaoToken 之后OpenSpec 的多轮 propose/apply 调用不会因为通道抖动中断这对需要连续多轮对话的 SDD 流程很关键。先说清楚 TaoToken 是什么它是一个模型 API 聚合服务提供统一的 Base URL 和 Key让你在 Claude Code、Cline、Codex 这类客户端里用同一套凭证调用不同模型。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 这个不加 UTM。适合谁适合需要长期跑 Agent 编码、又不想在多个模型供应商之间反复切换配置的 Java 团队。拿 Key 的路径很直接进控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面创建一个新 Key复制出来备用。如果你只是想先验证模型通不通可以用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 发一条消息试试如果是长期编码和 Agent 场景建议直接看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 它的额度模型更适合 OpenSpec 这种多轮调用。这里有个关键点OpenSpec 的工作流依赖 AI 客户端能读取项目根目录的AGENTS.md和project.md所以你的客户端必须支持项目级上下文注入。Claude Code 原生支持Cline 通过 MCP 也能做到。配置的时候Base URL 填https://taotoken.net/apiKey 填刚才复制的Model ID 填你选的模型比如claude-sonnet-4-5这类。三件套缺一不可少填一个就会出现 401 或者模型找不到的报错。我建议在正式跑 OpenSpec 之前先用一条最简单的请求验证通道。打开终端用 curl 打一发curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: claude-sonnet-4-5, messages: [{role: user, content: 回复 OK 两个字母即可}], max_tokens: 16 }返回里能看到choices[0].message.content是OK说明通道通了。这一步别跳过很多后面 OpenSpec 报的错根因都在这里没验证。3. 可复制配置OpenSpec 目录结构、AGENTS.md 与 Java 项目 settings 片段OpenSpec 的落地第一步是把目录结构建起来。在 Java 项目根目录和pom.xml同级执行初始化后你会得到这样一套结构your-java-project/ ├── AGENTS.md # 项目规则AI 每次会话优先读取 ├── project.md # 项目背景和知识库 ├── specs/ # 已实现的功能规范 └── changes/ # 待实现的变更提案AGENTS.md是整个工作流的宪法AI 每次会话都会先读它。Java 项目的AGENTS.md我建议至少写清楚这几件事技术栈版本、分层约定、异常处理规范、测试要求、禁止事项。下面是我在一个 Spring Boot 3 MyBatis-Plus 项目里实际用的模板你可以直接复制改# AGENTS.md ## 技术栈 - Java 17, Spring Boot 3.2.x - MyBatis-Plus 3.5.x, MySQL 8.0 - JUnit 5 Mockito, 测试覆盖率要求 70% ## 分层约定 - Controller 只做参数校验和响应封装禁止写业务逻辑 - Service 接口与实现分离接口放 service实现放 service.impl - Mapper 只做数据访问禁止在 Mapper 里写业务判断 - DTO / VO / Entity 严格分离禁止 Entity 直接返回给前端 ## 异常处理 - 业务异常统一抛 BizException携带错误码 - 全局异常由 GlobalExceptionHandler 处理禁止在 Controller 里 try-catch - 禁止吞异常catch 块必须记录日志或重新抛出 ## 测试要求 - 每个 Service 方法必须有对应的单元测试 - 涉及数据库的操作必须有集成测试 - 禁止提交没有测试覆盖的核心业务代码 ## 禁止事项 - 禁止使用 System.out.println 调试 - 禁止在循环里调用数据库 - 禁止硬编码魔法值必须定义为常量或枚举project.md放项目背景比如业务领域、核心实体关系、外部依赖。这份文件不用很长但要让 AI 理解这个项目在干什么。比如# project.md ## 业务背景 电商订单系统核心实体Order、OrderItem、Payment、Refund。 订单状态机CREATED - PAID - SHIPPED - COMPLETED任意状态可转 CANCELLED。 ## 外部依赖 - 支付网关通过 PaymentGatewayClient 调用超时 3s失败重试 2 次 - 消息队列RocketMQ订单状态变更后发送事件 ## 已知约束 - 订单号全局唯一由雪花算法生成 - 金额统一用 BigDecimal禁止用 double如果你用的是 Claude Code项目级配置放在.claude/settings.json如果用 Cline配置在.cline/settings.json或者通过 MCP 注入。下面是一个 Claude Code 的 settings 片段把模型通道指向 TaoToken{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-your-taotoken-key, ANTHROPIC_MODEL: claude-sonnet-4-5 }, permissions: { allow: [Read, Write, Bash(mvn *), Bash(git *)] } }注意ANTHROPIC_BASE_URL填的是https://taotoken.net/api不要带 UTM 参数也不要多加/v1客户端会自己拼。Key 从控制台拿Model ID 按你实际选的填。这三件套Base URL Key Model ID必须一致任何一处写错都会在 OpenSpec 调用时报错。如果你用 Codex配置在~/.codex/auth.json结构类似{ base_url: https://taotoken.net/api, api_key: sk-your-taotoken-key, model: claude-sonnet-4-5 }Cline 通过 MCP 接入的话在 MCP 配置里加一个 providerBase URL 同样填https://taotoken.net/api。配置完记得重启客户端让 settings 生效。4. 验证请求与成功结果从 Proposal 到生产级代码的完整跑通配置就绪后跑一个真实需求验证整条链路。我用的需求是订单超时未支付自动取消这是 Java 电商项目里很典型的一个功能涉及定时任务、状态机、幂等、消息通知足够验证 OpenSpec 的规范约束能力。第一步提交提案。在 Claude Code 里输入/opsx:propose 订单创建后 30 分钟未支付自动取消订单并释放库存发送取消通知。验收标准1) 超时时间可配置2) 取消操作幂等3) 取消后库存回滚4) 发送 RocketMQ 事件。AI 会在changes/目录下生成一个提案文件包含做什么、为什么做、验收标准。这一步的关键是验收标准要具体别写性能好这种模糊词要写超时时间可配置这种可验证的条目。第二步让 AI 生成规范和技术设计/opsx:applyAI 会读取AGENTS.md和project.md按你定义的分层约定生成 Spec 和 Design。我实测下来因为AGENTS.md里写死了Service 接口与实现分离禁止在 Controller 里 try-catchAI 生成的代码结构非常规整不会出现 Vibe Coding 那种把逻辑全塞进 Controller 的情况。第三步任务分解和实现。AI 会把功能拆成可独立验证的最小单元比如Tasks: 1. 新增 OrderTimeoutConfig 配置类读取超时时间 2. 在 OrderService 接口新增 cancelTimeoutOrder 方法 3. 实现 OrderServiceImpl.cancelTimeoutOrder包含幂等校验 4. 新增 OrderTimeoutScheduler 定时任务 5. 新增库存回滚逻辑 6. 发送 RocketMQ 取消事件 7. 编写单元测试和集成测试每个任务 AI 会逐个实现你可以逐个 review。这里有个技巧每完成一个任务就让它跑一次测试别等全部写完再跑。我试过让它一口气写完七个任务结果第三个任务的幂等逻辑和第五个任务的库存回滚有冲突排查花了半小时后来改成逐个任务验证问题在产生的那一步就暴露了。第四步验证代码质量。AI 实现完后跑一遍完整测试mvn clean test如果测试通过再跑一次静态检查mvn checkstyle:check spotbugs:check这两步是 Java 项目的质量闸门。OpenSpec 生成的代码因为遵循了AGENTS.md里的规范通常能直接过 checkstyle但 spotbugs 偶尔会报未使用的字段或者可能的空指针这时候把报错贴回给 AI让它按规范修复。第五步归档。功能验证通过后/opsx:archiveAI 会把changes/里的提案移到specs/形成项目知识库。下次有类似需求时AI 会先读specs/里的历史规范保持风格一致。这一步是 SDD 和 Vibe Coding 最大的区别Vibe Coding 的对话记录是一次性的SDD 的规范是累积的。成功的结果长这样specs/目录下多了一个order-timeout-cancel.md里面记录了完整的规范、设计决策和验收结果changes/目录清空mvn test全绿代码 review 时能追溯到每个决策的来源。这套流程跑通一次之后团队里任何人接手这个功能读规范就能理解不用去翻聊天记录。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 报错对照跑 OpenSpec 工作流时报错基本集中在模型通道和客户端配置上。我把实际遇到过的几类整理出来对照排查。401 Unauthorized。这是最常见的根因是 Key 不对或没生效。检查三处settings.json里的ANTHROPIC_API_KEY是不是从控制台复制的完整 KeyKey 有没有多余空格客户端重启了没有。如果 Key 确认没问题还是 401去控制台看这个 Key 的额度是不是用完了。我遇到过一次是 Key 复制时漏了最后两位排查了二十分钟。local proxy failed / connection refused。这个报错通常出现在客户端配置了本地代理但代理没启动。OpenSpec 本身不需要代理如果你在 settings 里配了HTTP_PROXY或HTTPS_PROXY环境变量先去掉。Base URL 直接填https://taotoken.net/api就行客户端会直连。如果公司网络有出口限制找运维开白名单别自己搭代理。reading choices 报错 / choices 字段为空。这个报错说明请求发出去了但返回体里没有choices字段。常见原因是 Model ID 填错了比如填了个不存在的模型名服务端返回了错误信息而不是正常的 completion 结构。检查ANTHROPIC_MODEL或model字段确认模型名拼写正确。另一个可能是max_tokens设得太小返回被截断把max_tokens调到 1024 以上再试。OAuth 相关报错 / token expired。如果你用的是 Claude Code 的 OAuth 登录模式而不是 API Key 模式会出现这个。OpenSpec 工作流建议用 API Key 模式别用 OAuth。在 settings 里显式配置ANTHROPIC_API_KEY客户端会优先用 Key 而不是 OAuth token。如果之前登录过 OAuth先退出登录再配 Key。OpenSpec 命令不识别 / opsx 未找到。这说明 OpenSpec 没装好或者没在项目根目录执行。确认在项目根目录有AGENTS.md的那一层执行命令确认 OpenSpec 的 skills 已经加载。Claude Code 里可以用/skills查看已加载的 skill 列表看到opsx:propose、opsx:apply、opsx:archive才算就绪。AI 生成的代码不符合 AGENTS.md 规范。这不是报错但很常见。根因通常是AGENTS.md写得太模糊比如只写了遵循分层约定但没写具体怎么分。把规范写具体比如Controller 禁止写业务逻辑比注意分层有效得多。另一个原因是AGENTS.md太长AI 读的时候截断了控制在 200 行以内比较稳。排查顺序建议先验证通道curl 那条命令再验证客户端配置三件套最后验证 OpenSpec 本身。大部分问题在前两步就能定位。6. 把 Vibe Coding 转成可审计工程Java 团队的落地建议OpenSpec 跑通之后真正的价值不在于AI 写得快了而在于AI 写得可审计了。Java 团队落地这套工作流有几个动作值得固化下来。第一把AGENTS.md当成代码来维护。它进 Git走 review改的时候要说明原因。我见过团队把AGENTS.md写成一次性文档三个月后没人更新AI 读到的还是过时的规范生成的代码自然对不上。建议每个 Sprint 回顾时检查一次AGENTS.md把新踩的坑补进去。第二规范先行代码后行。任何新功能先跑/opsx:propose把验收标准写清楚再跑/opsx:apply。别跳过提案直接让 AI 写代码那就退回 Vibe Coding 了。提案文件本身就是需求文档产品经理也能看懂沟通成本反而降低。第三测试是规范的一部分不是附加项。在AGENTS.md里写死测试覆盖率要求在 Tasks 里把编写测试作为独立任务。AI 生成的代码如果没有测试就不算完成。我实测下来把测试要求写进规范后AI 生成的单测质量明显提升因为它知道这些测试会被 review。第四归档形成知识库。/opsx:archive不是可选项是必选项。归档后的specs/是团队的知识资产新人接手时读规范比读代码快得多。我建议每个月整理一次specs/把过时的规范标记出来保持知识库的准确性。第五模型通道保持稳定。OpenSpec 的多轮调用对通道稳定性要求高通道抖动会导致 propose 到一半中断上下文丢失。用 TaoToken 这类聚合服务的好处是统一入口切换模型不用改配置。长期跑 Agent 编码的团队建议直接上 Coding Plan额度模型更适合这种高频多轮场景。这套流程跑顺之后你会发现 AI 编码的瓶颈从模型够不够聪明变成了规范够不够清晰。规范清晰了模型的能力才能被精确地释放出来。Java 开发者在这件事上有天然优势——你写过那么多 Interface 和设计文档把契约思维迁移到 AI 协作上就是 SDD 的核心。
返回列表