Refactor easysdd-feature and writing-to-explain skills for clarity and structure

- Updated easysdd-feature documentation to enhance descriptions, clarify workflow stages, and improve directory organization.
- Added new guidelines for routing user actions within the easysdd-feature skill.
- Revised writing-to-explain skill to emphasize teaching over commanding, improving guidance for AI-generated content.
- Introduced a new document, what-is-skills.md, to explain the purpose and structure of skills in the Claude Code environment.
This commit is contained in:
liuzhengdong
2026-04-15 15:36:10 +08:00
parent c4c0cd6531
commit 5e965d27a4
8 changed files with 753 additions and 480 deletions
+135 -115
View File
@@ -1,216 +1,236 @@
---
name: easysdd-feature-acceptance
description: Feature 工作流阶段三:验收闭环。确认实现是否符合方案 doc 各层约束,并把 feature 归并到整体架构文档。触发场景:"功能写完了验收一下"、"做最后检查"、"准备 merge"、"出验收报告"。前置依赖 easysdd-feature-implement。
description: feature 流程的阶段 3——做完整验收闭环。两件事一是逐层对照 design.md 核对实现有没有走样,发现偏差就当场修不是写在报告里"记一下";二是把这个 feature 归并到项目的整体架构文档里。最后产出一份 acceptance.md 作为整套流程的闭环凭证。前置依赖 easysdd-feature-implement 已完成。触发场景:用户说"功能写完了验收一下"、"做最后检查"、"准备 merge"、"出验收报告"。
---
# easysdd-feature-acceptance
## 涉及的路径
到这一步代码已经写完了,但流程没结束。这一阶段做两件事,缺一不可:
> 共享路径与命名约定以根技能 `easysdd` 第二节为准。本节只补充本阶段特有信息。
1. **核对实现有没有偏离方案**——逐层对照 design.md 的四个节,发现偏差当场修,**不是在报告里"记一下"**就过去
2. **把 feature 归并到整体架构**——对照方案 doc 第 4 节,实际去更新架构中心目录下的相关 doc
## 你的职责
为什么这两件事都重要?只做第一件,新功能加进去了但项目级架构 doc 还说着老结构,下一个 feature 的设计阶段读到的就是过期信息。只做第二件,可能把"实现已经偏离方案"的事实掩埋——架构 doc 写得很漂亮,代码却不是那么回事。
本阶段做两件事,缺一不可:
验收报告是工作流的闭环凭证。**没产出报告 = 工作流未完成**。这条不是仪式——后人查"上次这个功能到底验收时确认了哪些行为",没有报告就只能去翻 git diff 重新推断。
1. **核对实现是否符合方案 doc**——逐层对照四个节,发现偏差就停下来修正,不是在报告里"记一下"
2. **把 feature 归并到整体架构**——对照方案 doc 第 4 节,实际更新架构中心目录下的相关 doc
> 共享路径与命名约定看根技能 `easysdd` 第二节。
验收报告是工作流的闭环凭证——没产出报告 = 工作流未完成。
---
## 启动检查
1. **代码已实现到位**。检查 git status / 最近提交,确认有本功能的代码改动。
2. **方案 doc 完整**。方案 doc 有 YAML frontmatter,且 `doc_type=feature-design``feature` 与当前目录一致、`status=approved``summary` 非空、`tags` 至少 2 个。
### 1. 代码确实实现到位了
**标准 design**: 四个节(0 术语约定、1 决策与约束、2 接口契约、3 实现提示)都有实质内容,第 4 节(与项目级架构文档的关系)已填写
git status / 最近提交里能看到本功能的代码改动。没看到就是 implement 还没收尾,先回去
**Fastforward design**: 四个节(0 需求摘要、1 设计方案、2 验收标准、3 推进步骤)都有实质内容。验收报告按以下映射对照方案:
### 2. 方案 doc 完整
| 验收报告节 | 标准 design 对照 | Fastforward design 对照 |
|---|---|---|
| 第 1 节(接口契约核对) | 方案第 2 节(接口契约) | 方案1(设计方案)的改动点 |
| 第 2 节(行为与决策核对) | 方案第 1 节(决策与约束) | 方案第 0 节(需求摘要) |
| 第 3 节(测试约束核对) | 方案第 3 节(测试设计) | 方案第 2 节(验收标准) |
| 第 4 节(术语一致性) | 方案第 0 节(术语约定) | 无术语表,检查代码命名一致性即可 |
| 第 5 节(架构归并) | 方案第 4 节(架构关系) | 通常无架构变更,确实无关写"本次 fastforward 无架构维度变更" |
3. **checklist.yaml 存在且 steps 已完成**`checklist.yaml` 的生命周期以 `easysdd/reference/shared-conventions.md` 为准;本阶段只核对并更新 `checks`。检查同 feature 目录下的 `checklist.yaml`:
- 文件存在,`feature` 字段与当前 feature 目录一致
- `steps` 所有条目 status 为 `done`(若有 `pending` 说明 implement 未完成,先退回)
- `checks` 列表非空,且所有条目 status 为 `pending`
- 不存在 → 停下来,告诉用户先走 easysdd-feature-design 生成
4. **读全部上下文**:
- 方案 doc 全文(重点是第 1 节需求摘要 / 明确不做、第 2 节接口契约、第 3 节测试设计)
- checklist.yaml
- 架构中心目录下方案 doc 第 4 节提到的所有 doc
- `AGENTS.md`
- 本次功能的代码改动(用 git log / git diff 看)
5. **断点恢复**。如果 `acceptance.md` 已存在且有部分已填写的节,检查哪些节已有实质内容(有 checklist 勾选或文字填写),从下一个未完成节继续。同步检查 `checklist.yaml``checks` 中已 `passed` 的项,跳过已验证完的检查。向用户汇报:"上次验收做到第 X 节,我从第 Y 节继续。"
文件头有 YAML frontmatter`doc_type=feature-design``feature` 跟当前目录一致、`status=approved``summary` 非空、`tags` ≥ 2。
**标准 design**四个节0 术语约定、1 决策与约束、2 接口契约、3 实现提示)都有实质内容,4(与项目级架构文档的关系)已填写。
**Fastforward design**四个节0 需求摘要、1 设计方案、2 验收标准、3 推进步骤)都有实质内容。验收报告按下面这个对照表去映射方案:
| 验收报告节 | 标准 design 对照 | Fastforward design 对照 |
|---|---|---|
| 1 接口契约核对 | 方案第 2 节(接口契约) | 方案第 1 节(设计方案)的改动点 |
| 2 行为与决策核对 | 方案第 1 节(决策与约束) | 方案第 0 节(需求摘要) |
| 3 测试约束核对 | 方案第 3 节(测试设计) | 方案第 2 节(验收标准) |
| 4 术语一致性 | 方案第 0 节(术语约定) | 无术语表,检查代码命名一致性即可 |
| 5 架构归并 | 方案第 4 节(架构关系) | 通常无架构变更,确实无关写"本次 fastforward 无架构维度变更" |
### 3. checklist.yaml 状态
`checklist.yaml` 的生命周期看 `easysdd/reference/shared-conventions.md`。本阶段只核对并更新 `checks` 一段:
- 文件存在,`feature` 字段跟当前 feature 目录一致
- `steps` 所有条目 status 为 `done`(有 `pending` 说明 implement 没完成,先退回)
- `checks` 列表非空,所有条目 status 为 `pending`
- 不存在 → 停下来,让用户先回 design 阶段生成
### 4. 把上下文读全
- 方案 doc 全文(重点是第 1 节需求摘要 / 明确不做、第 2 节接口契约、第 3 节测试设计)
- checklist.yaml
- 架构中心目录下方案 doc 第 4 节提到的所有 doc
- `AGENTS.md`
- 本次功能的代码改动git log / git diff
### 5. 断点恢复
如果 `acceptance.md` 已存在且有部分填好的节,看哪些节已有实质内容(有 checklist 勾选或文字填写),从下一个未完成节继续。同时检查 `checklist.yaml``checks` 中已 `passed` 的项,跳过已验证完的检查。汇报一句:"上次验收做到第 X 节,我从第 Y 节继续。"
---
## 验收报告模板
逐节填写,**不要跳节**。报告路径:验收报告(放入 feature 目录,与 design.md 聚合;目录位置见主技能 `easysdd` 第二节"目录安排")
逐节填写**跳节**。报告路径 feature 目录下,跟 design.md 聚合(具体位置看根技能 `easysdd` 第二节"目录安排"
```markdown
# {功能名称} 验收报告
> 阶段:阶段三(验证闭环)
> 验收日期:YYYY-MM-DD
> 关联方案 doc:{方案 doc 路径}
> 阶段阶段 3验证闭环
> 验收日期YYYY-MM-DD
> 关联方案 doc{方案 doc 路径}
## 1. 接口契约核对
对照方案 doc 第 2 节接口契约,逐一核查实现与契约的一致性:
对照方案 doc 第 2 节接口契约逐一核查实现与契约的一致性
**契约示例逐项核对**:
**契约示例逐项核对**
- [ ] 示例 A{文件路径 + 函数名}):示例中的输入→输出 → 代码实际行为:{一致 / 偏差说明}
- [ ] 示例 B:...
- [ ] 示例 B...
**正式类型定义核对**(如方案 doc 中有补充类型定义):
**正式类型定义核对**(如方案 doc 中有补充类型定义)
- [ ] 类型 X:{关键字段} → 代码里对应定义:{一致 / 偏差说明}
- [ ] ...
- [ ] 类型 X{关键字段} → 代码里对应定义{一致 / 偏差说明}
**流程图核对**(如方案 doc 中有 Mermaid 图):
**流程图核对**(如方案 doc 中有 Mermaid 图)
- [ ] 图中的所有节点/调用关系,在代码中均有实际落点grep 确认)
- [ ] 图中的所有节点 / 调用关系在代码中均有实际落点grep 确认)
发现偏差,**停下来先修代码或回填方案 doc**;不得在报告里写"已知偏差,暂不处理"。
发现偏差**停下来先修代码或回填方案 doc**在报告里写"已知偏差暂不处理"是反模式——下一次有人按方案找代码时会被这个偏差绊倒
## 2. 行为与决策核对
对照方案 doc 第 1 节决策与约束:
对照方案 doc 第 1 节决策与约束
**需求摘要逐项验证**:
**需求摘要逐项验证**
- [ ] 行为 A:{描述 + 实测结果}
- [ ] 行为 B:{描述 + 实测结果}
- [ ] ...
- [ ] 行为 A{描述 + 实测结果}
- [ ] 行为 B{描述 + 实测结果}
**明确不做逐项核对**:
**明确不做逐项核对**
- [ ] 范围外事项 X **确实没做**(grep / 代码 review 确认)
- [ ] 范围外事项 X **确实没做**grep / 代码 review 确认
- [ ] 范围外事项 Y **确实没做**
- [ ] ...
**关键决策落地**:
**关键决策落地**
- [ ] 决策 D1:{决策内容} → 代码里如何体现:{描述}
- [ ] ...
- [ ] 决策 D1{决策内容} → 代码里如何体现{描述}
## 3. 测试约束核对
对照方案 doc 第 3 节测试设计,逐条测试约束验证:
对照方案 doc 第 3 节测试设计逐条测试约束验证
- [ ] **C1**:{约束断言}
- 验证方式:{类型系统 / 单测 / 集成测试 / 肉眼}
- 结果:{通过 / 未通过 + 原因 + 补救方案}
- [ ] **C2**:...
- [ ] ...
- [ ] **C1**{约束断言}
- 验证方式{类型系统 / 单测 / 集成测试 / 肉眼}
- 结果{通过 / 未通过 + 原因 + 补救方案}
- [ ] **C2**...
**前端改动必须浏览器肉眼验证**(AGENTS.md 硬要求):
**前端改动必须浏览器肉眼验证**AGENTS.md 硬要求——typecheck 通过不代表用户用起来对):
- [ ] UI 区域 X:浏览器验证 OK / 截图链接
- [ ] 交互行为 Y:浏览器验证 OK
- [ ] UI 区域 X浏览器验证 OK / 截图链接
- [ ] 交互行为 Y浏览器验证 OK
## 4. 术语一致性
对照方案 doc 第 0 节术语约定,grep 代码:
对照方案 doc 第 0 节术语约定grep 代码
- 术语 X:代码命中 N 处,全部一致 ✓
- 术语 Y:代码命中 N 处,全部一致 ✓
- **防撞车**:方案 doc 第 0 节列的禁用词(如有),grep 无命中 ✓
- 术语 X代码命中 N 处全部一致 ✓
- 术语 Y代码命中 N 处全部一致 ✓
- **防撞车**方案 doc 第 0 节列的禁用词如有grep 无命中 ✓
如有不一致,**停下来回到代码改正**,不得在报告里写"已知差异"后跳过。
发现不一致回到代码改正,别在报告里写"已知差异"后跳过——理由同第 1 节
## 5. 架构归并
对照方案 doc 第 4 节"与项目级架构文档的关系",逐项实际执行更新:
对照方案 doc 第 4 节"与项目级架构文档的关系"逐项**实际执行更新**
- [ ] 架构中心目录下的 doc X({路径}):
- 需要更新的内容:{描述}
- 已更新:✓ / 未更新(理由:{不需要更新的具体理由})
- [ ] 架构中心目录下的 doc Y:...
- [ ] 架构中心目录下的 doc X{路径}
- 需要更新的内容{描述}
- 已更新✓ / 未更新理由{不需要更新的具体理由}
- [ ] 架构中心目录下的 doc Y...
方案 doc 第 4 节为空或描述过于简略,在此补充评估:
如果方案 doc 第 4 节为空或描述过于简略在此补充评估
- 本 feature 新增了哪些模块 / 改变了哪些接口
- 架构总入口是否需要新增对本 feature 设计 doc 的引用
- `AGENTS.md` 是否需要补充新的规约或已知坑
架构归并是**实际写文件的动作**,不是自评"应该不需要改"。每条都必须有明确结论。
架构归并是**实际写文件的动作**不是自评"应该不需要改"。每条都有明确结论。
## 6. 遗留
- 后续优化点(已开 issue 或加入 issue 列表):{列表}
- 已知限制:{列表}
- 实现阶段"顺手发现"列表:{列表}
- 后续优化点已开 issue 或加入 issue 列表{列表}
- 已知限制{列表}
- 实现阶段"顺手发现"列表{列表}
```
---
## 核对节奏
逐节做,不要跳:
逐节做,别跳:
1. 第 1 节(接口契约)和第 2 节(行为与决策)——最容易暴露"实现没对齐方案"的两节,优先做
2. 第 3 节(测试约束)——逐条对照,涉及类型系统的让 typecheck 跑一遍,涉及单测/集成测试的让测试跑一遍
3. 第 4 节(术语)——用 Grep 工具搜索,把命中数和位置写进报告
4. 第 5 节(架构归并)——读方案 doc 第 4 节后逐项执行,**不允许"整体不影响架构"一句话带过**
5. 第 6 节(遗留)——把实现阶段攒下的"顺手发现"和已知限制都记进来
1. 第 1 节接口契约和第 2 节行为与决策——这两节最容易暴露"实现没对齐方案"先做
2. 第 3 节测试约束——逐条对照涉及类型系统的让 typecheck 跑一遍涉及单测 / 集成的让测试跑一遍
3. 第 4 节术语——用 Grep把命中数和位置写进报告
4. 第 5 节架构归并——读方案 doc 第 4 节后逐项执行"整体不影响架构"一句话带过是反模式,要么找出影响在哪、要么明确写"X 节列出的某项确认无影响(理由)"
5. 第 6 节遗留——把实现阶段攒下的"顺手发现"和已知限制都记进来
验收报告各节核对完成后,**逐条更新 `checklist.yaml``checks`**:
各节核对完后,**逐条更新 `checklist.yaml``checks`**
- 该检查项验证通过 → `status` 改为 `passed`
- 该检查项验证失败 → `status` 改为 `failed`,先修代码/方案再改 `passed`
- 所有 checks 的 status 都为 `passed`,验收报告才算完成
- 验证通过 → `status` 改为 `passed`
- 验证失败 → `status` 改为 `failed`先修代码 / 方案再改 `passed`
- 所有 checks 都为 `passed`验收报告才算完成
---
## 退出条件
- [ ] 验收报告 6 节都填完
- [ ] 第 1 节接口契约核对全部勾选,无未处理偏差
- [ ] 第 1 节接口契约核对全部勾选无未处理偏差
- [ ] 第 2 节行为与决策核对全部勾选
- [ ] 第 3 节测试约束核对全部勾选(未通过的有补救方案),前端改动已浏览器验证
- [ ] 第 3 节测试约束核对全部勾选未通过的有补救方案前端改动已浏览器验证
- [ ] 第 4 节术语一致性无遗漏
- [ ] 第 5 节架构归并每条都有明确结论,需要更新的 doc 已实际写入
- [ ] `checklist.yaml` 所有 checks 的 status 都已更新为 `passed`
- [ ] 第 5 节架构归并每条都有明确结论需要更新的 doc 已实际写入
- [ ] `checklist.yaml` 所有 checks 的 status 都已更新为 `passed`
- [ ] 用户终审确认
---
## 收尾提交
按根技能 `easysdd` 第五节约束 9"收尾提交scoped-commit"的规则执行。本阶段的特定要点:
- **提交范围**:功能代码方案 doc验收报告本次实际更新过的架构 doc
- 验收通过后告诉用户"验收报告已完成、架构归并已完成",紧接着问是否需要 commit
- **提交范围**:功能代码 + 方案 doc + 验收报告 + 本次实际更新过的架构 doc。代码交付要带文档,否则下次做 feature 的人查不到上下文。
- 验收通过后告诉用户"验收报告已完成、架构归并已完成",紧接着问是否需要 commit
---
## 退出后
告诉用户:"验收报告已就绪,架构文档已归并,easysdd-feature 工作流走完。后续如发现 BUG,走 issue 修复工作流(不再回到本工作流)。"
告诉用户"验收报告已就绪架构文档已归并easysdd-feature 工作流走完。后续如发现 BUG走 issue 修复工作流不再回到本工作流。"
然后**补问一次**是否需要代为提交本次代码和文档;用户同意时,按收尾提交规则执行到 commit 完成。
然后**补问一次**是否需要代为提交本次代码和文档用户同意时按收尾提交规则执行到 commit 完成。
同时按 `easysdd/reference/shared-conventions.md` 的收尾推荐规则执行(各一句话用户说"不用"立刻跳过):
同时按 `easysdd/reference/shared-conventions.md` 的收尾推荐规则各一句话用户说"不用"立刻跳过):
- 本次 feature 暴露出值得复用的坑点或经验 → "需要沉淀一条 learnings 吗?(走 `easysdd-compound`"
- 本次 feature 引入了超出单个功能的长期约束/技术选型 → "需要把这条决定归档吗?(走 `easysdd-decisions`"
- 引入了超出单个功能的长期约束 / 技术选型 → "需要把这条决定归档吗?(走 `easysdd-decisions`"
- 方案 doc 第 2 节有接口变更 → "需要更新开发者指南吗?(走 `easysdd-guidedoc`"
- 方案 doc 第 1 节有用户可见行为变更 → "需要更新用户指南吗?(走 `easysdd-guidedoc`"
- 新增/修改了库公开接口(组件、函数、命令等) → "需要更新库 API 参考文档吗?(走 `easysdd-libdoc`"
- 新增 / 修改了库公开接口(组件、函数、命令等) → "需要更新库 API 参考文档吗?(走 `easysdd-libdoc`"
可以建议:
可以建议
- 提交时把方案 doc + 验收报告 + 更新后的架构 doc 作同一次提交的一部分,代码交付要带文档
- 验收报告里"遗留"的后续优化点,真要做的话另开新一轮 easysdd-feature 流程,不要在现有 PR 里塞
- 提交时把方案 doc + 验收报告 + 更新后的架构 doc 作同一次提交的一部分
- 验收报告里"遗留"的后续优化点真要做的话另开新一轮 easysdd-feature 流程不要在现有 PR 里塞
## 反模式(看到就停)
---
- ❌ "测试都过了" → 测试约束 ≠ 测试用例,要逐条核对第 3 节测试设计
- ❌ "我肉眼看了一下没问题" → 按清单走,逐项勾选
- 1发现接口偏差后在报告里写"已知偏差"而不去修正代码或回填方案 doc
- ❌ 第 4 节术语 grep 发现不一致就在报告里写"已知差异",而不去改代码
-3前端改动只 typecheck 没在浏览器跑过 → AGENTS.md 硬要求
-5架构归并只写"整体不影响架构"一句话,没逐条核查方案 doc 第 4 节
- ❌ 架构 doc 需要更新而只写"建议以后更新"——归并是当下的动作,不是建议
- ❌ 报告写完没让用户终审就宣告"工作流完成"
- ❌ 工作流收尾时没有询问用户是否需要代为 commit 本次相关代码和文档
- ❌ 用户没明确同意就直接 `git commit`
## 容易踩的坑
- "测试都过了" → 测试约束 ≠ 测试用例,要逐条核对3测试设计
- "我肉眼看了一下没问题" → 按清单走,逐项勾选
-1发现接口偏差后在报告里写"已知偏差"而不去修代码或回填方案 doc
-4术语 grep 发现不一致就在报告里写"已知差异"而不去改代码
- 第 3 节前端改动只 typecheck 没在浏览器跑过 → AGENTS.md 硬要求
- 第 5 节架构归并只写"整体不影响架构"一句话,没逐条核查方案 doc 第 4 节
- 架构 doc 需要更新而只写"建议以后更新"——归并是当下的动作,不是建议
- 报告写完没让用户终审就宣告"工作流完成"
- 工作流收尾时没问用户是否需要代为 commit
- 用户没明确同意就直接 `git commit`
+31 -33
View File
@@ -1,60 +1,58 @@
---
name: easysdd-feature-brainstorm
description: Feature 工作流阶段零(可选):思考伙伴式对话,把模糊想法磨清晰到进 design 的程度产出 brainstorm.md。触发场景"有个想法没想清楚"、"先 brainstorm"、"功能方向模糊"。想法已明确则跳过直接走 design。不处理 BUG 修复或架构重构。
description: feature 流程的可选阶段 0——想法还模糊时用对话把它磨清晰到进 design 的程度。AI 在这里是思考伙伴,不是问卷机:主动提议、主动挑战假设、主动给方案空间。聊完产出 brainstorm.md 落盘。触发场景:用户说"有个想法没想清楚"、"先 brainstorm"、"功能方向还在摇摆"。想法已经清晰就跳过直接走 design,不要拉着用户做他觉得多余的发散。也不处理 bug 和重构。
---
# easysdd-feature-brainstorm
easysdd-feature 的可选 Stage 0。把"我想做点 X 吧"磨到"我要做 X 的这个切面,因为 Y",然后交给 design。
这是 easysdd-feature 的可选阶段 0。任务是把"我想做点 X 吧"磨到"我要做 X 的这个切面,因为 Y",然后交给 design 阶段去落地方案
**brainstorm 是创意空间,不是审计关卡。** 在这里探索、质疑、改变主意、发现原来想做的是另一件事——都是对的。压力和约束留给 design。
最重要的一句话:**brainstorm 是创意空间,不是审计关卡**。在这里探索、质疑、改变主意、聊着聊着发现真正想做的是另一件事——都正常。压力和约束留给 design,这一阶段的功能就是发散和收敛,越早卡死反而越没用
---
## 一、启动检查
## 开聊之前先做的检查
件事,任何一件不满足就不继续
件事,缺一件就先别进对话
1. **确认是新功能 brainstorm**——BUG 走 issue重构走独立方案已想清楚直接进 design。
2. **确认真的有模糊度**——如果你已经能写出 design 第 1 节需求摘要的初稿,告诉用户跳过 brainstorm 直接进 design。宁可漏判也不要误揽
3. **检查已有产物**——Glob `easysdd/features/` 下的 `brainstorm.md``design.md`,有近义文件先确认是接着改还是另起。
4. **断点恢复**——如果已 `brainstorm.md` 且有实质内容(不是空模板),读取内容后简短汇报:"上次 brainstorm 聊到了 {选定方向/最后话题},要接着聊还是推翻重来?"用户选接着聊则从最后位置继续,重问已回答的问题。
1. **确认是新功能 brainstorm**——bug 应该走 issue重构走独立方案想清楚的需求直接进 design。走错入口比拒绝触发还坏。
2. **确认真的有模糊度**——如果你已经能写出 design 第 1 节"需求摘要"的初稿,老实告诉用户跳过 brainstorm 直接进 design 更省事。这一阶段最大的反模式是揽下不属于自己的活
3. **看一下已有产物**——Glob 一下 `easysdd/features/`面有没有名字相近`brainstorm.md``design.md`。有的话先确认是接着改还是另起一个,不要默默覆盖别人的工作
4. **断点恢复**——如果已经有一份有内容的 `brainstorm.md`(不是空模板),读后简短汇报一句"上次聊到了 {选定方向 / 最后那个话题},要接着聊还是推翻重来?"用户选接着聊就从那儿继续,重问已回答的问题。
---
## 二、怎么聊
## 怎么聊
### 硬规则(违反就是反模式)
先讲几条容易做反的:
- **一次一个问题**。等用户答完再出下一题,不允许一次抛一堆
- **先给选项再提问**。优先用 2-4 个具体、有区别度的选项让用户挑,而不是让用户自由作文。选项本身就是你的思考。降级规则:环境没有 `AskUserQuestion` 用编号文本选项。
- **做思考伙伴,不做问卷机**。主动提议、主动挑战假设、主动带方案空间。"你觉得怎么做?"是偷懒——你应该说"我能想到三种方向A / B / C怎么看?"
- **不做技术选型**。"用什么库 / 表结构怎么设计 / 接口怎么定"一律推到 design。本阶段只谈用户感知和为什么做。但如果某个问题的答案取决于代码仓里实际实现(比如"现在这块是怎么做的"、"有没有类似的东西"**按需去读代码**,读完把发现带回对话即可,不展开技术设计讨论
- **开口前先扫仓库**。第一次提问之前完成Read `AGENTS.md` + 架构总入口Glob 已有 feature 目录Grep 用户描述关键词(防术语撞车);搜 learnings 目录看有无相关坑点记录。扫完在对话里简短汇报发现
- **一次只问一个问题**。一次抛三五个问题给用户TA 大概率只回最容易答的那个,深的就漏了
- **先给选项再提问**。用 2-4 个具体、有区别度的选项让用户挑就别让用户自由作文。选项本身就是你的思考——你已经替 TA 把方案空间走了一遍TA 只需要做选择题。环境支持 `AskUserQuestion` 就用,不支持就用编号文本选项。
- **做思考伙伴,不做问卷机**。"你觉得怎么做?"这种话是偷懒——你应该说"我能想到三种方向A / B / C倾向哪个,或者还有别的角度?"。后者才是伙伴的样子。
- **不在这一步做技术选型**。"用什么库、表怎么设计接口怎么定"通通推到 design。本阶段只谈用户感知层面——做这件事是为了帮谁解决什么问题。但如果某个问题的答案得看代码仓里实际是怎么写的("现在这块是怎么做的"、"有没有类似的东西已经在了"**按需去读代码**,读完把发现带回对话——别就着这个发现展开技术设计讨论,那是 design 阶段的事
- **开口前先扫一遍仓库**。第一次提问之前完成这几件:读 `AGENTS.md` + 项目架构总入口Glob 已有 feature 目录Grep 一下用户描述里的关键词(防术语撞车);搜 learnings 目录看有没有相关的踩坑记录。扫完在对话里简短报告发现,让用户知道你不是凭空在跟 TA 聊
### 对话节奏
没有固定步骤表。大致节奏是
没有固定步骤表。大致分三个动作,但随时可以回到上一步——聊着聊着发现方向不对、冒出新角度,跟着走就行
1. **理解**——从用户的想法出发,问一个好问题挖背后的动机或场景。在探索中自然带出这些视角(挑当时有价值的问,不是逐条过):这事帮谁解决什么?不做的话现在怎么绕的?有没有更小的版本抓到大部分价值?
2. **发散**——提议 2-3 个具体的候选方向,每个写 1-2 句描述 + 核心价值 + 主要代价。至少一个反直觉候选(反转、去约束、类比)。**所有候选呈现完再给推荐**,不要先锚定一个再补充。
3. **收敛**——用户选定方向后,轻轻勾勒:核心用户行为是什么?有什么明显不做的?最大的未知是什么?这是 design 热身,不是替 design 做决定。
对话随时可以回到上一步。聊着聊着发现方向不对、冒出新角度——正常,跟着走。
1. **理解**——从用户的想法出发,问一个好问题挖背后的动机或场景。这几个视角在合适的时候带出来(不是逐条过):这事帮谁解决什么?现在不做的话他们怎么绕过去的?有没有更小的版本抓到大部分价值?
2. **发散**——提议 2-3 个具体的候选方向,每个写 1-2 句描述核心价值主要代价。**至少一个反直觉候选**(反转一下、去掉一个常见约束、做个跨领域类比)。所有候选呈现完再给推荐——要是先锚定一个再补充别的,用户的判断会被你的开场白污染
3. **收敛**——用户选定方向后,轻轻勾勒一下:核心用户行为是什么?有什么明显不做的?最大的未知是什么?这是 design 热身,不是替 design 做决定,所以别陷进细节
---
## 三、落盘
## 聊完落盘
对话收敛后写 brainstorm note 到 `features/{feature}/brainstorm.md`
对话收敛后写 brainstorm note 到 `easysdd/features/{feature}/brainstorm.md`
### feature 目录
### feature 目录怎么建
- **日期前缀**:从环境信息取今天日期,不要猜。
- **slug**AI 根据选定方向自拟一个英文小写连字符 slug写进 note 时顺带告知用户。用户有异议再改——不用专门一轮。如果 design 阶段改名,只 rename slug 部分,日期前缀动,整个目录一起 rename。
- 目录不存在就创建;已存在则参考启动检查第 3 条,不默默覆盖
- **日期前缀**:从环境信息取今天日期,不要靠记忆猜。
- **slug**:根据选定方向自拟一个英文小写连字符 slug写进 note 时顺便告诉用户一声。用户有异议再改不用专门一轮"slug 你觉得叫什么"的对话——这种小决定 AI 替用户先拟好更顺手。如果 design 阶段改名,只 rename slug 部分,日期前缀动,整个目录一起 rename。
- 目录不存在就创建;已存在的话回到上面"开聊之前先做的检查"第 3 条。
### brainstorm note 格式
### brainstorm note 模板
```markdown
# {功能名称} Brainstorm
@@ -76,12 +74,12 @@ easysdd-feature 的可选 Stage 0。把"我想做点 X 吧"磨到"我要做 X
遗留给 design 的问题直接列在这里。}
```
> 备注(仓库扫描发现、术语撞车提示、learnings 引用等)按需加在末尾,不设独立 section。
仓库扫描发现、术语撞车提示、learnings 引用这类备注按需加在末尾,不另开 section。
---
## 四、退出
## 退出
brainstorm note 落盘后,确认一件事:**用户说"可以进 design 了"**
brainstorm note 落盘后,确认用户说"可以进 design 了"再结束本阶段
然后告诉用户下一步触发 `easysdd-feature-design`。**不要自己顺手开始写 design**——阶段间的人工 checkpoint 是 easysdd 硬约束
**别自己顺手开始写 design**——阶段间的人工 checkpoint 是 easysdd 整套流程的硬约束,原因在根技能里讲过:跨阶段无停顿地往下跑,用户会发现自己来不及在每一步把关,最后实现完才知道走偏了。所以这一步告诉用户下一步触发 `easysdd-feature-design` 就够了
+81 -91
View File
@@ -1,158 +1,148 @@
---
name: easysdd-feature-design
description: Feature 工作流阶段一:起草方案 doc三层结构+测试设计+架构关系)。触发场景:"开始设计方案"、"design doc"、"准备实现 XX"。先收集代码/文档证据,再按三层模板一次性生成完整初稿(含 YAML frontmatter),用户整体 review 拍板后作为实现与验收的唯一输入
description: feature 流程的阶段 1——为新功能起草一份方案文件作为后续实现和验收的唯一输入。先收集证据读架构、读相关代码、grep 防术语撞车、查归档),然后一次性写出完整初稿(含 YAML frontmatter + 三层结构 + 测试设计),交给用户整体 review迭代到拍板。拍板后从 design.md 里抽出 checklist.yaml 给后面两个阶段用。触发场景:"开始设计方案"、"写 design doc"、"准备实现 XX",前提是已经知道做什么、为谁做、怎么算成功
---
# easysdd-feature-design
## 涉及的路径
这一阶段的产出是一份方案文件 `design.md`,加上从中抽出的行动清单 `checklist.yaml`。这两份东西后面会被两个阶段消费——implement 照着推进、acceptance 照着核对,所以这里写错或写漏,下游就跟着错。
> 共享路径命名约定根技能 `easysdd` 第二节为准。本节只补充本阶段特有信息:到本阶段,feature 目录通常已由 brainstorm 阶段创建好;若不存在则在本阶段创建。
> 共享路径命名约定根技能 `easysdd` 第二节。本阶段一般 feature 目录已由 brainstorm 创建好了;没有的话在这一步建。
## 你的职责
为这个功能起草一份方案 doc。要求是先做证据化阅读与检索再按三层模板一次性生成完整初稿含 YAML frontmatter最后组织用户整体 review 并迭代到拍板。
**核心原则:方案 doc 是给人扫的,不是给人读的。** 读者应该 5 分钟内抓到要点,需要细节时有地方查。
理解这个角色之后,下面有三件事要先搞清楚——为什么这么写、按什么顺序做、退出的标准是什么。
---
## 一、全局规则(先看这个)
## 方案文件是给人扫的,不是给人读的
1. **5 分钟可扫完**:方案 doc 的读者目标是快速抓要点。如果一个节超过 1 屏,就该砍或拆。
2. **术语先锁死**:所有新增术语必须做 grep 防撞车(代码 + 架构中心目录 + 所有 feature 的方案 doc
3. **示例优先于定义**接口行为先用具体示例说明API 用输入→输出,组件用 Props→渲染结果 / Events 示例),复杂时再补正式类型定义
4. **推进按功能可见度**:先最小闭环,再叠细节;不是按代码文件顺序推进
5. **新逻辑优先独立文件**:添加新功能时,新增的内聚逻辑单元默认创建独立文件,而不是往已有文件里追加。改动计划里每个新增逻辑单元必须标注"新建文件"或"追加到已有文件(理由)"
6. **只保留高价值约束**:禁止重复表述同一条规则,避免噪音。一条信息只出现在它最自然的位置
7. **流程与模板分离**:先按流程执行,再按模板写文档;不要边写边切换流程控制逻辑
整个 design 的写作风格都围绕这个原则。读者打开 design.md 是想 5 分钟内抓到要点,需要细节时知道去哪查——不是要逐字精读。这条原则推出几条具体做法:
1. **每节超过 1 屏就该砍或拆**。一屏装不下意味着读者会失去定位感
2. **术语先锁死**。所有新增术语在动笔前做一遍 grep覆盖代码、架构中心目录、所有 feature 的方案文件。术语撞车的代价是后面别人查代码找错地方——预防的成本远低于事后理顺的成本
3. **示例优先于定义**。接口行为先用具体示例API 用输入→输出,组件用 Props→渲染 / Events 示例),复杂时再补正式类型。读者看到具体输入输出比看一段抽象描述更快建立模型
4. **推进按"功能可见度"走,不按代码文件顺序**。先做最小闭环(一条端到端能跑通的路径),再叠细节。这样每一步都能独立验证,途中发现走偏也只损失一步
5. **新逻辑默认放新文件**。新增的内聚逻辑单元默认建独立文件,而不是往已有文件追加。改动计划里每条都标"新建文件"或"追加到已有文件(理由)"。原因是文件越大越难分清职责,往老文件加东西会让后人查 git blame 时把不相关的改动也读一遍
6. **同一条信息只在最自然的位置出现一次**。重复表述会让读者反复确认"这两条是不是同一件事",比缺一条还烦。
7. **流程归流程,模板归模板**。先按下文流程走完再按模板填内容,不要边写边切流程。
---
## 二、流程什么时候做什么
## 流程什么时候做什么
### 1) 触发与前置检查
### 1. 启动检查
启动时先完成以下检查,未通过不进入起草
进入这一阶段先过这几条,没过别动笔
1. **需求输入是否清晰**确认至少有用户目标、核心行为、成功标准明确不做。
- 缺失则先补齐;若用户自己也说不清,先走 brainstorm 阶段
2. **是否已有同名方案 doc**。检查方案 doc 是否已存在,有重名先确认是接着改还是新建
3. **读前置资料**。在动笔前先读
- `AGENTS.md`
- 架构总入口(项目级架构权威)
- 架构索引(项目级架构 doc 索引)
- 与用户需求相关的既有代码和架构中心目录下的子系统架构 doc
4. **归档检索(按需)**——是否值得搜、优先搜哪些目录,以根技能 `easysdd` 第五节约束 7 为准;本阶段至少优先考虑以下目录:
- 技巧库目录:`python easysdd/tools/search-yaml.py --dir easysdd/tricks --filter status=active --query "{feature 关键词}"`
- 探索归档目录:`python easysdd/tools/search-yaml.py --dir easysdd/explores --query "{feature 关键词}"`
- 知识沉淀目录:`python easysdd/tools/search-yaml.py --dir easysdd/learnings --query "{feature 关键词}"`
- 决策归档目录:`python easysdd/tools/search-yaml.py --dir easysdd/decisions --filter status=active --query "{feature 关键词}"`
- 已有 feature 方案:`python easysdd/tools/search-yaml.py --dir easysdd/features --filter doc_type=feature-design --query "{feature 关键词}"`
1. **需求输入是否清晰**——确认至少有用户目标、核心行为、成功标准明确不做这四项。缺了就先补;用户自己也说不清就回退到 brainstorm
2. **是否已有同名方案文件**——存在的话先确认是接着改还是新建
3. **读前置资料**——动笔前必读 `AGENTS.md`、项目架构总入口、架构索引、与需求相关的现有代码和子系统架构 doc。读这一步是为了让你写的方案和现有代码能接得上不读直接动手大概率写出脱离实际的方案
4. **归档检索**——值不值得搜、优先搜哪些目录,规则在根技能 `easysdd` 第五节约束 7。本阶段至少考虑这几个目录
命中后优先复用,并在方案 doc 记录引用来源。
- 技巧库:`python easysdd/tools/search-yaml.py --dir easysdd/tricks --filter status=active --query "{关键词}"`
- 探索归档:`python easysdd/tools/search-yaml.py --dir easysdd/explores --query "{关键词}"`
- 知识沉淀:`python easysdd/tools/search-yaml.py --dir easysdd/learnings --query "{关键词}"`
- 决策归档:`python easysdd/tools/search-yaml.py --dir easysdd/decisions --filter status=active --query "{关键词}"`
- 已有 feature 方案:`python easysdd/tools/search-yaml.py --dir easysdd/features --filter doc_type=feature-design --query "{关键词}"`
5. **断点恢复**。如果 `design.md` 已存在且有部分节内容:
命中后优先复用,并在方案文件里记下引用来源——这样后人看到这份方案能顺着引用一路追回去。
5. **断点恢复**——`design.md` 已经存在且有部分内容时:
- `status=draft` 且各节基本完整 → 上次写完了还没 review跳到整体 review 步骤
- 部分节缺失 → 汇报"上次方案写到第 X 节,我补齐剩余节后统一给你 review",只补缺失,不重写已完成
- 部分节缺失 → 汇报"上次方案写到第 X 节,我补齐剩下的再统一给你 review",只补缺失,不重写已完成
### 2) 着陆区评估
### 2. 着陆区评估
前置检查中已读过目标代码,在动笔起草前做一次快速评估**新功能要落地的文件/模块能不能干净地接住这次改动?**
启动检查里读过目标代码后,动笔前再做一次快速判断**新功能要落地的文件 / 模块能不能干净地接住这次改动?**
评估维度:目标文件行数、职责数量、与新功能的耦合方式。涉及前端时还需看:组件树层级是过深、状态归属是清晰(本地 state / props 传递 / 全局 store
看几个维度:目标文件行数、职责数量、与新功能的耦合方式。涉及前端时还要看组件树层级是不是过深、状态归属是不是清晰(本地 state / props 传递 / 全局 store
按严重程度分流:
| 情况 | 处理方式 |
| 情况 | 处理 |
|---|---|
| 健康,直接加 | 正常推进,不额外处理 |
| 需要微重构extract file / extract function | 纳入第 3 节推进顺序作为**第 1 步**scope 锁死为"只搬不改行为",退出信号"搬完后既有功能不变" |
| 需要架构级变更(职责重划分、模块拆合、接口重新设计) | 在第 1 节记为**前置依赖**,建议拆成独立 feature 先解决;当前 feature 暂缓或标"等前置完成后再推进" |
| 健康,直接加 | 正常推进,不额外动作 |
| 需要微重构extract file / extract function | 纳入第 3 节推进顺序**第 1 步**scope 锁死为"只搬不改行为",退出信号"搬完后既有功能不变" |
| 需要架构级变更(职责重划分、模块拆合、接口重新设计) | 在第 1 节记为**前置依赖**,建议拆成独立 feature 先解决;当前 feature 暂缓或标"等前置完成后再推进" |
评估结论写进方案 doc 第 3 节"改动计划"的开头(见同目录 `reference.md`)。如果是"健康,直接加",不需要写——只在有动作时才记录
为什么要做这一步?硬塞功能进一个本来就长得不健康的文件,得到的是一个更长更不健康的文件,下一次改动就更难。提前把"该不该先重构"放到台面上,让用户做决定,而不是 AI 偷偷在 PR 里夹带
### 3) 一次性起草
评估结论写进方案文件第 3 节"改动计划"开头(具体格式见同目录 `reference.md`)。"健康,直接加"的情况不用写——只在有动作时才记。
按下文三层模板一次性生成完整初稿,不要分批让用户先看半成品。初稿的 YAML frontmatter 里 `status` 固定写 `draft`
### 3. 一次性起草
### 4) 整体 review
按下文三层模板**一次写出完整初稿**,不要分批让用户先看半成品。初稿的 YAML frontmatter 里 `status``draft`
向用户发出一次整体 review 提示。用户可以对任意部分提修改意见,你按意见修订后再次确认,直到用户明确"方案可以了"。用户明确放行后,把 YAML frontmatter 的 `status``draft` 改成 `approved`
为什么不分批?分批 review 的问题是用户每次只看到局部,发现不了"第 1 节的范围跟第 3 节的推进步骤对不上"这种跨节问题。只有完整初稿摆出来,用户才能扫到全局一致性
### 5) 生成 checklist.yaml
### 4. 整体 review
方案 doc 确认后,从 design.md 中提取行动清单,落盘为同目录下的 `checklist.yaml`。这份清单的生命周期以 `easysdd/reference/shared-conventions.md` 为准本阶段负责生成implement 只推进 `steps`acceptance 只核对 `checks`
向用户发一次整体 review 提示。用户对任意部分提修改意见,你按意见改完再次确认,反复直到用户明确"方案可以了"。用户放行后把 frontmatter 的 `status``draft` 改成 `approved`
`design.md` / `checklist.yaml` 的完整模板、frontmatter 示例、节锚点、提取格式见同目录 `reference.md`。本阶段只保留提取原则:
### 5. 生成 checklist.yaml
- `steps`:从第 3 节"推进顺序"逐步提取,每步一条
- `checks`:从以下来源综合提取——
方案确认后,从 design.md 里抽出行动清单,落到同目录 `checklist.yaml`。这份清单的生命周期看 `easysdd/reference/shared-conventions.md`本阶段负责生成implement 只推进 `steps`acceptance 只核对 `checks`。三个阶段各管一段,互不越界——这样每个阶段都能从 yaml 上看出自己的工作进度。
`design.md``checklist.yaml` 的完整模板、frontmatter 示例、节锚点、提取格式都在同目录 `reference.md` 里。本技能只保留提取原则:
- `steps`:从第 3 节"推进顺序"逐步抽,一步一条
- `checks`:从这几处综合抽——
- 第 1 节"明确不做"的每条 → 范围守护检查项
- 第 2 节关键接口契约 → 接口一致性检查项
- 第 3 节测试设计的每条测试约束 → 测试验证检查项
落盘后用 `validate-yaml.py --file {checklist.yaml 路径} --yaml-only` 校验语法。
### 6) 退出
### 6. 退出
完成退出条件核对后结束本阶段,并引导进入阶段实现。
按下文退出条件清单核对完,引导用户进入阶段 2 实现。
---
## 三、模板格式
## 模板格式
`design.md` / `checklist.yaml` 的完整参考拆到同目录 `reference.md`,包括
`design.md` / `checklist.yaml` 的完整参考拆到同目录 `reference.md`
- YAML frontmatter 示例
- 顶层节锚点要求
- `checklist.yaml` 完整格式与状态语义
- 第 0-4 节各自该写什么
本技能只保留流程约束:按参考一次性起草完整初稿,不分批吐半成品。
本技能只保留流程层面的约束:按那份参考一次性起草完整初稿,不分批吐半成品。
整体 review 的提示词同样在 `reference.md`。规则不变:**只发一次整体 review**,不要逐节拆开确认。
---
## 四、review 提示
## 退出条件
整体 review 提示词见同目录 `reference.md`。本阶段要求仍然不变:只能发一次整体 review不逐节拆开确认。
---
## 五、退出条件
用户整体 review 通过,且以下全部满足:
用户整体 review 通过,并且下面这些都满足:
- [ ] 做过术语 grep 防撞车并记录结果
- [ ] YAML frontmatter 存在,`doc_type` / `feature` / `status` / `summary` / `tags` 填写完整
- [ ] 需求摘要含"不做什么"且后文扩范围
- [ ] 记录了关键决策被拒方案
- [ ] 每个关键接口有具体示例API输入→输出组件Props→渲染 / Events覆盖正常 + 主要错误路径
- [ ] 示例通过注释标了来源位置(文件路径 + 函数/组件名)
- [ ] 推进步骤 4-8 步,每步可独立验证
- [ ] 测试设计按功能点组织,每个功能点都包含测试约束/验证方式/关键用例骨架
- [ ] YAML frontmatter 存在,`doc_type` / `feature` / `status` / `summary` / `tags` 都填了
- [ ] 需求摘要含"不做什么"且后文没有偷偷扩范围
- [ ] 记录了关键决策被拒方案
- [ ] 每个关键接口有具体示例API输入→输出组件Props→渲染 / Events覆盖正常路径和主要错误路径
- [ ] 示例通过注释标了来源位置(文件路径 + 函数 / 组件名)
- [ ] 推进步骤 4-8 步,每步可独立验证
- [ ] 测试设计按功能点组织,每个功能点都测试约束 / 验证方式 / 关键用例骨架
- [ ] 记录了高风险实现约束
- [ ] 用户确认通过后frontmatter 的 `status` 已更新为 `approved`
- [ ] `checklist.yaml` 已从 design.md 提取生成,且通过 `validate-yaml.py` 校验
- [ ] `checklist.yaml` 的 steps 条目数第 3 节推进顺序一致
- [ ] 用户确认通过后frontmatter 的 `status` 改成了 `approved`
- [ ] `checklist.yaml` 已从 design.md 抽出生成,且通过 `validate-yaml.py` 校验
- [ ] `checklist.yaml` 的 steps 条目数第 3 节推进顺序一致
文件路径:方案 doc若 feature 目录不存在则创建;同一 feature 的 design.md / checklist.yaml / acceptance.md 聚合在同一 feature 目录,目录位置见主技能 `easysdd` 第二节"目录安排"
文件路径:方案文件在 `easysdd/features/{feature}/`feature 目录不存在就在这一步建。命名约定看根技能 `easysdd` 第二节
---
## 六、反模式(看到就停)
## 容易踩的坑
- ❌ 未读 `AGENTS.md` 和相关架构文档就动笔
- ❌ 术语未做防撞车检查
- ❌ 用散文描述接口行为,无具体示例
- ❌ 把契约层写成全字段百科——已有且不变的接口不要重复
- ❌ 强行画图——模块 ≤ 2 个、调用线性时不需要图
- ❌ 推进步骤过细(>8 步)
- ❌ 只给半份文档就让用户先 review
- ❌ 在需求摘要或改动计划里偷偷扩范围
下面这些是过去反复出现的反模式,遇到就停一下问自己是不是又掉进去了:
---
## 七、退出后
告诉用户:"方案 doc 已就绪(含测试设计),行动清单 `checklist.yaml` 已生成,下一步是阶段二:分步实现。可以触发 easysdd-feature-implement 技能。"
- 没读 `AGENTS.md` 和相关架构文档就动笔——写出来的方案大概率跟现有代码对不上
- 术语没做防撞车检查——撞了之后 git blame 找原因要花十倍时间
- 用散文描述接口行为没给具体示例——读者建不起模型review 时没法判断
- 把契约层写成全字段百科——已经存在且不变的接口别重复抄
- 强行画图——模块就 ≤ 2 个、调用又是线性的,画图反而模糊重点
- 推进步骤拆得太细(>8 步)——细到每步都没什么独立价值
- 只给半份文档让用户先 review——用户看不出全局一致性
- 在需求摘要或改动计划里偷偷扩范围——后面验收时对不上
+67 -59
View File
@@ -1,70 +1,74 @@
---
name: easysdd-feature-fastforward
description: Feature 快速通道——需求清晰、范围小时,写一份紧凑 design.md(含 YAML frontmatter后直接进实现。触发场景:"快速模式"、"fastforward"、"别那么多步骤"、"直接开干"。不适合跨子系统需要术语梳理的复杂功能
description: feature 流程的快速通道——需求清晰、范围小时压缩掉完整 design 流程,写一份紧凑 design.md 经用户一次确认后直接进实现。压缩的是发散和分阶段 review不是质量标准——代码指针、验收标准这些一条都不能省。触发场景:用户说"快速模式"、"fastforward"、"别那么多步骤"、"直接开干"。不适合跨子系统需要梳理新术语、或推进步骤超过 4 步的复杂功能——这些情况要主动告诉用户回完整流程
---
# easysdd-feature-fastforward
**feature 系列的快速通道**——需求清晰且范围小时,压缩掉完整 design 细化流程,只产出一份紧凑的 `design.md`,一次用户确认后直接进实现
并不是每个功能都值得走完整的 brainstorm → design → implement → acceptance 四步流程。需求一句话能说清、改动就在两三个文件里、没什么术语撞车风险——这种功能硬走完整流程会让用户觉得"AI 在加戏"。fastforward 就是为这种情况留的快速通道
但**压缩的是流程,不是质量**——代码指针、验收标准、明确不做这些一条都不能省。fastforward 不是"敷衍版的 design",而是"省掉了发散讨论和分阶段 review 的 design"。
---
## 一、适用场景
## 什么时候走 fastforward
满足以下**全部条件**才走 fastforward
面几条**全部满足**才走:
1. **需求清晰**用户能说出"做什么、为谁、怎么算成功",不需要发散讨论
2. **范围明确**改动集中在少数文件或模块,不需要梳理多个子系统的对接点
3. **复杂度低**没有复杂状态机、并发逻辑、术语撞车风险或架构变更
4. **用户主动选**用户明说"快速模式"、"fastforward"、"快点搞"、"别那么多步骤直接做"、"直接开干"等
1. **需求清晰**——用户能说出"做什么、为谁、怎么算成功",不需要发散讨论
2. **范围明确**——改动集中在少数文件或模块,不需要梳理多个子系统的对接点
3. **复杂度低**——没有复杂状态机、并发逻辑、术语撞车风险或架构变更
4. **用户主动选**——用户明说"快速模式"、"fastforward"、"快点搞"、"别那么多步骤"、"直接开干"等
**不适合 fastforward 的情况**(遇到就告知用户完整 feature 工作流)
下面这些情况遇到就主动告诉用户完整 feature 流程
- 涉及多个子系统的数据流向变更
- 需要引入新术语或有概念撞车风险
- 需要引入新术语或有概念撞车风险
- 推进步骤超过 4 步
- 用户自己说不清楚边界
- 改动可能影响现有核心架构
---
## 二、涉及的路径
> 共享路径与命名约定以根技能 `easysdd` 第二节为准。本节只补充 fastforward 特有信息。
为什么这几条划得这么死fastforward 跳过的不是仪式而是"用户在多个 checkpoint 上跟你对齐方案的机会"。范围一大、概念一新,跳过这些 checkpoint 意味着实现完用户才发现你理解的不是同一回事——这时候返工的成本比走完整流程贵得多。
---
## 三、你的职责
## 涉及的路径
用户交代需求后,**快速阅读相关代码**(必须看涉及的主要文件,不需要通读全部架构文档),然后一次性产出紧凑的 `design.md`(含 YAML frontmatter让用户整体确认确认后给出实现指引
> 共享路径与命名约定看根技能 `easysdd` 第二节。本节只补充 fastforward 特有信息
---
## 四、启动检查
## 你做的事
1. **确认适用性**:按第一节条件判断是否适合 fastforward不适合就主动说出原因建议走完整流程
2. **查重**:检查 `easysdd/features/` 下是否已有同名 feature 目录——有的话先问用户是继续还是新建
3. **读代码**Glob + Read 快速浏览用户描述中涉及的主要文件;必要时 Grep 关键词确认改动范围
不读相关代码就产出 design.md 是反模式——哪怕 fastforward 也要看主要文件。
用户交代需求后,**快速读相关代码**(必须看涉及的主要文件,不需要通读全部架构文档),然后一次性产出紧凑的 `design.md`(含 YAML frontmatter让用户整体确认确认后给出实现指引。
---
## 五、design.md 结构
## 启动检查
fastforward 的 `design.md` 比完整方案 doc 精简,但**必须包含 YAML frontmatter + 以下 4 节,一次性产出**,不分批。
1. **确认适用性**——按上面那几条判断是不是适合 fastforward。不适合就主动告诉用户原因建议走完整流程
2. **查重**——检查 `easysdd/features/` 下是不是已经有同名 feature 目录。有的话先问是继续还是新建
3. **读代码**——Glob + Read 快速浏览用户描述里涉及的主要文件;必要时 Grep 关键词确认改动范围
不读相关代码就直接产出 design.md 是反模式——fastforward 也要看主要文件。原因是没读代码写出来的方案大概率跟实际项目结构对不上,省下这一步会让后面整阶段全跑偏。
---
## design.md 结构
fastforward 的 `design.md` 比标准方案精简,但**必须包含 YAML frontmatter + 下面 4 节,一次性产出**,不分批。
### YAML frontmatter
开头必须写统一 frontmatter便于 `search-yaml.py``features/` 下检索。必填字段:
开头必须写统一 frontmatter便于 `search-yaml.py``features/` 下检索。必填字段
- `doc_type`: 固定写 `feature-design`
- `feature`: 当前 feature 目录名
- `status`: 初稿写 `draft`,用户确认后改成 `approved`;被替代时写 `superseded`
- `summary`: 一句话描述本功能目标
- `tags`: 可检索标签列表,至少 2 个
- `doc_type`固定写 `feature-design`
- `feature`当前 feature 目录名
- `status`初稿写 `draft`,用户确认后改成 `approved`;被替代时写 `superseded`
- `summary`一句话描述本功能目标
- `tags`可检索标签列表,至少 2 个
推荐模板:
模板
```markdown
---
@@ -89,12 +93,14 @@ tags: [export, csv, orders]
- **明确不做**...(至少 1-2 条)
```
"明确不做"不是凑数——这一节最重要的就是它。后面验收要靠它划出范围边界,没写就等于范围开放。
### 第 1 节:设计方案
关键设计决策,写清楚:
- 改动的主要文件和位置(代码指针:文件路径 + 函数/类型名)
- 新增的类型/接口(如有,用 TypeScript / Rust 伪代码)
- 改动的主要文件和位置(代码指针:文件路径 + 函数 / 类型名)
- 新增的类型 / 接口(如有,用 TypeScript / Rust 伪代码)
- 关键边界情况的处理方式
```markdown
@@ -120,9 +126,9 @@ tags: [export, csv, orders]
### 第 2 节:验收标准
**这是 fastforward 和普通方案 doc 的关键差异**——不变量和验收标准在这里就写好,不留占位。验收报告(`acceptance.md`)将直接从这里抽验收点。
**这是 fastforward 和标准方案 doc 的关键差异**——验收标准在这里就写好,不留占位。`acceptance.md`直接从这里抽验收点,留占位等于后面验收无据可依
每条验收点必须是**可操作的步骤 + 期待结果**,不接受"功能正常运行"这种不可验证的描述。
每条验收点必须是**可操作的步骤 + 期待结果**,不接受"功能正常运行"这种不可验证的描述。原因很简单:不可验证的标准等于没标准。
```markdown
## 2. 验收标准
@@ -144,7 +150,9 @@ tags: [export, csv, orders]
### 第 3 节:推进步骤
简化版推进顺序,**不超过 4 步**。每步要有退出信号(怎么算这步做完)。超过 4 步意味着不适合 fastforward需要告知用户切换到完整流程。
简化版推进顺序,**不超过 4 步**。每步要有退出信号(怎么算这步做完)。
为什么卡 4 步?超过 4 步意味着这件事已经不"简单"了——继续走 fastforward 只会让 implement 阶段失去节奏。遇到这种情况告知用户切到完整流程。
```markdown
## 3. 推进步骤
@@ -155,9 +163,9 @@ tags: [export, csv, orders]
---
## 六、确认与 checklist.yaml
## 用户确认与 checklist.yaml
产出 `design.md`向用户发一次整体确认提示:
产出 `design.md` 后向用户发一次整体确认提示:
> "fastforward design.md 已就绪,请整体 review 后确认:
> - 需求摘要是否准确?明确不做的部分有没有遗漏?
@@ -166,45 +174,45 @@ tags: [export, csv, orders]
>
> 确认后直接进入实现阶段。"
用户可以提修改意见,修订后再次确认用户明确说"可以了"视为放行,把 frontmatter 的 `status` 更新为 `approved`
用户可以提修改意见,修订后再次确认用户明确说"可以了"视为放行,把 frontmatter 的 `status` 改成 `approved`
**确认后立即从 design.md 提取行动清单,落盘为同目录下的 `checklist.yaml`**。清单格式和生命周期 `easysdd/reference/shared-conventions.md` 为准;本阶段只负责初始生成。提取规则:
**确认后立即从 design.md 行动清单,落同目录 `checklist.yaml`**。清单格式和生命周期 `easysdd/reference/shared-conventions.md`本阶段只负责初始生成。提取规则:
- `steps`:从第 3 节"推进步骤"逐步提取
- `checks`:从第 0 节"明确不做"项 + 第 2 节"验收标准"各条提取
- `steps`:从第 3 节"推进步骤"逐步
- `checks`:从第 0 节"明确不做"项 + 第 2 节"验收标准"各条
落盘后用 `validate-yaml.py --file {checklist.yaml 路径} --yaml-only` 校验语法。
---
## 七、退出条件
## 退出条件
- [ ] 第 0 节含"明确不做"(至少 1-2 条)
- [ ] YAML frontmatter 存在,`doc_type` / `feature` / `status` / `summary` / `tags` 填写完整
- [ ] 第 1 节每个改动点都有代码指针(文件路径 + 函数/类型名)
- [ ] 第 2 节包含功能验收 + 至少一条异常或回归检查,每条可验证
- [ ] YAML frontmatter 存在,`doc_type` / `feature` / `status` / `summary` / `tags` 都填了
- [ ] 第 1 节每个改动点都有代码指针(文件路径 + 函数 / 类型名)
- [ ] 第 2 节包含功能验收 + 至少一条异常或回归检查,每条可验证
- [ ] 第 3 节推进步骤 ≤ 4 步,每步有退出信号
- [ ] 用户明确确认
- [ ] 用户确认后frontmatter 的 `status`更新为 `approved`
- [ ] `checklist.yaml` 已从 design.md 提取生成,且通过 `validate-yaml.py` 校验
- [ ] 用户确认后frontmatter 的 `status`改成 `approved`
- [ ] `checklist.yaml` 已从 design.md 抽出生成,且通过 `validate-yaml.py` 校验
**文件路径**:方案 doc 和 checklist.yamlfeature 目录不存在则创建;两者聚合在同一 feature 目录,目录位置见主技能 `easysdd` 第二节"目录安排"
文件路径:方案 doc 和 checklist.yaml 都在同一 feature 目录feature 目录不存在就在这一步建。位置看根技能 `easysdd` 第二节"目录安排"
---
## 八、退出后
## 退出后
告诉用户:"design.md 已确认,行动清单 `checklist.yaml` 已生成,直接进入实现阶段。可以触发 `easysdd-feature-implement` 技能。"
不要自己顺手开始写代码——用户确认是硬约束。
自己顺手开始写代码——用户确认是硬约束,理由跟标准流程一样:跨阶段无停顿地往下跑会让用户来不及把关
---
## 九、反模式(看到就停)
## 容易踩的坑
- 需求不清楚还硬走 fastforward——先问清楚或建议走完整流程
- 不读相关代码就产出 design.md
- 第 2 节验收标准写"功能正常"、"表现符合预期"这种不可操作的描述
- 第 3 节超过 4 步还不提示切换到完整流程
- 产出后经用户确认就开始实现
- 把 fastforward 当成"敷衍了事的借口"——紧凑不等于粗糙,代码指针和验收标准一条都不能省
- 需求不清楚还硬走 fastforward——先问清楚或建议走完整流程
- 不读相关代码就产出 design.md
- 第 2 节验收标准写"功能正常"、"表现符合预期"这种不可操作的描述
- 第 3 节超过 4 步还不提示切完整流程
- 产出后经用户确认就开始实现
- 把 fastforward 当成"敷衍了事的借口"——紧凑不等于粗糙,代码指针和验收标准一条都不能省
+128 -103
View File
@@ -1,154 +1,179 @@
---
name: easysdd-feature-implement
description: Feature 工作流阶段二:按方案 doc 分步实现代码,完成后输出汇报。触发场景:"方案确认了开始实现"、"按方案写代码"、"开工",且方案 doc标准设计含测试设计或 fastforward 设计含验收标准)已 approved。前置依赖 easysdd-feature-design 或 easysdd-feature-fastforward
description: feature 流程的阶段 2——按 design.md 的推进顺序写代码,写完用统一格式做完成汇报给用户 review。前提是 design.md 已经 approved标准 design 含测试设计,或 fastforward design 含验收标准),并且同目录下有 checklist.yaml。触发场景用户说"方案确认了开始实现"、"按方案写代码"、"开工"。实现中遇到方案没覆盖到的情况(新概念、范围外文件、需要打补丁分支)要主动停下来回到方案谈,不要硬冲
---
# easysdd-feature-implement
到这一步用户已经在方案上签过字了,你的活是把方案变成代码。听起来直白,但实际容易出问题的不是写代码本身,而是**实现路上发现方案没覆盖到的情况时怎么办**——硬冲下去就把方案当摆设了,停下来回去谈又觉得麻烦。下面整套规则就是为了让"停下来"成为默认动作。
## 涉及的路径
> 共享路径与命名约定看根技能 `easysdd` 第二节。到这一步 feature 目录已经由 brainstorm 或 design 创建好。
> 共享路径与命名约定以根技能 `easysdd` 第二节为准。本节只补充本阶段特有信息到本阶段feature 目录已由 brainstorm 或 design 阶段创建好。
## 你的职责
按方案 doc 的"推进顺序"完整实现这个功能。**一次性写完所有代码,完成后输出统一的完成汇报,等用户 review**。实现过程中如遇方案之外的情况(新概念、范围外文件、补丁分支)必须主动停下来处理(见"违规信号"),不要带着疑问硬冲。
---
## 启动检查
1. **方案 doc 完整性**。检查方案 doc:
- 文件头有 YAML frontmatter,且 `doc_type=feature-design`
- `feature` 字段与当前 feature 目录一致
- `status=approved`
- `summary` 非空,`tags` 至少 2 个
动手前先过这几关:
**标准 design节编号 0/1/2/3/4额外检查**:
- 第 0 节(术语约定)有内容
- 第 2 节(接口契约)有具体代码指针
- 第 3 节(实现提示)里的改动计划已落到具体路径与函数
- 第 3 节(实现提示)里的推进顺序步骤明确,有退出信号
- **第 3 节(实现提示)里的测试设计按功能点覆盖,且每个功能点都包含测试约束/验证方式/用例骨架**
### 1. 方案文件够不够撑实现
**Fastforward design节编号 0/1/2/3额外检查**:
- 第 0 节(需求摘要)含"明确不做"
- 第 1 节(设计方案)有改动点(代码指针:文件路径 + 函数/类型名)
- 第 2 节(验收标准)每条可验证(操作步骤 + 期待结果)
- 第 3 节(推进步骤)步骤明确,有退出信号
打开 design.md先看 frontmatter
- 任何一项不达标 → 停下来,告诉用户先走 easysdd-feature-design 补齐
2. **checklist.yaml 存在且有效**`checklist.yaml` 的生命周期以 `easysdd/reference/shared-conventions.md` 为准;本阶段只消费并推进 `steps`。检查同 feature 目录下的 `checklist.yaml`:
- 文件存在,且 `feature` 字段与当前 feature 目录一致
- `steps` 列表非空,且每条 status 为 `pending`(或接续上次中断时部分为 `done`
- 不存在 → 停下来,告诉用户先走 easysdd-feature-design 生成
3. **读所有上下文**(动手前必读):
- 方案 doc 全文
- checklist.yaml
- 需求来源(用户描述 + brainstorm note,如有)
- `AGENTS.md`
- 第 2 节契约示例里提到的所有既有代码文件(只读相关函数即可,不必通读)
4. **跟用户确认从哪一步开始**。通常是第 1 步,但也可能是接续上次中断(参考 checklist.yaml 中已 `done` 的步骤)。
- 文件头有 YAML frontmatter`doc_type=feature-design`
- `feature` 字段跟当前 feature 目录一致
- `status=approved`
- `summary` 非空,`tags` 至少 2 个
## 强制规则
然后看节内容——标准 design 和 fastforward design 的检查项不一样:
### 规则 1:严格按推进顺序(以 checklist.yaml 为准)
**标准 design节编号 0/1/2/3/4**
- 第 0 节(术语约定)有内容
- 第 2 节(接口契约)有具体代码指针
- 第 3 节(实现提示)的改动计划落到具体路径和函数
- 第 3 节的推进顺序步骤明确,有退出信号
- 第 3 节的测试设计按功能点覆盖,每个功能点都有测试约束 / 验证方式 / 用例骨架
- 按 `checklist.yaml``steps` 列表顺序执行,不合并步骤,不跳步
- 每完成一步,立即把该步 `status``pending` 改为 `done`
- **不"顺手把下一步也做了"**——这是最常见的违规
**Fastforward design节编号 0/1/2/3**
- 第 0 节(需求摘要)含"明确不做"
- 第 1 节(设计方案)有改动点(文件路径 + 函数 / 类型名)
- 第 2 节(验收标准)每条可验证(操作步骤 + 期待结果)
- 第 3 节(推进步骤)步骤明确,有退出信号
### 规则 2:全部完成后输出统一完成汇报
任一项不达标就停下来,告诉用户先回 `easysdd-feature-design` 补齐。原因是方案漏的项实现时一定要现场补——而现场补意味着用户没在方案上把过关,等于绕过了 checkpoint。
所有步骤代码写完后,使用下面的固定模板输出一份完成汇报,然后**停下来等用户 review**。**不允许"大致完成了"、"应该没问题"这种含糊汇报**。
### 2. checklist.yaml 在不在、能不能用
`checklist.yaml` 的生命周期看 `easysdd/reference/shared-conventions.md`。本阶段只消费并推进 `steps` 这一段:
- 文件存在,`feature` 字段跟当前 feature 目录一致
- `steps` 列表非空,每条 status 为 `pending`(接续上次中断时部分会是 `done`,正常)
- 不存在 → 停下来,让用户回 `easysdd-feature-design` 生成
### 3. 把上下文读全
动手前必读:
- 方案 doc 全文
- checklist.yaml
- 需求来源(用户描述 + brainstorm note如有
- `AGENTS.md`
- 第 2 节契约示例里提到的所有现有代码文件——读相关函数即可,不必通读
### 4. 跟用户确认从哪一步开始
通常是第 1 步,但如果是接续上次中断,参考 checklist.yaml 里已 `done` 的步骤,从下一步继续。
---
## 实现期间的几条核心约束
下面这些不是凭空的禁令,每条背后都有具体代价。理解了为什么再去执行才不会僵化。
### 严格按 checklist.yaml 的步骤顺序走
`steps` 列表顺序执行,不合并步骤、不跳步。每完成一步立即把该步 `status``pending` 改为 `done`
最常见的违规是**"顺手把下一步也做了"**——为什么不行?因为方案里把动作切成步骤是有用意的:每一步都对应一个独立可验证的退出信号。两步合在一起做意味着出问题时你不知道是哪一步引入的,回滚也回不到一个干净的中间态。
### 不做方案外的改动
读代码时如果发现值得重构的点(参考 `AGENTS.md` 里"边实现边识别"那节),只要**不在本次功能影响面内**,就记成后续 issue不要顺手改。
记录格式:
```markdown
> 顺手发现:{文件:行号} {问题简述}。不在本次范围,记录待后续 issue。
```
为什么这么严?顺手改的代码不在方案里,验收时核对不上;后人看 git blame 也分不清哪些改动是为了这次功能、哪些是顺手。一次混进去三五个"顺手",整个 PR 就讲不清楚到底改了什么。
### 术语守护
新写的类型名、函数名、变量名都要去方案 doc 第 0 节对照,不允许出现 doc 里没有的新概念。觉得需要引入新概念时,先停下来改方案 doc 第 0 节、grep 防撞车、用户确认,再继续写代码。
这条的代价同样具体:术语撞车意味着将来同一个概念在代码里有两个名字,或者两个不同的概念共用同一个名字——后者尤其致命,会让搜索完全失效。
### 出现"需要打补丁分支"的冲动时停下来
如果你写代码写到一半冒出 `if (特殊情况) { 特殊处理 }` 这种结构,**停**。
新功能里出现这种补丁分支基本只有一个原因:方案没覆盖到这种情况。继续硬写下去得到的是一段"为了让代码能跑而加的特殊逻辑",下次别人改这块时根本不知道这个分支为什么存在。正确做法是回到方案谈,要么把这个情况补进 design 里、要么砍掉、要么明确为遗留问题。
---
## 写完后输出统一汇报
所有步骤写完后用下面这个固定模板出一份汇报,然后**停下来等用户 review**。
为什么要固定模板?因为含糊汇报("大致完成了"、"应该没问题")等于把验证责任全推给用户。固定模板逼着把改了哪些文件、是否触碰方案外的东西、是否引入新概念这几件事一一说清楚,用户拿着这份汇报就能定向去看,不用从 git diff 重读一遍。
```markdown
## 实现完成汇报
### 动了哪些文件
{运行 git status,贴出真实输出}
{运行 git status,贴真实输出}
### 改了哪些函数 / 类型(按步骤分组)
**步骤 N:{步骤名}**
- file:line 函数名 改动类型(新增 / 修改 / 删除)
### 改了哪些函数 / 类型按步骤分组
**步骤 N{步骤名}**
- file:line 函数名 改动类型新增 / 修改 / 删除
- ...
### 是否触碰到方案外的文件?
{是 / 否。是的话说明为什么,以及是否已同步更新方案 doc}
### 是否触碰到方案外的文件
{是 / 否。是的话说明为什么以及是否已同步更新方案 doc}
### 是否引入了方案 doc 第 0 节里没有的新概念 / 抽象?
{是 / 否。是的话说明已在方案 doc 第 0 节补充并做过 grep 防撞车}
### 是否引入了方案 doc 第 0 节里没有的新概念 / 抽象
{是 / 否。是的话说明已在第 0 节补充并做过 grep 防撞车}
### 推进顺序退出信号核对
{对照 checklist.yaml steps,逐条列出 action + exit_signal + status应全为 done}
{对照 checklist.yaml steps逐条列出 action + exit_signal + status应全为 done}
### 测试约束自检
**标准 design**:
{对照方案第 3 节测试设计,每个功能点的测试约束——当前实现是否满足?靠什么保证(类型系统 / 单测 / 集成 / 运行时 assert)?}
**标准 design**
{对照方案第 3 节测试设计每个功能点的测试约束——当前实现是否满足靠什么保证类型系统 / 单测 / 集成 / 运行时 assert}
**Fastforward design**:
{对照方案第 2 节验收标准,逐条核对是否满足}
**Fastforward design**
{对照方案第 2 节验收标准逐条核对是否满足}
```
汇报完后**停下来**等用户 review。用户提修改意见按意见修订,修订完再次发简短确认,直到用户明确放行进入验收阶段。
汇报后停下等 review。用户提修改意见按意见改,改完再次发简短确认,反复直到用户明确放行进入验收阶段。
### 规则 3:不做方案外的改动
---
阅读代码时若发现值得重构的点(AGENTS.md "边实现边识别" 一节),如果**不在本次功能影响面内**,记录成后续 issue,**不要顺手改**。
## 测试用例怎么落
记录格式:
方案第 3 节测试设计里的**关键用例骨架**是实现测试的输入,不是装饰——按骨架写出完整测试用例。
```markdown
> 顺手发现:{文件:行号} {问题简述}。不在本次范围,记录待后续 issue。
```
注意一个常见误解:**测试通过 ≠ 测试约束满足**。测试通过只说明你写的那些用例都过了,但不说明每条测试约束都被某个用例覆盖了。所以汇报时要逐项确认每个功能点的测试约束都已被某个用例覆盖。
### 规则 4:术语守护
如果某条测试约束靠类型系统保证(比如 TypeScript 的类型签名直接排除了某种调用),在汇报里说明"该类型签名已落地,编译期保证"。
- 新写的类型名 / 函数名 / 变量名都要去方案 doc 第 0 节对照
- 不允许出现 doc 里没有的新概念
- 觉得需要引入新概念时,**先停下来改方案 doc 第 0 节,grep 防撞车,用户确认,再继续写代码**
## 违规信号(出现就主动叫停)
下面的任一信号出现,**你必须主动停下来告诉用户**,不要硬着头皮继续:
- 你引入了方案 doc 第 0 节没提的新概念 / 新类型 / 新抽象
- 你在一个步骤里触碰了超过方案声明的文件集
- 你写出了"顺便也优化了一下 X"这种描述
- 你的汇报内容含糊("大致完成了"、"应该没问题")
- 你开始加 `if (特殊情况) { 特殊处理 }` 这类补丁式分支——**新功能不应出现这种结构**,出现说明需求或方案漏掉了一种情况
叫停后的处理:
- 回到方案 doc,补齐遗漏(必要时新开一版方案)
- 或者撤回本步重来
- **绝不要"先这样吧,后面再改"**——这是技术债起点
## 测试用例落地规则
方案第 3 节测试设计里的**关键用例骨架**是实现测试的输入,不是点缀——实现时必须按骨架写出完整测试用例。**测试通过 ≠ 测试约束满足**——要逐项确认每个功能点的测试约束都已被某个测试用例覆盖。
如果某条测试约束靠类型系统保证,在汇报里说明"该类型签名已落地,编译期保证"。
---
## 退出条件
- [ ] `checklist.yaml` 所有 steps 的 status 都更新为 `done`
- [ ] 完成汇报已输出,用户明确 review 通过
- [ ] 没有违规信号未处理
- [ ] `checklist.yaml` 所有 steps 的 status 都更新为 `done`
- [ ] 完成汇报已输出用户明确 review 通过
- [ ] 没有未处理的"需要叫停"信号
- [ ] 第 3 节测试设计里每个功能点的测试约束都有测试覆盖fastforward 时对照第 2 节验收标准)
- [ ] 没有"顺手发现"被偷偷修掉(都进了 issue 列表)
- [ ] 没有方案外的文件改动(或改动已同步更新方案 doc)
- [ ] 没有"顺手发现"被偷偷修掉都进了 issue 列表
- [ ] 没有方案外的文件改动或改动已同步更新方案 doc
---
## 退出后
告诉用户:"所有步骤完成,方案 doc 已同步。下一步是阶段三:验证闭环。可以触发 easysdd-feature-acceptance 技能。"
告诉用户"所有步骤完成方案 doc 已同步。下一步是阶段 3验证闭环。可以触发 easysdd-feature-acceptance 技能。"
**不要自己顺手开始写验收报告**——验收阶段需要独立的 checklist 节奏。
自己顺手开始写验收报告——验收阶段需要独立的 checklist 节奏,提前进入会让验收的把关性失效
## 反模式(看到就停)
---
- ❌ 代码只写了一部分就发完成汇报——汇报只在全部步骤完成后发一次
- ❌ 汇报里写"修改了相关文件"而不列具体 file:line
- ❌ 看到方案外的代码顺手改了
- ❌ 引入新类型但没回去更新方案 doc 第 0 节
- ❌ 加 `if (用户是 X) { 特殊处理 }` 补丁分支而不停下来反思方案
- ❌ 用户 review 还没通过就自己进入验收阶段
- ❌ 测试设计里的用例骨架一条都没实现,或测试约束未逐条验证
## 容易踩的坑
- 代码只写了一部分就发完成汇报——汇报只在全部步骤完成后发一次
- 汇报里写"修改了相关文件"而不列具体 file:line
- 看到方案外的代码顺手改了
- 引入新类型但没回去更新方案 doc 第 0 节
- `if (用户是 X) { 特殊处理 }` 补丁分支而不停下来反思方案
- 用户 review 还没通过就自己进入验收阶段
- 测试设计里的用例骨架一条都没实现,或测试约束没逐条验证
+60 -78
View File
@@ -1,133 +1,115 @@
---
name: easysdd-feature
description: 新功能开发子工作流入口——检查已有产物,路由到 brainstorm/design/implement/acceptance。触发场景:"做新功能"、"加个 X 能力"、"有个新需求"、"帮我实现 XX",且不属于 BUG 修复。已知阶段意图优先触发对应子技能
description: 新功能开发时进入这套子流程——把"加个 X 能力"从模糊想法走到验收闭环中间有方案文件做存档AI 和用户后面回头都能查到当时怎么想的、为什么这样定的。触发场景偏向新增能力("做新功能"、"加个 X"、"实现 XX"),不处理已有代码的 bug。本技能只做路由根据已有产物决定下一步走 brainstorm / design / fastforward / implement / acceptance 中的哪一个
---
# easysdd-feature
**easysdd 家族的新功能开发子工作流**——从模糊想法到验收闭环,全程有 spec 存档,防止术语撞车、范围失控、设计决定无从追溯
新功能开发是 easysdd 里走得最完整的一条流程。AI 直接拿到需求就写代码,三个老问题会反复出现——名字跟原代码对不上、改着改着改出范围、改完不留存档。这条流程在"需求"和"代码"之间塞了一份方案文件,让两边都有个交接点
本技能是路由中心,不替代子技能干活。
整套流程是这样的:
```
(想法还模糊时先 brainstorm) → 方案设计(含测试设计)→ 分步实现 → 验收闭环
```
本技能本身不写代码、不写文档,只做一件事:看一下当前 feature 走到哪一步了,告诉用户该触发哪个子技能。
---
## 一、为什么需要 feature 工作流
## 文件放哪儿
直接把需求丢给 AI 写代码会遇到术语撞车、范围失控、不留存档三大问题(详见根技能 `easysdd` 第一节)。
easysdd-feature 在"需求"和"代码"之间加缓冲层:
```
(想法模糊时 brainstorm) → 方案设计(含测试设计) → 分步实现 → 验收闭环
```
---
## 二、目录安排
本节是 easysdd-feature 子工作流目录约定的唯一定义处。
### feature 目录位置
`easysdd/features/` 下,每个 feature 一个子目录 `{feature}/`,里面住着该 feature 的所有 spec 产物:
整套 feature 流程的产物都聚在 `easysdd/features/` 下,每个 feature 一个独立目录:
```
easysdd/
└── features/ ← feature 聚合根
└── {feature}/ ← feature 目录
├── brainstorm.md ← brainstorm noteStage 0可选)
├── design.md ← 方案 docStage 1 YAML frontmatter + 测试设计)
├── checklist.yaml ← 行动清单Stage 1 生成,Stage 2/3 更新
└── acceptance.md ← 验收报告Stage 3
└── features/
└── {feature}/
├── brainstorm.md ← 阶段 0 的产物(可选)
├── design.md ← 阶段 1 的方案文件(带 YAML frontmatter + 测试设计)
├── checklist.yaml ← 阶段 1 顺手生成2/3 阶段更新
└── acceptance.md ← 阶段 3 的验收报告
```
**feature 目录命名格式**`YYYY-MM-DD-{英文 slug}`
目录命名是 `YYYY-MM-DD-{英文 slug}`
- **日期前缀**:取该 feature 目录**首次创建**当天的日期,一经确定不变(哪怕后续 slug 改了,日期前缀也不动)
- **英文 slug**:小写字母 + 数字 + 连字符,简短能一眼看出功能(如 `user-auth``export-csv`
- 两部分用连字符 `-` 连接
- 日期取**首次创建当天**,定了就不动——后续 slug 改了,日期前缀也保持原样
- slug 用小写字母、数字、连字符,简短能一眼看出做的是什么(`user-auth``export-csv` 这种
> `{feature}` 是占位符,代表具体 feature 目录名。正文用自然语言术语(方案 doc、feature 目录),字面路径看上面目录树
为什么所有产物聚在一个目录?这样以后回头查"上次那个导出 CSV 的功能当时怎么决定的"brainstorm、design、acceptance 都在一处,不用东找西找。这也是为什么 feature 和 issue 的产物分别放在 `easysdd/features/``easysdd/issues/`——两类问题的归档逻辑不一样,混在一起后面找东西会乱
### 组织规则
1. **一个 feature = 一个 feature 目录**。同一 feature 的 brainstorm / design / acceptance 永远聚合在一起,不允许分散
2. **brainstorm note 也归属 feature 目录**。Stage 0 开始时 slug 未定AI 根据对话内容自拟临时 slug 并告知用户用户有异议再改不用专门确认Stage 1 design 如果改了 slug只改 slug 不改日期前缀,整个目录一起重命名
3. **feature 和 issue 的产物不要混**`easysdd/features/``easysdd/issues/` 是并列的,不允许交叉存放
如果实现 feature 时顺手发现了一个 bug正确做法是把它记成新的 issue**不要在 feature 的 PR 里偷偷修**。混着改会让验收时分不清"这次新增的范围到底是哪些",后面回头看也找不到为什么改了那行代码。
---
## 三、四个阶段(标准流程)
## 四个阶段
| 阶段 | 子技能 | 主导者 | 产出 |
| 阶段 | 子技能 | 产出 | 谁主导 |
|---|---|---|---|
| brainstorm可选 | `easysdd-feature-brainstorm` | AI 做思考伙伴,用户拍板 | brainstorm note |
| 方案设计(含测试设计) | `easysdd-feature-design` | AI 起草,用户整体 review 拍板 | 方案 docYAML frontmatter + 三层结构 + 测试设计)+ checklist.yaml |
| 分步实现 | `easysdd-feature-implement` | AI 按方案执行 | 代码 + 阶段汇报 |
| 验收闭环 | `easysdd-feature-acceptance` | AI 逐层核对方案,用户终审 | 验收报告 + 架构归并 + 收尾提交确认 |
| 0 brainstorm可选 | `easysdd-feature-brainstorm` | brainstorm.md | AI 做思考伙伴,用户拍板 |
| 1 方案设计 | `easysdd-feature-design` | design.md + checklist.yaml | AI 起草,用户整体 review |
| 2 分步实现 | `easysdd-feature-implement` | 代码 + 阶段汇报 | AI 按方案执行 |
| 3 验收闭环 | `easysdd-feature-acceptance` | acceptance.md | AI 逐层核对,用户终审 |
**阶段之间有 checkpoint**:每个阶段退出条件未满足,下一阶段不得开始。用户明确放行,AI 不自作主张往下走
阶段之间有人工 checkpoint。为什么要这样卡?一是让用户在每个阶段结束时有一次明确的把关机会,二是防止 AI 一口气从需求跑到代码、跑出来用户才发现走偏了。所以默认情况下,上一个阶段没拿到用户明确放行,下一个阶段就别开始
**Stage 0 是可选的**只有想法明显模糊时才走。想法已经清晰的用户直接从 Stage 1 方案设计开始
阶段 0 是可选的——只有想法明显模糊时才走。如果用户已经能清楚说出"做什么、为谁做、怎么算成功",直接从阶段 1 开始更省事
## 三·五、Fastforward 模式(快速通道)
### Fastforward 模式
当用户需求**已经清晰**且功能**范围足够小**时,可以跳过完整方案设计流程,直接走 fastforward
需求已经很清楚、范围又小的时候,走完整四阶段会嫌啰嗦。这时候有 fastforward
```
用户交代需求 → AI 产出紧凑 design.md含验收标准→ 用户一次确认 → 直接实现
用户需求 → AI 写一份精简 design.md含验收标准)→ 用户一次确认 → 直接实现
```
| 触发条件 | 子技能 |
|---|---|
| 用户说"快速模式"、"fastforward"、"直接开干"、"别那么多步骤" | `easysdd-feature-fastforward` |
触发:用户说"快速模式"、"fastforward"、"直接开干"、"别那么多步骤"这一类,去 `easysdd-feature-fastforward`
fastforward 的 `design.md`标准流程共用同一 feature 目录,但同样必须带统一 YAML frontmatter正文内容是精简的 4 节结构(需求摘要 + 设计方案 + **验收标准** + 推进步骤)验收标准在这里就写好,不留占位,后续 `easysdd-feature-acceptance` 直接从中抽取验收点;确认后同样生成 `checklist.yaml`
fastforward 的 design.md标准流程共用同一 feature 目录,frontmatter 也一致,只是正文压成 4 节(需求摘要 + 设计方案 + 验收标准 + 推进步骤)验收标准在这里就写好,不留占位——因为后面 acceptance 阶段会直接从这里抽
**不适合 fastforward 的情况**:跨多个子系统、有术语撞车风险、推进步骤超过 4 步——遇到这些情况告知用户走标准流程。
什么时候**别**走 fastforward跨多个子系统、有术语撞车风险、推进步骤超过 4 步遇到这几种情况就劝用户走标准流程,原因是范围一大,跳过 design 阶段意味着 AI 和用户在同一份方案上没对齐过,实现完很容易发现彼此理解的不是同一回事
---
## 四、路由:用户该用哪个子技能
## 路由:用户现在该走哪个子技能
启动本技能后,先 **Glob 检查 `easysdd/features/` 下的已有产物**不要只听用户口头描述用户说"设计写完了"不等于方案真的完整——主动读一遍确认
### 路由表
进入本技能后,先 Glob 一下 `easysdd/features/` 看已经有哪些产物。**不要只听用户口头描述**——用户说"设计写完了"不一定真完整,自己读一遍才有数
| 当前状态 | 触发哪个子技能 |
|---|---|
| 只有模糊想法,说不清真问题、边界、或"不做什么" | 询问用户是否先走 brainstorm见下方判断注意事项 |
| 只有想法但已经清晰(知道做什么、为谁、怎么算成功) | `easysdd-feature-design` |
| 用户主动说"先 brainstorm 一下 / 帮我想想" | `easysdd-feature-brainstorm` |
| 用户说"快速模式"、"fastforward"、"直接开干"、"别那么多步骤" | `easysdd-feature-fastforward` |
| brainstorm note 已存在,用户说"可以进设计了" | `easysdd-feature-design` |
| 方案 doc 三层结构完整(含不变量与架构关系),但代码还没动 | `easysdd-feature-implement` |
| fastforward design.md 已确认(含 YAML frontmatter + 验收标准) | `easysdd-feature-implement` |
| 代码已写完,要做验收 | `easysdd-feature-acceptance` |
| 不确定方案 doc 是否完整 | 自己读一遍,按上面的表对号入座 |
| 想法模糊,说不清真问题 / 边界 / 不做什么 | 问一下要不要先走 brainstorm判断方法见下) |
| 想法清晰(知道做什么、为谁、怎么算成功) | `easysdd-feature-design` |
| 用户主动说"先 brainstorm 一下" | `easysdd-feature-brainstorm` |
| 用户说"快速模式"、"fastforward" | `easysdd-feature-fastforward` |
| brainstorm.md 已存在,用户说可以进设计了 | `easysdd-feature-design` |
| design.md 三层结构完整、代码还没动 | `easysdd-feature-implement` |
| fastforward design.md 已确认 | `easysdd-feature-implement` |
| 代码已写完,要做验收 | `easysdd-feature-acceptance` |
| 不确定 design.md 是否完整 | 自己读一遍,按上面对号入座 |
### Stage 0 的判断注意事项
### 怎么判断用户该不该走阶段 0
Stage 0 的识别信号不是"用户描述的字数少",而是"用户能不能清楚说出这三项"
判断信号不是"用户描述的字数少",而是用户能不能清楚说出这三件事
- 要解决的**真问题**是什么
- 用户感知的**核心行为**是什么
- 有没有一条明确的**"不做什么"**
- 要解决的真问题是什么
- 用户感知的核心行为是什么
- 有没有一条明确的"不做什么"
三项只要有一项模糊,就是 Stage 0 的候选。但 Stage 0 **不强制**:如果用户明确说"我想清楚了,直接做设计",不要强行拉他去 brainstorm。如果不确定问用户一次让用户选——宁可漏判(让用户直接进设计)也不要误判(逼用户做觉得多余的发散)。
三项有一项模糊,brainstorm 就值得走。但别强推——如果用户明确说"我想清楚了,直接做设计",就尊重他的判断。不确定的时候问一句让用户选宁可漏判(让用户直接进设计),也别误判(逼一个想清楚的用户做觉得多余的发散)。
---
## 五、与 easysdd-issue 工作流的边界
## issue 工作流的边界
- **feature 工作流处理**:新功能、新能力——"从来没有的东西要加进来"
- **issue 工作流处理**:已有代码里的 BUG、异常行为、文档错误——"本来应该好的东西坏了"
- **灰色地带**:如果在 feature 实现阶段发现了顺手可以修的 BUG**记录为 issue不在 feature PR 里偷偷修**。保持每条路径的退出条件清晰;混路径会让 checkpoint 失效
- feature 处理"从来没有的东西要加进来"——新功能、新能力
- issue 处理"本来应该好的东西坏了"——bug、异常、文档错误
灰色地带在前面已经讲过feature 实现时发现的 bug 记成新 issue不在 feature PR 里顺手修。
---
## 六、相关文档
## 相关文档
- `easysdd/SKILL.md` — easysdd 家族根技能,跨阶段共同约束在那里
- `AGENTS.md` — 全项目代码规范feature 实现时同样遵守
- 架构总入口 — 方案设计阶段需要查
- 项目架构总入口 — 方案设计阶段需要查
+236
View File
@@ -0,0 +1,236 @@
# 什么是 Skill——写之前先读这份
在 Claude Code 里你经常干这种事:每开一个新会话,都要把同一份操作手册贴进聊天——部署步骤、提交规范、某个框架的 API 约定、某种文档的固定写法。贴久了烦,也容易忘贴。
Skill 就是把这份手册变成一个带着 YAML 头的 Markdown 文件放在约定位置Claude 会在需要的时候自己把它读进来。跟 CLAUDE.md 不同的地方是CLAUDE.md 是每次会话一开始就全文塞进上下文的skill 的正文平时不占上下文,只有 Claude 判断该用的时候才展开。所以你可以堆一堆长篇的参考材料,平时不花钱,用的时候才花。
Skill 和过去的 custom command 已经合并。`.claude/commands/deploy.md``.claude/skills/deploy/SKILL.md` 都生成 `/deploy` 斜杠命令。skill 比 command 多了一个目录装周边文件、支持 frontmatter 控制触发行为、以及让 Claude 自己按相关性调用。
---
## 放哪里
| 放的位置 | 路径 | 谁能用 |
|---|---|---|
| 个人 | `~/.claude/skills/<skill-name>/SKILL.md` | 你所有项目 |
| 项目 | `.claude/skills/<skill-name>/SKILL.md` | 只在这个项目 |
| Plugin | `<plugin>/skills/<skill-name>/SKILL.md` | 装了这个 plugin 的地方 |
| Managed | 企业统一下发 | 全组织 |
同名冲突时优先级enterprise > personal > project。plugin 用 `plugin-name:skill-name` 命名空间隔离不跟别的冲突。skill 和老的 `.claude/commands/` 同名时skill 优先。
---
## 一个 skill 长什么样
每个 skill 是个目录,入口是 `SKILL.md`
```
my-skill/
├── SKILL.md ← 必须,主入口
├── reference.md ← 可选,详细参考材料(按需加载)
├── examples.md ← 可选,例子
└── scripts/
└── helper.py ← 可选,脚本,由 Claude 执行不加载为上下文
```
`SKILL.md` 必须有,其他都可选。周边文件要在 `SKILL.md` 里用链接或说明引用出来Claude 才知道它们存在、什么时候该读。
---
## SKILL.md 的 frontmatter 字段
正文前面用 `---` 包一段 YAML规定这个 skill 的行为:
```yaml
---
name: my-skill
description: 这个 skill 干什么、什么时候用
disable-model-invocation: false
user-invocable: true
allowed-tools: Read Grep
---
```
只有 `description` 是推荐填的。所有字段:
| 字段 | 作用 |
|---|---|
| `name` | 斜杠命令名。不填就用目录名。只能小写字母、数字、连字符,最多 64 字符 |
| `description` | **关键字段**。Claude 靠这个判断什么时候自动调用这个 skill。不填就取正文第一段 |
| `when_to_use` | 补充触发条件和常见触发词。跟 `description` 合起来在 skill 列表里最多 1536 字符,超了被截断 |
| `argument-hint` | 自动补全时提示参数形式,比如 `[issue-number]` |
| `disable-model-invocation` | `true` 时 Claude 不会自动调用,只能用户手动 `/name` 触发。适合有副作用的操作(部署、提交、发消息) |
| `user-invocable` | `false` 时不在 `/` 菜单里显示,只让 Claude 自己按需调用。适合"背景知识"型的 skill |
| `allowed-tools` | 这个 skill 激活时 Claude 可以免审核使用的工具。空格分隔 |
| `model` / `effort` | 这个 skill 激活时用哪个模型 / 花多少思考预算 |
| `context: fork` | 把这个 skill 放进 fork 出来的 subagent 跑,不污染主上下文 |
| `agent` | 搭配 `context: fork` 用,指定用哪种 agent`Explore` / `Plan` / `general-purpose` / 自定义) |
| `hooks` | 绑定到这个 skill 生命周期的 hook |
| `paths` | glob 模式。设了以后 Claude 只在操作匹配路径的文件时自动调用 |
| `shell` | 内联 shell 命令用什么解释器,默认 `bash`,可选 `powershell` |
`name` 必须跟目录名一致。改 name 等于改目录名。
---
## description 为什么这么要紧
Claude 判断要不要调用一个 skill只能看 `description``when_to_use` 两段话。正文平时不在它的上下文里。所以 description 必须:
1. **写清楚这个 skill 做什么**——不是"关于 X 的",而是"用来做 X"
2. **写清楚什么时候该触发**——列具体的用户说法、文件类型、任务特征
3. **front-load 最常见的触发场景**——因为尾部可能被 1536 字符限制截掉
反面教材:`description: 一个关于 API 设计的 skill`——Claude 不知道是该在写 API 时触发、还是在 review API 时触发、还是在解释 API 给新人听时触发。
好例子:`description: 写新的 API endpoint 时触发——检查命名约定、错误返回格式、请求验证。触发词:"加一个接口"、"新 endpoint"、"implement API"。不覆盖 GraphQL只管 REST。`
写 description 时有个小陷阱Claude 默认**偏少触发**,怕用错。所以 description 要**稍微往"推销"的方向写一点**——"即使用户没明说 X只要任务有 Y 特征就触发",比中性描述更有效。
---
## 渐进式加载progressive disclosure
Skill 体系有三层:
1. **Metadata**name + description——一直在 Claude 上下文里,判断是否触发用
2. **SKILL.md 正文**——触发后才加载进上下文
3. **周边文件 / 脚本**——Claude 按 SKILL.md 的指引按需读取;脚本是执行的,不加载为上下文
这决定了 SKILL.md 的体积管理:
- 官方建议 SKILL.md **控制在 500 行以内**
- 超了就把详细参考API 细节、长例子、完整模板)拆到同目录 `reference.md` / `examples.md`
- 在 SKILL.md 里明确说"详细看 reference.md"Claude 才知道什么时候读
注意skill 一旦触发SKILL.md 的渲染结果**进入会话就留在那里**,后面不会重新读文件。所以写 SKILL.md 要写成"贯穿整个任务的指引"而不是"一次性步骤"。
---
## Skill 内容的两种性质
思考一下你的 skill 属于哪一种,会影响怎么写:
**参考型Reference**——给 Claude 补一套背景知识让它用在当前对话里。API 约定、代码规范、项目领域知识、某个库的坑。这类 skill 让 Claude 按需触发即可,`disable-model-invocation` 留默认。
**任务型Task**——指导 Claude 做一个特定的多步动作。部署、提交、生成某种文档。这类你通常希望自己手动触发(`/skill-name`),所以给它加 `disable-model-invocation: true`
两种的写法也不同:参考型像文档("遇到 X 时考虑 Y"),任务型像 playbook"第一步、第二步、第三步")。
---
## 传参数给 skill
skill 里用 `$ARGUMENTS` 拿到用户传的所有参数:
```yaml
---
name: fix-issue
description: 修 GitHub 上的某个 issue
disable-model-invocation: true
---
修 GitHub issue $ARGUMENTS按项目代码规范来。
```
用户跑 `/fix-issue 123`Claude 收到的就是"修 GitHub issue 123按项目代码规范来"。
拿单个参数用 `$ARGUMENTS[N]` 或简写 `$N`0-based
```yaml
Migrate $0 component from $1 to $2.
```
用户跑 `/migrate SearchBar React Vue``$0` = `SearchBar``$1` = `React``$2` = `Vue`。多词参数用引号包:"hello world"。
---
## 动态注入上下文
SKILL.md 里可以写 `` !`<shell command>` ``,在 skill 发给 Claude 之前执行命令,把输出替换到 placeholder 里。适合给 skill 注入实时数据。
```yaml
---
name: pr-summary
description: 总结一个 PR 的改动
allowed-tools: Bash(gh *)
---
## PR 信息
- diff: !`gh pr diff`
- 评论: !`gh pr view --comments`
## 任务
总结这个 PR……
```
多行命令用 ` ```! ` 开头的代码块。Claude 收到的是命令**运行完的结果**,不是命令本身。
---
## 让 skill 在 subagent 里跑
`context: fork` + `agent: Explore`(或别的 agent 类型skill 在一个新开的隔离上下文里跑,不看当前会话历史。适合"我要研究一下 X"这种只需要产出一份总结、不需要主会话上下文的任务。
```yaml
---
name: deep-research
description: 深入研究一个话题
context: fork
agent: Explore
---
深入研究 $ARGUMENTS
1. 用 Glob 和 Grep 找相关文件
2. 读代码、分析
3. 总结发现,给出具体文件引用
```
注意:`context: fork` 只对有明确任务的 skill 有意义。纯"约定文档"型的 skill"写 API 时用这些命名"fork 进去只会看到约定但没任务,什么都不做就返回。
---
## 免审核工具 allowed-tools
`allowed-tools` 字段授权 skill 激活时可以免审核调用指定工具:
```yaml
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
```
这不限制有哪些工具可用(别的工具还是能调,只是会触发权限提示),只是对列出的工具免审核。
---
## 常见坑
**Skill 不触发**
- 看 description 里有没有用户会自然说出的关键词
- 在 Claude Code 里问 "What skills are available?" 确认 skill 被发现了
- 重新措辞请求,往 description 里的说法靠
- 直接用 `/skill-name` 强制触发
**Skill 触发太频繁**
- description 写得更具体,缩小触发范围
- 加 `disable-model-invocation: true` 改成只手动触发
**Description 被截断**
- 多个 skill 挤在一起时,每个 description 会被截到适配字符预算
- 把最重要的触发场景前置到 description 开头
- 单个 skill 的 description + when_to_use 合起来 1536 字符上限,超了也被截
- 环境变量 `SLASH_COMMAND_TOOL_CHAR_BUDGET` 可以调高总预算
**Skill 触发后效果慢慢消失**
- SKILL.md 内容在会话里不会重新读取,只是模型可能选了别的工具/方式
- 写"贯穿任务的指引"而不是"一次性步骤"
- 用 hooks 做硬强制
- 长会话压缩后重新 `/skill-name` 再调用一次恢复上下文
---
## 进一步参考
- 官方文档https://code.claude.com/docs/en/skills
- Agent Skills 开放标准https://agentskills.io
- 相关:[Subagents](https://code.claude.com/docs/en/sub-agents)、[Plugins](https://code.claude.com/docs/en/plugins)、[Hooks](https://code.claude.com/docs/en/hooks)、[Permissions](https://code.claude.com/docs/en/permissions)
+15 -1
View File
@@ -1,6 +1,6 @@
---
name: writing-to-explain
description: 写任何"让人看懂某件事"的散文时先用这个技能——教程、使用说明、科普、技术博客、讲解型随笔、README 开头、SKILL.md 开头、系统总入口、给新人讲"这是什么"。强制触发场景:用户说"写文档"、"写教程"、"写介绍"、"写科普"、"写博客"、"解释一下 X"、"讲讲 X 是怎么回事"、"写 README"、"重写这段"、"这段太 AI 味了"、"写得像人话"。即使用户没明说,只要任务是产出面向人类读者、目的是让 TA 理解某件事的散文都优先触发——AI 默认写出来的东西擅长展示知识结构不擅长把理解搭进读者脑子里需要这个技能纠正。不适用于规则手册、API 参考、操作步骤这类追求完备性的技术参考文档
description: 写任何目的是让另一个脑子建立理解的东西时触发——教程、使用说明、科普、技术博客、README、SKILL.md、给 AI 读的指令文档、解释型随笔、架构说明、onboarding 材料。关键判断:输出要在读者(人或 AI脑子里建立对某件事的真正理解而不只是罗列事实或列举规则。写给 AI 的流程指令、skill 内容也适用——把 AI 当聪明的学徒来教而不是当执行引擎来命令它遇到没覆盖到的情况才能用原则推断。不适用于严格的参考资料API 字段表、schema 定义、参数列表)
---
# writing-to-explain
@@ -75,6 +75,19 @@ AI 默认会把难的地方一笔带过或用更抽象的词糊过去。糊过
AI 默认把人格磨平了——输出中性说明文体。这种文体最容易写,也最没读头。动笔前问自己:如果这段话是当面跟朋友讲,我会怎么讲?照那个讲法写下来。
## 教会读者,不要命令读者(写给 AI 也一样)
写给人的文章不会用 "你必须 X"、"绝对不要 Y" 这种口气——会显得居高临下。但 AI 写给 AI 读的指令文档SKILL.md、流程文件、规则集就特别爱用 MUST / NEVER / ALWAYS / 严禁 / 必须,以为这样更"硬"、更可靠。
其实反过来。命令式的规则只覆盖列出来的那几种情况,遇到没列到的边界情况,执行端只会两种反应:要么死板照搬规则结果做错事,要么完全失去判断依据瞎猜。教学式的说明把**为什么这样做**讲清楚,执行端遇到新情况能用原理自己推——"哦原来是为了避免 X那这种情况下应该 Y"。
写给 AI 跟写给聪明学徒一个道理:你不会跟一个新来的工程师说"提交前必须运行 lint",你会说"提交前跑一下 lint不然 CI 会挂,回头还得再推一次很烦"。后者 TA 才知道遇到 lint 挂了该怎么权衡,遇到 CI 改了配置该怎么调整。
这个原则也适用于写 skill 的 description——别堆"触发词列表:'加功能'、'新接口'、'实现 X'……"。AI 调用 skill 时是看概念匹配的,给概念("做新功能开发时触发")比给死字符串列表覆盖面更广,遇到用户用了没列到的说法也能命中。
自检:写的指令里凡是出现 MUST / NEVER / ALWAYS / 严禁 / 必须,停一下问"我有没有讲为什么?"没讲就补上原因,让读者(人或 AI能在边界情况里自己判断。规则越硬执行端越呆。
## 沿着阅读时间线推演读者状态
写每一段时都在模拟读者读完上一段后脑子里的状态TA 现在懂了什么、还不懂什么、下一秒最想问什么、有没有动力继续。下一段恰好对接 TA 当下的状态。
@@ -104,5 +117,6 @@ AI 默认把人格磨平了——输出中性说明文体。这种文体最容
- 文章有没有作者的声音?全是中性说明文体就没了
- 每段第一句连起来读,是不是一条读者会自然走过去的认知路径?跳跃就重排
- 参考/导航节被写成对话句了吗?换成中性陈述
- 有没有 MUST / NEVER / ALWAYS / 严禁 这种硬命令?讲了为什么吗?没讲就补原因,让读者能自己判断边界
- 有没有自己压出来的复合词(翻车、收口、落档、范围失控这类)?换回大白话
- 删掉任意一句话,读者还能不能顺着认知路径走完?能就该删