教程概述
系列目录:Superpowers 教程系列索引
writing-plans 是 Superpowers 的第二个核心技能。它的作用是将 brainstorming 产生的设计文档转化为可执行的实现计划。
你将学到
- ✅ writing-plans 的触发时机
- ✅ 原子化任务的特征
- ✅ 任务分解的最佳粒度
- ✅ 任务模板结构
- ✅ 从计划到执行的流程
为什么需要 writing-plans?
没有计划的问题
flowchart LR
A[设计文档] --> B[AI 开始实现]
B --> C[中途发现遗漏]
C --> D[返工]
D --> E[任务切换]
E --> F[上下文丢失]
F --> G[质量下降]
style B fill:#ffcccc
style C fill:#ffcccc
style F fill:#ffcccc
有计划的优势
flowchart TD
A[设计文档] --> B[writing-plans]
B --> C[原子任务清单]
C --> D[逐任务执行]
D --> E[任务完成检查]
E --> F[上下文保持]
F --> G[高质量交付]
style B fill:#e1f5ff
style C fill:#e1f5ff
style E fill:#e1f5ff
效果对比
| 指标 | 无计划 | 有计划 |
|---|---|---|
| 任务切换次数 | 10+ | 0-2 |
| 上下文丢失 | 频繁 | 罕见 |
| 遗漏功能 | 常见 | 罕见 |
| 平均任务时长 | 15-30 分钟 | 2-5 分钟 |
| 代码质量 | 不稳定 | 稳定 |
writing-plans 技能详解
触发时机
writing-plans 在以下场景自动触发:
- brainstorming 完成后 - 设计文档获得批准
- 多步骤任务 - 需要多个文件/组件的修改
- 复杂功能 - 涉及数据模型、API、前端等多个层面
核心原则
1. YAGNI (You Aren’t Gonna Need It)
✅ 只做当前需要的功能
❌ 不做"可能有用的"扩展
示例:
❌ "创建一个通用的 BaseComponent,预留各种扩展点"
✅ "创建一个 CommentComponent,只实现当前需要的功能"
2. 原子化任务
✅ 好任务:创建 tags 表迁移文件
❌ 坏任务:实现整个标签系统
原子任务特征:
- 2-5 分钟可以完成
- 有明确的完成标准
- 可以独立验证
- 不依赖其他任务(或依赖明确)
3. 完整代码而非伪代码
✅ 好计划:包含完整的代码示例
❌ 坏计划:"创建模型,添加字段"
示例:
✅ "创建 tags 表,包含以下字段:
- id: BIGINT PRIMARY KEY AUTO_INCREMENT
- name: VARCHAR(50) UNIQUE NOT NULL
- slug: VARCHAR(50) UNIQUE NOT NULL
- description: TEXT NULL
- created_at: TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
任务清单结构
标准任务模板
每个任务包含以下字段:
## Task 1: [任务名称]
**预估时间**: 3 分钟
**目标**: [一句话描述任务目标]
**文件路径**:
- `path/to/file1.ext` (新建/修改)
- `path/to/file2.ext` (新建/修改)
**实现步骤**:
1. [步骤 1 - 具体操作]
2. [步骤 2 - 具体操作]
3. [步骤 3 - 具体操作]
**代码示例**:
```language
[完整的代码示例,而非伪代码]
验证命令:
[可以运行来验证的命令]
验收标准:
- 文件创建成功
- 代码通过 lint
- 单元测试通过
- 功能手动验证通过
依赖任务: [Task 0 或 无]
### 完整计划示例
以下是为"标签系统"生成的完整计划:
```markdown
# 标签系统实现计划
**设计文档**: `.project/designs/feature-tag-system-2026-02-28.md`
**预估总时间**: 45 分钟
**任务数量**: 12
---
## Phase 1: 数据库迁移
### Task 1: 创建 tags 表迁移文件
**预估时间**: 2 分钟
**目标**: 创建 tags 表的数据库迁移脚本
**文件路径**:
- `database/migrations/20260228_create_tags_table.sql` (新建)
**实现内容**:
```sql
CREATE TABLE tags (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) UNIQUE NOT NULL COMMENT '标签名称',
slug VARCHAR(50) UNIQUE NOT NULL COMMENT 'URL 友好名称',
description TEXT NULL COMMENT '标签描述',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_slug (slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='标签表';
验证命令:
# 检查迁移文件是否存在
ls -la database/migrations/20260228_create_tags_table.sql
# 语法检查(如果有 SQL lint 工具)
sqlint database/migrations/20260228_create_tags_table.sql
验收标准:
- 迁移文件创建成功
- SQL 语法正确
- 包含所有必需字段
依赖任务: 无
Task 2: 创建 article_tags 关联表迁移
预估时间: 2 分钟
目标: 创建文章 - 标签多对多关联表
文件路径:
database/migrations/20260228_create_article_tags_table.sql(新建)
实现内容:
CREATE TABLE article_tags (
article_id BIGINT NOT NULL COMMENT '文章 ID',
tag_id BIGINT NOT NULL COMMENT '标签 ID',
PRIMARY KEY (article_id, tag_id),
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE,
INDEX idx_tag_id (tag_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章 - 标签关联表';
验证命令:
ls -la database/migrations/20260228_create_article_tags_table.sql
验收标准:
- 关联表结构正确
- 外键约束配置正确
- 索引配置合理
依赖任务: Task 1
Task 3: 运行数据库迁移
预估时间: 3 分钟
目标: 执行迁移脚本,创建实际表结构
文件路径:
- 无(执行操作)
实现步骤:
- 备份当前数据库
- 运行迁移脚本
- 验证表结构
验证命令:
# 备份数据库
mysqldump -u root -p blog_db > backup_$(date +%Y%m%d_%H%M%S).sql
# 运行迁移
mysql -u root -p blog_db < database/migrations/20260228_create_tags_table.sql
mysql -u root -p blog_db < database/migrations/20260228_create_article_tags_table.sql
# 验证表创建
mysql -u root -p blog_db -e "SHOW TABLES LIKE 'tags';"
mysql -u root -p blog_db -e "DESCRIBE tags;"
mysql -u root -p blog_db -e "DESCRIBE article_tags;"
验收标准:
- 迁移无错误
- tags 表创建成功
- article_tags 表创建成功
- 外键约束生效
依赖任务: Task 1, Task 2
Phase 2: 后端模型
Task 4: 创建 Tag 模型类
预估时间: 3 分钟
目标: 创建 Tag 的 ORM 模型
文件路径:
app/Models/Tag.php(新建)
实现内容:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Tag extends Model
{
protected $fillable = [
'name',
'slug',
'description',
];
/**
* 获取所有关联的文章
*/
public function articles(): BelongsToMany
{
return $this->belongsToMany(Article::class, 'article_tags')
->withTimestamps();
}
/**
* 生成 URL 友好的 slug
*/
public static function createWithSlug(string $name): self
{
$slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $name)));
return self::create([
'name' => $name,
'slug' => $slug,
]);
}
}
验证命令:
# 语法检查
php -l app/Models/Tag.php
# 运行模型测试
php artisan test --filter=TagTest
验收标准:
- 模型类创建成功
- fillable 字段正确
- 关联关系定义正确
- 辅助方法实现正确
依赖任务: Task 3
Task 5: 创建 TagRepository
预估时间: 4 分钟
目标: 实现标签数据访问层
文件路径:
app/Repositories/TagRepository.php(新建)
实现内容:
<?php
namespace App\Repositories;
use App\Models\Tag;
use Illuminate\Database\Eloquent\Collection;
class TagRepository
{
public function __construct(
private Tag $model
) {}
/**
* 获取所有标签
*/
public function getAll(): Collection
{
return $this->model->withCount('articles')->get();
}
/**
* 通过 slug 查找标签
*/
public function findBySlug(string $slug): ?Tag
{
return $this->model->where('slug', $slug)->first();
}
/**
* 创建或获取标签
*/
public function findOrCreate(string $name): Tag
{
$tag = $this->model->where('name', $name)->first();
if (!$tag) {
$tag = Tag::createWithSlug($name);
}
return $tag;
}
/**
* 同步文章的标签
*/
public function syncTags(int $articleId, array $tagNames): void
{
$tagIds = collect($tagNames)
->map(fn($name) => $this->findOrCreate($name)->id)
->all();
$this->model->newModelQuery()
->find($tagIds)
->first()
?->articles()
->sync($articleId);
}
}
验证命令:
php -l app/Repositories/TagRepository.php
验收标准:
- Repository 方法完整
- 类型提示正确
- 包含文档注释
依赖任务: Task 4
[继续 Task 6-12…]
## 任务分解策略
### 按层次分解
功能实现 ├── 数据库层 │ ├── 创建迁移文件 │ └── 执行迁移 ├── 模型层 │ ├── 创建模型类 │ └── 创建 Repository ├── 服务层 │ ├── 创建 Service │ └── 实现业务逻辑 ├── API 层 │ ├── 创建 Controller │ └── 定义路由 └── 前端层 ├── 创建组件 └── 编写样式
### 按 CRUD 分解
资源管理 ├── Create │ ├── 创建表单组件 │ ├── 实现验证逻辑 │ └── 编写创建 API ├── Read │ ├── 创建列表组件 │ ├── 创建详情组件 │ └── 编写查询 API ├── Update │ ├── 创建编辑表单 │ ├── 实现更新逻辑 │ └── 编写更新 API └── Delete ├── 实现删除确认 ├── 编写删除 API └── 处理级联删除
### 按测试分解
测试驱动 ├── 单元测试 │ ├── 模型测试 │ ├── Repository 测试 │ └── Service 测试 ├── 集成测试 │ ├── API 测试 │ └── 数据库测试 └── E2E 测试 ├── 用户流程测试 └── 性能测试
## 最佳实践
### 1. 任务粒度控制
✅ 好:创建单个函数/类/组件 ❌ 坏:实现整个模块
判断标准:
- 能在 2-5 分钟内完成吗?
- 能写出具体的验证命令吗?
- 有明确的完成标准吗?
### 2. 依赖关系明确
```markdown
**依赖任务**: Task 1, Task 2
执行顺序:
Task 1 → Task 2 → Task 3
↓
Task 4 (依赖 Task 2)
3. 验证命令具体
✅ 好:php artisan test --filter=TagTest
❌ 坏:运行测试
✅ 好:curl http://localhost:8000/api/tags | jq
❌ 坏:测试 API
4. 代码示例完整
✅ 好:完整的函数/类实现
❌ 坏:伪代码或注释
原因:
- AI 可以直接实现
- 用户可以看到预期结果
- 减少理解偏差
常见问题
Q1: 任务分解太细怎么办?
答:可以合并相关任务:
原计划:
Task 1: 创建 Tag 模型
Task 2: 创建 TagRequest 验证类
Task 3: 创建 TagResource 资源类
合并后:
Task 1: 创建 Tag 相关类(模型、验证、资源)
Q2: 任务执行中发现遗漏怎么办?
答:暂停当前任务,更新计划:
1. 标记当前任务为"阻塞"
2. 添加新的遗漏任务
3. 重新排序
4. 继续执行
Q3: 计划太长,看不完
答:要求 AI 分阶段展示:
请先展示 Phase 1 的任务,完成后再展示后续阶段。
计划保存位置
.project/plans/
└── plan-<feature>-<date>.md
例如:
.project/plans/
└── plan-tag-system-2026-02-28.md
与其他技能协作
writing-plans → subagent-driven-development
计划完成
↓
自动触发 subagent-driven-development
↓
分派任务给子代理执行
writing-plans → test-driven-development
每个任务开始
↓
自动触发 test-driven-development
↓
先写测试再实现
小结
writing-plans 的核心价值:
- 可执行性 - 计划不是文档,是操作手册
- 原子化 - 2-5 分钟的小任务
- 完整性 - 包含代码示例和验证命令
- 可追溯 - 每个任务有明确验收标准
关键要点
- ✅ YAGNI 原则 - 不做多余的事
- ✅ 原子任务 - 小步快跑
- ✅ 完整代码 - 不是伪代码
- ✅ 明确验证 - 有具体命令
系列导航: