spec-kit 架构哲学与实践指南
目标:深入但不晦涩地理解 spec-kit 的设计哲学、核心抽象与工程实践方式,并通过代码示例说明如何在真实项目中落地。
一、spec-kit 是什么?
spec-kit 本质上是一套 "以规范(Spec)为中心" 的工程方法论 + 工具集合。
它解决的不是"怎么写代码",而是:
在引入大模型(LLM)参与研发后,如何让需求、约束、代码、评审、演进保持一致性与可控性。
可以把 spec-kit 理解为:
- 不是框架(Framework)
- 不是脚手架(Scaffold)
- 而是 工程认知结构(Engineering Mental Model)
二、spec-kit 的核心架构哲学
1. Spec First,而不是 Code First
传统研发流程:
需求文档 → 代码实现 → 测试 → 返工
spec-kit 的流程:
Spec(可执行约束) → 生成 / 修改代码 → 验证 Spec
Spec 是唯一的真相来源(Single Source of Truth)。
Spec 不只是说明性文档,而是:
- 可以被 LLM 理解
- 可以被工程流程引用
- 可以作为代码生成与修改的边界
2. 把"隐性工程经验"显式化
在真实项目中,大量关键规则是:
- 只存在于资深工程师脑中
- 写在 PR 评论里
- 或者靠"踩坑"传承
spec-kit 的目标:
把这些经验固化为 Spec
例如:
- 禁止数据库迁移
- CI/CD 需要人工确认
- 生产配置不允许修改
这些都不应只是"口头约定"。
3. 约束优先,而不是能力优先
大模型的风险在于:
- 能力很强
- 但边界模糊
spec-kit 的基本假设:
如果不先定义清楚不能做什么,模型一定会越界。
因此 spec-kit 强调:
- 明确禁止项(Forbidden)
- 明确需要人工确认项(Manual Approval)
- 明确允许的变更范围(Allowed Scope)
4. Spec 是"可组合的模块"
Spec 并不是一大坨文档,而是:
- 可拆分
- 可复用
- 可组合
典型的 Spec 结构:
/spec
├── architecture.md
├── constraints.md
├── coding-style.md
├── security.md
└── runtime.md
不同项目可以复用同一套 Spec 子集。
三、spec-kit 的核心组成
1. Constitution / Project Spec
这是 spec-kit 的"宪法层"。
特点:
- 项目级别
- 长期稳定
- 极少频繁修改
示例(简化版):
markdown
# Project Constitution
## Runtime
- Python 3.10
- Conda environment
## Forbidden
- 禁止数据库 schema 迁移
- 禁止修改生产配置
## Manual Approval Required
- 新增第三方依赖
- CI/CD 配置修改
2. Task Spec(任务级规范)
用于约束一次具体改动。
示例:
markdown
# Task Spec: 新增翻译接口
## Goal
- 增加 `/translate` HTTP API
## Constraints
- 不得修改现有接口签名
- 不得引入新依赖
## Acceptance Criteria
- 单测覆盖率 ≥ 80%
- P95 延迟 < 500ms
3. Code Style / Engineering Spec
用于统一代码风格与工程实践。
markdown
## Python Code Style
- 必须使用 type hints
- 公共函数必须有 docstring
- 禁止在函数中直接 print
四、spec-kit 的工作流(工程视角)
标准工作流
1. 编写 / 更新 Spec
2. 让 LLM 基于 Spec 生成或修改代码
3. 人类 Review 是否符合 Spec
4. 代码 & Spec 同步演进
关键点:
❌ 不允许只改代码不改 Spec
五、Spec 驱动代码的示例
示例 1:受 Spec 约束的函数实现
Spec:
markdown
## Function: translate_text
Constraints:
- 不得进行网络重试
- 超时必须抛出异常
代码实现:
python
from typing import Dict
import requests
def translate_text(text: str, target_lang: str) -> Dict[str, str]:
"""
Translate text to target language.
Raises:
TimeoutError: if request times out
"""
try:
resp = requests.post(
"http://translator/api",
json={"text": text, "lang": target_lang},
timeout=2.0,
)
resp.raise_for_status()
return resp.json()
except requests.Timeout:
# Spec 明确要求抛异常,而不是重试
raise TimeoutError("Translation request timed out")
示例 2:Spec 约束依赖管理
Spec:
markdown
## Dependencies
- 禁止自动新增依赖
- 新依赖必须人工确认
工程实践:
text
# requirements.txt
# ⚠️ 修改前必须人工确认
requests==2.32.3
LLM 即使"知道"更好的库,也不能越过 Spec。
六、spec-kit 与传统工程方式的本质差异
| 维度 | 传统工程 | spec-kit |
|---|---|---|
| 规范位置 | 文档/口头 | 工程核心 |
| 约束 | 事后 Review | 事前定义 |
| LLM 使用 | 写代码 | 遵守规范的协作者 |
| 风险控制 | 人 | Spec + 人 |
七、什么时候 不适合 用 spec-kit
spec-kit 并非银弹。
不适合场景:
- 一次性脚本
- 强探索性原型(Spec 尚不稳定)
- 极小团队、极短生命周期项目
适合场景:
- 中大型工程
- 多人协作
- 高风险(生产 / 安全 / 成本)项目
八、一句话总结
spec-kit 的本质不是"让 AI 更聪明",而是"让工程边界更清晰"。
当 Spec 足够清晰:
- 人和模型都不容易犯错
- 工程可以稳定演进
- 复杂度被锁在"规则层",而不是"人脑里"
如果你愿意,下一步我可以帮你:
- 把你当前项目的约束整理成一套完整 spec-kit
- 给出一份「适配 Claude / GPT 的 spec 模板」
- 或结合你现有的 Python / LLM 项目做实战拆解