












传统开发流程中,我们面临几个核心痛点:
需求文档 → 规格 → 测试 → 实现 → 验证
↑ |
└──────── AI 全程参与 ──────────┘
| 工具 | 职责 | 阶段 |
|---|---|---|
| Oh-My-OpenCode | 多模型编排,Sisyphus 主 agent 协调规划 | 全程 |
| OpenCode (Plan 模式) | 分析需求、生成规格、制定实现计划 | 规格阶段 |
| OpenCode (Build 模式) | 编写代码、重构、修复 bug | 实现阶段 |
| SDD | 将需求转化为机器可读的 API 规格(OpenAPI/ADR) | 设计阶段 |
| ATDD | 将验收条件转化为可执行测试(Cucumber/JUnit) | 测试阶段 |
| OpenSpec | 规格阶段的流程框架,物理隔离规格与代码,防止 AI 提前写代码 | 规格阶段 |
# 安装 OpenCode
curl -fsSL https://opencode.ai/install | bash
# 或
npm install -g opencode-ai
# 安装 Oh-My-OpenCode
npm install -g oh-my-opencode
# 在 opencode.json 中启用插件
# ~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-20250514",
"plugin": ["oh-my-opencode"]
}
┌─────────────────────────────────────────────────┐
│ Tab 键切换 │
│ │
│ [Plan 模式] [Build 模式] │
│ - 只分析,不修改 - 完整工具权限 │
│ - 生成规格/计划 - 执行实际代码变更 │
│ - 安全探索代码库 - 运行命令/测试 │
└─────────────────────────────────────────────────┘
使用原则:
在项目根目录创建 AGENTS.md,这是 AI 了解项目的核心入口:
# 初始化(AI 自动扫描项目生成)
/init
# 然后手工完善
# 项目名:订单服务 (order-service)
## 技术栈
- Java 17 + Spring Boot 3.x
- Maven 构建
- MySQL 8.0(通过 JPA/Hibernate 访问)
- Redis(缓存层)
- Cucumber + JUnit 5(验收测试)
## 项目结构
- `src/main/java/com/example/order/` - 主代码
- `controller/` - REST 控制器
- `service/` - 业务逻辑
- `repository/` - 数据访问
- `domain/` - 领域对象/实体
- `dto/` - 请求/响应 DTO
- `src/test/` - 测试代码
- `java/.../acceptance/` - Cucumber 验收测试
- `resources/features/` - .feature 文件
## 代码规范
- 所有公开方法必须有 Javadoc
- Service 层统一抛出自定义 BusinessException,不允许直接抛 RuntimeException
- Controller 层只做参数校验和 DTO 转换,不含业务逻辑
- 字段验证使用 Jakarta Validation 注解
- 禁止在 Service 层直接使用 HttpServletRequest
## 接口规范
- 统一响应格式:`{ "code": 200, "message": "success", "data": {} }`
- 错误码定义在 `ErrorCode` 枚举中
- 分页接口使用 `PageRequest` 参数
## 测试规范
- 每个新功能必须有对应的 .feature 文件(ATDD)
- 验收测试覆盖正常流程 + 至少 2 个边界/异常场景
- 单元测试使用 Mockito,不依赖真实数据库
## Git 规范
- 分支命名:feature/xxx、fix/xxx、refactor/xxx
- commit message 格式:`type(scope): description`
提交到 Git,让团队所有成员的 OpenCode 都读到相同的上下文。
# 在消息中 @mention 子 agent
@explore 帮我找所有实现了 OrderService 接口的类
@general 并行检查以下三个文件的代码规范符合情况:
- OrderController.java
- OrderService.java
- OrderRepository.java
Oh-My-OpenCode(npm 包:oh-my-opencode,GitHub:code-yeongyu/oh-my-openagent)是 OpenCode 的增强插件,提供:
| 能力 | 说明 |
|---|---|
| Sisyphus 主 agent | 智能编排器,自动分解任务、并行调度子 agent |
| Prometheus 规划师 | 采访模式,在动手前深度规划,适合 SDD 阶段 |
| ultrawork 命令 | 一键启动全量 agent,推进任务直到完成 |
| Hash 锚定编辑 | 每行代码有内容 hash,杜绝过期行错误 |
| Background Agents | 同时运行 5+ 个专项 agent |
| LSP + AST-Grep | IDE 级别的代码重构和搜索 |
# 启动后在 OpenCode TUI 中输入:
/start-work # 调用 Prometheus,采访式规划,适合 SDD 阶段
ultrawork # 或 ulw,一键全力推进任务
/init-deep # 为项目所有子目录生成层级 AGENTS.md
Oh-My-OpenCode 会自动根据任务类型路由到最合适的模型:
任务类型 → 模型
─────────────────────────────────────
架构设计/复杂推理 → claude-opus 或 kimi-k2.5
代码实现/重构 → gpt-5.x-codex
前端/UI → visual-engineering 专项模型
快速单文件修改 → 轻量快速模型
无需手动切换模型,Sisyphus 自动判断。
安装后,~/.config/opencode/opencode.json 会自动更新。项目级配置放在 .opencode/oh-my-opencode.jsonc:
{
// 项目级 Oh-My-OpenCode 配置
"agents": {
"sisyphus": {
// 覆盖默认模型(可选)
"model": "anthropic/claude-opus-4-6"
}
},
"background_tasks": {
"max_concurrent": 3 // 最多同时运行 3 个后台 agent
}
}
SDD(Specification-Driven Development)的核心理念:
代码是规格的实现,而不是需求的直接翻译
工作流:
产品需求文档
↓ (Plan 模式 + Prometheus)
API 规格(OpenAPI YAML)+ 架构决策记录(ADR)
↓ (Build 模式)
代码实现
↓
与规格对齐验证
Step 1:用 Plan 模式 + /start-work 生成规格草稿
# 切换到 Plan 模式(Tab 键)
# 输入:
我需要设计一个订单创建接口。业务需求:
- 用户可以提交包含多个商品的订单
- 需要校验库存是否充足
- 订单金额需要计算折扣
- 支持多种支付方式(微信、支付宝、银行卡)
- 订单提交成功后异步发送确认邮件
请用 /start-work 采访我,然后生成 OpenAPI 规格。
Prometheus 会问你:
Step 2:规格文件落地
AI 生成后保存为 docs/api/order-api.yaml:
openapi: 3.0.0
info:
title: Order Service API
version: 1.0.0
paths:
/api/v1/orders:
post:
summary: 创建订单
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
responses:
'201':
description: 订单创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/OrderResponse'
'400':
description: 参数校验失败
'409':
description: 库存不足
components:
schemas:
CreateOrderRequest:
type: object
required: [userId, items, paymentMethod]
properties:
userId:
type: string
description: 用户 ID
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
minItems: 1
paymentMethod:
type: string
enum: [WECHAT, ALIPAY, BANK_CARD]
couponCode:
type: string
description: 优惠券码(可选)
# ... 其他 schema 定义
有了规格,对 AI 的指令变得精确:
# 切换到 Build 模式
# 输入:
根据 @docs/api/order-api.yaml 中的规格,
实现 POST /api/v1/orders 接口,包括:
1. CreateOrderRequest DTO(带 Jakarta Validation 注解)
2. OrderController(只做参数校验,业务逻辑委托给 Service)
3. OrderService 接口及实现(包含库存校验逻辑)
4. 统一响应格式封装
遵循 @AGENTS.md 中的代码规范。
ATDD(Acceptance Test-Driven Development):
先写验收测试,再写实现代码,以测试通过作为完成标志
使用 Gherkin 语言(.feature 文件)描述业务场景,让业务人员、测试、开发共同理解需求:
Feature: 创建订单
作为一个已登录用户
我想要提交订单
以便购买商品
Scenario: 正常创建订单
Given 用户 "user001" 已登录
And 商品 "SKU001" 库存为 10
When 用户提交包含 2 件 "SKU001" 的订单
Then 返回状态码 201
And 订单状态为 "PENDING_PAYMENT"
And 商品 "SKU001" 库存减少为 8
Scenario: 库存不足时拒绝创建
Given 用户 "user001" 已登录
And 商品 "SKU001" 库存为 1
When 用户提交包含 5 件 "SKU001" 的订单
Then 返回状态码 409
And 错误信息包含 "库存不足"
# Plan 模式下输入:
基于 @docs/api/order-api.yaml 的 createOrder 接口,
帮我生成完整的 Cucumber feature 文件,要覆盖:
1. 正常流程(单商品、多商品)
2. 库存不足场景
3. 无效优惠券场景
4. 无效支付方式场景
5. 并发下单场景(幂等性)
保存到 src/test/resources/features/order/create-order.feature
有了 .feature 文件,让 AI 生成对应的 Step 实现:
# Build 模式下输入:
根据 @src/test/resources/features/order/create-order.feature,
生成对应的 Cucumber Step Definitions,要求:
- 使用 Spring Boot Test + MockMvc
- 使用 @MockBean 模拟 OrderService
- 每个 Step 方法要简洁,复杂逻辑抽取到 helper 方法
- 保存到 src/test/java/com/example/order/acceptance/OrderStepDefs.java
写 .feature 文件(红)
↓
生成 Step Definitions(红)
↓
AI 生成业务代码(绿)
↓
运行验收测试
↓
全部通过 → 完成
失败 → 让 AI 修复(迭代)
运行测试的提示词:
运行 mvn test -Dtest=AcceptanceTest,
如果有失败的用例,分析原因并修复,直到全部通过。
在实践 SDD 时,一个常见问题是:AI 不等规格确认就开始写代码。Plan 模式的 ask 权限只是弹出确认框,并不强制阻止。当团队成员有时候直接在 Build 模式下开始工作,规格文档就很容易被跳过。
OpenSpec 解决这个问题的方式是:用目录结构和 agent 权限,在物理层面隔离规格阶段和实现阶段。
OpenSpec 不是 OpenCode 的竞争者,而是 SDD 的流程框架,与 OpenCode 互补。
OpenSpec 为每个功能维护一个独立目录:
openspec/
└── changes/
└── create-order/ # 每个功能一个目录
├── proposal.md # 功能提案(需求描述)
├── design.md # 架构/设计决策
├── tasks.md # 拆解的实施任务
└── specs/
├── api.yaml # OpenAPI 规格
└── events.yaml # 领域事件规格(如需要)
三个核心命令:
| 命令 | 作用 |
|---|---|
/opsx:propose |
开启新功能规格流程,AI 采访后生成 proposal.md |
/opsx:apply |
规格确认后,解锁代码文件权限,开始实现 |
/opsx:archive |
功能完成后,归档规格文档 |
opencode-plugin-openspec(GitHub: Octane0411/opencode-plugin-openspec)是专门为 OpenCode 打造的 OpenSpec 插件,提供一个名为 openspec-plan 的专用 agent。
与 Plan 模式的关键区别:
| 对比项 | Plan 模式 | openspec-plan agent |
|---|---|---|
| 对文件写入的控制 | ask 权限(弹确认框) |
deny 权限(物理禁止写代码文件) |
| 强制性 | 低,人可以绕过 | 高,连 AI 自己也无法绕过 |
| 适用场景 | 个人探索、快速迭代 | 团队协作、有规范要求的项目 |
# 安装 OpenSpec CLI
npm install -g @fission-ai/openspec
# 安装 OpenCode 插件(可选,但推荐)
# 在 opencode.json 的 plugin 数组中添加:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-20250514",
"plugin": ["oh-my-opencode", "opencode-plugin-openspec"]
}
初始化项目:
# 在项目根目录
openspec init
这会创建 openspec/ 目录和基础配置。
阶段一:提案(Propose)
# 在 OpenCode 中,使用 openspec-plan agent
# 此时 AI 无法修改任何业务代码
/opsx:propose create-order
我要实现创建订单功能:
- 用户提交多商品订单
- 校验库存
- 支持优惠券
- 异步发送确认邮件
AI 采访并生成 openspec/changes/create-order/proposal.md:
# Proposal: 创建订单功能
## 背景
用户需要能够一次性提交包含多个商品的订单。
## 业务规则
- **原子性**:多商品订单中任一商品库存不足,整单取消
- **优惠券**:每单限用一张,固定金额减免
- **邮件**:异步发送,失败不影响订单主流程
## 接口设计决策
- 幂等键:通过 `X-Idempotency-Key` 请求头实现
- 错误策略:409 表示库存不足,404 表示商品/优惠券不存在
## 未解决问题
- [ ] 并发下单时的库存锁定策略(乐观锁 vs 悲观锁)?
人工 Review proposal.md,确认无误后继续。
阶段二:生成规格
# 仍在 openspec-plan agent 中(仍无法写业务代码)
根据 proposal.md,生成:
1. OpenAPI 规格到 openspec/changes/create-order/specs/api.yaml
2. 架构决策记录到 openspec/changes/create-order/design.md
3. 任务拆解到 openspec/changes/create-order/tasks.md
人工 Review,若 Review 通过:
/opsx:apply create-order
这一步将规格文件复制到 docs/api/,同时解锁业务代码文件的写入权限,后续可切换回普通 Build 模式继续工作。
阶段三:实现(接续 ATDD 流程)
/opsx:apply 之后,流程与不使用 OpenSpec 的 ATDD 流程完全相同:
specs/api.yaml 生成 Cucumber .feature 文件| 情况 | 建议 |
|---|---|
| 团队 ≤ 2 人,文档纪律好 | 可以不用,Plan 模式 + 人工自律即可 |
| 团队 3+ 人,需要流程保障 | 推荐引入,防止规格被跳过 |
| AI 经常在规格未确认时就开始写代码 | 强烈推荐,openspec-plan agent 物理阻断 |
| 需要规格文档可追溯、可归档 | 推荐,/opsx:archive 提供完整归档机制 |
┌──────────────────────────────────────────────────────────────┐
│ 一个功能的完整流程 │
└──────────────────────────────────────────────────────────────┘
1. 需求澄清(Oh-My-OpenCode Prometheus + Plan 模式)
├─ /start-work 采访模式,明确需求边界
├─ 生成功能说明文档
└─ 确定接口契约
2. 规格设计(SDD + OpenSpec + openspec-plan agent)
├─ /opsx:propose 开启规格流程(物理禁止写业务代码)
├─ AI 采访生成 proposal.md
├─ AI 生成 OpenAPI YAML 到 openspec/changes/<feature>/specs/
├─ 人工 Review 规格,确认无误
├─ /opsx:apply 解锁代码权限,规格复制到 docs/api/
└─ 提交规格文件到 Git
3. 验收测试先行(ATDD + Build 模式)
├─ AI 生成 .feature 文件
├─ 人工 Review 场景覆盖度
├─ AI 生成 Step Definitions 骨架
└─ 此时测试全部为红(失败)
4. 并行实现(Oh-My-OpenCode ultrawork)
├─ Sisyphus 分解任务
├─ 多个 Background Agent 并行工作:
│ ├─ Agent A:实现 Controller + DTO
│ ├─ Agent B:实现 Service + 业务逻辑
│ └─ Agent C:实现 Repository + 数据层
└─ 各 Agent 完成后合并
5. 验证(Build 模式)
├─ 运行验收测试(Cucumber)
├─ AI 修复失败用例
└─ 测试全绿 → 功能完成
6. 代码 Review(explore subagent)
└─ @explore 检查是否符合 AGENTS.md 规范
7. 归档(OpenSpec)
└─ /opsx:archive 归档规格文档,保留可追溯记录
.feature 文件,不开始写 Serviceopenspec-plan agent 物理隔离规格与代码阶段场景:为电商平台实现"创建订单"功能
打开 OpenCode,切换到 Plan 模式,输入:
我要实现一个订单创建功能。
请用 /start-work 采访我,完成后给出功能规格摘要。
基本需求:
- 用户选择商品和数量,提交订单
- 要检查库存
- 要支持优惠券
- 成功后发邮件通知
Prometheus 会问:
# Plan 模式继续:
根据以上澄清,生成完整的 OpenAPI 3.0 规格,
保存到 docs/api/create-order.yaml
AI 生成的 docs/api/create-order.yaml:
openapi: 3.0.0
info:
title: Order Service
version: 1.0.0
paths:
/api/v1/orders:
post:
summary: 创建订单
operationId: createOrder
tags: [orders]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
example:
userId: "user_123"
items:
- skuId: "SKU_001"
quantity: 2
paymentMethod: "ALIPAY"
couponCode: "SAVE10"
responses:
'201':
description: 订单创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'400':
description: 请求参数不合法
'404':
description: 商品不存在或优惠券不存在
'409':
description: 库存不足
components:
schemas:
CreateOrderRequest:
type: object
required: [userId, items, paymentMethod]
properties:
userId:
type: string
minLength: 1
items:
type: array
minItems: 1
items:
type: object
required: [skuId, quantity]
properties:
skuId:
type: string
quantity:
type: integer
minimum: 1
maximum: 99
paymentMethod:
type: string
enum: [WECHAT, ALIPAY, BANK_CARD]
couponCode:
type: string
OrderResponse:
type: object
properties:
orderId:
type: string
status:
type: string
enum: [PENDING_PAYMENT, PAID, CANCELLED]
totalAmount:
type: number
discountAmount:
type: number
finalAmount:
type: number
createdAt:
type: string
format: date-time
ApiResponse:
type: object
properties:
code:
type: integer
message:
type: string
data:
$ref: '#/components/schemas/OrderResponse'
人工 Review 后,提交到 Git。
切换回 Plan 模式(或保持 Plan 模式),输入:
根据 @docs/api/create-order.yaml 和以下业务规则:
- 库存不足时全部取消(原子性)
- 每单只能用一张优惠券(固定金额减免)
- 邮件异步发送,不影响主流程
生成 Cucumber feature 文件,覆盖:
1. 正常创建(无优惠券)
2. 使用有效优惠券
3. 商品库存不足(全部回滚)
4. 部分商品库存不足(全部回滚)
5. 优惠券不存在
6. 无效的支付方式
保存到 src/test/resources/features/order/create-order.feature
生成的 create-order.feature:
Feature: 创建订单
作为一个已注册用户
我希望能够提交包含多个商品的订单
以便完成购买流程
Background:
Given 商品库存数据如下:
| skuId | stock |
| SKU_001 | 10 |
| SKU_002 | 5 |
Scenario: 正常创建订单(无优惠券)
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 2 |
And 支付方式为 "ALIPAY"
Then 返回状态码 201
And 订单状态为 "PENDING_PAYMENT"
And 商品 "SKU_001" 库存变为 8
Scenario: 使用有效优惠券创建订单
Given 优惠券 "SAVE10" 面值为 10 元,状态为可用
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 1 |
And 支付方式为 "WECHAT"
And 使用优惠券 "SAVE10"
Then 返回状态码 201
And 响应中 discountAmount 为 10
Scenario: 单个商品库存不足时全部回滚
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 20 |
And 支付方式为 "ALIPAY"
Then 返回状态码 409
And 错误信息包含 "库存不足"
And 商品 "SKU_001" 库存保持为 10
Scenario: 多商品中有一个库存不足时全部回滚
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 2 |
| SKU_002 | 10 |
And 支付方式为 "ALIPAY"
Then 返回状态码 409
And 商品 "SKU_001" 库存保持为 10
And 商品 "SKU_002" 库存保持为 5
Scenario: 优惠券不存在
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 1 |
And 支付方式为 "ALIPAY"
And 使用优惠券 "INVALID_CODE"
Then 返回状态码 404
And 错误信息包含 "优惠券不存在"
Scenario: 无效支付方式被拒绝
When 用户 "user_123" 提交以下订单:
| skuId | quantity |
| SKU_001 | 1 |
And 支付方式为 "BITCOIN"
Then 返回状态码 400
# 切换到 Build 模式
根据 @src/test/resources/features/order/create-order.feature,
生成 Cucumber Step Definitions:
- 使用 Spring Boot Test
- 使用 @SpringBootTest + MockMvc 做集成测试
- 数据用 @Sql 注解初始化
- 保存到 src/test/java/com/example/order/acceptance/CreateOrderStepDefs.java
生成的 Step Definitions 骨架(节选):
@SpringBootTest
@AutoConfigureMockMvc
@CucumberContextConfiguration
public class CreateOrderStepDefs {
@Autowired
private MockMvc mockMvc;
@Autowired
private InventoryRepository inventoryRepository;
private ResultActions result;
private CreateOrderRequest.Builder requestBuilder;
@Given("商品库存数据如下:")
public void 商品库存数据如下(DataTable dataTable) {
List<Map<String, String>> rows = dataTable.asMaps();
rows.forEach(row -> {
Inventory inv = new Inventory();
inv.setSkuId(row.get("skuId"));
inv.setStock(Integer.parseInt(row.get("stock")));
inventoryRepository.save(inv);
});
}
@When("用户 {string} 提交以下订单:")
public void 用户提交以下订单(String userId, DataTable dataTable) {
requestBuilder = CreateOrderRequest.builder().userId(userId);
List<OrderItem> items = dataTable.asMaps().stream()
.map(row -> OrderItem.builder()
.skuId(row.get("skuId"))
.quantity(Integer.parseInt(row.get("quantity")))
.build())
.collect(Collectors.toList());
requestBuilder.items(items);
}
@And("支付方式为 {string}")
public void 支付方式为(String paymentMethod) throws Exception {
CreateOrderRequest request = requestBuilder
.paymentMethod(PaymentMethod.valueOf(paymentMethod))
.build();
result = mockMvc.perform(
post("/api/v1/orders")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
);
}
@Then("返回状态码 {int}")
public void 返回状态码(int statusCode) throws Exception {
result.andExpect(status().is(statusCode));
}
@Then("订单状态为 {string}")
public void 订单状态为(String status) throws Exception {
result.andExpect(jsonPath("$.data.status").value(status));
}
// ... 其他 Step 实现
}
此时运行测试,全部为红(因为业务代码还没写)。
切换到 Build 模式,使用 ultrawork:
根据 @docs/api/create-order.yaml 和 @AGENTS.md 的规范,
实现创建订单功能。
要求:
1. CreateOrderRequest DTO(带完整 Bean Validation)
2. OrderController(委托给 Service,不含业务逻辑)
3. OrderService 接口 + OrderServiceImpl(包含库存事务性扣减)
4. 邮件异步发送(Spring @Async)
5. 全局异常处理器(BusinessException → 标准响应格式)
测试在 @src/test/resources/features/order/create-order.feature
ultrawork
Sisyphus 自动分解为多个并行子任务,Background Agents 同时工作。
生成的 OrderServiceImpl.java(核心逻辑节选):
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final InventoryRepository inventoryRepository;
private final OrderRepository orderRepository;
private final CouponService couponService;
private final EmailService emailService;
@Override
@Transactional
public OrderResponse createOrder(CreateOrderRequest request) {
// 1. 验证并锁定库存(悲观锁,原子性保证)
List<InventoryLock> locks = lockInventory(request.getItems());
// 2. 计算金额
BigDecimal totalAmount = calculateTotal(request.getItems());
BigDecimal discountAmount = BigDecimal.ZERO;
// 3. 处理优惠券
if (StringUtils.hasText(request.getCouponCode())) {
Coupon coupon = couponService.validateAndUse(request.getCouponCode());
discountAmount = coupon.getDiscountAmount();
}
// 4. 创建订单
Order order = Order.builder()
.userId(request.getUserId())
.status(OrderStatus.PENDING_PAYMENT)
.totalAmount(totalAmount)
.discountAmount(discountAmount)
.finalAmount(totalAmount.subtract(discountAmount))
.paymentMethod(request.getPaymentMethod())
.build();
order = orderRepository.save(order);
// 5. 异步发送确认邮件(失败不影响订单)
emailService.sendOrderConfirmationAsync(order);
return OrderResponse.from(order);
}
/**
* 锁定库存,任一商品不足则抛出异常触发回滚
*/
private List<InventoryLock> lockInventory(List<OrderItem> items) {
return items.stream()
.map(item -> {
Inventory inventory = inventoryRepository
.findBySkuIdWithLock(item.getSkuId())
.orElseThrow(() -> new BusinessException(
ErrorCode.PRODUCT_NOT_FOUND,
"商品不存在: " + item.getSkuId()
));
if (inventory.getStock() < item.getQuantity()) {
throw new BusinessException(
ErrorCode.INSUFFICIENT_STOCK,
"库存不足: " + item.getSkuId()
);
}
inventory.setStock(inventory.getStock() - item.getQuantity());
inventoryRepository.save(inventory);
return new InventoryLock(item.getSkuId(), item.getQuantity());
})
.collect(Collectors.toList());
}
}
运行 mvn test -Dtest="**/acceptance/**"
如果有失败的测试,逐一分析并修复,直到全部通过。
AI 自动运行测试、分析失败原因、修复代码,循环直到全绿。
✓ 正常创建订单(无优惠券)
✓ 使用有效优惠券创建订单
✓ 单个商品库存不足时全部回滚
✓ 多商品中有一个库存不足时全部回滚
✓ 优惠券不存在
✓ 无效支付方式被拒绝
Tests run: 6, Failures: 0, Errors: 0
@explore 检查新增的代码是否符合 @AGENTS.md 中的规范,
特别检查:
1. Service 层是否直接抛了 RuntimeException(应该用 BusinessException)
2. Controller 是否包含了业务逻辑
3. 公开方法是否都有 Javadoc
project/
├── AGENTS.md # AI 项目说明书(必须提交 Git)
├── .opencode/
│ ├── oh-my-opencode.jsonc # Oh-My-OpenCode 项目级配置
│ └── skills/ # 项目自定义 Skills
│ └── java-conventions/
│ └── SKILL.md
├── openspec/ # OpenSpec 规格目录
│ └── changes/
│ └── create-order/ # 每个功能一个目录
│ ├── proposal.md
│ ├── design.md
│ ├── tasks.md
│ └── specs/
│ └── api.yaml
├── docs/
│ └── api/ # 已 apply 的 OpenAPI 规格(SDD 产物)
│ ├── order-api.yaml
│ └── user-api.yaml
└── src/
└── test/
└── resources/
└── features/ # Cucumber feature 文件(ATDD 产物)
└── order/
└── create-order.feature
每个功能开发前:
/opsx:propose 开启规格流程(3+ 人团队)?/opsx:apply 解锁代码权限?.feature 文件并 Review?每个功能开发中:
每个功能完成后:
@explore 做了规范检查?AGENTS.md 是否需要更新?/opsx:archive 归档规格文档?AGENTS.md 的"代码规范"部分AGENTS.md.feature 文件的情况下完成功能开发AGENTS.md 中的规范部分(只有人工修改)/opsx:propose,直接进入 Build 模式Q:OpenSpec 和 Plan 模式有什么本质区别,必须两者都用吗?
A:Plan 模式的文件写入控制是"弹确认框"(ask),人可以绕过。openspec-plan agent 使用 deny 权限,物理禁止写业务代码文件,AI 自身也无法绕过。小团队(1-2 人)靠自律用 Plan 模式即可;3+ 人团队推荐加 OpenSpec 作为流程护栏。两者不是非此即彼,而是深度互补。
Q:OpenSpec 的 /opsx:apply 后,规格还能改吗?
A:可以,/opsx:apply 只是复制规格文件并解锁权限,openspec/changes/<feature>/specs/ 目录仍然存在。改动规格后需要手动同步到 docs/api/,建议通过 PR 记录规格变更。
Q:Plan 模式下 AI 能修改文件吗?
A:默认情况下修改操作会弹出确认框(ask 权限),而非直接禁止。可以在 opencode.json 中将 plan agent 的 edit 权限设为 deny 实现完全只读。
Q:Oh-My-OpenCode 的 ultrawork 命令会不会乱改代码?
A:不会,它仍然受 OpenCode 的权限体系约束。可以在 .opencode/oh-my-opencode.jsonc 中配置 background_tasks.max_concurrent 控制并发度。
Q:AGENTS.md 写多少内容合适?
A:不宜过长(超过 500 行会占用大量 context window),核心规范放 AGENTS.md,细节规范通过 opencode.json 的 instructions 字段引用外部文件。
Q:Cucumber 测试跑得很慢怎么办?
A:验收测试(/acceptance/)和单元测试(/unit/)分开执行。验收测试走真实 Spring 上下文,慢是正常的,可以配 CI 并行执行。
Q:AI 生成的代码质量不稳定怎么办?
A:AGENTS.md 写得越详细,输出越稳定。另外可以创建团队专属的 Skill,把编码规范以 Skill 形式注入:.opencode/skills/java-conventions/SKILL.md。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。