Spec Kit:GitHub 官方推出的规范驱动开发工具包——Go 语言项目实战
2025 年 10 月,GitHub 发布了一个名为Spec Kit的开源工具包,迅速在开发者社区引发热议。它不是一个普通的开发工具,而是一套完整的规范驱动开发(Spec-Driven Development)工作流——让开发者从"即兴编码"(Vibe Coding)的随意性中解脱出来,转向以可执行的规格说明为核心的工程化开发模式。
本文将带你全面了解 Spec Kit 的核心概念、安装配置,并通过一个完整的Go 语言项目实战——构建一个高性能的二维码生成 API 服务,展示规范驱动开发如何落地。
一、Spec Kit 是什么?
1.1 从"即兴编码"到"规范驱动"
过去一年,"即兴编码"(Vibe Coding)随着 AI 编程助手的普及而流行——开发者用自然语言描述需求,AI 直接生成代码。这种方式虽然快速,但也带来了问题:
| 痛点 | 表现 |
|---|---|
| 上下文丢失 | AI 忘记之前的决策,需要反复解释 |
| 实现偏离 | 生成的代码能运行,但不符合预期意图 |
| 技术选型失控 | AI 选择过时或不合适的框架 |
| 文档缺失 | 完成需求后难以追溯设计原则 |
GitHub 产品经理 Den Delimarsky 一语道破问题本质:"我们把编码代理当成搜索引擎,其实应该把它们当成字面意义上的结对程序员。"
Spec Kit 正是为了解决这些问题而生。它的核心理念是:将规格说明作为一等公民,让 AI 基于清晰、可执行的规范生成代码,而非靠零散的提示词拼凑。
1.2 Spec Kit 的核心原则
根据 GitHub 官方发布,Spec Kit 遵循以下设计原则:
- 规格即通用语言:规格说明成为主要工件,代码只是其在特定语言和框架中的表达
- 可执行规格:规格必须精确、完整、无歧义,足以生成可工作的系统
- 持续精化:AI 持续分析规格中的歧义、矛盾和遗漏
- 分支探索:从同一规格生成多种实现方案,探索不同技术选型
- 双向反馈:生产环境的实际表现反哺规格的优化
1.3 四阶段开发流程
Spec Kit 将开发过程组织为四个门控阶段,每个阶段验证通过后才能进入下一阶段:
| 阶段 | 命令 | 核心活动 | 产出物 |
|---|---|---|---|
| Specify | /specify | 定义"做什么"(用户旅程、功能需求) | 功能规格说明书 |
| Plan | /plan | 定义"怎么做"(技术栈、架构、约束) | 技术方案设计 |
| Tasks | /tasks | 分解可执行的任务单元 | 任务清单 |
| Implement | /implement | AI 基于前三步生成代码 | 可运行的代码 |
这种结构化流程将模糊的提示转化为可操作、可验证的开发步骤,让 AI 从"代码生成器"升级为"遵循规范的结对程序员"。
二、环境准备与安装
2.1 系统要求
在开始之前,确保你的环境满足以下要求:
- 操作系统:macOS、Linux,或 Windows with WSL2
- Python:3.11 或更高版本
- Git:任意版本
- AI 助手:支持 Claude Code、GitHub Copilot、Gemini CLI 等
2.2 安装 Spec Kit CLI
Spec Kit 基于 Python 构建,推荐使用 uv 包管理器进行安装:
# 安装 uv(如果尚未安装)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 安装 specify-cli
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
安装完成后,你可以通过以下命令验证是否成功:
specify --version
2.3 初始化 Go 项目
我们将在实战中构建一个 Go 语言的二维码生成 API 服务。首先创建项目目录并初始化:
# 创建项目目录
mkdir go-qrcode-api
cd go-qrcode-api
# 初始化 Go 模块
go mod init github.com/yourusername/go-qrcode-api
# 初始化 Spec Kit 项目
specify init . --ai claude
# 可根据实际情况选择 claude/copilot/gemini
初始化完成后,项目目录中会生成 .specify 文件夹,包含以下结构:
.specify/
├── memory/ # 存储项目级原则和规范
│ └── constitution.md # 项目章程(核心规范)
├── scripts/ # Spec Kit 的调用脚本
├── templates/ # 各阶段的模板文件
└── ...
三、Go 项目实战:构建二维码生成 API
接下来,我们将通过完整的四阶段流程,开发一个高性能的二维码生成 API 服务。这个服务将提供以下功能:
- 支持生成自定义尺寸、颜色的二维码
- 支持嵌入 Logo 图片
- 提供 RESTful API 接口
- 包含完整的单元测试
3.1 第一阶段:建立项目章程(/constitution)
在开始任何功能开发前,我们首先需要定义项目的基本原则和技术约束。Spec Kit 通过 /constitution 命令来实现这一点。
在 AI 助手(如 Claude Code 或 GitHub Copilot)中执行:
/constitution
这是一个 Go 语言开发的二维码生成 API 服务。技术栈要求:使用 Go 1.22+、标准库 net/http、go-qrcode 库生成二维码、zerolog 日志、testify 测试框架。项目结构采用整洁架构分层:handler、service、model。所有 API 需返回标准 JSON 格式,错误处理统一使用 HTTP 状态码 + 错误信息。必须包含单元测试,测试覆盖率不低于 80%。代码需通过 golangci-lint 检查。
AI 会根据这个指令生成详细的项目章程,保存在 .specify/memory/constitution.md 中。这个章程将成为后续所有决策的"宪法",确保生成的代码始终符合项目规范。
章程的核心内容示例:
# Go QR Code API 项目章程
## 技术栈标准
- **语言版本**:Go 1.22 或更高
- **Web 框架**:标准库 net/http(无第三方 Web 框架)
- **二维码生成**:github.com/skip2/go-qrcode
- **日志**:github.com/rs/zerolog
- **测试**:github.com/stretchr/testify
## 架构原则
- **整洁架构**:项目分为 handler(接口层)、service(业务层)、model(数据层)
- **依赖方向**:外层依赖内层,内层不感知外层
## 代码质量
- **测试覆盖率**:核心逻辑不低于 80%
- **代码规范**:通过 golangci-lint 检查(启用全部默认 linters)
- **错误处理**:所有 API 返回 `{"code": xxx, "message": "xxx"}` 格式
3.2 第二阶段:定义功能需求(/specify)
现在,我们开始定义第一个功能——二维码生成接口。使用 /specify 命令描述"做什么":
/specify
开发一个二维码生成 API 接口,支持以下功能:
1. POST /api/qrcode/generate 接收 JSON 请求,返回二维码图片(PNG 格式)
2. 请求参数支持:content(二维码内容,必填)、size(图片尺寸,默认 256)、color(前景色,默认#000000)、bgColor(背景色,默认#ffffff)
3. 参数验证:content 不能为空,size 在 100-1000 之间
4. 错误时返回 JSON 格式的错误信息
5. 成功时返回 image/png 格式的图片
AI 会生成详细的功能规格说明书,保存在 specs/[分支名]/spec.md 中。这个文件包含:
- 用户故事:从用户视角描述使用场景
- 功能需求列表:每条需求都有唯一编号(FR-001、FR-002 等)
- 验收标准:如何验证功能是否正确实现
- 待澄清项:标记为
[NEEDS CLARIFICATION]的模糊点
同时,Spec Kit 会自动创建一个 Git 分支,分支名格式为 [序号]-[功能简短描述],确保每个功能在独立的上下文中开发。
3.3 第三阶段:澄清需求边界(/clarify)
AI 在生成规格时,可能会发现一些需要明确的边界条件。这时会触发 /clarify 交互:
AI 助手: 我注意到有几个需要澄清的问题:
问题 1:二维码内容的长度限制? 二维码能存储的数据量有限,是否需要设置最大长度限制?
问题 2:Logo 嵌入的支持? 需求中没有提到 Logo 嵌入,后续是否需要这个功能?
问题 3:输出格式除了 PNG,是否需要支持 SVG 或其他格式?
你可以通过交互式对话来澄清这些边界条件:
> /clarify
内容长度限制在 2000 字符以内。Logo 嵌入作为 v2 版本,暂时不支持。输出格式仅支持 PNG 即可。
clarify 过程会被完整记录,确保所有决策都有据可查。
3.4 第四阶段:制定技术方案(/plan)
有了清晰的"做什么",接下来通过 /plan 定义"怎么做"。这个阶段 AI 会进行技术调研、架构设计和接口定义。
执行命令:
/plan
使用 go-qrcode 库实现二维码生成。handler 层负责参数解析和验证,service 层负责二维码生成逻辑。需要定义清晰的 API 契约(OpenAPI 规范)。采用测试驱动开发,先写测试再实现。
AI 会生成详细的技术方案,包括:
- 技术选型分析:为什么选择 go-qrcode 及其替代方案对比
- API 契约:完整的 OpenAPI 规范(YAML/JSON)
- 数据模型:请求/响应的 Go 结构体定义
- 模块划分:handler、service 的职责边界
- 测试策略:单元测试、集成测试的设计
生成的 API 契约示例(specs/[分支名]/openapi.yaml):
openapi: 3.0.0
info:
title: QR Code Generation API
version: 1.0.0
paths:
/api/qrcode/generate:
post:
summary: Generate QR code
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- content
properties:
content:
type: string
maxLength: 2000
size:
type: integer
default: 256
minimum: 100
maximum: 1000
color:
type: string
pattern: '^#[0-9A-Fa-f]{6}$'
default: '#000000'
bgColor:
type: string
pattern: '^#[0-9A-Fa-f]{6}$'
default: '#ffffff'
responses:
'200':
description: QR code image
content:
image/png: {}
'400':
description: Invalid parameters
content:
application/json:
schema:
type: object
properties:
code:
type: integer
message:
type: string
3.5 第五阶段:任务分解(/tasks)
有了完整的技术方案,接下来通过 /tasks 命令将工作分解为可执行的任务单元。
执行:
/tasks
AI 会基于前面的 spec.md、plan.md 和 constitution.md,生成详细的任务清单(tasks.md):
# 任务清单:二维码生成 API
## Phase 1: 项目初始化与环境配置
- [ ] 创建 go.mod 并添加依赖(go-qrcode, zerolog, testify)
- [ ] 配置 golangci-lint
- [ ] 创建项目目录结构(handler/service/model)
## Phase 2: 数据模型与 API 契约
- [ ] 定义请求结构体(QRCodeRequest)
- [ ] 定义错误响应结构体(ErrorResponse)
- [ ] 实现参数验证逻辑
## Phase 3: Service 层实现
- [ ] 实现 QRCodeService 接口
- [ ] 实现二维码生成核心逻辑
- [ ] 添加错误处理
## Phase 4: Handler 层实现
- [ ] 实现 HTTP 路由注册
- [ ] 实现请求解析
- [ ] 实现响应写入
## Phase 5: 单元测试
- [ ] 编写 Service 层测试(覆盖正常/异常场景)
- [ ] 编写 Handler 层测试(使用 net/http/httptest)
- [ ] 确保测试覆盖率达标
## Phase 6: 集成与验证
- [ ] 启动 HTTP 服务器
- [ ] 手动测试 API
- [ ] 性能基准测试
每个任务都设计为小而独立,便于 AI 逐步实现,也便于开发者 review。
3.6 第六阶段:代码实现(/implement)
最后,执行 /implement 命令,让 AI 基于前面的所有规范生成代码。
/implement
AI 会按照任务清单的顺序,逐个任务生成代码。在执行过程中,它会:
- 遵循测试驱动开发:先编写测试(预期失败),再实现功能(让测试通过)
- 进行自我验证:运行测试、执行 lint 检查
- 遇到问题时暂停:插入
[NEEDS CLARIFICATION]标记并询问 - 请求权限:执行需要管理员权限的命令时会请求确认
实现完成后,生成的代码结构如下:
.
├── go.mod
├── go.sum
├── main.go # 入口文件
├── handler/
│ └── qrcode_handler.go # HTTP 处理层
├── service/
│ └── qrcode_service.go # 业务逻辑层
├── model/
│ └── qrcode.go # 数据模型
└── tests/
├── handler_test.go # handler 层测试
└── service_test.go # service 层测试
3.7 查看成果
让我们看看 AI 根据规范生成的 Go 代码质量如何。
model/qrcode.go(数据模型与验证):
package model
import (
"encoding/hex"
"errors"
"regexp"
)
type QRCodeRequest struct {
Content string `json:"content"`
Size int `json:"size"`
Color string `json:"color"`
BgColor string `json:"bgColor"`
}
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (r *QRCodeRequest) Validate() error {
if r.Content == "" {
return errors.New("content cannot be empty")
}
if len(r.Content) > 2000 {
return errors.New("content length exceeds 2000 characters")
}
if r.Size < 100 || r.Size > 1000 {
r.Size = 256 // 默认值
}
if r.Color == "" {
r.Color = "#000000"
}
if !isValidHexColor(r.Color) {
return errors.New("invalid color format")
}
if r.BgColor == "" {
r.BgColor = "#FFFFFF"
}
if !isValidHexColor(r.BgColor) {
return errors.New("invalid bgColor format")
}
return nil
}
func isValidHexColor(color string) bool {
match, _ := regexp.MatchString("^#[0-9A-Fa-f]{6}$", color)
return match
}
service/qrcode_service.go(核心业务逻辑):
package service
import (
"image/color"
qrcode "github.com/skip2/go-qrcode"
)
type QRCodeService interface {
Generate(content string, size int, fgColor, bgColor string) ([]byte, error)
}
type qrCodeServiceImpl struct{}
func NewQRCodeService() QRCodeService {
return &qrCodeServiceImpl{}
}
func (s *qrCodeServiceImpl) Generate(content string, size int, fgColor, bgColor string) ([]byte, error) {
// 解析颜色
fg, err := parseHexColor(fgColor)
if err != nil {
return nil, err
}
bg, err := parseHexColor(bgColor)
if err != nil {
return nil, err
}
// 生成二维码
qr, err := qrcode.New(content, qrcode.Medium)
if err != nil {
return nil, err
}
// 设置颜色
qr.ForegroundColor = fg
qr.BackgroundColor = bg
// 生成 PNG 字节数组
return qr.PNG(size)
}
func parseHexColor(hexStr string) (color.RGBA, error) {
// 去掉#前缀
if len(hexStr) == 7 && hexStr[0] == '#' {
hexStr = hexStr[1:]
}
// 解析 RGB 值
// ... 实现略
}
handler/qrcode_handler.go(HTTP 处理层):
package handler
import (
"encoding/json"
"net/http"
"your-project/model"
"your-project/service"
"github.com/rs/zerolog/log"
)
type QRCodeHandler struct {
qrService service.QRCodeService
}
func NewQRCodeHandler(qrService service.QRCodeService) *QRCodeHandler {
return &QRCodeHandler{
qrService: qrService,
}
}
func (h *QRCodeHandler) Generate(w http.ResponseWriter, r *http.Request) {
// 只接受 POST
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// 解析请求
var req model.QRCodeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
h.respondError(w, http.StatusBadRequest, "Invalid request body")
return
}
// 参数验证
if err := req.Validate(); err != nil {
h.respondError(w, http.StatusBadRequest, err.Error())
return
}
// 调用 service 生成二维码
imgData, err := h.qrService.Generate(
req.Content, req.Size, req.Color, req.BgColor,
)
if err != nil {
log.Error().Err(err).Msg("Failed to generate QR code")
h.respondError(w, http.StatusInternalServerError, "Failed to generate QR code")
return
}
// 返回图片
w.Header().Set("Content-Type", "image/png")
w.WriteHeader(http.StatusOK)
w.Write(imgData)
}
func (h *QRCodeHandler) respondError(w http.ResponseWriter, code int, message string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
json.NewEncoder(w).Encode(model.ErrorResponse{
Code: code,
Message: message,
})
}
从代码可以看出,AI 严格遵循了项目章程的要求:
- ✅ 使用标准库 net/http,无第三方 Web 框架
- ✅ 整洁架构分层(handler/service/model)
- ✅ 统一的错误响应格式
- ✅ 参数验证逻辑完善
四、实战经验与避坑指南
4.1 优点与收获
通过本次 Go 项目实战,可以体会到 Spec Kit 带来的价值:
| 维度 | 改进 |
|---|---|
| 代码质量 | 生成的代码结构清晰,完全符合项目规范,测试覆盖率高 |
| 需求可追溯 | 每个功能都有完整的 spec 文档,可以追溯到最初的需求来源 |
| 技术选型可控 | 通过 constitution 锁定了技术栈,避免 AI 随意选择 |
| 团队协作 | 新成员通过阅读 spec 就能快速理解项目全貌 |
4.2 常见问题与解决方案
问题 1:AI 规划时间过长
- 现象:plan 阶段可能耗时 30 分钟以上,消耗大量 token
- 解决:将范围缩小到单个功能或特性,避免一次性规划整个系统
问题 2:过度工程化
- 现象:AI 倾向于设计复杂的架构,远超实际需求
- 解决:在 constitution 中明确要求"保持简单",并在 prompt 中加入"不要过度设计"
问题 3:生成中断
- 现象:implement 阶段可能因上下文窗口满而中断
- 解决:使用
/implement 继续执行命令从中断处恢复
问题 4:澄清不足
- 现象:某些边界条件未被澄清,导致实现偏离预期
- 解决:主动使用
/clarify命令,不要等 AI 提问
五、总结与展望
Spec Kit 代表了一种AI 辅助开发的新范式——从"让 AI 写代码"升级到"让 AI 遵循规范写代码"。它不是要取代开发者的创造力,而是为创造力提供更可靠的工程基础。
对于 Go 语言开发者来说,Spec Kit 特别契合 Go 的简洁、规范、工程化的哲学。通过本文的实战,我们看到了:
- 需求即资产:spec 成为可版本化、可复用的核心资产
- 技术无关性:同一套 spec 可以生成不同技术栈的实现
- 质量内建:从源头(规范)就开始保证代码质量
当然,Spec Kit 还处于早期阶段,它更适合作为新项目启动、新功能开发、遗留系统现代化的辅助工具。对于追求极致效率的开发者,可以尝试将 Spec Kit 用于特定功能的开发,而不是整个应用的重构。
正如 GitHub 所说:"当代码不再是开发的起点,而是需求的自然产物时,软件的本质究竟是代码的集合,还是解决问题的意图表达?"
也许,Spec Kit 正在帮我们找到答案。
附:常用命令速查表
| 命令 | 用途 | 执行时机 |
|---|---|---|
/speckit.constitution | 定义项目章程 | 项目初始化 |
/speckit.specify | 定义功能需求 | 每个功能开始 |
/speckit.clarify | 澄清需求边界 | specify 之后 |
/speckit.plan | 制定技术方案 | specify 之后 |
/speckit.tasks | 分解任务 | plan 之后 |
/speckit.implement | 生成代码 | tasks 之后 |
/speckit.analyze | 分析项目状态 | 任意时刻 |
