| name | skill-chain-planner |
| description | Decompose complex tasks into multi-skill chains with a two-layer execution model (deterministic orchestrator + inner tool-call loop), reliability pillars (cache-first / tool-call repair / cost & budget guard), feedback loops, degradation matrix, execution state machine, and security review. Generates step-by-step plans for using `skill-for-skills` to construct each skill and compose them into a working pipeline. Triggered by: "任务分解", "skill链规划", "复杂任务拆分", "多skill协作", "chain planner", "工作流拆分", "多步骤任务", "skill pipeline", "架构规划", "多步工作流", "pipeline设计", "skill依赖分析", "skill编排", "任务流水线", "可靠性规划", "降级矩阵", "执行状态机", "反馈循环", "预算守卫", "两层执行模型". |
| version | 2.0.0 |
| metadata | {"tags":"planning, architecture, workflow, skill-chain, decomposition","output_template":"templates/data-exchange-format.md"} |
| allowed-tools | Read Write Glob WebSearch |
| context | fork |
| agent | Plan |
Skill Chain Planner
Purpose
根据用户描述的复杂任务,输出一份完整的 Skill 链创建规划:将任务拆解为多个单一职责的子 Skill,设计各 Skill 之间的数据流转与执行顺序,并指导用户如何使用 skill-for-skills 逐个创建这些 Skill,最终组合为可工作的 Skill 链。
本 Skill 不直接生成任何 Skill 文件,它只输出规划文档,让用户拿着规划去使用 skill-for-skills。
When to Use
- 用户描述了一个多步骤的复杂任务,需要一个以上 Skill 协作完成
- 用户发现单个 Skill 无法高效完成某个工作流,需要拆分为多个专注的子 Skill
- 用户需要将一个现有的大流程拆解为多个 Skill 的流水线
- 用户不清楚如何组合使用多个 Skill 解决实际问题
- 用户需要一份"先创建什么、再创建什么、最后如何串联"的行动指南
When NOT to Use
- 用户只想创建一个简单的单 Skill 任务 —— 应直接使用
skill-for-skills
- 用户询问 Skill 概念或规范本身 —— 应引导阅读
skill-for-skills/sum.md
- 用户描述的已经是单一职责的简单功能 —— 不需要链式分解
Workflow / Steps
Step 1: 系统化任务分析
使用 5W1H + C 框架系统化解析用户描述的复杂任务,将分析结果记录在分析草稿中:
1.1 Why(动机)
- 用户最终要解决什么根本问题?
- 不做会有什么后果?衡量标准是什么?
1.2 What(目标与产出)
- 核心目标是什么?用一句话概括。
- 最终产出物是什么?(文件、数据、报告、通知等)
- 产出物的格式和质量标准是什么?
1.3 Where(范围与边界)
- 任务涉及的范围是什么?(哪些文件/系统/数据)
- 明确的不在范围的内容是什么?
- 输出文件应保存在哪个目录下?
1.4 When(时效性)
- 是否有时间要求?(一次性任务/定期执行/实时响应)
- 数据的新鲜度要求是什么?
1.5 Who(用户与受众)
1.6 How(已知方法与工具)
- 用户已经知道要使用什么方法或工具?
- 已经有哪些现成的资源可用?(已有 Skill、已有脚本、已有数据)
1.7 Constraints(约束条件)
- 技术约束:平台限制、可用工具、网络环境
- 数据约束:数据量级(<100条 / 100-10000条 / >10000条)、格式、敏感级别
- 安全约束:是否需要处理敏感信息?输出是否可以公开?
- 质量约束:准确率要求、容错要求
1.8 初步节点识别
- 从用户描述中提取自然出现的流程节点
- 标记节点之间的关系(顺序、并行、循环、条件)
- 记录用户已明确说出的步骤和暗示存在的步骤
1.9 完整性检查
如果以上信息存在模糊或缺失(特别是 Why、What、Constraints),先输出你的理解并向用户确认,确认后再继续。确认内容应包含:
## 我对任务的理解
**核心目标**:...
**输入**:...
**输出**:...
**流程节点**:A → B → C → D
**关键约束**:...
**需要确认**:❓ 以下内容需要您补充确认——
1. 产出物格式是否有特定要求?...
2. 数据量级大约多少?...
3. ...
1.10 隐含假设验证
主动识别用户描述中隐含但未声明的假设,逐条检验其合理性:
## 隐含假设清单
### 假设 1:[描述]
- **来源**:用户说"X"但隐含假设了"Y"
- **风险**:如果这个假设不成立,会导致什么后果?
- **验证方式**:如何确认这个假设是真的?
- **结论**:✅ 合理|⚠️ 需确认|❌ 需修正
常见隐含假设类型:
- 工具可用性假设:用户假设 markitdown/某个库已安装 → 验证:检查是否有安装检测机制
- 格式兼容性假设:用户假设 A 格式可以直接转换为 B 格式 → 验证:是否存在信息丢失风险
- 性能假设:用户假设"很快就能完成" → 验证:数据量级 × 处理速度 = 预估耗时
- 环境假设:用户假设文件在某个路径 → 验证:路径是否存在?权限是否足够?
- 知识假设:用户假设你了解某个领域术语 → 验证:该术语是否需要澄清?
1.11 任务可行性预判
在开始分解前,对整体任务做一次可行性快速评估:
## 可行性预判
### 工具可行性
- 任务需要的所有工具是否在 Claude Code 能力范围内? ✅ ⚠️ ❌
- 如果涉及外部工具,是否有安装/配置指导? ✅ ⚠️ ❌
### 数据可行性
- 输入数据量是否在合理处理范围内? ✅ ⚠️ ❌
- 数据格式是否明确且可访问? ✅ ⚠️ ❌
### 复杂度评估
- 预估需要多少个子 Skill? [1-3] [4-6] [7+]
- 是否有明显的技术难点? 说明:...
- 任务是否可在一轮会话中完成? ✅ ⚠️ ❌
如果可行性评估出现 ❌,在向用户输出的理解确认中包含风险警告。
Step 2: 复杂度判定与路径选择
目标: 在进入耗时分解之前,先用评分制判断该任务是适合单个 Skill 还是需要多 Skill 链。简单任务直接输出单 Skill 推荐文件并终止,避免浪费分析成本。
基于 Step 1 的分析结果,从 5 个维度快速评估任务复杂度:
| 维度 | 评分 1(简单) | 评分 2(中等) | 评分 3(复杂) |
|---|
| 处理阶段数 | 1 个阶段(如纯转换、纯分析) | 2-3 个阶段 | 4+ 个阶段 |
| 领域跨度 | 单一领域知识 | 2 个领域 | 3+ 个领域 |
| 输出产物数 | 1 个明确产物 | 2-3 个产物 | 4+ 个产物 |
| 条件分支复杂度 | 无分支,纯线性 | 1-2 个条件分支 | 3+ 个分支或包含循环/重试 |
| 独立可复用性 | 各阶段紧密耦合,不可独立使用 | 部分阶段可独立使用 | 多数阶段有独立的复用价值 |
评分规则:
- 总分 ≤ 7:该任务适合作为单个 Skill 实现 → 走 2A 单 Skill 路径
- 总分 8-12:边界情况,默认走单 Skill 路径但标注 "可考虑拆分" → 走 2A 路径
- 总分 ≥ 13:该任务需要多 Skill 链 → 走 2B 多 Skill 链路径(继续分解)
评分结果输出格式:
## 复杂度判定
| 维度 | 评分 | 依据 |
|------|------|------|
| 处理阶段数 | {1-3} | {简述阶段} |
| 领域跨度 | {1-3} | {涉及的领域} |
| 输出产物数 | {1-3} | {产物列表} |
| 条件分支复杂度 | {1-3} | {分支情况} |
| 独立可复用性 | {1-3} | {可复用判断} |
| **总分** | **{N}** | → {单 Skill / 多 Skill 链} |
2A. 单 Skill 路径(总分 ≤ 12)
该任务无需拆分为多个 Skill。直接将 Step 1 的分析结果输出为单 Skill 推荐文件,然后终止规划流程。
输出文件:./skill-plan-{task-name}.md(项目根目录)
文件内容模板:
---
plan_type: single-skill
generated_at: "{YYYY-MM-DD HH:MM:SS}"
complexity_score: {N}/15
source: skill-chain-planner v1.5
---
# {任务名称} — Skill 规划
## 复杂度判定结果
| 维度 | 评分 |
|------|------|
| 处理阶段数 | {1-3} |
| 领域跨度 | {1-3} |
| 输出产物数 | {1-3} |
| 条件分支复杂度 | {1-3} |
| 独立可复用性 | {1-3} |
| **总分** | **{N}/15** |
**结论**:该任务复杂度较低(≤12/15),适合作为单个 Skill 实现,无需拆分为 Skill 链。
## 任务理解
- **核心目标**:{Step 1.2 的输出}
- **输入**:{Step 1.2 的输入描述}
- **输出**:{Step 1.2 的输出描述}
- **关键约束**:{Step 1.7 的关键约束}
## 建议的 Skill 规格
使用 `/skill-for-skills` 创建该 Skill 时的参考规格:
Skill 名称: {建议的 kebab-case 名称}
核心功能: {一句话 core_function}
触发词: [{3-5 个触发关键词}]
建议工具: [{从功能类型推断的工具列表}]
Workflow 步骤:
- {步骤1}
- {步骤2}
...
## 下一步操作
在 Claude Code 中输入以下命令创建该 Skill:
/skill-for-skills {核心功能描述 + 触发词}
或直接粘贴上述 Skill 规格。
输出后终止流程,不再执行后续步骤。
2B. 多 Skill 链路径(总分 ≥ 13)
该任务需要拆分为多 Skill 链。继续执行以下分解流程。
任务分解
基于 Step 1 的分析结果,将复杂任务按功能边界拆分为多个子任务。每个子任务遵循 单一职责原则——只做一件事,并且做好。
2B.1 识别节点类型
从 Step 1.8 的初步节点出发,使用四种节点类型标注每个候选子任务:
| 节点类型 | 特征 | 典型例子 |
|---|
| 转换 | 数据/文件从一种形态变为另一种形态 | docx→md, JSON→CSV, 非结构化→结构化 |
| 分析 | 需要理解、总结、判断、提取 | 内容总结、分类、质量审查、差异对比 |
| 生成 | 需要创作、撰写、组合、产出 | 写报告、生成图表、构造回复、组装模板 |
| 操作 | 读写文件、调用 API、执行命令、触发流程 | 下载文件、发送通知、清理缓存、备份 |
2B.2 选择分解模式
根据任务特征选择合适的分解模式:
| 模式 | 适用场景 | 分解方式 |
|---|
| 管道分解 | 处理流程有明显的线性阶段 | 按处理阶段切分:A_raw → A_clean → A_analyzed → A_report |
| 扇出分解 | 同一输入需要多种不同处理 | 输入同时进入多个并行子任务:A → (B1, B2, B3) |
| 分层分解 | 任务包含不同抽象层次 | 底层操作 → 中层逻辑 → 上层策略 |
| 关注点分解 | 任务混合了不同领域知识 | 按知识领域拆分:数据部分 / 算法部分 / 展示部分 |
| 阶段分解 | 任务周期长、各阶段差异大 | 准备期 / 执行期 / 验证期 / 交付期 |
2B.3 分解启发式规则
- 经验法则#1 — 每个子任务的 Workflow 不超过 5 步。如果需要超过 5 步,说明该子任务可能还可以进一步拆分。
- 经验法则#2 — 每个子任务的 description 应能在 1-2 句话内说清。如果说不清,说明粒度太大。
- 经验法则#3 — 如果两个子任务总是同时出现且顺序固定,考虑是否应合并。
- 经验法则#4 — 如果某个子任务需要多个不同领域的专业知识,考虑进一步拆分。
- 经验法则#5 — 输出物作为拆分的锚点:每个子任务应该产出 1 个明确的输出物。
2B.4 分解粒度检查
完成初步分解后,逐条检查:
停止条件判断:
- 子任务数 > 8:说明分解粒度过细 → 返回 2B.2 重新选择更粗粒度的分解模式(如将管道分解改为分层分解),或建议用户分组分阶段实施
- 子任务数 2-8:继续进入 Step 3
- 注:子任务数 < 2 的情况已在 Step 2 复杂度判定阶段(2A 路径)处理,此处不再检查
2B.5 输出——子任务清单(记录在分析草稿中)
使用以下结构化的子任务模板。字段说明中的 [类型] 标记遵循统一类型系统:text=自由文本, enum(A|B)=枚举, int=整数, bool=true/false, ref=交叉引用。
### 子任务 1: {task-name} // kebab-case, 如 doc-converter
- **类型**: [enum(转换|分析|生成|操作)] (required)
- **描述**: [text, max=200] (required) — 一句话描述该子任务做什么
- **输入**: [text] (required)
- 来源: ref(用户|上游Skill名|文件系统)
- 格式: [text] (required) — 如 .md, .json, .csv
- **输出**: [text] (required)
- 产物: [text] (required) — 如 "转换后的markdown文件"
- 路径: [path] (required) — 如 ./<skill-name>/output/
- 格式: [text] (required)
- **上游依赖**: [ref(null|子任务名)] (required) — null=起始任务
- **下游影响**: [ref(子任务名)] (optional)
- **Tags**: [list<text>] (optional) — 如 ["文档处理", "格式转换"]
### 子任务 2: {task-name}
// ... 同上结构
2B.6 隐式耦合检测
检查子任务之间是否存在"看不到却相互依赖"的隐式耦合:
## 隐式耦合检查清单
### 文件级耦合
- [ ] 是否有两个子任务读写了同一文件?(→ 存在竞态风险)
- [ ] 是否有子任务依赖特定文件名但该文件名未被契约约束?(→ 命名冲突风险)
- [ ] 是否有子任务修改了共享目录下的文件但不负责清理?(→ 残留文件风险)
### 环境级耦合
- [ ] 是否有子任务依赖特定的工作目录?(→ 路径假设风险)
- [ ] 是否有子任务依赖环境变量或配置文件?(→ 环境不一致风险)
- [ ] 是否有子任务依赖系统命令或 PATH?(→ 跨平台风险)
### 时序级耦合
- [ ] 是否有子任务假设某个文件在特定时间点已存在?(→ 时序风险)
- [ ] 是否有子任务假设其他子任务已完成特定操作?(→ 隐式顺序依赖)
- [ ] 并行执行的子任务是否可能互相干扰?(→ 并发风险)
### 语义级耦合
- [ ] 是否有两个子任务使用不同命名但指代同一概念?(→ 术语不一致风险)
- [ ] 是否有子任务假设了其他子任务内部的实现细节?(→ 封装破坏风险)
- [ ] 是否有子任务依赖的数据格式标准未在契约中明确定义?(→ 隐含格式假设)
发现耦合时:
- 文件级/环境级耦合 → 在 Step 3 契约中明确定义共享资源的访问协议
- 时序级耦合 → 在 Step 4 架构中明确串行化或加锁
- 语义级耦合 → 建立公共术语表,统一命名
2B.7 边界任务推断
主动推断用户未提及但逻辑上必需的边界任务:
## 边界任务推断
### 初始化类任务
- 是否需要创建输出目录?谁负责创建?何时创建?
- 是否需要检查依赖是否已安装?谁负责检查?
- 是否需要下载原始数据?从哪里下载?
### 清理类任务
- 中间文件是否需要清理?何时清理?谁负责清理?
- 临时下载的文件是否需要删除?
- 失败时是否需要回滚已产生的中间结果?
### 验证类任务
- 每个子任务的输出是否需要格式验证?
- 链的最终结果是否需要整体验证?
- 是否需要对比预期输出和实际输出?
### 通知类任务
- 任务完成时是否需要通知用户?
- 任务失败时是否需要输出详细的错误报告?
- 长时间运行的任务是否需要进度通知?
推断原则: 如果某个边界任务对于链的正确运行是必需的,则将其作为独立子任务加入清单(返回 2B.1 重新标记)。如果只是"锦上添花"的优化,则在 Step 4 架构设计的 Notes 中记录。
Step 3: 定义 Skill 接口契约
在进入架构设计之前,先为每个子 Skill 定义清晰的接口契约。接口契约是 Skill 之间协作的合同,必须先于架构设计确定。
3.1 定义输入契约
对每个子任务,明确回答:
输入来源:
- 上游 Skill 名称:...
- 用户直接提供:...
- 从文件系统读取:...(路径格式)
输入格式:
- 文件格式:.md / .json / .csv / .txt / ...
- 数据结构:字段列表、类型、是否必填
- 数据量预期:<1KB / 1KB-1MB / >1MB
输入验证规则:
- 必填字段缺失时怎么办?
- 格式不正确时怎么办?
- 数据为空时怎么办?
3.2 定义输出契约
对每个子任务,明确回答:
输出物名称:...
输出格式:.md / .json / .csv / ...
保存路径:./<skill-name>/<分类目录>/<文件名>
关键字段:...
输出验证标准:
- 如何判断输出是正确的?
- 如何判断输出是完整的?
3.3 定义错误契约
每个子 Skill 必须定义以下三种情况的行为:
| 情况 | 行为要求 |
|---|
| 输入不合法 | 记录错误信息后终止,向前端输出明确的错误信息 |
| 执行过程中异常 | 尽可能输出已处理的部分结果 + 错误信息 |
| 下游依赖不可用 | 重试 X 次(默认 3 次)后报错,给出替代建议 |
3.4 契约一致性校验
逐对检查上下游 Skill 的接口契约是否匹配:
循环依赖检测: 检查整个依赖图中是否存在 A → B → C → A 的循环。发现循环时:
- 识别循环链中的各个 Skill
- 检查是否有 Skill 可以合并以打破循环
- 如果无法合并,返回 Step 2 重新审视分解方式,消除不必要的交叉依赖
3.5 输出——接口契约文档(记录在分析草稿中)
每个 Skill 的接口契约使用以下精确模板。扩展字段可通过 x- 前缀追加。
### Skill: {skill-name} // ref: 子任务清单中的名称
- **schema_version**: "1.0" // 接口契约版本号
- **input**:
- source: [enum(upstream|user|filesystem)] (required)
- upstream_skill: [ref(null|skill-name)] — 当 source=upstream 时必填
- format: [enum(.md|.json|.csv|.txt|.yaml|.xml|binary)] (required)
- encoding: [text] (optional, default="utf-8")
- schema: [text] (optional) — 字段列表、类型、是否必填
- validation_rules: [list<text>] (optional)
- 空值: [text] — 数据为空时的行为
- 格式错误: [text] — 格式不匹配时的行为
- 字段缺失: [text] — 必填字段缺失时的行为
- **output**:
- artifact: [text] (required) — 输出物名称,如 "清洗后的数据文件"
- format: [enum(.md|.json|.csv|.txt|.yaml|.xml|binary)] (required)
- path: [path] (required) — 如 ./<skill-name>/output/<file>.<ext>
- fields: [list<text>] (optional) — 输出包含的关键字段列表
- verification: [list<text>] (optional)
- correctness: [text] — 如何判断输出是正确的(如 "抽样验证 JSON schema")
- completeness: [text] — 如何判断输出是完整的(如 "行数与输入一致")
- **error_handling**: [object] (required)
- on_invalid_input: [text] — 输入不合法时的行为
- on_execution_error: [text] — 执行中异常时的行为
- on_dependency_failure: [text] — 下游不可用时的行为(含重试次数和间隔)
- **stability**: [enum(stable|candidate|experimental)] (optional, default="stable")
// stable=已固化, candidate=可能微调, experimental=可能大改
- **extensions**: [object] (optional) — 自定义扩展字段
3.6 隐式状态传递检测
识别契约中未明确定义但实际存在的状态传递路径:
## 隐式状态检测清单
### 文件系统状态
- [ ] 下游 Skill 是否假设输入文件在某个特定绝对路径?(→ 应在契约中显式定义路径)
- [ ] 下游 Skill 是否假设工作目录与上游相同?(→ 应在契约中约定工作目录)
- [ ] 下游 Skill 是否依赖上游在输出文件之外创建的任何文件?(→ 应显式加入契约)
### 环境状态
- [ ] 是否有子任务依赖之前步骤设置的环境变量?(→ 环境变量应记录在契约中)
- [ ] 是否有子任务依赖系统默认编码/时区/语言?
- [ ] 是否有子任务依赖特定的 Shell 状态(如$? 退出码)?
### 内存状态
- [ ] Skill 之间是否传递了文件名之外的任何隐式状态?(如"第一个文件的第 X 行")
- [ ] 是否假设了"数据已排序""数据已去重"等未被契约保证的状态?
### 修复策略
发现隐式状态传递时:
- 如果是必需的依赖 → 显式加入契约(Step 3),作为输入字段
- 如果不是必需但存在风险 → 在契约中注明"注意:下游不应假设 XXX"
3.7 静默降级识别
检查接口契约中"看起来正常但实际异常"的场景——这是最难排查的问题来源:
## 静默降级检查表
### 内容层面
- 输出格式正确但内容为空 → 下游是否得到正确的空数据标记?
- 输出字段都存在但值异常(如全部为 null)→ 是否有字段级校验?
- 输出是一个合法文件但实际是错误提示(如"404 Not Found"写入 out.md)→ 输出是否实际可消费?
### 边界层面
- 上游输出 0 行数据 → 下游能否正确处理空数据集?
- 上游输出 1 行数据 → 下游算法是否需要至少 2 行才能运行?
- 上游输出超过 10000 行数据 → 下游是否有性能风险?
### 数据类型层面
- JSON 字段类型自动转换(如 "123" → 123)→ 下游是否期望字符串?
- 浮点数精度损失 → 下游是否需要精确值?
- 日期格式不一致 → 下游是否接受多种格式?
- 特殊字符/转义问题 → 下游能否正确处理包含引号、换行符的数据?
### 修复策略
每个识别出的静默降级风险应在契约中增加显式验证步骤:
"如果上游输出 X 条件,则输出明确的状态标记(如 status: empty_data),而不是让下游收到一个看似正常的空文件"
3.8 接口版本兼容性标注
预见未来接口变更的可能性,提前规划兼容策略:
## 接口兼容性标注
每个 Skill 的输出契约应标注:
### 稳定字段(Stable)
- 字段名、类型、语义在未来版本中保持不变的字段
- 下游可以安全依赖
### 候选字段(Candidate)
- 当前存在但未来可能调整的字段
- 下游应使用"防御性读取"(检查字段是否存在)
### 扩展字段(Extension)
- 预留给未来功能但当前可能为空的字段
- 下游应忽略空值
兼容性原则: 仅增加新字段,不修改或删除已有字段。如果必须修改,则提升接口版本号并在 usage-guide 中说明迁移方案。
Step 4: 设计 Skill 链架构
基于子任务清单和接口契约,设计完整的 Skill 链架构。
4.1 架构模式选择
根据 Step 2B.2 选择的分解模式和 Step 3 定义的接口契约,选择合适的架构模式:
| 模式 | 结构 | 适用场景 | 优点 | 缺点 |
|---|
| 严格管道 | A → B → C → D | 处理流程严格线性、每步依赖上一步 | 简单清晰、易于推理 | 整体延迟 = 各步之和 |
| 扇出/扇入 | A → (B,C) → D | 同一输入需要多种独立处理后再合并 | 并行提升效率 | 需要合并步骤,增加复杂度 |
| CQRS 分离 | 读链与写链独立 | 查询操作和写入操作差异大 | 读写互不影响 | 需要维护两条链 |
| 编排器模式 | Coordinator → (A,B,C) | 需要一个总控调度多个子 Skill | 集中控制、灵活调度 | 编排器自身较复杂 |
| 职责链 | A → B 或 A → C(条件分支) | 根据条件走不同路径 | 灵活应对多分支 | 分支条件需在契约中明确定义 |
| 发布-订阅 | A → 广播 → (B,C,D) | 同份输出供多个下游独立使用 | 松耦合 | 需要约定数据格式标准 |
| 分层架构 | 基础层 → 业务层 → 展现层 | 有明显抽象层次差异 | 关注点分离清晰 | 层级间调用开销 |
| 重试/补偿 | A → (失败→重试/补偿) → B | 关键步骤不能失败 | 高可用 | 补偿逻辑实现复杂 |
选择原则: 优先选择最简单的模式。管道模式是最安全的起点,仅在明确需要时才切换到复杂模式。
4.2 设计执行顺序
绘制 Skill 链执行顺序图:
# 严格串行(管道模式)
[Skill A] → [Skill B] → [Skill C] → [Skill D]
# 混行模式(扇出 + 管道)
┌→ [Skill B] ─┐
[Skill A] ┤ ├→ [Skill D] → [Skill E]
└→ [Skill C] ─┘
# 条件分支
[Skill A] → 判断条件 ─┬→ [Skill B] ─┐
└→ [Skill C] ─┴→ [Skill D]
4.3 定义数据流转
明确每个环节的数据流转方式:
- 文件传递:上游写入文件 → 下游读取文件。最简单可靠的方式。
- 中间文件统一存放在
./skill-chain-planner/plans/<task-name>/intermediate/ 下
- 文件名格式:
<步骤号>-<Skill名>-<输出物名称>.md
- 参数传递:通过
$ARGUMENTS 或位置参数传递。适合简单数据和标记。
- 混合传递:大块数据走文件,控制参数走命令行。最灵活的方式。
4.4 识别复用与合并机会
- 直接复用:是否已有现成的 Skill 可以替代某个子任务?
- 调整后复用:现有 Skill 是否需要小幅修改才能复用?→ 记录升级需求
- 合并建议:是否有多个小 Skill 适合合并为一个?(参考经验法则#3)
- 拆分建议:是否有 Skill 仍然太复杂需要进一步拆分?→ 回到 Step 2
4.5 输出——架构设计文档(记录在分析草稿中)
架构文档统一格式。通过 notes 字段承载扩展信息。
## Skill 链架构
- **schema_version**: "1.0"
### 架构模式
- **primary**: [enum(pipeline|fanout|layered|orchestrator|chain|cqrs|pubsub)] (required)
- **fallback**: [enum(...)] (optional) — 主模式不可用时的备选
- **rationale**: [text] (required) — 选择该模式的原因
### 执行顺序
- **type**: [enum(serial|parallel|hybrid|conditional)] (required)
- **flow_diagram**: [text] (required) — 文字版流程图
// 示例严格串行
[A:doc-converter] → [B:md-formatter] → [C:summarizer] → [D:report-writer]
### 数据流转表
| Step | Skill | Input Source | Output Path | Format | Protocol |
|------|-------|-------------|-------------|--------|----------|
| 1 | A | [ref] | [path] | [enum] | [enum(file|arg|mixed)] |
| 2 | B | [ref] | [path] | [enum] | [enum(file|arg|mixed)] |
### 复用决策
- **skills_existing**: [list<ref>] (optional) — 可复用的已有 Skill
- **skills_new**: [list<ref>] (required) — 需新建的 Skill
- **upgrade_needed**: [list<ref>] (optional) — 需升级的现有 Skill
### 架构质量属性
- **idempotency**: [enum(full|conditional|none)] (required)
- **observability**: [enum(full|partial|manual)] (required)
- **max_concurrency**: [int, min=1, max=16] (required) — 最大并行数
- **recovery_strategy**: [enum(restart|skip|fallback|compensate)] (required)
### extensions: [object] (optional)
// 自定义扩展,如部署约束、环境需求等
4.6 幂等性分析
检查链中每个 Skill 被重复执行时的行为——这是链的健壮性基石:
## 幂等性评估
### 天然幂等(可安全重复执行)
- 读取操作不会产生副作用
- 覆盖式写入(每次写同一路径,覆盖上次结果)
- 纯转换操作(相同的输入 → 相同的输出)
### 需注意(重复执行可能产生不同结果)
- 追加式写入(每次执行在文件末尾追加内容 → 分次执行会产生重复数据)
- 调用外部 API(第二次执行时 API 返回可能不同)
- 时间戳/随机数生成(每次执行结果不同)
- 发送通知(每次执行都会发送一次通知,可能造成骚扰)
### 修复策略
- 追加式写入 → 改为覆盖式写入,或在契约中声明"每次执行从头开始"
- API 调用 → 缓存上游 API 响应以确保重用时一致性
- 通知类 Skill → 添加重放检测机制:检查是否已在本次会话中发送过
4.7 可观测性设计
确保链中各步骤的执行状态对用户是透明的——没有"黑盒":
## 可观测性检查清单
### 进度可见性
- 用户能否知道链的执行到了哪一步?(→ 每步应有唯一标识符,执行时输出)
- 长时间运行的步骤是否有进度指示?(→ 超过 30 秒的步骤应有中间进度输出)
- 并行步骤的执行顺序是否可理解?(→ 应标明并行组关系)
### 失败可见性
- 某步失败时,用户能否获得足够的信息定位原因?(→ 错误信息必须包含:步骤名、失败原因、输入来源引用)
- 失败时是否能区分"输入错误"、"系统错误"和"未知错误"?(→ 三类错误应有不同标识)
### 结果可见性
- 用户能否方便地查看每步的中间输出?(→ 中间文件路径应在报告中列出)
- 最终产出的来源是否可追溯?(→ 每个输出字段应可追溯到来源步骤)
### 日志标准
规划中定义统一的日志格式标准供各 Skill 使用(强制包含 trace_id):
[trace_id][Step N/] 开始|进度: X/Y|成功|失败(原因)
### 链路追踪(trace_id 传播)
为整条链生成唯一 `trace_id`,贯穿所有 Skill 的日志、中间产物元数据与错误报告,使任何输出都可回溯到来源步骤:
- [ ] 是否为整条链分配唯一 `trace_id` 并写入每个中间产物文件头?(→ 失败时可快速定位来源步骤与调用)
- [ ] 每个 Skill 的错误输出是否携带 `trace_id` + 步骤名 + 输入来源引用?(→ 三件套缺一不可,否则无法回溯)
- [ ] 并行分支是否在 `trace_id` 后追加分支标识(如 `trace_id#branch-B`)?(→ 并行场景下区分分支来源)
- [ ] trace_id 是否写入 `chain-overview.md` 质量属性与 `reliability-design.md` 审计字段?(→ 规划阶段即固化追踪约定)
4.8 资源竞争分析
当链中包含并行执行的分支时,检查是否存在资源竞争隐患:
## 资源竞争检查
### 文件写入冲突
- [ ] 并行分支是否写入同一文件?(→ 竞态条件,必须串行化)
- [ ] 并行分支是否写入同一目录的同名文件?(→ 文件覆盖,必须使用唯一文件名)
- [ ] 并行分支是否读取一个正在被另一个分支写入的文件?(→ 脏读风险)
### 资源耗尽风险
- [ ] 并行执行的分支总数 × 单步内存需求是否接近内存上限?(→ 限制并行数)
- [ ] 是否有分支下载大文件的同时其他分支也在大量读写磁盘?(→ I/O 争用)
- [ ] 是否有分支使用独占资源(如不可重入的 API)?(→ 加锁或串行化)
### 修复策略
- 文件冲突 → 每个分支写入独立子目录,命名包含分支标识
- 资源耗尽 → 使用扇出控制(最大并行数 = min(CPU核数, 4))
- 独占资源 → 改为串行访问或添加排队机制
4.9 执行模型分层设计(两层执行模型)
明确链的执行采用"外层确定性编排器 + 内层工具调用循环"两层模型,避免"自由 Agent 自选工具"导致的跑偏、难复现、成本失控。这是链能否被确定性复现的根基:
## 执行模型分层
### 外层 - 确定性编排器(Orchestrator)
- 调度方式: [enum(deterministic|free_agent)] - 默认 deterministic(按固定顺序调度 pipeline)
- 执行顺序来源: 本 Step 4.2 的执行顺序图
- 职责: 组装每个 Skill 的输入(args + upstream.data)、按序调度、收集输出、做字段覆盖检查
- 禁止: 让 LLM 自由决定下一个调用哪个 Skill(易跑偏、难复现、成本高)
### 内层 - 工具调用循环(每个 LLM 驱动的 Skill)
对每个 LLM 驱动的 Skill,定义其内层循环:
1. 组装 system = 该 Skill 的 SKILL.md 指令(稳定前缀);user = args + upstream.data
2. 调用 LLM
3. 校验输出 schema(不符 → 工具调用修复:反馈校验错误重试 ≤3 → 降级默认 + 告警,status=repaired)
4. 产出结构化输出 + 审计/成本元数据
5. 字段覆盖检查(upstream 覆盖下游 args 必填)→ 不符触发上游重生成或 error
### 双轨 Skill 分类(逐个标注)
| Skill | 驱动方式 | 是否调 LLM | 内层循环 |
|-------|---------|-----------|---------|
| <name> | [enum(llm|pure_python|llm_no_skill)] | 是/否 | 有(校验+修复)/无 |
- `llm` = LLM 驱动且有对应 Skill 作 system prompt(方法论密集)
- `pure_python` = 纯确定性逻辑,无 LLM 调用(如解析/排期/导出)
- `llm_no_skill` = LLM 驱动但方法论轻,内联 prompt(暂不建 Skill)
### 分层原则
- 外层确定性,内层才允许 LLM 自由度(且受 schema 校验约束)
- 纯确定性 Skill 不进入内层循环,直接执行
- 每个内层循环独立超时、独立重试、独立降级(隔离故障域,单 Skill 失败不拖垮全链)
4.10 反馈循环与校验回流设计
若链中存在校验型 Skill(如 validate-* / check-*),设计"校验失败 → 据修复建议重跑上游 → 再校验"的反馈循环,避免一次校验不过即全链作废:
## 反馈循环设计
### 校验型 Skill 识别
- 链中是否存在校验型 Skill: [bool] - 如 validate-* / check-* / review-*
- 校验项清单: [list<text>] - 如 ["依赖闭包", "难度阶梯", "字段覆盖"]
### 失败 → 上游重跑映射
| 校验项失败 | 重跑的上游 Skill | upstream 携带 |
|-----------|----------------|-------------|
| <校验项> | [ref(skill-name)] | fixes + 原始上游数据 |
### 循环约束
- 最大重生成轮次: [int, default=2] - 超过则交付当前结果 + 标注未过项(不无限循环)
- 重跑范围: 仅重跑受影响的上游 + 其全部下游(级联),不重跑无关分支
- 终止条件: 所有校验项通过 OR 达到最大轮次
### 防振荡
- [ ] 同一校验项连续 2 轮失败是否判定为"无法自动修复"并交付+标注?(→ 防止 validate<→regenerate 死循环)
- [ ] 重跑是否携带上一轮的 fixes 作为约束?(→ 避免重复犯同一错误)
4.11 局部重生成设计
预见用户对链产出的局部不满(如"资源不够""阶段不对"),设计从受影响 Skill 起的级联重跑,避免每次都全链重生成:
## 局部重生成设计
### 可重生成性标注
| Skill | 可局部重生成 | 重跑会级联影响的下游 |
|-------|------------|-------------------|
| <name> | [bool] | [list<ref(skill-name)>] |
### 反馈 → 起始 Skill 路由
| 用户反馈类型 | 重跑起始 Skill | 级联下游 |
|------------|--------------|---------|
| <反馈> | [ref(skill-name)] | [list<ref>] |
### 版本与缓存复用
- 重生成后产物版本号 +1(如 plan.version += 1)
- 未受影响的 Skill 输出是否可缓存复用: [bool] - 是则跳过其重跑,直接复用上次输出
- 重跑范围最小化: 据 Step 4.3 数据流转图,从受影响 Skill 起级联重跑其全部下游,其余复用
### 约束
- [ ] 局部重生成是否复用全量生成的编排逻辑(仅 start_tool 不同)?(→ 避免两套编排代码)
- [ ] 反馈是否注入对应 Skill 的 args/upstream?(→ 用户反馈要能影响重跑)
Step 5: 风险评估与容错设计
在架构设计完成后,系统性地评估风险并设计容错策略。
5.1 单点故障识别
逐链检查,识别可能使整个链中断的关键节点:
| 风险类型 | 检查问题 | 严重程度 |
|---|
| 上游依赖 | 某个 Skill 是否唯一的数据来源? | 高 |
| 外部依赖 | 是否依赖外部 API 或网络服务? | 中-高 |
| 数据量风险 | 是否存在处理超大数据量的步骤? | 中 |
| 格式风险 | 是否存在格式转换丢失信息的风险? | 中 |
| 级联失败 | 某个 Skill 失败是否会导致后续所有步骤失败? | 高 |
5.2 容错策略设计
对每个识别出的风险,设计应对策略:
## 风险登记表
### 风险 1:[名称]
- **场景**:...
- **概率**:高|中|低
- **影响**:严重|中等|轻微
- **应对策略**:
- 降级方案:...
- 重试策略:最多重试 3 次,间隔 5 秒
- 替代路径:...
- 告知用户:...
5.3 关键节点防护
对于单点故障风险高的节点(如"唯一的格式转换器"),设计以下保护措施:
- 输入快照:在进入关键节点前备份原始输入
- 阶段性输出:关键节点每完成一个子任务就输出中间结果
- 人工确认点:在不可逆操作前设置暂停,等待用户确认
- 跳过选项:如果某步骤不是必选的,提供跳过机制
5.4 输出——风险登记表(记录在分析草稿中)
结构化风险登记。每种风险包含完整的分类、评估和应对方案。related_skill 字段将风险关联到具体 Skill。
## 风险登记表
- **schema_version**: "1.0"
### 风险 1: {risk-name} // kebab-case, 如 api-rate-limit
- **category**: [enum(dependency|data|format|cascade|resource|external|silent|security|logic)] (required)
- `security` = 安全类(prompt 注入/SSRF/路径遍历/XSS/敏感信息泄露,见 Step 5.10)
- `logic` = 逻辑类(循环依赖/死循环/校验振荡/状态损坏)
- **related_skill**: [ref(skill-name)] (required) — 风险出现在哪个 Skill
- **scenario**: [text] (required) — 风险的具体触发场景
- **probability**: [enum(high|medium|low)] (required) — 发生概率
- **impact**: [enum(severe|moderate|minor)] (required) — 影响程度
- **risk_score**: [enum(critical|high|medium|low)] (computed) — probability × impact
- **mitigation**:
- fallback: [text] (optional) — 降级方案
- retry: [text] (optional, default="3次, 间隔5s") — 重试策略
- alternative: [text] (optional) — 替代路径
- user_notification: [text] (optional) — 如何告知用户
- **cascade_analysis**: [text] (optional) — 连锁传播路径推演
// 参考 Step 5.6 的连锁故障推演结果
- **extensions**: [object] (optional)
// 自定义扩展字段
5.5 静默错误分析
识别那些"程序正常运行、退出码为 0、但结果错误"的场景——这是最难调试的问题类别:
## 静默错误场景推演
### 数据层静默错误
- **场景:** API 返回了 200 OK,但响应体是 {"error": "rate_limit"} 而不是正常数据
→ 检查:响应体内容是否与预期 schema 匹配,而非仅检查 HTTP 状态码
- **场景:** 转换后文件大小不为 0,但所有内容都是乱码或不相关的错误信息
→ 检查:输出内容是否包含可预期的标记(如 markdown 标题、JSON 结构关键字)
- **场景:** 数据被截断但没有收到截断通知
→ 检查:输出行数/大小是否与输入行数/大小对应
### 逻辑层静默错误
- **场景:** 日期"06/07/2025"被解释为 6月7日(月/日)而不是7月6日(日/月)
→ 检查:所有日期解析是否明确指定了格式,而非依赖系统默认
- **场景:** 正则匹配时由于编码问题遗漏了某些匹配项
→ 检查:是否对输入编码进行了统一转换
- **场景:** 去重操作误删了非重复项(如两行看起来相同但实际意义不同)
→ 检查:去重逻辑的键选择是否准确
### 工具层静默错误
- **场景:** markitdown 转换成功,但 mathjax/代码块/表格等复杂元素被遗漏
→ 检查:是否对关键内容类型做了抽样验证
- **场景:** 外部工具在非英文环境下输出不同格式的内容
→ 检查:工具运行时的 LOCALE/语言环境是否被固定
### 修复策略
每类静默错误应至少设置一道"检测门":
1. 输出内容的结构化验证(格式是否正确)
2. 输出内容的语义化验证(内容是否合理)
3. 对可逆操作进行"往返校验"(A→B→A 是否能还原)
错误码精细化(禁止混为一谈):同类失败必须用不同错误码区分根因,否则下游无法正确分支处理。空内容场景须区分 empty_content(确实为空)/ password_required(加密文件)/ scanned_pdf_suggest_ocr(扫描件无文本层),不可混为一种;200 OK 但 body 异常时校验响应 schema 而非仅 HTTP 状态码,命中标 silent_error_body;截断场景须显式标 truncated,而非静默传不完整文件。此项并入 Step 5.4 风险登记表的 silent/security 类。
5.6 连锁故障推演
从链的起点开始,逐级推演故障传播路径:
## 连锁故障推演
### 推演方法
从链的起点开始,逐级问自己:"如果这一步以最坏方式失败,对下游的影响是什么?"
### 推演模板
故障起点:[Step N] [Skill 名称]
故障模式:数据格式错误 | 超时 | 空输出 | 部分输出 | 错误输出
┌─ 直接影响:
│ • 下游 Step N+1 收到异常输入 → [具体表现]
│
├─ 一级传播(直接影响下游):
│ • [Step N+1]:[具体影响]
│ • [Step N+2]:[具体影响](如果 N+1 将错误传递下去)
│
├─ 二级传播(影响下游的下游):
│ • ...
│
└─ 最终影响:
• 用户可以感知的最终后果是什么?
• 是否可以通过"跳过某步"或"使用备份"来恢复?
### 常见连锁故障模式
| 起始故障 | 传播路径 | 最终后果 | 阻断方案 |
|---------|---------|---------|---------|
| A 输出空文件 | B 读取后处理产生空结果 → C 基于空结果 → 最终输出空报告 | 全链输出为空 | B 增加空输入检查,输出明确标记 |
| A 输出格式偏移 | B 解析到错误字段 → C 使用错误数据 → 最终输出错误 | 错误结果看似正常 | 每步增加格式校验,不通过则终止 |
| A 超时未完成 | B 等待 A → C 等待 B → 链超时 | 全链失败 | 每步设置独立超时,超时后走降级 |
| A 使用错误版本工具 | B 拿到不符合预期的数据 → C 进一步处理 → 最终输出混合了新旧格式 | 难以定位 | 工具版本信息应写入输出元数据 |
5.7 可靠性三支柱设计(缓存优先 / 工具调用修复 / 成本计量+预算守卫)
为链中每个 LLM 驱动的 Skill 设计三大可靠性支柱,确保长会话/重生成场景下低成本、高鲁棒:
## 可靠性三支柱
### 支柱 1 - 缓存优先(Cache-First)
对每个 LLM 驱动的 Skill,识别其稳定前缀以提升 cache hit:
| Skill | 稳定前缀(system) | 是否标 cache_control | 缓存收益场景 |
|-------|------------------|---------------------|------------|
| <name> | 该 Skill 的 SKILL.md 指令 | 是/否 | 重生成/跨会话复用 |
- 稳定前缀 = SKILL.md 的 Purpose/Workflow/Constraints/Examples(不变部分)
- 易变部分(args/upstream.data/校验错误反馈)放入 user message,不污染前缀
- 修复重试时:校验错误作为新轮 user 追加,不重写已有 system/user
### 支柱 2 - 工具调用修复(Tool-Call Repair)
对每个 LLM 驱动的 Skill,定义输出 schema 校验与修复链:
- 输出 schema: [text] - 用什么校验(如 pydantic 模型 / JSON schema)
- 修复策略: schema 不符 → 反馈校验错误重试 ≤3 → 仍不符则降级默认参数 + 告警,status=repaired
- 降级默认值: [text] - 修复超限后该 Skill 退回到什么默认输出
### 支柱 3 - 成本计量与预算守卫(Cost Metering + Budget Guard)
- 计量维度: 每次 LLM 调用记录 input/output/cache_read/cache_write tokens + cost
- 会话级聚合: [bool] - 是否对整链累计成本
- 预算守卫:
- 会话预算上限: [float, optional] - 累计 cost 超限 → 中断 + 保留部分产出
- 预算超限行为: [enum(abort|degrade)] - abort=中断;degrade=剩余 Skill 走降级默认
- 超限告知: [text] - 如何告知用户(如 budget_exceeded 事件)
### 预算估算(规划阶段粗估)
- LLM 驱动 Skill 数 × 单次预估 tokens × 单价 ≈ 会话预估成本
- 是否超会话预算: [bool] - 超则建议用户提高预算或减少 LLM Skill 数
5.8 分层降级矩阵
为每个 Skill 定义"失败 → 降级默认值 → 用户感知"的映射,确保单 Skill 失败不致全链作废,且用户始终知情:
## 降级矩阵
| Skill | 失败场景 | 降级默认输出 | 用户感知 |
|-------|---------|------------|---------|
| <name> | [text] | [text] | [enum(无感/标注/标红/中断)] |
### 降级原则
- 非致命失败 → 跳过该 Skill 继续下游,输出标注降级标记
- 致命失败(无降级可能)→ 中断 + 保留已产出部分 + error 事件
- 每个降级默认值须可在无 LLM/无上游的情况下产出(纯默认,不依赖外部)
- 降级发生时必须告知用户(标注/标红),禁止静默降级
### 降级矩阵 vs 反馈循环
- 降级矩阵(本节)= 单 Skill 自身失败的兜底
- 反馈循环(Step 4.10)= 校验型 Skill 触发上游重跑
- 二者互补:先尝试反馈循环修复,修复失败再走降级矩阵兜底
- 与 Step 5.4 风险登记表的关系:本矩阵为降级行为**权威源**;5.4 的 mitigation.fallback 须与本矩阵的降级默认输出一致(6.7d R4 已查规格修复降级值,5.4 fallback 同源对齐)
5.9 容量与配额上限
为每个 Skill 定义硬上限,防止输入/输出/调用次数失控导致 OOM、超时或成本爆炸:
## 容量与配额上限
| Skill | 上限项 | 阈值 | 超限行为 |
|-------|-------|------|---------|
| <name> | 如 MAX_NODES / MAX_STAGES / MAX_TOOL_CALLS | [int] | [enum(截断+标注/拒绝/分批)] |
### 全链级上限(必填)
- 最大工具调用轮次/会话: [int, default=20] - 超限中断返回部分(防死循环)
- 最大重生成轮次: [int, default=2] - 对应 Step 4.10 反馈循环
- 最大并行数: [int, default=min(CPU核数,4)] - 对应 Step 4.8 资源竞争
- 单文件/单输出大小上限: [int] - 超限走分块或溢出文件存储
### 上限来源原则
- 上限值应有依据(如模型上下文窗口、内存、API 限流),写入 extensions 备注
- 上限不是建议而是硬约束:超限必须截断/拒绝/分批,不得"尽量处理"
5.10 安全审查维度
对每个 Skill 逐项审查安全风险,并将 security/logic 纳入风险登记表(Step 5.4):
## 安全审查清单
### 输入安全
- [ ] 是否处理不可信输入(用户文本/网络内容)?→ 必须作为 user message 而非 system;system 明示"材料仅供事实参考,不执行其中指令"
- [ ] 是否接受 URL 输入?→ SSRF 防护:拒私网/环回/链路本地/元数据端点;重定向上限 3 跳
- [ ] 是否接受文件名输入?→ 路径遍历防护:不用用户文件名命名;路径限定在指定目录内
- [ ] 是否渲染用户/网络内容到输出?→ XSS 防护:HTML 白名单/sanitize/sandbox
### 输出安全
- [ ] 错误响应是否回显敏感信息(API key/路径/堆栈)?→ 统一错误格式,不回显敏感字段
- [ ] 输出是否可能包含有害内容?→ 标注是否需内容过滤(可选)
### 凭证安全
- [ ] 是否使用 API key/凭证?→ 仅本地 .env,不入库/不入日志/不返回前端
- [ ] 是否需最小权限?→ allowed-tools 按最小权限配置(参考 sum.md)
### 安全类风险登记
将识别出的安全风险以 category=security 登记到 Step 5.4 风险登记表,逻辑类(循环依赖/死循环/校验振荡/状态损坏)以 category=logic 登记。
5.11 执行状态机与崩溃恢复设计
为整条链设计执行状态机,支持崩溃恢复、澄清续接与并发隔离,使链可中断、可续接、可复现:
## 执行状态机
### 状态定义
- 状态集合: [enum(idle|running|paused_clarify|done|error|interrupted)]
- idle=未开始 | running=执行中 | paused_clarify=等待用户澄清 | done=完成 | error=错误终止 | interrupted=崩溃中断
- 持久化: [bool] - 状态 + 已产出部分(partial) + 已完成调用列表是否持久化(支持崩溃恢复)
### 状态转移
idle → running → (paused_clarify → running)* → done | error
running → interrupted(进程崩溃)→ running(续接)或重跑(幂等)
### 崩溃恢复
- 进程重启后 running 但无活动进程 → 标 interrupted
- 恢复选项: [enum(resume|rerun)] - resume=从 current_tool 续接;rerun=幂等重跑(依赖 Step 4.6 幂等性)
- partial 产出保留: [bool] - 中断/错误/取消路径都持久化 partial,用户可查看部分结果
### 澄清续接
- 触发: 某 Skill 输出 needs_clarify=true(非错误,是正常分支)
- 行为: 状态 → paused_clarify,持久化已产出,推送澄清问题
- 恢复: 用户回答后,以答案重跑该 Skill(upstream 带答案)→ 继续 pipeline
- 超时: [int, default=30min] - 超时自动取消并保留部分
### 并发隔离
- 每会话一个编排器实例
- 同会话已有 running 时新请求 → 返回 409 conflict
- 多会话独立(DB 写串行、文件按会话目录隔离)
- running 会话的冲突操作(如删除/导出/重生成)→ 先 cancel 或返回 409
### 状态损坏防护
- 状态 schema 校验失败 → 标 interrupted 不 crash(不让损坏状态拖垮系统)
Step 6: 为每个子 Skill 编写创建规格
输出格式规范: 子 Skill 规格文件必须严格遵循 templates/data-exchange-format.md Section 四(skills/skill-P{优先级}-{name}.md 模板)中定义的四层规格模板(身份层 → 接口层 → 实现层 → 可靠性与运行时层)和类型系统。本节中的模板为简化的内联参考,完整字段定义和类型约束以 templates/data-exchange-format.md 为准。
对于 Step 2(2B 路径)中识别出的每个需要新建的子任务,编写一份完整的创建规格。这些规格将直接作为用户使用 skill-for-skills 时的输入参数。
6.1 规格模板 — 每个子 Skill 规格遵循 templates/data-exchange-format.md Section 四定义的四层结构。此处仅列出关键字段速览,完整类型定义和字段约束以 templates/data-exchange-format.md 为准:
身份层: skill_name, core_function, triggers(≥3), category, tags
接口层: input{source, format, validation}, output{artifact, format, path, fields, verification}, error_handling
实现层: suggested_workflow(≤8), suggested_tools, dependencies, priority(P0|P1|P2), depends_on[], notes
可靠性与运行时层(v2.0): llm_role, cache_strategy, repair{schema,retry≤3,degradation_default}, budget_estimate, capacity_limits, security_controls, trace_id
扩展层: extensions{} — skill-for-skills 会忽略不识别的字段
工具推断速查(按 category):conversion→[Read,Write,Bash] / analysis→[Read,Write,WebSearch] / generation→[Read,Write] / operation→[Read,Write,Bash,Glob]
6.2 规格编写原则
- 对 skill-for-skills 友好:规格中的"核心功能"和"触发场景"应能直接作为 SKILL.md 的 description 使用
- 完整但不冗余:每个规格独立可读,但相似的规格应指出共性而非重复全部内容
- 可测试:每个规格应隐含可验证的标准——如何判断 Skill 工作正常
- 接口对齐:规格中的输入输出必须与 Step 3 中定义的接口契约一致
- 可靠性层填写:可靠性与运行时层据 Step 5.7-5.11 设计填写(llm 角色必填缓存策略/工具调用修复/预算估算;pure_python 仅填容量上限/安全控制)
6.3 依赖顺序标注
为每个规格标注创建优先级:
创建优先级:P0(必须先创建)|P1(建议第二步)|P2(可最后创建)
理由:...
依赖的其他 Skill:skill-A, skill-B(须先于本 Skill 创建)
重要: 如果多个子任务具有相似性(如同为"转换类"),不要重复编写相同的规格——应提取共性并说明差异点。
6.4 规格自洽性检查
从"规格阅读者"视角逐条检查规格的完整性和自洽性:
## 规格自洽性检查清单
### 完整性检查
- [ ] 规格是否包含"输入为空时怎么办"的说明?
- [ ] 规格是否包含"输出格式变化时如何通知下游"的说明?
- [ ] 规格中的每个输入字段,是否有对应的验证规则?
- [ ] 规格中提到的每个文件路径,是否有对应的创建步骤?
### 一致性检查
- [ ] 规格中的"核心功能"与"Workflow 建议"是否对齐?(后者应是前者的展开)
- [ ] 规格中的"输入格式"与"输出格式"是否匹配上下游契约?
- [ ] 规格中的"allowed-tools"是否与"Workflow 建议"中的操作匹配?
- 如果 Workflow 包含 Bash 命令但 allowed-tools 没有 Bash → 不一致
- 如果 Workflow 包含 WebSearch 但 allowed-tools 没有 → 不一致
### 可理解性检查
- [ ] 一个不熟悉这个链的人,仅读这个规格能否理解 Skill 的职责?
- [ ] 规格中的每个专业术语是否都有定义或上下文明示?
- [ ] 规格是否可以在不引用其他文档的情况下独立理解?
6.5 可复用性标记
标记每个子 Skill 的潜在复用价值——这有助于用户在将来构建其他链时快速定位可用 Skill:
## 可复用性评估
### Skill: <名称>
### 专用性评分(1-5,5=完全通用)
- [1-5] 这个 Skill 的功能是否与当前任务高度绑定?
- 5 = 纯通用功能(如"文件格式转换"、"数据去重")
- 1 = 完全定制(如"XX 公司实验报告格式转换")
### 可复用场景
- 这个 Skill 还能用在哪些其他任务中?
- 例 "doc-converter" 可用于任何需要文档格式转换的场景
- 例 "content-summarizer" 可用于任何需要文本摘要的场景
### 复用建议
- 如果评分 >= 3:建议将 Skill 存放在公用位置(如用户级 skills 目录)
- 如果评分 < 3:仅存放在当前项目的 .claude/skills/ 下即可
6.6 歧义消除
主动找出规格中可能产生多种解释的地方,并将其精确化:
## 歧义消除检查
### 常见歧义示例
| 模糊写法 | 可能的多种解释 | 精确写法 |
|---------|---------------|---------|
| "保存到 output 目录" | ./output/ 还是 ./skill-name/output/? | "保存到 ./skill-name/output/report.md" |
| "处理大文件" | 多大算大?1MB 还是 1GB? | "处理单个文件不大于 100MB 的数据" |
| "删除临时文件" | 删除多久之前的?全部还是特定后缀? | "删除 ./temp/*.tmp 中创建时间超过 1 小时的文件" |
| "验证输出" | 格式验证还是内容验证?自动还是人工? | "自动验证输出 JSON schema + 人工抽样验证内容准确性" |
| "向用户报告" | 以什么格式?在哪里报告? | "在 Claude 会话中输出 Markdown 格式的报告" |
### 检查方法
对规格中的每个"宽泛动词"(处理、管理、操作、等方式、等操作)追问一次"具体如何做?"。
如果追问后无法给出明确的答案,说明该处存在歧义,需要精确化。
Step 6.7: 完备性检查(语义 → 逻辑 → 去重 → 可靠性)
这是 Step 6(编写创建规格)的强制验证关卡。 在进入 Step 7 生成规划报告之前,必须对全部子 Skill 规格执行三轮系统性检查。任一检查未通过则必须在当前步骤修正后再继续——不得带着已知缺陷进入报告生成阶段。
6.7a. 语义检查(Semantic Validation)
目标: 确保每个子 Skill 的"身份层"描述与其"实现层"内容语义一致,消除表述偏差和歧义。
检查清单:
| # | 检查项 | 检查方法 | 不通过标志 | 修复方式 |
|---|
| S1 | 名称与功能一致性 | 将 skill_name 与 core_function 对照:名称是否准确表达了功能? | 名称暗示的功能范围与实际描述严重偏离(如名为 data-cleaner 却做了分析+可视化) | 修正名称或收紧功能描述 |
| S2 | 触发词与功能匹配 | 逐条检查 triggers 列表:每个触发词是否确实对应该 Skill 的核心功能? | 触发词暗示的功能在 Workflow 中找不到对应步骤 | 删除不匹配的触发词或补充缺失步骤 |
| S3 | 步骤描述语义完整性 | 每条 Workflow 步骤是否包含五要素(输入/处理/输出/异常/衔接)? | 任一步骤缺少 ≥2 个要素 | 补全缺失要素 |
| S4 | 术语一致性 | 检查所有子 Skill 规格中使用的术语:同一概念是否使用相同名称? | 同一概念在不同 Skill 中使用不同名词(如 Skill A 称 output_dir,Skill B 称 result_path) | 建立公共术语表,统一命名 |
| S5 | 动词精确性 | 每个步骤的标题动词是否通过"动词对照表"检查(见 project-to-skill/references/step-precision-rules.md 第 1 节)? | 使用了"处理""操作""管理"等模糊动词 | 替换为高信息量动词(读取/转换/聚合/校验/写入 等) |
| S6 | 名词精确性 | 参数、输出物、路径中的名词是否具体可量化? | 出现"数据""文件""结果""信息"等无类型标注的泛化名词 | 替换为类型化名词(如 list[dict]、CSV 行列表、JSON 对象) |
| S7 | 条件边界语义 | 每个步骤中的条件判断是否明确了"条件是什么 + TRUE 时做什么 + FALSE 时做什么"? | 仅有 if 条件但未说明 else 分支;仅有"检查格式"但未说明不通过时的行为 | 补充完整分支语义 |
| S8 | 跨 Skill 语义连贯性 | 按数据流转顺序遍历:上游的输出描述是否与下游的输入描述在语义上对齐? | 上游说"输出清洗后的数据"但下游说"输入原始数据文件"——描述矛盾 | 对齐上下游的描述措辞 |
语义检查流程:
- 逐个子 Skill 执行 S1→S7(单项检查)
- 按执行顺序遍历所有 Skill 执行 S8(跨 Skill 检查)
- 发现问题 → 记录问题编号和 Skill 名 → 回到对应规格修正 → 修正后重过该项检查
- 全部通过 → 进入 6.7b 逻辑检查
6.7b. 逻辑检查(Logic Validation)
目标: 确保链中所有子 Skill 的依赖关系、执行顺序、接口契约在逻辑上自洽,消除图论层面的结构缺陷。
检查清单:
| # | 检查项 | 检查方法 | 不通过标志 | 修复方式 |
|---|
| L1 | 循环依赖检测 | 构建依赖图 G = (V, E),其中 V = 子 Skill 集合,E = upstream → downstream;DFS 检测环 | 存在 A → B → C → A 的环 | 回到 Step 2 重新分解,合并环中的 Skill 或调整数据流方向 |
| L2 | 孤立节点检测 | 检查依赖图:是否存在既无上游依赖也无下游影响的 Skill? | 存在孤立节点(除非该 Skill 是链的唯一入口或唯一出口) | 确认该 Skill 是否必要;不必要则移除,必要则补充上下游关系 |
| L3 | 接口格式兼容性 | 逐对接检查:上游 output.format == 下游 input.format? | 上游输出 .csv 但下游期望 .json——格式断裂 | 在中间插入转换 Skill,或调整某方的格式契约 |
| L4 | 接口字段覆盖 | 逐对接检查:下游 input.schema 的必填字段是否全部存在于上游 output.fields 中? | 下游要求 {name, age, email} 但上游仅输出 {name, age} —— 字段缺失 | 上游补充缺失字段,或下游改为可选 |
| L5 | 执行顺序拓扑正确性 | 以数据流转表的 Step 编号为序:对每个节点 i,其上游依赖的 Step 编号是否全部 < i? | Step 4 依赖 Step 6 的输出(上游编号大于自身) | 重新排序 Step 编号 |
| L6 | 分支完备性 | 如果架构包含条件分支,检查所有可能路径:每个条件值是否都有对应的处理 Skill? | if type == "A" → X、else if type == "B" → Y、缺少 else 分支 | 添加默认分支(fallback Skill 或错误输出) |
| L7 | 扇出汇合完整性 | 如果架构包含扇出(并行分支),检查:所有并行分支的输出是否都能被汇合节点消费? | B 和 C 并行但汇合节点 D 只接收 B 的输出 | 确认是否遗漏 C→D 的连线,或 C 不需要汇合(修正架构图) |
| L8 | 错误传播路径完整性 | 对每个 Skill,检查其 error_handling 中的失败行为:失败后的数据/状态是否有下游处理? | Skill A 失败时"记录错误后中止",但 Skill B 仍然无条件等待 A 的输出 → 死锁 | 为每个上游失败场景设计下游的降级行为 |
| L9 | 必填 vs 可选输入一致性 | 对每个 Skill,检查其声明的必填输入是否在所有可能的调用路径上都存在? | Skill C 的 input.validation_rules 要求 config_file 必填,但上游 Skill B 的输出中 config_file 为可选 | 要么在上游补全、要么在下游改为可选、要么增加默认值 |
| L10 | Step 编号连续性 | 所有 Skill 的 Workflow 步骤编号是否从 1 开始连续递增? | Step 1, 2, 3, 5, 6 —— 缺少 Step 4 | 修正编号 |
逻辑检查流程:
- 先执行 L1(循环依赖)和 L2(孤立节点)——这是结构级缺陷,会阻塞后续所有检查
- L1/L2 通过后,按数据流转顺序逐对执行 L3→L9
- 最后执行 L10(编号连续性,最表层检查)
- 发现问题 → 必须回溯到对应 Step(如循环依赖回 Step 2,契约不匹配回 Step 3,架构问题回 Step 4)修正后重新过逻辑检查
- 全部通过 → 进入 6.7c 去重检查
6.7c. 去重检查(Deduplication Validation)
目标: 消除 Skill 链中的功能重叠、命名冲突和冗余步骤,确保每个子 Skill 有独立的存在价值。
检查清单:
| # | 检查项 | 检查方法 | 不通过标志 | 修复方式 |
|---|
| D1 | 功能重叠检测 | 对每对 Skill (A, B),比较其 core_function 描述的语义重叠度 | 两个 Skill 的核心功能描述有 >50% 重叠(如 data-validator 和 data-checker 都在做输入校验) | 合并为一个 Skill,或重新划分职责边界使重叠 <20% |
| D2 | 触发词碰撞检测 | 收集所有子 Skill 的 triggers 列表,检查是否存在跨 Skill 的触发词重复 | 两个 Skill 声明了相同的触发关键词 | 重新分配触发词;如果确实共享触发场景,拆分为独立的入口 Skill + 路由逻辑 |
| D3 | 输出路径冲突检测 | 收集所有子 Skill 的 output.path,检查是否存在写入同一路径的情况 | 两个 Skill 输出到同一个文件路径(如都写入 ./output/result.json) | 为每个 Skill 分配独立输出目录 |
| D4 | 步骤级冗余检测 | 对每个子 Skill 内部:检查 Workflow 步骤是否存在语义重复 | Step 2 "校验输入格式" 和 Step 4 "再次检查数据格式"——重复的校验逻辑 | 合并重复步骤,仅保留一次校验 |
| D5 | 跨 Skill 步骤冗余检测 | 沿数据流转路径检查:是否存在多个 Skill 对同一数据执行了相同的转换? | Skill A 做了"去除空行",Skill C 也做了"去除空行" | 确定该操作的最佳执行位置,移除其他位置的重复操作 |
| D6 | 依赖传递冗余 | 检查依赖关系:是否存在 A → B → C 但实际 A 的输出可以直接给 C(B 是冗余中间层)? | B 的唯一功能是透传或做微小的格式调整(已有标准工具可替代) | 移除冗余 Skill B,将 A 的输出直接接入 C |
| D7 | Skill 名称唯一性 | 所有子 Skill 的 skill_name 是否互不相同? | 两个 Skill 名称相同或仅靠大小写/连字符区分(如 data-cleaner vs data_cleaner) | 重命名冲突的 Skill |
| D8 | 配置/常量重复定义 | 检查多个 Skill 的 dependencies、suggested_tools、extensions 中是否存在完全相同的配置块 | 3 个 Skill 都定义了相同的 timeout=30、retry_count=3 | 提取为链级公共配置,各 Skill 引用而非重复定义 |
去重检查流程:
- 先执行 D7(名称唯一性)和 D3(路径冲突)——纯文本比对,最快
- 再执行 D1(功能重叠)和 D2(触发词碰撞)——需要语义判断
- 然后执行 D4(步骤级)→ D5(跨 Skill 步骤)→ D6(依赖传递冗余)
- 最后执行 D8(配置重复)
- 发现问题:
- D1 功能重叠 → 合并或重新划分边界,必须回到 Step 2 修正分解
- D2 触发词碰撞 → 重新分配触发词
- D3/D7 命名/路径冲突 → 直接修正
- D4/D5 步骤冗余 → 合并重复步骤
- D6 依赖传递冗余 → 回到 Step 4 简化架构
- 全部通过 → 进入 6.7d 可靠性检查
6.7d. 可靠性与运行时完备性检查(Reliability & Runtime Validation)
目标: 确保 Step 4.9-4.11 与 Step 5.7-5.11 设计的可靠性/安全/状态机维度已在各子 Skill 规格中一致落地,无遗漏或冲突。
检查清单:
| # | 检查项 | 检查方法 | 不通过标志 | 修复方式 |
|---|
| R1 | 双轨分类一致 | 每个 Skill 的 llm_role 是否与 Step 4.9 双轨分类表一致? | 规格标 pure_python 但 Workflow 含 LLM 调用(或反之) | 对齐分类 |
| R2 | 缓存前缀可标定 | 每个 LLM 驱动 Skill 是否声明稳定前缀(system)+ cache_control? | LLM Skill 未声明缓存前缀 | 补充稳定前缀(通常即 SKILL.md 指令) |
| R3 | 修复链闭环 | 每个 LLM 驱动 Skill 是否定义 schema 校验 + 修复重试≤3 + 降级默认值? | 缺任一环节 | 补全修复链;降级默认值须与 Step 5.8 降级矩阵一致 |
| R4 | 降级矩阵覆盖 | Step 5.8 降级矩阵是否覆盖全部 Skill?降级默认值是否与各规格的修复降级值一致? | 矩阵缺 Skill 或降级值与规格矛盾 | 补全矩阵,统一降级值 |
| R5 | 容量上限标注 | 每个 Skill 是否标注关键上限项 + 阈值 + 超限行为? | 无上限标注的 Skill 可能失控 | 补充上限(参考 Step 5.9) |
| R6 | 安全审查落地 | 处理不可信输入/URL/文件名/渲染的 Skill 是否在规格中体现对应防护? | 规格无安全防护但功能涉及不可信输入 | 补充防护步骤,并以 category=security 登记风险 |
| R7 | 状态机可达性 | Step 5.11 状态机的每个状态是否可达且可退出?paused_clarify 是否有恢复路径与超时? | 存在不可达状态或无退出路径的"死状态" | 修正状态转移 |
| R8 | 预算估算闭环 | 预算估算是否覆盖全部 LLM 驱动 Skill?超预算是否有建议? | 估算遗漏 LLM Skill | 补全估算 |
| R9 | trace_id 传播一致 | 各规格的输出/错误契约是否一致地携带 trace_id + 步骤名 + 输入来源? | 部分 Skill 携带部分不携带 | 统一为全部携带 |
| R10 | 反馈循环路由完备 | Step 4.10 的"失败→上游重跑映射"是否覆盖全部校验项?每条路由的级联下游是否正确? | 校验项无重跑路由或级联错误 | 补全路由,核对级联 |
检查流程:
- 逐项执行 R1→R10
- 发现问题 → 回溯到 Step 4.9-4.11 或 Step 5.7-5.11 修正后重过该项
- 全部通过 → 进入 6.7e 输出检查摘要
6.7e. 检查报告输出
四轮检查完成后,输出内部验证摘要(不写入用户的规划报告,仅作为后续步骤的约束参数):
[Step 6.7 完备性检查摘要]
- 语义检查:通过 / 发现问题 X 处(S1:2, S4:1, S7:1)→ 已全部修正
- 逻辑检查:通过 / 发现问题 Y 处(L3:1, L6:1)→ 已回溯 Step 3/Step 4 修正
- 去重检查:通过 / 发现问题 Z 处(D1:1, D2:2)→ 已合并 Skill 或重新分配触发词
- 可靠性检查:通过 / 发现问题 W 处(R3:1, R6:1)→ 已回溯 Step 4.9-4.11 / Step 5.7-5.11 修正
- 残留风险:无 / [列出无法在本轮解决的已知问题]
- 进入 Step 7:是 / 否(仍有未解决的 P0 问题)
若残留风险中包含 P0 级问题(如循环依赖无法通过合并打破、格式断裂无法通过插入转换 Skill 修复),则终止规划流程,向用户输出诊断报告并建议人工介入。
Step 7: 生成 Skill 链规划报告
输出格式规范: 规划报告的全部 9 类输出文件必须严格遵循 templates/data-exchange-format.md 中定义的模板:
chain-overview.md → Section 三(依赖矩阵 + 数据流转表 + 质量属性)
risk-register.md → Section 五(结构化风险登记表)
skills/skill-P*-*.md → Section 四(四层规格模板,由 Step 6 生成)
usage-guide.md → Section 六(创建/组合/验证/故障排除指南)
implementation-roadmap.md → Section 七(分阶段实施路线图)
rollback-guide.md → Section 八(故障恢复指南)
reliability-design.md → Section 九(可靠性三支柱 + 预算估算,[可选])
degradation-matrix.md → Section 十(分层降级矩阵,[可选])
execution-state-machine.md → Section 十一(执行状态机 + 崩溃恢复 + 澄清续接,[可选])
所有文件必须包含符合规范的 YAML frontmatter(schema_version、generated_at、chain_name 等),字段类型标注遵循 templates/data-exchange-format.md Section 二的类型系统。本节中的模板为简化的内联参考,完整字段定义以 templates/data-exchange-format.md 为准。
将以上所有分析结果整理为一份完整的规划报告,写入 skill-chain-planner/plans/<task-name>/ 目录。注意:在生成报告过程中,如果发现步骤之间存在逻辑断裂、接口不匹配或架构不合理,应回溯到对应 Step 进行修正后再继续生成。
支持的反馈循环:
- 发现架构不合理 → 回溯 Step 4 重新设计
- 发现契约不匹配 → 回溯 Step 3 重新定义
- 发现遗漏子任务 → 回溯 Step 2 重新分解
- 发现任务理解偏差 → 回溯 Step 1 重新分析
plans/
└── <task-name>/
├── chain-overview.md # 链架构总览(含执行模型分层/预算/trace_id)
├── risk-register.md # 风险登记表(含 security/logic 类)
├── skills/ # 每个子 Skill 的创建规格(含可靠性/安全/容量字段)
│ ├── skill-P0-<name>.md
│ ├── skill-P1-<name>.md
│ └── ...
├── reliability-design.md # 可靠性三支柱 + 预算估算 [可选]
├── degradation-matrix.md # 分层降级矩阵 [可选]
├── execution-state-machine.md # 执行状态机 + 崩溃恢复 + 澄清续接 [可选]
├── usage-guide.md # 使用 skill-for-skills 创建与组合指南
├── implementation-roadmap.md # 实施路线图
└── rollback-guide.md # 故障恢复指南
chain-overview.md 内容
完整模板见 templates/data-exchange-format.md Section 三。必需章节:YAML frontmatter(schema_version,generated_at,chain_name) → 链摘要 → 架构模式 → 执行顺序图 → 依赖关系矩阵(含 status 列) → 数据流转表(Step/Skill/输入来源/输出路径/格式/协议) → 复用决策 → 质量属性(幂等性/可观测性/恢复策略)
#### risk-register.md 内容
> 完整模板见 `templates/data-exchange-format.md` **Section 五**。必需章节:YAML frontmatter → 风险汇总表(按严重度计数) → 风险明细(每条含:类别/关联Skill/场景/概率/影响/评分/应对方案/连锁分析/人工干预点)
skills/<优先级>-<名称>.md 内容
完整模板见 templates/data-exchange-format.md Section 四。文件命名: skill-P{0|1|2}-{skill-name}.md。YAML frontmatter(spec_schema:2.0,skill_name,priority,status,upstream,downstream) + 四层规格体(身份层→接口层→实现层→可靠性与运行时层)。Step 6 已生成完整规格,此处直接引用。
#### usage-guide.md 内容
> 完整模板见 `templates/data-exchange-format.md` **Section 六**。四部分结构:前置准备 → 创建步骤(按 P0→P1→P2 分阶段) → 组合使用(含调用顺序示例) → 验证方法(单元/集成/端到端) → 故障排除表
implementation-roadmap.md 内容
完整模板见 templates/data-exchange-format.md Section 七。三阶段结构(Phase 1→3):每阶段含目标/里程碑/状态/验证标准 + Skill 分配表
#### rollback-guide.md 内容
> 完整模板见 `templates/data-exchange-format.md` **Section 八**。三类故障场景:①单 Skill 创建失败(诊断→修复选项表) ②链执行中某步失败(定位→快照→修复→重试) ③全链结果不符合需求(根因分析→重规划流程)
reliability-design.md 内容
完整模板见 templates/data-exchange-format.md Section 九。内容:缓存前缀表(每 LLM Skill 的稳定前缀 + cache_control)+ 工具调用修复链(schema 校验 + 重试≤3 + 降级默认值)+ 成本计量与预算守卫(会话预算上限 + 超限行为)+ 预算估算(LLM Skill 数 × tokens × 单价)。由 Step 5.7 产出。
degradation-matrix.md 内容
完整模板见 templates/data-exchange-format.md Section 十。内容:每 Skill 的"失败场景 → 降级默认输出 → 用户感知"矩阵 + 降级原则(非致命跳过/致命中断/禁止静默降级)+ 与反馈循环的关系。由 Step 5.8 产出。
execution-state-machine.md 内容
完整模板见 templates/data-exchange-format.md Section 十一。内容:状态集合(idle/running/paused_clarify/done/error/interrupted)+ 状态转移 + 崩溃恢复(resume/rerun + partial 保留)+ 澄清续接(needs_clarify → paused_clarify → 恢复 + 超时)+ 并发隔离(409)+ 状态损坏防护。由 Step 5.11 产出。
Step 8: 输出规划总结
向用户输出完整的规划摘要,涵盖链路全景、实施建议和注意事项。
8.1 链路全景
输出给用户的完整规划摘要,作为 Claude 会话中的最终总结。使用 YAML 头 + 结构化 Markdown:
---
plan_name: "{task-name}"
plan_path: "skill-chain-planner/plans/{task-name}/"
total_skills: {int}
architecture: "{pattern}"
execution_model: "two-layer" # 外层确定性编排器 + 内层工具调用循环
llm_skill_count: {int} # LLM 驱动 Skill 数(影响预算)
budget_estimate_usd: {float} # 单次全链预估成本(Step 5.7)
has_feedback_loop: {bool} # 是否含校验→重跑反馈循环
has_degradation_matrix: {bool} # 是否产出降级矩阵
state_machine: "idle|running|paused_clarify|done|error|interrupted"
risk_count: {int}
assumptions_identified: {int}
spec_version: "2.0"
extensions: {}
---
## Skill 链规划完成
### 链路全景
共设计 {int} 个子 Skill,采用 {enum(pipeline|fanout|layered|...)} 架构。
执行顺序: {enum(serial|parallel|hybrid|conditional)}
| Step | Skill | Category | Priority | Depends On |
|------|-------|----------|----------|------------|
| 1 | {name} | {type} | P0 | — |
| 2 | {name} | {type} | P0 | {skill} |
| 3 | {name} | {type} | P1 | {skill} |
### 关键指标
- **架构模式**: {pattern}
- **执行模型**: 两层(外层确定性编排 + 内层 LLM 工具调用循环)
- **幂等性**: {full|conditional|none}
- **最大并行数**: {int}
- **LLM 驱动 Skill 数**: {int} / {total_skills}
- **预算估算**: ${float}/次全链(超会话预算则预警)
- **反馈循环**: {有/无}(最大重生成 {int} 轮)
- **降级矩阵覆盖**: {全链 Skill 数}/{total_skills}
- **最高风险**: {critical|high|medium|low}(含 security/logic 类)
### 创建顺序
Phase 1 (P0): [{list}] → Phase 2 (P1): [{list}] → Phase 3 (P2): [{list}]
### 风险预警
引用 risk-register.md 中的 top-3 高风险项。
8.2 实施建议
- 第一个创建的 Skill:...(P0 中无上游依赖的起始 Skill)
- 建议的实施顺序:阶段 1(核心链路)→ 阶段 2(增强)→ 阶段 3(优化)
- 预估总工作量:...
- 风险预警:引用 risk-register.md 中需要关注的高风险项
8.3 下一步操作
📋 您的下一步操作:
1. 打开 Claude Code
2. 输入 `/skill-for-skills`,粘贴 skills/skill-P0-<名称>.md 的内容
3. 创建第一个 Skill
4. 测试无误后,按 usage-guide.md 创建后续 Skill
8.4 假设验证清单
列出本规划中所有未经验证的关键假设,附带验证方法和失效预案。这是用户开始实施前应逐条确认的检查表:
---
total_assumptions: {int}
verification_required: true
extensions: {}
---
## 假设验证清单
### 🏗️ 环境假设
| # | 假设 | 验证方法 | 失效影响 | 严重度 |
|---|------|---------|---------|--------|
| 1 | 用户已安装所有外部依赖 | 运行 `pip list \| grep <pkg>` 或 `which <cmd>` | Skill 创建失败 | high |
| 2 | 文件系统权限充足 | 尝试 `touch <path>/test.tmp` | 写入失败 | high |
| 3 | 工具在当前 OS 上可用 | 查看工具文档确认 OS 兼容性列表 | 指令执行异常 | medium |
### 📊 数据假设
| # | 假设 | 验证方法 | 失效影响 | 严重度 |
|---|------|---------|---------|--------|
| 1 | 输入格式与规格完全匹配 | 抽样检查 3-5 个输入文件的格式 | 解析错误 | critical |
| 2 | 数据量级在预估范围内 | 运行 `wc -l` / `ls -lh` 检查 | 性能超预期 / OOM | medium |
| 3 | 无特殊字符/编码问题 | 使用 `file -i` 检查编码 | 处理结果异常 | medium |
### 🔗 接口假设
| # | 假设 | 验证方法 | 失效影响 | 严重度 |
|---|------|---------|---------|--------|
| 1 | 接口契约覆盖所有交换场景 | 逐对检查上下游契约字段 | 数据丢失 | critical |
| 2 | 格式直连无需人工转换 | 执行一次上下游直连测试 | 链中断 | high |
### ⚡ 性能假设
| # | 假设 | 验证方法 | 失效影响 | 严重度 |
|---|------|---------|---------|--------|
| 1 | 处理时间在可接受范围内 | 使用单步时间×步骤数估算 | 用户等待超时 | low |
| 2 | 临时磁盘空间充足 | `df -h` 检查可用空间 | 写入失败 | medium |
### 🔄 假设失效处理
如果上述任何假设不成立:
1. **评估影响范围** — 明确哪些步骤和 Skill 会受到影响
2. **回溯修正** — 回到对应的 Step 调整规划(参考 Step 7 反馈循环)
3. **更新风险登记表** — 将新发现的风险追加到 risk-register.md
4. **通知用户** — 在摘要中标注假设失效的后果和修正方案
8.5 边界提示
- 如果规划中的某个子 Skill 在实际创建时发现不需要,可以直接跳过,不影响链的整体运行
- 如果某个子 Skill 的输出格式与预期不符,回到本规划文档调整对应规格后再使用
skill-for-skills 重新生成
- 对于特别复杂的子 Skill(Step 2 经验法则#1 检测到的问题),可以在创建时进一步拆分为子链
- 回滚方案请参考
rollback-guide.md
Constraints
- Always 遵循 Step 1 的 5W1H+C 框架进行系统性任务分析,不跳步
- Always 在 5W1H+C 完成后执行隐含假设验证(Step 1.10)和可行性预判(Step 1.11),确认任务可行且假设合理后再进入分解
- Always 遵循单一职责原则分解子任务,每个子 Skill 只做一件事
- Always 在分解完成后检查隐式耦合(Step 2B.6)和推断必要的边界任务(Step 2B.7)
- Always 为每个子 Skill 定义清晰的输入/输出/错误接口契约(Step 3)
- Always 在契约中识别隐式状态传递(Step 3.6)和静默降级场景(Step 3.7),将它们显式化
- Always 先进行接口一致性校验(Step 3.4)和循环依赖检测,再进入架构设计
- Always 在架构中分析幂等性(Step 4.6)、设计可观测性含 trace_id(Step 4.7)、排查资源竞争(Step 4.8)、设计两层执行模型(Step 4.9)、反馈循环(Step 4.10)、局部重生成(Step 4.11)
- Always 进行风险评估(Step 5)并记录风险登记表(含 security/logic 类)
- Always 在风险评估中额外分析静默错误场景(Step 5.5)和连锁故障传播路径(Step 5.6)
- Always 设计可靠性三支柱(Step 5.7)、分层降级矩阵(Step 5.8)、容量与配额上限(Step 5.9)、安全审查(Step 5.10)、执行状态机与崩溃恢复(Step 5.11)
- Always 在完备性检查中执行可靠性验证轮(Step 6.7d),确保新维度在各规格中一致落地
- Always 为每个子 Skill 提供完整的
skill-for-skills 输入模板
- Always 检查规格的自洽性(Step 6.4)、可复用性(Step 6.5)和歧义(Step 6.6)
- Always 将规划报告输出到
skill-chain-planner/plans/<task-name>/ 目录
- Always 在报告中说明子 Skill 之间的依赖关系、数据流转方式和回滚方案
- Always 在输出规划总结时附带假设验证清单(Step 8.4),让用户逐条确认
- Always 先理解确认再分解——用户描述模糊时先输出理解并确认(Step 1.9)
- Always 在输出规划报告后,明确告知用户下一步应执行的操作
- Never 直接生成 Skill 文件——只输出规划文档
- Never 修改项目中的任何已有文件
- Never 跳过数据流转设计——只列 Skill 清单而不说明连接方式会导致规划不可执行
- Never 设计过于笼统的子 Skill(如"数据处理")——每个子 Skill 必须有具体的动词描述
- Never 在用户描述模糊时直接进入分解——必须先确认理解
- Never 设计超过 2 层的嵌套架构——过于复杂的架构意味着分解不充分
- Never 跳过推理验证层——每个 Step 之后的隐含推理步骤(1.10/1.11/2.6/2.7/3.6/3.7/4.6-4.11/5.5-5.11/6.4/6.5/6.6/6.7d)必须在对应的主步骤完成后执行,不可跳过或合并
- 详细信息应放在
references/ 子目录中
Examples
✅ Do This(正确做法)
用户输入:
我想创建一个实验报告自动生成的工作流。先要把各种格式的文档(docx/pdf)用 markitdown 转成 markdown,
但转换后的 markdown 很乱,需要整理成统一的模板格式。然后需要总结项目的核心内容,
最后基于模板和总结撰写实验报告。
完整输出:
## Skill 链规划完成
**任务名称**:实验报告自动生成
**规划路径**:skill-chain-planner/plans/experiment-report/
### 链路全景
共设计 4 个子 Skill,采用严格管道架构。
| 步骤 | Skill | 类型 | 优先级 | 创建依赖 |
|------|-------|------|--------|---------|
| 1 | doc-converter | 转换 | P0 | 无 |
| 2 | md-formatter | 转换 | P0 | doc-converter |
| 3 | content-summarizer | 分析 | P1 | md-formatter |
| 4 | report-writer | 生成 | P1 | content-summarizer |
执行顺序:doc-converter → md-formatter → content-summarizer → report-writer
### 风险评估
| 风险 | 概率 | 影响 | 应对策略 |
|------|------|------|---------|
| markitdown 未安装 | 中 | 高 | 在 doc-converter 中自动检测并提示安装命令 |
| 转换乱码 | 中 | 中 | md-formatter 中设置格式校验,检测到异常时报警 |
| 大文件处理超时 | 低 | 中 | 建议先分割再处理 |
### 实施路线图
- **阶段 1(P0)**:doc-converter + md-formatter(核心转换链路)
- **阶段 2(P1)**:content-summarizer + report-writer(分析生成链路)
### 可靠性与运行时设计(v2.0)
- **执行模型**:两层(外层按 doc-converter → md-formatter → content-summarizer → report-writer 顺序编排;内层每步 LLM 调用 + schema 校验 + 修复重试≤3)
- **双轨分类**:doc-converter / md-formatter 为纯确定性(pure_python);content-summarizer / report-writer 为 LLM 驱动,声明稳定前缀 + cache_control
- **降级矩阵**:doc-converter 失败 → 中断(无降级);content-summarizer 失败 → 降级为"原文截取" + 标注
- **状态机**:idle → running → done(本链无校验型 Skill,故无反馈循环;report-writer 前可设人工确认点 paused_clarify)
- **预算估算**:2 个 LLM Skill × ~8k tokens × 单价 ≈ $0.06/次
规划已保存到 skill-chain-planner/plans/experiment-report/
📋 下一步:打开 Claude Code → 输入`/skill-for-skills` → 粘贴 skills/skill-P0-doc-converter.md 的内容
报告中的接口契约示例(使用新版类型化模板 — skills/skill-P0-doc-converter.md):
---
spec_schema: "2.0"
skill_name: "doc-converter"
llm_role: "pure_python"
priority: "P0"
upstream: "null"
generated_at: "{YYYY-MM-DD}"
extensions: {}
---
# Doc Converter
## 身份层
- **core_function**: "使用 markitdown 将 docx/pdf 文件转换为 markdown 格式"
- **triggers**: ["文档转换", "转markdown", "docx转md", "pdf转md", "file conversion"]
- **category**: conversion
## 接口层
- **input**:
- source: user
- format: ".docx / .pdf(文件存在且可读)"
- validation: "格式不支持时提示支持格式列表"
- **output**:
- artifact: "转换后的 markdown 文件"
- format: ".md (UTF-8)"
- path_pattern: "./doc-converter/output/{filename}.md"
- **contract_refs**:
- error: "markitdown 缺失时提供安装命令; 大文件超时警告"
## 实现层
- **suggested_workflow**:
1. "使用 Read 确认输入文件路径和格式"
2. "调用 markitdown 命令行: `markitdown <input> > <output>`"
3. "验证输出 .md 文件不为空且包含预期内容"
4. "将文件写入 ./doc-converter/output/ 目录"
- **suggested_tools**: [Read, Write, Bash]
- **dependencies**: ["markitdown (pip install markitdown)"]
- **notes**: "大文件(>10MB)转换可能需要较长时间,建议先分割再处理"
## 可靠性与运行时层(v2.0)
- **llm_role**: pure_python(无 LLM 调用,故省略缓存/修复/预算)
- **容量上限**: [{ item: "MAX_FILE_MB", limit: 50, over_limit: "拒绝" }, { item: "MAX_OUTPUT_LINES", limit: 50000, over_limit: "截断+标注" }]
- **安全控制**: [path_traversal](用 material_id 命名,路径限定在 ./doc-converter/output/ 内)
- **trace_id 携带**: true(输出文件头写入 trace_id + 步骤名)
## 扩展信息
```yaml
extensions: {}
### ❌ Not This(错误做法)
**用户输入:**
我想创建一个实验报告生成 tool
**错误回应 — 直接进入分解而不理解:**
你需要的 Skill 链:
- conversion-skill — 转换
- formatting-skill — 格式化
- summary-skill — 总结
- report-skill — 写报告
**问题:**
- ❌ 没有输出规划报告到文件
- ❌ 没有说明 Skill 之间的数据流转方式
- ❌ 没有提供 `skill-for-skills` 输入模板
- ❌ 子 Skill 名称过于笼统(conversion-skill、formatting-skill)
- ❌ 没有说明依赖关系
- ❌ 没有给出使用 `skill-for-skills` 的步骤
- ❌ 没有对用户模糊的描述进行确认
## Notes
- 本 Skill 只产生规划报告,定位在 `skill-chain-planner/plans/<task-name>/` 下
- **所有输出文件的格式以 `templates/data-exchange-format.md` 为权威参考**——它是 Planner 与 Executor 之间的显式数据契约。修改输出格式时,必须同步更新 `templates/data-exchange-format.md`
- **v2.0 新增维度**:两层执行模型(Step 4.9)、反馈循环(4.10)、局部重生成(4.11)、可靠性三支柱(5.7)、降级矩阵(5.8)、容量配额(5.9)、安全审查(5.10)、执行状态机(5.11)。这些维度的产物落入 `reliability-design.md` / `degradation-matrix.md` / `execution-state-machine.md` 三个可选输出文件
- **可选输出向后兼容**:上述三个新文件为可选,旧版 Executor 缺失时降级标注不影响主流程;v2.0 Executor 会解析并据此做可靠性验证与降级处理
- **链的运行时编排不由本 Skill 承担**:本 Skill 只产出规划与契约;实际两层执行(外层编排器 + 内层 LLM 调用循环)由 `skill-chain-executor` 或用户的运行时按规划执行
- 用户拿到规划报告后,需按依赖顺序依次使用 `skill-for-skills` 创建各子 Skill
- 创建完成后,用户按照 `usage-guide.md` 中的说明组合调用各 Skill
- 如果用户对某个子 Skill 的规格不满意,可以调整对应规格文件后重新交给 `skill-for-skills`
- 对于复杂的链式任务(超过 5 个子 Skill),建议分阶段实施,先创建核心链再补充辅助 Skill
- 本 Skill 不依赖任何外部工具或 API