# Strategy 抽象化合并方法论

**适用场景**：已有 N 条 req-specific 的具体 strategy（每条是"为 req X 设计的解法"），
想把它们合并成 M 条抽象 pattern（每条是"跨 req 可迁移的方法套路 / skill"），
N 通常 100-300，M 目标 20-40。

**记录时间**：2026-04-22（193 → 27 实操时）

---

## 一、核心立场

> **strategy 作为"skill"的价值在于迁移复用**。合并的目的是识别"同一种做事方法"
> 跨 req 重现的规律，不是机械压缩数量。

因此：
- 合不合的唯一标准是**方法论本身是否相同**，不是 cap 集合是否重叠
- **宁可过细不过粗**——过细还能查询，过粗会让后续工作失真
- **不信任自动化聚类结果**，但可作为起点
- **不用 embedding**（LLM 生成的 strategy 文本有大量命名漂移，embedding 对"方法差异"敏感度低）

---

## 二、五步执行流程

### Step 1 · 准备特征数据

对每条 strategy 提取以下信号：

| 信号 | 用途 |
|---|---|
| **cap_signature**（set of canonical cap ids） | 机械粗筛基础 |
| **name**（strategy 名） | 理解命名者的本意 |
| **phase 列表**（phase 名 + 简述） | 理解执行步骤 |
| **reasoning**（选择理由） | 理解作者强调的差异点 |
| **body.source** / workflow_outline 里的 implements | 关键技术锚点（工具/模型/参数）|

⚠️ 不要只取名字——名字往往是被 LLM 即兴起的，方法论藏在 phases 和 reasoning 里。

### Step 2 · 机械粗筛（不是最终结果）

算法选择：**中心贪心 + Jaccard 相似度**

```python
# 按 cap_count 降序排列（cap 多的做中心候选）
indices.sort(key=lambda i: -cap_count[i])

for center_idx in indices:
    if assigned: continue
    members = [center_idx]
    for other in indices:
        if other not in assigned and Jaccard(cap[center], cap[other]) >= threshold:
            members.append(other); assigned.add(other)
    clusters.append(members)
```

**关键选择**：

- ❌ 不用传递闭包：A-B=0.6, B-C=0.6 不代表 A-C 相似，容易滚成假大簇
- ✅ 中心-成员结构：每个簇所有成员都和中心相似，不跨中心扩散
- **阈值 0.5** 是起点（0.4 太松、0.7 太紧；193 条时 0.5 产出 67 簇适合审）
- 0-cap strategy 单独处理（没有 signature 可比）

粗筛产出：候选簇 + 单例。把每个簇的成员（带 name/phases/reasoning）输出到 md，供下一步人工判断。

### Step 3 · 人工判断（核心环节）

**不要信任粗筛结果**。逐簇读内容，问三个问题：

#### 判断三问（按优先级）

**Q1：方法论主轴是否相同？**（决定能否合并）

方法论主轴即"怎么做"的根本路径。典型主轴：

| 主轴 | 判别特征 |
|---|---|
| 提示词直出 | 核心是单条 prompt，无多节点 |
| 工作流编排 | Coze/ComfyUI/Lovart 串节点，LLM + 批量生图 + 后处理 |
| 参考图驱动 | 上传图做 anchor（风格/主体/构图）|
| 局部重绘 | Inpaint 蒙版，主体保持其余换 |
| 分层合成 | 分别生成底/人/光/字再合 |
| 双图融合 | 主体 + 目标两张图合一 |
| 模板填充 | 预设模板 + 数据源灌入 |
| 图生视频 | 静态图作首帧/尾帧驱动视频 |

主轴不同 → **不合并**（即使 cap 完全一样）。

**Q2：技术锚点是否相同？**（决定同主轴下要不要再拆）

技术锚点 = 工具生态 / 模型 / 关键参数：
- Coze vs ComfyUI（都"工作流"，但技能栈完全不同）
- Midjourney --sref vs IP-Adapter vs ControlNet（都"参考图驱动"，但技术路径不同）
- Nano Banana 多模态 vs GPT-Image 2 文字渲染（都"AI 直出"，但模型特定能力不同）

技术锚点不同 → 同主轴也拆开（他们是不同的 skill）。

**Q3：产出形态是否与合并相容？**（次要维度）

- 一条出九宫格一条出长图，方法（Coze 批量拼合）完全一致 → **合并**
- 方法相同但产出不同 → 产出是参数层的事，不影响合并
- 产出相同但方法不同 → 不合并（产出不是方法论）

#### 决策树

```
两条 strategy 应该合并吗？
├─ 方法论主轴相同吗？
│   ├─ No → 不合并
│   └─ Yes ↓
├─ 技术锚点相同吗？（工具/模型/关键技术）
│   ├─ No → 不合并（同主轴但不同 skill）
│   └─ Yes ↓
└─ 合并（产出形态差异可接受）
```

### Step 4 · 命名抽象 strategy

每个 pattern 起名的规则：

- 必须体现**方法论**，不是产出：❌ "九宫格生成"  ✅ "Coze 工作流编排全自动套路"
- 用"**套路**"/"**skill**"后缀（和"路线"/"流派"这种 req-specific 叫法区分开）
- 结构：`[工具/生态] + [核心动作] + 套路`  例如：
  - "Nano Banana 多模态单模型直出套路"
  - "双图融合虚拟试穿套路"
  - "QA 闭环自动优化套路"
  - "Character Sheet 多视角参考表套路"

避免：
- 过于通用的后缀如"套路"前不带任何区分词（"AI 生成套路" 无信息量）
- req-specific 词汇（"表情包套路"太窄，改为"多情绪矩阵批量生成套路"）
- 英文术语堆砌（"Prompt-driven Single-Step Generation Pattern"）

### Step 5 · 质量检查

合并完成后验证：

| 检查 | 期望 |
|---|---|
| 每个 pattern 的成员能用一句话描述共通做法 | ✓ |
| pattern 数量在 20-40（针对 100-300 条 strategy）| ✓（过少过合，过多过散）|
| 单例 pattern 不超过总量 20% | 允许 1:1 的"独特方法"，但不能全是单例 |
| 最大簇不超过总量 15% | 超过说明粒度太粗 |
| 每条具体 strategy 被分配到一个（且仅一个）pattern | ✓ |

---

## 三、反模式清单

**以下做法即使诱人也要避免：**

### 反模式 1 · 按 cap 重合度机械合并
- 典型：Jaccard >= 0.7 传递闭包 → 45 条归一大类
- 问题：基础 cap（CAP-001 文生图、CAP-008 批量、CAP-014 文字）人人都用，重合度高不代表方法同
- 对策：cap 只做粗筛，判断要看 phases + reasoning

### 反模式 2 · 按 name 文本相似度合并
- 典型：用 2-gram Jaccard 比 strategy name
- 问题：LLM 生成的 name 命名漂移严重（"3D夸张风格路线"和"多镜头拟人化故事视频流派"都用"多维"和"拟人化"词汇，但方法完全不同）
- 对策：名字只是参考，以 phases 为准

### 反模式 3 · 用 embedding 做相似度
- 典型：把每条 strategy 文本化后 embed，cosine > 0.85 合并
- 问题：embedding 对"讨论话题"敏感，对"方法差异"不敏感（两条都讨论"生成猫咪表情包"得分很高，但一条是 prompt 直出，一条是 ComfyUI 换装，不该合并）
- 对策：看不见的信号不用

### 反模式 4 · 用传递闭包
- 典型：A-B=0.6、B-C=0.6，推出 A-B-C 一簇
- 问题：A-C 可能 0.2，真实不相似，但被强行归到一起
- 对策：中心-成员结构（每个成员必须和簇中心相似，不跨中心传递）

### 反模式 5 · 按产出形态分类
- 典型：把所有"九宫格"归一类、所有"视频"归一类
- 问题：产出相同但方法可以天差地别；同方法应用到不同产出反而被拆开，失去迁移复用价值
- 对策：方法优先，产出次要

### 反模式 6 · 过度细分到失去抽象
- 典型：每条 strategy 都有自己独特之处 → 27 条变 50+ pattern
- 问题：没达到抽象目的，相当于 1:1 映射
- 对策：强制合并"大同小异"，抓主轴忽略细节差异

### 反模式 7 · 过度合并到失去信息
- 典型：所有 AI 生成归为"AI 生成套路"
- 问题：抽象层级太高，查询时无区分度
- 对策：至少区分"方法论 × 技术锚点"两维

---

## 四、边界情况处理

### 情况 1 · Strategy 跨多个 pattern

**示例**：REQ_045 的"AI脚本驱动·批量生图·文字嵌入·宫格自动排版一体化流派" 同时涉及：
- Coze 工作流编排（P04）
- 网格直出（P15）
- AI 文字渲染（P26）

**处理**：归到**主要方法**那个 pattern（通常是方法论主轴最重的那个）。这里归 P04，因为 Coze 编排是灵魂，网格和文字只是其中一个环节。

### 情况 2 · 单例 strategy

**示例**：只有 1 条成员的候选 pattern。

**处理**：
- 若确实是独特方法（无其他 strategy 可合并），保留为单例 pattern
- 若是因数据稀少导致的漏判（比如 alt strategy 没生成），归到最近的 pattern
- 判断标准：这条 strategy 的方法论是否将来可能被其他 req 采用？是则独立，否则合并

### 情况 3 · 0-cap 或 body 缺失的 strategy

**处理**：优先用 salvage 脚本补全 body（参考 `salvage_placeholder_strategies.py`），再参与合并。无法补全的标 `data_degraded`，不参与聚类。

### 情况 4 · Selected 和 Alt 归到同一 pattern

**这是正常的**。一个 req 的 selected 和 alt 如果用同一方法（只是参数不同）就应归同一 pattern。
不同 req 各自的 alt 归到同一 pattern 也正常——说明那个方法在多 req 下都被考虑过但未被选中。

### 情况 5 · 方法论混合型 strategy

**示例**：一条 strategy 前半用 Coze 工作流后半用 ComfyUI 精修。

**处理**：归到**阶段数占比最大**的那个 pattern。若真 50-50，归到**门槛更低**的那个（工作流 > ComfyUI）。

---

## 五、实操产出形式

完成后给用户审核的 md 应包含：

```markdown
## P01 · 套路名
> 一句话方法论描述

**成员（N）**：
- REQ_XXX selected/alt name
- REQ_YYY selected/alt name
...
```

以及汇总表：

```
| # | 套路 | 成员数 |
|---|---|---|
| P01 | ... | 17 |
```

用户审核时主要看：
1. **套路命名**是否一眼看懂方法论
2. **成员是否符合命名**（粗翻，找明显不搭的）
3. **边界是否合理**（有没有想拆/想合的冲动）

用户通常只会"看一眼没问题就行"，所以方案要**一读即懂**，命名和分类要经得起 5 秒直觉判断。

---

## 六、后续入库建议

合并方案确认后：

1. **保留**全部原具体 strategy 作为 knowledge（带 `version` 标记，如 `howard_strategy_instance`）
2. **新建**抽象 strategy（约 N/6 条，N=具体 strategy 数量）
3. `requirement_strategy` 改 M:N：每 req 关联其具体 strategy 对应的抽象 pattern
4. `strategy_capability` 重建为抽象 strategy ↔ cap signature（取簇内 cap 联合集或频次 ≥50% 的核心集）
5. `strategy_resource` 为抽象 strategy ↔ 簇内所有成员 resource 联合集

---

## 七、本次（2026-04-22）实操验证

| 指标 | 值 |
|---|---|
| 输入具体 strategy 数量 | 193 |
| 机械粗筛候选簇数（Jaccard>=0.5 中心贪心）| 67（31 多簇 + 36 单例）|
| 人工判断后最终 pattern 数 | **27** |
| pattern 分布 | 最大 17 成员 / 平均 7 / 最小 1 |
| 耗时（纯判断环节） | ~30 分钟 |

关键观察：
- 粗筛的 31 多簇最终**拆成了 20+ 个 pattern**（方法论主轴不同被拆）
- 但也有**跨候选簇的 strategy 被合并**（机械聚类因 cap 不完全重合未识别，但方法论相同）
- 说明机械聚类召回和精度都不够，**人工判断不可省**

---

## 参考脚本

- `knowhub/scripts/salvage_placeholder_strategies.py` - 占位 strategy 修复（Step 0 前置）
- `knowhub/scripts/ingest_all_strategies.py` - 全量入库含 alt（本方法论的输入数据准备）
- Phase 3 聚类脚本（center-greedy clustering） - 本方法论 Step 2 的实现
