如果你还在用“感觉”和“关键词”来驱动 AI 编程助手,那么你很可能已经陷入了 Vibe Coding 的陷阱。这种依赖模糊描述和反复试错的开发方式,表面上解放了双手,实则让代码质量、项目一致性和团队协作变得一团糟。你得到的可能是一堆能跑但难以维护的“一次性代码”,或者更糟——一个充满幻觉和错误的半成品。
问题的核心不在于 AI 的能力,而在于我们与 AI 协作的方式。当开发流程缺乏明确的规范和约束时,再强大的模型也会像脱缰的野马,方向全凭运气。这正是 IBM 提出 Spec Kit 和 规范驱动开发 理念的背景: 将 AI 编程从“艺术创作”转变为“工程实践” 。
本文将带你深入理解 Vibe Coding 的局限性,并手把手教你如何通过 Spec Kit 这套方法论和工具集,构建一个可预测、可复用、可协作的 AI 编程工作流。这不是一个简单的插件介绍,而是一套从思想到实践的完整工程化解决方案。无论你是个人开发者希望提升代码质量,还是团队负责人寻求规范的 AI 协作流程,这篇文章都将提供清晰的路径和可落地的操作指南。
1. Vibe Coding:效率幻觉与它的真实代价
在深入新方案之前,我们必须先认清现状。Vibe Coding 是当前大多数开发者使用 AI 编程助手(如 Cursor、GitHub Copilot)的默认模式:开发者向 AI 描述一个模糊的需求或感觉(“vibe”),AI 生成代码,开发者再基于结果进行微调或重新描述,如此循环。
1.1 Vibe Coding 的典型工作流与问题
一个典型的 Vibe Coding 场景可能是这样的:
- 你在 IDE 里对 AI 说:“帮我写一个用户登录的 API,用 Spring Boot,要安全一点。”
-
AI 生成了一段包含
@PostMapping、UserService的代码。 -
你发现它没做参数校验,于是补充:“加上参数校验,用
@Valid。” - AI 更新了代码,但校验逻辑不完整。
- 你又发现它没有处理异常,于是继续:“捕获校验异常,返回统一的错误格式。”
- ……
这个过程看似高效,实则隐藏了四大致命问题:
| 问题维度 | 具体表现 | 长期影响 |
|---|---|---|
| 代码质量不可控 | AI 对“安全一点”、“性能好”的理解是模糊的。生成的代码可能缺乏必要的加密、日志、事务边界或错误处理。 | 系统漏洞、性能瓶颈、难以调试的线上问题。 |
| 项目一致性差 |
今天生成的代码用 Lombok,明天可能用原生 Getter/Setter;A 模块的异常处理是
try-catch
,B 模块是全局异常处理器。
| 代码库变成风格迥异的“缝合怪”,维护成本指数级上升。 |
| 上下文碎片化 | 每次交互都是独立的“对话”。AI 不知道项目的整体架构、已定义的规范、团队约定的最佳实践。 | 需要开发者在每次提示中重复交代背景,效率低下,且容易遗漏关键约束。 |
| 知识无法沉淀 | 优秀的提示词(Prompt)和生成的优质代码片段散落在个人聊天记录中,无法形成团队资产。 | 团队无法复用成功经验,新人上手成本高,同样的错误会反复出现。 |
1.2 为什么我们离不开 Vibe Coding?(以及为什么必须离开)
Vibe Coding 之所以流行,是因为它门槛极低,符合人类“用自然语言描述需求”的直觉,并能快速产生“看起来能用”的代码。对于原型验证、探索性编程或简单脚本编写,它确实能提供即时满足感。
然而,一旦进入严肃的、协作的、需要长期维护的软件工程项目,Vibe Coding 的短板就暴露无遗。 它本质上是一种“提示词驱动”的开发,其质量上限完全取决于开发者即时编写提示词的能力和运气 。这与软件工程所追求的确定性、可重复性和标准化背道而驰。
2. Spec Kit 与规范驱动开发:为 AI 编程引入“图纸”
Spec Kit 是 IBM 提出的一套旨在解决上述问题的理念和工具集合。其核心思想是 规范驱动开发 :在编写代码之前,先明确、形式化地定义“好代码”的规范。这些规范将作为 AI 编程的“图纸”和“质检标准”。
2.1 核心概念解析
- 规范 :对代码结构、风格、安全、性能、API 设计等方面的明确要求。它不仅仅是编码风格(如缩进),更包括架构约束(如分层)、设计模式(如 DTO 的使用)、安全规则(如 SQL 注入防护)等。
- Spec :规范的具体表现形式。它可以是一个配置文件、一组规则描述、一个测试用例模板,甚至是一段用于验证的代码。
- Kit :管理和应用这些 Spec 的工具集。包括规范的定义、存储、检索、验证以及与 IDE/AI 助手的集成。
2.2 Spec Kit 与传统开发方法的对比
为了更清晰地理解 Spec Kit 的价值,我们可以将其与熟悉的开发范式进行对比:
| 方法 | 核心驱动力 | 与 AI 的协作方式 | 优点 | 缺点 |
|---|---|---|---|---|
| TDD | 测试用例 | AI 根据失败的测试生成代码。 | 目标明确,代码质量高。 | 编写测试用例本身需要成本;AI 可能过度拟合测试而忽略设计。 |
| Vibe Coding | 自然语言提示 | AI 根据模糊描述生成代码,人工迭代修正。 | 灵活,入门简单。 | 不可预测,一致性差,难以协作。 |
| Spec Kit (SDD) | 结构化规范 | AI 根据预先定义的、机器可读的规范生成和验证代码。 | 可预测、可复用、可协作、知识可沉淀 。 | 需要前期投入来定义和维护规范。 |
Spec Kit 可以看作是 TDD 的演进和 Vibe Coding 的工业化升级 。它吸收了 TDD“先定义预期结果”的思想,但将“测试用例”扩展为更全面的“开发规范”。同时,它用结构化的“规范”取代了 Vibe Coding 中非结构化的“提示词”,使得 AI 协作过程变得可管理、可优化。
3. 环境准备:从零搭建你的第一个 Spec Kit 工作区
理论讲完,我们开始实战。假设我们要为一个新的 Spring Boot 微服务项目引入 Spec Kit。以下是完整的准备步骤。
3.1 基础工具栈
你需要准备以下工具,它们构成了 Spec Kit 实践的基础设施:
-
IDE
:Visual Studio Code。因其强大的插件生态和与 AI 工具的良好集成,是实践 Spec Kit 的首选。确保安装以下插件:
- Cursor :或任何你偏好的、支持自定义上下文和规范的 AI 编程助手。
- YAML/JSON 支持插件。
- 版本控制 :Git。用于管理代码和——更重要的是——管理你的 Spec 规范文件。
- 文档工具 :Markdown。用于编写规范的非技术描述部分。
3.2 创建规范仓库
这是 Spec Kit 的核心:一个独立于业务代码的 Git 仓库,专门用于存放所有规范。我们称之为
spec-repo
。
# 1. 创建规范仓库目录
mkdir my-project-specs
cd my-project-specs
git init
# 2. 创建规范的目录结构
mkdir -p specs/backend/spring-boot
mkdir -p specs/frontend/react
mkdir -p specs/shared/security
mkdir -p templates
mkdir -p docs
# 3. 初始化一个 README 说明
echo "# 项目开发规范仓库 (Spec Kit)" > README.md
echo "此仓库存放所有机器可读的开发规范,用于驱动 AI 辅助编程。" >> README.md
这个结构将不同类型的规范(后端、前端、共享)分门别类,
templates
用于存放代码模板,
docs
用于存放补充文档。
3.3 配置 AI 助手上下文
为了让 Cursor 等 AI 助手能“看到”并理解你的规范,你需要将规范仓库作为上下文提供给它们。有两种主要方式:
方式一:在 Cursor 中直接引用本地路径(适用于个人项目)
在 Cursor 的聊天框或设置中,可以将
my-project-specs
目录添加为“项目上下文”或“知识库”。
方式二:将规范发布为内部文档网站(适用于团队)
使用如
MkDocs
、
Docusaurus
等工具,将
spec-repo
中的 Markdown 和 YAML 文件渲染成网站。然后,在 AI 助手的配置中,填入该网站的地址(许多高级 AI 助手支持读取网页内容作为上下文)。
# 示例:MkDocs 的 mkdocs.yml 配置片段
site_name: 我的项目开发规范
nav:
- 首页: index.md
- 后端规范:
- Spring Boot: specs/backend/spring-boot/overview.md
- 共享规范:
- 安全规范: specs/shared/security/requirements.md
theme: readthedocs
4. 定义你的第一批核心规范
规范的定义是 Spec Kit 成功的关键。规范应该具体、可验证、可执行。我们从最常见的开始。
4.1 API 接口规范 (
specs/backend/spring-boot/api-contract.yml
)
这个 YAML 文件定义了所有 REST API 必须遵守的契约。
# specs/backend/spring-boot/api-contract.yml
api_standards:
version: "1.0"
base:
response_wrapper: # 统一响应体
enabled: true
class: "com.example.common.wrapper.ResponseResult<T>"
success_field: "code"
success_value: 200
data_field: "data"
message_field: "msg"
error_handling: # 统一异常处理
global_controller_advice: "com.example.common.handler.GlobalExceptionHandler"
business_exception: "com.example.common.exception.BusinessException"
controller:
annotation: "@RestController"
request_mapping: "@RequestMapping("/api/v1")"
naming_pattern: "*Controller"
method_standards:
create:
method: "POST"
annotation: "@PostMapping"
return_type: "ResponseResult<{Entity}DTO>"
request_body: "@RequestBody @Valid {Entity}CreateRequest"
get:
method: "GET"
annotation: "@GetMapping("/{id}")"
return_type: "ResponseResult<{Entity}DetailDTO>"
update:
method: "PUT"
annotation: "@PutMapping("/{id}")"
return_type: "ResponseResult<Void>"
request_body: "@RequestBody @Valid {Entity}UpdateRequest"
delete:
method: "DELETE"
annotation: "@DeleteMapping("/{id}")"
return_type: "ResponseResult<Void>"
validation:
enabled: true
package: "javax.validation.constraints.*"
message_source: "ValidationMessages.properties"
关键点解释 :
-
response_wrapper:强制所有 API 返回统一的包装类,确保前端处理逻辑一致。 -
{Entity}占位符:在具体生成时,AI 会根据上下文(如“生成一个 UserController”)将其替换为具体的实体名。 -
明确的注解和返回类型:消除了“用
@RestController还是@Controller”之类的模糊性。
4.2 代码风格与安全检查清单 (
specs/backend/spring-boot/code-style.md
)
这是一个供 AI 和开发者自检的 Markdown 清单。
# 后端代码风格与安全清单
## 必须遵守
- [ ] 所有 Controller 类名以 `Controller` 结尾。
- [ ] 所有 Service 接口以 `Service` 结尾,实现类以 `ServiceImpl` 结尾。
- [ ] 使用 Lombok 的 `@Data`、`@Builder` 等注解减少样板代码,但实体类必须显式定义 `equals` 和 `hashCode` 方法。
- [ ] 数据库查询必须使用 MyBatis-Plus 或 JPA,**禁止**在代码中拼接 SQL 字符串。
- [ ] 所有用户输入在进入 Service 层前必须经过校验(JSR-303)。
- [ ] 日志记录:使用 SLF4J,在关键业务逻辑、异常捕获处记录日志,级别为 `INFO` 或 `ERROR`。
## 建议遵守
- [ ] 单个方法行数不超过 50 行。
- [ ] 使用 Java Stream API 或集合工具类代替手写循环。
- [ ] 第三方 API 调用必须设置合理的超时时间。
4.3 实体与 DTO 生成模板 (
templates/spring-boot-entity.java
)
这是一个可复用的代码模板,AI 可以根据它快速生成结构一致的类。
// templates/spring-boot-entity.java
package {package}.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* {table_comment} 实体类
* 对应数据库表: {table_name}
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("{table_name}")
public class {Entity} implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键ID */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 创建时间 */
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/** 更新时间 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
// TODO: 根据数据库表字段,在此处添加其他属性。
// 示例:
// /** 用户名 */
// @NotBlank(message = "用户名不能为空")
// private String username;
//
// /** 状态:0-禁用,1-启用 */
// private Integer status;
// 注意:所有字段需添加清晰的Javadoc注释。
}
5. 实战:使用 Spec Kit 生成一个完整的用户管理模块
现在,让我们在真实的 Spring Boot 项目中应用以上规范。假设项目已初始化,我们需要一个包含 CRUD 的
User
管理模块。
5.1 第一步:向 AI 提供规范上下文
在 Cursor 中,开启一个新对话。首先,将我们定义好的规范文件内容粘贴进去,或者通过引用文件的方式让 AI 知晓。你可以这样说:
“接下来我们将基于以下规范进行开发。请仔细阅读这些规范,并在后续所有代码生成中严格遵守。” (然后附上
api-contract.yml、code-style.md和spring-boot-entity.java模板的核心内容)
5.2 第二步:生成实体类
给出明确的指令,并引用规范:
“根据
spring-boot-entity.java模板,为User实体生成代码。数据库表名为sys_user,包含以下字段:username(字符串,非空),status(整数,0-禁用,1-启用)。请将生成的完整代码放在com.example.demo.entity包下。”
AI 应该生成如下代码:
// 文件路径:src/main/java/com/example/demo/entity/User.java
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 系统用户 实体类
* 对应数据库表: sys_user
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键ID */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 用户名 */
@NotBlank(message = "用户名不能为空")
private String username;
/** 邮箱 */
@Email(message = "邮箱格式不正确")
private String email;
/** 状态:0-禁用,1-启用 */
private Integer status;
/** 创建时间 */
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/** 更新时间 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
验证点
:检查是否使用了正确的注解(
@TableName
,
@TableId
),是否添加了参数校验(
@NotBlank
,
@Email
),是否符合 Lombok 和 MyBatis-Plus 的规范。
5.3 第三步:生成 Controller、Service 和 DTO
继续给出组合指令:
“现在,请根据
api-contract.yml规范,为User实体生成完整的 CRUD API。需要生成:
UserController,放在com.example.demo.controller包下。UserService接口和UserServiceImpl实现类,放在com.example.demo.service包下。- 对应的
UserCreateRequest、UserUpdateRequest、UserDTO、UserDetailDTO,放在com.example.demo.model.dto包下。 请确保所有 API 的返回类型、注解、校验规则都严格遵循api-contract.yml中的定义。”
由于指令清晰且规范明确,AI 会生成高度一致且可直接使用的代码。以下是
UserController
的示例:
// 文件路径:src/main/java/com/example/demo/controller/UserController.java
package com.example.demo.controller;
import com.example.demo.model.dto.*;
import com.example.demo.service.UserService;
import com.example.common.wrapper.ResponseResult;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping
public ResponseResult<UserDTO> createUser(@RequestBody @Valid UserCreateRequest request) {
UserDTO user = userService.create(request);
return ResponseResult.success(user);
}
@GetMapping("/{id}")
public ResponseResult<UserDetailDTO> getUser(@PathVariable Long id) {
UserDetailDTO user = userService.getById(id);
return ResponseResult.success(user);
}
@PutMapping("/{id}")
public ResponseResult<Void> updateUser(@PathVariable Long id, @RequestBody @Valid UserUpdateRequest request) {
userService.update(id, request);
return ResponseResult.success();
}
@DeleteMapping("/{id}")
public ResponseResult<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseResult.success();
}
}
关键优势 :你不再需要逐条纠正 AI 的注解、返回类型或方法命名。因为规范已经定义了一切,生成的结果是确定性的。
6. 将规范验证集成到 CI/CD 流程
规范驱动开发的最后一步是自动化验证,确保所有提交的代码都符合规范。这可以通过静态代码分析工具实现。
6.1 使用 Checkstyle 和 SpotBugs
在项目的
pom.xml
中添加插件,并将你的
code-style.md
部分规则转化为 Checkstyle 的 XML 配置。
<!-- pom.xml 片段 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<configLocation>checkstyle.xml</configLocation> <!-- 你的规范配置文件 -->
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError> <!-- 检查失败则构建失败 -->
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.3.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
6.2 在 Git Hook 或 CI 中运行检查
你可以在开发者提交代码时(pre-commit hook)或在合并请求时(CI Pipeline)运行这些检查。
# 示例:GitLab CI 配置片段 (.gitlab-ci.yml)
code-quality-check:
stage: test
script:
- mvn checkstyle:check
- mvn spotbugs:check
only:
- merge_requests # 仅在合并请求时运行
这样,任何不符合规范的代码都无法进入主分支,从流程上保障了代码库的一致性。
7. 常见问题与排查思路
在实践 Spec Kit 的过程中,你可能会遇到以下典型问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| AI 生成的代码不符合规范 |
1. 规范描述不够具体或存在歧义。
2. AI 未正确加载或理解规范上下文。 |
1. 检查规范 YAML/文档的语法和逻辑。
2. 在 AI 对话中,要求其复述关键规范以确认理解。 |
1. 细化规范,使用更精确的术语和示例。
2. 在提示词中明确引用规范文件名和章节。 |
| 规范文件过多,难以管理 | 规范缺乏层次和索引。 | 审视规范仓库的目录结构。 |
建立规范的索引文件(如
specs/README.md
),说明每个规范的用途和适用范围。按领域(如支付、用户)而非技术类型分层。
|
| 团队成员不遵守规范 |
1. 规范理解成本高。
2. 缺乏便捷的验证工具。 | 调研团队开发流程。 |
1. 为关键规范制作简短的培训视频或示例。
2. 将规范检查集成到 IDE 实时提示或 CI 流水线,变“要求遵守”为“无法违反”。 |
| 规范与快速原型开发冲突 | 规范可能过于繁琐,阻碍了探索性编程。 | 评估当前项目阶段。 | 建立规范分级制度 :核心规范(必须)、推荐规范(应该)、原型规范(可以)。在项目初期或 Spike 阶段,允许暂时放宽部分规范。 |
8. 最佳实践与工程建议
- 从核心规范开始,逐步丰富 :不要试图一次性定义所有规范。从最影响代码质量和团队协作的方面入手,如 API 响应格式、错误处理、日志规范。随着项目发展,逐步添加数据库、缓存、消息队列等规范。
- 规范即代码,同样需要评审和维护 :将规范文件纳入版本控制。对规范的任何修改,都应像修改业务代码一样,发起合并请求,经过团队评审。
-
为规范编写“规范”
:定义规范的元规则。例如,所有 YAML 规范文件必须包含
version和scope字段;所有 Markdown 清单必须用“必须遵守”和“建议遵守”来区分优先级。 -
与架构决策记录结合
:将重要的架构决策(如为什么选择某种响应包装格式)记录在
spec-repo/docs/adr目录下。这能让 AI 和团队成员理解规范背后的“为什么”,而不仅仅是“是什么”。 - 定期回顾和优化规范 :每个季度或重大项目里程碑后,回顾规范的有效性。是否有未被遵守的规范?是否有新的最佳实践需要纳入?及时淘汰过时的规范。
告别 Vibe Coding,拥抱 Spec Kit 和规范驱动开发,本质上是将软件工程中“定义-构建-验证”的严谨性引入到 AI 辅助编程中。它要求我们在享受 AI 带来的速度红利之前,先花时间定义好“好代码”的标准。这份前期投入,将在代码质量、团队协作和项目可维护性上带来数十倍的回报。
你可以从今天开始,为你的个人项目创建一个最简单的
specs
文件夹,定义两三条你最在意的 API 或代码风格规则。然后,在下次使用 AI 编程时,有意识地将这些规则作为提示词的一部分。你会立刻感受到,从“猜我想要什么”到“按图纸施工”的转变,那种确定性和掌控感,才是工程师与 AI 协作的正确姿势。



1万+

被折叠的 条评论
为什么被折叠?



