来了一个需求,你打开 Cursor:“帮我做个用户认证系统”。AI 秒回一堆代码,跑起来了,提交,上线。
几个月以后,功能越来越多,bug 也越来越多。你让 AI 反复修复,bug 反而越来越多。打开代码一看:逻辑散落在五个文件里,密码验证写了两遍,错误处理各有各的风格。
这就是”vibe-coding”的代价:一时爽,维护火葬场。
AI:我的锅?
你说”做个认证”,AI它会基于训练数据里最常见的模式给你代码。AI学习了好多好的代码,也学习了太多的垃圾代码。它的生存有很多不确定性,可能用 JWT,可能用 Session,可能压根不管密码。 是因为你没说清楚。
我的观点是应该由你来驱动AI,而不是AI来驱动你, 为了解决这些GitHub、AWS、Anthropic 等公司都给我给出了同一个思路:Spec-driven Development (SDD)。 核心逻辑很简单:与其让 AI 猜,不如先写份”规范”(Spec)。
规范不是传统的需求文档,而是可执行的蓝图——清晰到 AI 不需要猜测,就能生成符合预期的代码。从”代码即真相”转向”意图即真相”。
代表方案:
- Kiro(AWS):三阶段工作流(Requirements → Design → Tasks),适合大型项目
- Spec Kit(GitHub):开源灵活,四阶段流程(Specify → Plan → Tasks → Implement)
写规范到底在写什么
一份好的规范长这样:你告诉 AI,这个认证系统要用 bcrypt,JWT 的访问令牌 15 分钟过期、刷新令牌 7 天过期,用 Joi 验证邮箱格式和密码长度(至少 8 位),单 IP 15 分钟内只能尝试登录 5 次,错误要返回正确的 HTTP 状态码,日志里不能出现密码明文。然后给几个示例请求和响应的 JSON。
AI 拿到这份规范,不需要猜”安全”是什么意思,不需要自己决定用哪种加密方式。它只需要实现。
Google 在 2024 年的一次内部迁移中,让 AI 自动处理了 80% 的代码修改。Airbnb 用 6 周时间迁移了 3500 个测试文件,原本预计要 1.5 年。关键是什么?清晰的规范。
用Spec Kit 举一个例子
以 GitHub Spec Kit 为例,它把整个过程拆成四步:
1. Specify 阶段:写产品需求,不谈技术
## Feature: User Authentication
### User Story
As a user, I want to securely register and login,
so that I can access personalized features.
### Success Criteria
- User can register with email/password
- Password must be at least 8 characters
- Email must be unique
- Login returns JWT token
- Failed login after 5 attempts locks account for 15 minutes2. Plan 阶段:技术方案设计
## Technical Approach
### Stack
- bcrypt for password hashing (12 salt rounds)
- JWT with RS256 algorithm
- Access token: 15min, Refresh token: 7d
- Joi for input validation
- Redis for rate limiting
### API Endpoints
POST /auth/register
POST /auth/login
POST /auth/refresh3. Tasks 阶段:拆分任务
AI 会生成类似这样的任务列表:
- [ ] Create User model with email/password fields
- [ ] Implement bcrypt password hashing
- [ ] Create POST /auth/register endpoint
- [ ] Add Joi validation for email and password
- [ ] Implement JWT token generation
- [ ] Add rate limiting with Redis
- [ ] Create POST /auth/login endpoint
- [ ] Add error handling and logging4. Implement 阶段:逐个实现
用命令行工具或 AI 逐个实现任务:
# 使用 Spec Kit CLI
spec-kit implement task-1
# 或者用 AI prompt
# "请根据 task-1 的规范实现用户注册功能"每个 Spec 文件都是 Markdown,可以用普通编辑器写,也可以配合 AI 生成。关键是结构化:清晰的分阶段、明确的验收标准、具体的技术细节。
但现实没那么美好:并非所有场景都需要规范
我们找一个同事,用一个已有的项目进行了一个用SDD 和传统的AI辅助的对比测试。让它在一个已有项目里加个新功能——一个 3-5 个故事点的中型需求。结果 AI 生成了一堆 Markdown 文件让她 review:“冗长、重复,有些还包含代码片段。老实说,我宁愿直接 review 代码。”
最后没完成实现,因为”在同样的时间里,我用’普通’的 AI 辅助写代码可能早就做完了,而且会更有控制感”。
问题出在哪?规范本身也需要成本。写一个简单函数的规范要 15-30 分钟,一个完整的 API 端点要 1-2 小时。如果 AI 最后还是会犯错、需要你反复调试,这个时间就不一定值得。
另一个陷阱是”虚假的控制感”。即使你写了详尽的规范、设置了检查清单,AI 还是会忽略一些指令。她发现,AI 做了一堆研究、记录了现有类的结构,但最后生成代码时把这些类重新写了一遍,制造了重复。
真正的问题:上下文过载
试用了几个 SDD 工具后,我发现四个痛点:
1. 文档太多:Spec Kit 生成的 Markdown 文件分散在多个目录,光是 review 这些文档就要花不少时间
2. 额外工具:Kiro 要装 AWS CLI,Spec Kit 要配置特定的工作流,学习成本不低
3. 学习曲线:每个工具都有自己的流程(三阶段、四阶段),要记住哪个阶段该做什么
4. 上下文失控:当规范文件太多,AI 反而会分散注意力。它可能记住了 Specify 阶段的需求,但忘了 Plan 阶段的技术约束;或者在实现时重新发明了一遍已有的类
核心矛盾是:SDD 想通过更多文档来控制 AI,但文档本身成了新的负担。
渐进式披露:少即是多
更好的思路是:不要一次性把所有信息塞给 AI,而是按需提供。
我的方案是 Plan Mode + 渐进式披露 + Subagent 隔离,核心是控制上下文边界。
完整工作流
步骤 1:Plan Mode 生成设计
// 在 Plan Mode 中描述需求
实现用户认证系统:注册、登录、JWT token
前端用 React,后端用 Express
// Plan Mode 输出(不写代码)
前端任务:
- LoginForm 组件(表单验证)
- AuthContext(token 管理)
- API 调用封装
后端任务:
- POST /auth/register(bcrypt 12 rounds)
- POST /auth/login(JWT: access 15min, refresh 7d)
- Rate limiting 中间件(Redis: 5次/15min)步骤 2:用 Subagent 隔离上下文
关键是前后端分离,让不同 subagent 的交集最小:
// 启动两个独立的 subagent
@subagent-frontend
根据 plan 实现前端认证功能(LoginForm + AuthContext)
@subagent-backend
根据 plan 实现后端认证接口(/auth/register + /auth/login + rate limiting)前端 subagent 只看到前端代码和 API 规范,后端 subagent 只看到后端代码和数据库 schema。它们不会互相干扰,生成的代码冲突少,合并回主 agent 时更安全。
步骤 3:Skill 按需注入 Context
关键来了:不要在 Plan 阶段把所有规范都写进去,而是用 Skill 在 Subagent 需要时才加载。
# .cursor/skills/api-standard/SKILL.md
# 后端 subagent 创建 API 时自动触发
API 规范:
- 错误码:400 (参数错误) / 401 (未授权) / 429 (限流) / 500 (服务器错误)
- 响应格式:{ data, error, message }
- 认证头:Authorization: Bearer <token>
- 日志:不记录密码、token 等敏感信息# .cursor/skills/react-patterns/SKILL.md
# 前端 subagent 创建组件时自动触发
React 规范:
- 表单用 Formik + Yup 验证
- 状态管理用 Context API
- API 调用统一封装在 services/ 目录
- 错误提示用 toast 组件这样,后端 subagent 在实现 /auth/register 时,自动读取 api-standard skill 获得错误码规范;前端 subagent 在写 LoginForm 时,自动读取 react-patterns skill 获得表单验证方案。按需加载,不提前,不过载。
步骤 4:Command 减少重复输入
每次创建端点都要说”用 async/await、加验证、统一错误处理”太累了:
# .cursor/commands/add-auth-endpoint.md
创建认证端点:
- bcrypt 12 rounds
- JWT access 15min
- Joi 验证 email/password
- 返回标准错误码(参考 api-standard skill)在 subagent 中调用 command,直接应用模板,不用每次重复提示词。
为什么这样更好
上下文隔离:前端 subagent 不会看到后端的数据库逻辑,后端 subagent 不会尝试修改 React 组件。各管各的,冲突自然少。
渐进式披露:Plan 阶段只给设计框架,不写具体规范。Skill 在 subagent 需要时才注入(后端需要 API 规范时加载,前端需要 React 模式时加载),Command 提供可复用模板。AI 的注意力始终聚焦在当前任务。
合并友好:前端改 src/components/,后端改 routes/ 和 models/,文件路径不重叠,合并回主 agent 时几乎零冲突。
对比:
| 维度 | SDD 工具 | Plan + Subagent + Skill + Command |
|---|---|---|
| 文档数量 | 多个 Markdown 文件 | 只有 plan,无需维护 spec |
| 上下文控制 | 一次性加载所有规范 | Subagent 隔离 + Skill 按需注入 |
| 代码冲突 | AI 可能混淆不同模块 | 前后端分离,交集最小 |
| 学习成本 | 学习特定工作流 | 熟悉的对话模式 |
| 适用场景 | 大型项目、团队协作 | 个人开发、中小需求 |
Subagent 隔离是关键。前后端分开执行,不仅降低了单个 agent 的上下文复杂度,还让代码上下文合并变得简单。这种方式保留了”先思考再实现”的价值,但避免了文档过载。
真正的转变
SDD 提出了一个重要问题:如何更好地与 AI 协作?
从 vibe-coding 到 spec-driven,本质上是在改变 AI 的定位:不再是”你说一句我猜一句”的对话伙伴,而是”你给蓝图我负责实现”的执行者。
但蓝图不一定要是多阶段流程、几十个 Markdown 文件。渐进式披露 + Subagent 隔离可能是更好的答案:Plan Mode 生成设计,Subagent 按职责分离(前端/后端),Skill 按需注入规范,Command 提供模板。既保留了”先思考”的价值,又避免了上下文过载和代码冲突。
关键是找到适合自己的平衡点:在清晰表达意图和快速迭代之间,在流程规范和灵活度之间。