让AI更懂你,松哥教你一招!

AI 写的代码总是跑偏?今天我们来聊聊这个问题。

松哥最近在用 CodeBuddy 开发项目,发现了一个让人头疼的问题。

每次让 CodeBuddy 帮我写功能,我只是随口说了一句需求,结果 AI 理解的和我想要的不一样:

  • 我说"帮我做个客户管理",AI 给我写了一个带 Redis 缓存的复杂系统,但我的项目根本没有 Redis
  • 我说"加个跟进记录功能",AI 用了 MongoDB,但我的数据库是 MySQL
  • 我说"做个销售漏斗",AI 给我写了一堆图表组件,但我只是想要一个简单的状态流转

每次都要反复沟通、反复修改,效率极低。

后来松哥发现了 OpenSpec 这个工具,专门解决这个问题。它的核心思想是:

先写规范,再写代码。让 AI 和你在动手之前就达成共识。

今天松哥就带大家用 OpenSpec + CodeBuddy ,从零开发一个简易的 CRM(客户关系管理)系统,手把手教你怎么用规范驱动开发提升效率。


准备工作

技术栈说明

我们要开发的 CRM 系统,技术栈如下:

层次 技术选型
后端框架 Spring Boot 3.x
数据库 MySQL 8.0
ORM MyBatis-Plus
缓存 暂不引入(保持简单)
认证 JWT
前端 Vue 3 + Element Plus
构建工具 Maven

安装 Node.js

OpenSpec 是一个 Node.js 工具,需要先安装 Node.js(版本 20.19.0 或以上)。

去 Node.js 官网 下载安装即可。

安装完成后,验证:

bash 复制代码
node -v
# 输出类似:v22.0.0

npm -v
# 输出类似:10.0.0

安装 OpenSpec

bash 复制代码
npm install -g @fission-ai/openspec@latest

安装完成后,验证:

bash 复制代码
openspec --version
# 输出类似:openspec/1.x.x

安装腾讯 CodeBuddy

安装完成后,用腾讯云账号登录即可。

创建项目并初始化 OpenSpec

创建 Spring Boot 项目

用 Spring Initializr 创建项目,配置如下:

plain 复制代码
Project:    Maven
Language:   Java
Spring Boot: 3.2.x
Group:      com.example
Artifact:   crm
Java:       17

Dependencies:
  - Spring Web
  - Spring Data JPA(或 MyBatis-Plus)
  - MySQL Driver
  - Spring Security
  - Lombok
  - Validation

下载解压后,用 IDE 打开项目。

初始化 OpenSpec

在项目根目录打开终端,执行:

bash 复制代码
# 进入项目目录
cd /path/to/your/crm-project

# 初始化 OpenSpec,指定 CodeBuddy 工具
openspec init --tools codebuddy

执行后,OpenSpec 会在项目中创建以下目录结构:

plain 复制代码
crm-project/
├── openspec/
│   ├── specs/          # 系统规范(源代码真理)
│   └── changes/        # 待开发的功能变更
├── .codebuddy/
│   ├── skills/         # OpenSpec 注入的 AI 技能
│   └── commands/       # OpenSpec 注入的斜杠命令
└── src/
    └── ...(Spring Boot 源码)

这时候 OpenSpec 已经把自己的"技能"注入到了 CodeBuddy 里,后续在 CodeBuddy 对话框里就可以直接使用 /opsx:propose 等命令了。

CRM 系统功能规划

在开始写代码之前,我们先梳理一下 CRM 系统要做哪些功能。

核心功能模块

一个基础的 CRM 系统,通常包含以下模块:

plain 复制代码
CRM 系统
├── 用户管理
│   ├── 登录 / 登出
│   └── 用户信息管理
├── 客户管理
│   ├── 客户列表
│   ├── 新增 / 编辑客户
│   ├── 客户详情
│   └── 客户搜索
├── 跟进记录
│   ├── 添加跟进记录
│   ├── 查看跟进历史
│   └── 跟进提醒
└── 销售机会
    ├── 机会列表
    ├── 阶段管理(销售漏斗)
    └── 赢单 / 输单

开发顺序

我们按照以下顺序逐步开发:

  1. 第一步:用户认证(登录 / JWT)
  2. 第二步:客户管理(CRUD)
  3. 第三步:跟进记录
  4. 第四步:销售机会

每一步都用 OpenSpec 先写规范,再让 CodeBuddy 实现。

开发用户认证模块

用 OpenSpec 提议功能

打开 CodeBuddy 对话框,输入:

plain 复制代码
/opsx:propose add-user-auth

CodeBuddy 会自动创建以下文件:

plain 复制代码
openspec/changes/add-user-auth/
├── proposal.md      ← 为什么做、做什么
├── specs/
│   └── auth/
│       └── spec.md  ← 具体需求和场景
├── design.md        ← 技术方案
└── tasks.md         ← 实现清单

查看并确认规范

OpenSpec 生成的 proposal.md 大概是这样的:

markdown 复制代码
# 提议:用户认证模块

## 意图
CRM 系统需要用户认证,确保只有授权用户才能访问系统数据。

## 范围
- 用户登录接口(用户名 + 密码)
- JWT Token 生成和验证
- 登出接口
- 当前用户信息查询

## 方案
使用 Spring Security + JWT 实现无状态认证。
Token 存储在客户端,服务端不维护 Session。

specs/auth/spec.md 大概是这样的:

markdown 复制代码
# 认证规范

## 新增需求

### 需求:用户登录
系统 SHALL 在用户提供正确的用户名和密码后,返回 JWT Token。

#### 场景:登录成功
- 给定:用户名 admin,密码正确
- 当:POST /api/auth/login
- 那么:返回 200,包含 token 字段
- 并且:token 有效期为 24 小时

#### 场景:密码错误
- 给定:用户名 admin,密码错误
- 当:POST /api/auth/login
- 那么:返回 401,包含错误信息

### 需求:Token 验证
系统 SHALL 对所有非公开接口验证 JWT Token。

#### 场景:Token 有效
- 给定:请求头携带有效 Token
- 当:访问任意受保护接口
- 那么:正常返回数据

#### 场景:Token 无效或过期
- 给定:请求头携带无效或过期 Token
- 当:访问任意受保护接口
- 那么:返回 401

design.md 大概是这样的:

markdown 复制代码
# 设计:用户认证

## 技术方案
- Spring Security 配置白名单(/api/auth/** 不需要认证)
- JWT 工具类:生成、解析、验证 Token
- JwtAuthenticationFilter:每次请求验证 Token
- UserDetailsService:从数据库加载用户信息

## 数据库设计
表名:sys_user
字段:
- id(主键)
- username(用户名,唯一)
- password(密码,BCrypt 加密)
- real_name(真实姓名)
- status(状态:0 禁用,1 启用)
- create_time(创建时间)
- update_time(更新时间)

## 接口设计
POST /api/auth/login    → 登录
POST /api/auth/logout   → 登出
GET  /api/auth/me       → 当前用户信息

tasks.md 大概是这样的:

markdown 复制代码
# 任务

## 1. 数据库
- [ ] 1.1 创建 sys_user 表
- [ ] 1.2 插入初始管理员账号(admin/123456)

## 2. 实体和 Mapper
- [ ] 2.1 创建 SysUser 实体类
- [ ] 2.2 创建 SysUserMapper 接口

## 3. JWT 工具
- [ ] 3.1 引入 jjwt 依赖
- [ ] 3.2 创建 JwtUtils 工具类

## 4. Spring Security 配置
- [ ] 4.1 创建 SecurityConfig 配置类
- [ ] 4.2 创建 JwtAuthenticationFilter 过滤器
- [ ] 4.3 创建 UserDetailsServiceImpl 实现类

## 5. 认证接口
- [ ] 5.1 创建 AuthController
- [ ] 5.2 实现登录接口
- [ ] 5.3 实现登出接口
- [ ] 5.4 实现当前用户信息接口

## 6. 测试
- [ ] 6.1 测试登录成功
- [ ] 6.2 测试密码错误
- [ ] 6.3 测试 Token 验证

:::success 重要:在让 CodeBuddy 开始写代码之前,先仔细阅读这些规范文件,确认它们符合你的预期。如果有不对的地方,直接修改文件内容即可。

:::

让 CodeBuddy 实现代码

确认规范无误后,在 CodeBuddy 对话框输入:

plain 复制代码
/opsx:apply

CodeBuddy 会按照 tasks.md 的清单,逐个任务实现代码:

plain 复制代码
CodeBuddy:正在实现 add-user-auth...

✓ 1.1 创建 sys_user 表(src/main/resources/sql/init.sql)
✓ 1.2 插入初始管理员账号
✓ 2.1 创建 SysUser 实体类
✓ 2.2 创建 SysUserMapper 接口
✓ 3.1 引入 jjwt 依赖(pom.xml)
✓ 3.2 创建 JwtUtils 工具类
✓ 4.1 创建 SecurityConfig 配置类
✓ 4.2 创建 JwtAuthenticationFilter 过滤器
✓ 4.3 创建 UserDetailsServiceImpl 实现类
✓ 5.1 创建 AuthController
✓ 5.2 实现登录接口
✓ 5.3 实现登出接口
✓ 5.4 实现当前用户信息接口
✓ 6.1-6.3 编写测试用例

所有任务完成!

验证实现

plain 复制代码
/opsx:verify

CodeBuddy 会检查实现是否符合规范:

plain 复制代码
CodeBuddy:验证 add-user-auth...

完整性:✓ 所有任务完成
正确性:✓ 接口符合规范定义
一致性:✓ 代码风格与设计文档一致

可以归档!

归档并进入下一步

plain 复制代码
/opsx:archive
plain 复制代码
CodeBuddy:归档 add-user-auth...
✓ 规范已合并到 openspec/specs/auth/spec.md
✓ 变更已移至 openspec/changes/archive/
准备好开发下一个功能!

开发客户管理模块

提议功能

plain 复制代码
/opsx:propose add-customer-management

生成的规范示例

proposal.md:

markdown 复制代码
# 提议:客户管理模块

## 意图
CRM 的核心是管理客户信息。需要支持客户的增删改查,
以及按条件搜索客户。

## 范围
- 客户列表(分页 + 搜索)
- 新增客户
- 编辑客户信息
- 删除客户(软删除)
- 客户详情

## 方案
使用 MyBatis-Plus 实现 CRUD,支持逻辑删除。
分页使用 MyBatis-Plus 的 Page 对象。

specs/customer/spec.md:

markdown 复制代码
# 客户管理规范

## 新增需求

### 需求:客户列表
系统 SHALL 支持分页查询客户列表,并支持按姓名、手机号、公司搜索。

#### 场景:分页查询
- 给定:已登录用户
- 当:GET /api/customers?page=1&size=10
- 那么:返回第 1 页,每页 10 条客户数据
- 并且:包含总记录数

#### 场景:按姓名搜索
- 给定:已登录用户
- 当:GET /api/customers?keyword=张三
- 那么:返回姓名或公司名包含"张三"的客户

### 需求:新增客户
系统 SHALL 支持新增客户,手机号不能重复。

#### 场景:新增成功
- 给定:手机号未被使用
- 当:POST /api/customers,携带客户信息
- 那么:返回 200,客户创建成功

#### 场景:手机号重复
- 给定:手机号已存在
- 当:POST /api/customers
- 那么:返回 400,提示"手机号已存在"

### 需求:软删除
系统 SHALL 使用软删除,删除后数据不从数据库物理删除。

#### 场景:删除客户
- 给定:客户存在
- 当:DELETE /api/customers/{id}
- 那么:客户 deleted 字段置为 1,不再出现在列表中

design.md:

markdown 复制代码
# 设计:客户管理

## 数据库设计
表名:crm_customer
字段:
- id(主键)
- name(客户姓名,必填)
- phone(手机号,唯一)
- email(邮箱)
- company(公司名称)
- position(职位)
- source(来源:1 官网,2 转介绍,3 广告,4 其他)
- status(状态:1 潜在,2 意向,3 成交,4 流失)
- owner_id(负责人 ID,关联 sys_user)
- remark(备注)
- deleted(逻辑删除:0 正常,1 已删除)
- create_time
- update_time

## 接口设计
GET    /api/customers          → 客户列表(分页 + 搜索)
POST   /api/customers          → 新增客户
GET    /api/customers/{id}     → 客户详情
PUT    /api/customers/{id}     → 编辑客户
DELETE /api/customers/{id}     → 删除客户

tasks.md:

markdown 复制代码
# 任务

## 1. 数据库
- [ ] 1.1 创建 crm_customer 表

## 2. 实体和 Mapper
- [ ] 2.1 创建 Customer 实体类(含 @TableLogic 逻辑删除)
- [ ] 2.2 创建 CustomerMapper 接口
- [ ] 2.3 创建 CustomerDTO(请求参数)
- [ ] 2.4 创建 CustomerVO(返回数据)

## 3. Service 层
- [ ] 3.1 创建 CustomerService 接口
- [ ] 3.2 实现 CustomerServiceImpl
- [ ] 3.3 实现分页查询(含关键词搜索)
- [ ] 3.4 实现新增(手机号唯一性校验)
- [ ] 3.5 实现编辑
- [ ] 3.6 实现软删除

## 4. Controller 层
- [ ] 4.1 创建 CustomerController
- [ ] 4.2 实现所有 CRUD 接口
- [ ] 4.3 添加参数校验(@Valid)

## 5. 测试
- [ ] 5.1 测试分页查询
- [ ] 5.2 测试手机号重复校验
- [ ] 5.3 测试软删除

实现代码

plain 复制代码
/opsx:apply

CodeBuddy 会生成以下关键代码:

Customer 实体类(自动生成):

java 复制代码
@Data
@TableName("crm_customer")
public class Customer {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private String phone;
    private String email;
    private String company;
    private String position;
    private Integer source;
    private Integer status;
    private Long ownerId;
    private String remark;
    @TableLogic  // MyBatis-Plus 逻辑删除
    private Integer deleted;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

CustomerController(自动生成):

java 复制代码
@RestController
@RequestMapping("/api/customers")
@RequiredArgsConstructor
public class CustomerController {

    private final CustomerService customerService;

    @GetMapping
    public Result<Page<CustomerVO>> list(CustomerQueryDTO query) {
        return Result.ok(customerService.page(query));
    }

    @PostMapping
    public Result<Void> add(@Valid @RequestBody CustomerDTO dto) {
        customerService.add(dto);
        return Result.ok();
    }

    @GetMapping("/{id}")
    public Result<CustomerVO> detail(@PathVariable Long id) {
        return Result.ok(customerService.getById(id));
    }

    @PutMapping("/{id}")
    public Result<Void> update(@PathVariable Long id,
                               @Valid @RequestBody CustomerDTO dto) {
        customerService.update(id, dto);
        return Result.ok();
    }

    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        customerService.delete(id);
        return Result.ok();
    }
}

归档

plain 复制代码
/opsx:archive

开发跟进记录模块

提议功能

plain 复制代码
/opsx:propose add-followup-records

规范要点

这个模块的核心规范要点:

specs/followup/spec.md** 关键需求**:

markdown 复制代码
### 需求:添加跟进记录
系统 SHALL 支持为客户添加跟进记录,记录跟进方式和内容。

#### 场景:添加成功
- 给定:客户存在,当前用户已登录
- 当:POST /api/customers/{customerId}/followups
- 那么:跟进记录创建成功,关联到该客户

### 需求:跟进历史
系统 SHALL 按时间倒序展示客户的所有跟进记录。

#### 场景:查看历史
- 给定:客户有 5 条跟进记录
- 当:GET /api/customers/{customerId}/followups
- 那么:返回 5 条记录,最新的在最前面

design.md** 数据库设计**:

markdown 复制代码
表名:crm_followup
字段:
- id(主键)
- customer_id(客户 ID,外键)
- type(跟进方式:1 电话,2 微信,3 邮件,4 拜访,5 其他)
- content(跟进内容,必填)
- next_follow_time(下次跟进时间,可选)
- creator_id(创建人 ID)
- create_time

实现和归档

plain 复制代码
/opsx:apply
/opsx:archive

开发销售机会模块

提议功能

plain 复制代码
/opsx:propose add-opportunity-management

规范要点

specs/opportunity/spec.md** 关键需求**:

markdown 复制代码
### 需求:销售阶段流转
系统 SHALL 支持销售机会在不同阶段之间流转。
阶段定义:
1. 初步接触
2. 需求确认
3. 方案报价
4. 商务谈判
5. 赢单(终态)
6. 输单(终态)

#### 场景:推进阶段
- 给定:机会处于"需求确认"阶段
- 当:PUT /api/opportunities/{id}/stage,body: {stage: 3}
- 那么:阶段更新为"方案报价"

#### 场景:标记赢单
- 给定:机会处于任意非终态阶段
- 当:PUT /api/opportunities/{id}/win
- 那么:阶段更新为"赢单",记录赢单时间

### 需求:销售漏斗统计
系统 SHALL 提供各阶段机会数量和金额的统计。

#### 场景:查看漏斗
- 给定:系统中有若干销售机会
- 当:GET /api/opportunities/funnel
- 那么:返回每个阶段的机会数量和预计金额合计

design.md** 数据库设计**:

markdown 复制代码
表名:crm_opportunity
字段:
- id(主键)
- customer_id(关联客户)
- title(机会标题)
- amount(预计金额)
- stage(阶段:1-6)
- expected_close_date(预计成交日期)
- owner_id(负责人)
- win_time(赢单时间)
- lose_reason(输单原因)
- deleted(逻辑删除)
- create_time
- update_time

实现和归档

plain 复制代码
/opsx:apply
/opsx:archive

同时推进多个功能

当你对 OpenSpec 熟悉之后,可以同时开发多个功能,互不干扰。

创建多个变更

plain 复制代码
/opsx:propose add-data-export
/opsx:propose add-dashboard-stats

这时候 openspec/changes/ 目录下会有两个文件夹:

plain 复制代码
openspec/changes/
├── add-data-export/
│   ├── proposal.md
│   ├── specs/
│   ├── design.md
│   └── tasks.md
└── add-dashboard-stats/
    ├── proposal.md
    ├── specs/
    ├── design.md
    └── tasks.md

切换工作

plain 复制代码
# 先实现数据导出
/opsx:apply add-data-export

# 切换到统计看板
/opsx:apply add-dashboard-stats

# 回来继续数据导出
/opsx:apply add-data-export

批量归档

当多个功能都完成后,可以一次性归档:

plain 复制代码
/opsx:bulk-archive

CodeBuddy 会检查所有已完成的变更,并一次性归档。

查看项目规范全貌

随着功能不断增加,openspec/specs/ 目录会积累完整的系统规范:

plain 复制代码
openspec/specs/
├── auth/
│   └── spec.md      ← 认证规范
├── customer/
│   └── spec.md      ← 客户管理规范
├── followup/
│   └── spec.md      ← 跟进记录规范
└── opportunity/
    └── spec.md      ← 销售机会规范

这些规范文件就是你系统的"活文档",随时可以查阅。

用 CLI 查看项目状态:

bash 复制代码
# 查看所有变更
openspec list

# 查看某个变更的详情
openspec show add-customer-management

# 交互式仪表板(可视化查看)
openspec view

常见问题解答

Q1:OpenSpec 生成的规范不符合我的预期,怎么办?

A: 直接修改规范文件!

OpenSpec 生成的规范只是一个起点,你可以随时修改 proposal.md、specs/、design.md、tasks.md 中的任何内容。

修改完成后,再执行 /opsx:apply,CodeBuddy 会按照修改后的规范来实现代码。

Q2:CodeBuddy 实现的代码有 Bug,怎么办?

A: 两种处理方式:

方式一:直接告诉 CodeBuddy 修复

plain 复制代码
这段代码有问题:[粘贴代码]
错误信息是:[粘贴错误]
请修复

方式二:更新规范后重新实现

如果 Bug 是因为规范描述不清楚导致的,先更新 specs/ 中的场景描述,然后重新执行 /opsx:apply。

Q3:项目已经开发了一半,还能用 OpenSpec 吗?

A: 完全可以!

OpenSpec 的设计哲学是"棕地优先"(Brownfield-first),专门为修改现有系统设计的。

对于已有的代码,可以先用 /opsx:explore 让 CodeBuddy 分析现有代码,然后再提议新功能:

plain 复制代码
/opsx:explore
plain 复制代码
帮我分析一下现有的用户模块,了解当前的实现方式

CodeBuddy 会读取现有代码,然后在后续的规范中自动考虑现有实现。

Q4:团队协作时,OpenSpec 怎么用?

A: 把 openspec/ 目录提交到 Git 仓库。

团队成员可以:

  • 查看 openspec/specs/ 了解系统现有功能
  • 查看 openspec/changes/ 了解正在开发的功能
  • 在 PR 中 Review 规范文件(而不只是代码)

这样,规范就成了团队的"共同语言"。

Q5:OpenSpec 支持哪些 AI 编程助手?

A: 支持 20+ 种,包括:

  • 腾讯 CodeBuddy
  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • 等等...

小结

好啦,今天松哥带大家完整走了一遍用 OpenSpec + CodeBuddy 开发 CRM 系统的流程。

核心工作流程

plain 复制代码
1. openspec init --tools codebuddy   ← 初始化
2. /opsx:propose <功能名>             ← 生成规范
3. 审查并修改规范文件                  ← 人工确认
4. /opsx:apply                       ← AI 实现代码
5. /opsx:verify                      ← 验证实现
6. /opsx:archive                     ← 归档,进入下一个功能

OpenSpec 核心价值

传统 AI 编程 OpenSpec + CodeBuddy
随口说需求,AI 可能理解错 先写规范,双方达成共识
代码写完才发现方向不对 规范阶段就能发现问题
上下文越来越长,AI 容易遗忘 规范写在文件里,永不丢失
团队协作靠口头沟通 规范文件就是共同语言
不知道 AI 做了什么 tasks.md 清单一目了然

适合使用 OpenSpec 的场景

  • 功能较复杂,需求容易被误解
  • 团队协作开发
  • 需要长期维护的项目
  • 对代码质量要求高

好啦,今天的教程就到这里。如果你在实践过程中遇到了问题,或者有什么心得体会,欢迎小伙伴们在评论区留言交流!

如果觉得这篇文章对你有帮助,别忘了点赞转发,让更多小伙伴看到~

相关推荐
sell-cloud1 小时前
Prompt Engineering要凉了?Fable 5.5能“猜“意图,但银行正在封杀AI Agent——企业AI的真正护城河是什么
人工智能·prompt
Navicat中国3 小时前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI3 小时前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区3 小时前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris5 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy5 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V5 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI5 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技5 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人
海宇数据6 小时前
零信任架构实战:基于海宇网上踪迹欺诈行为识别构建自动化信贷资信评估网关
运维·人工智能·架构·自动化