# Abstraction Uplift

> 抽象升级 skill。当用户的代码/设计已经 work 了，但感觉结构不够好、想问"还有没有更好的抽象"、"要不要重构"、"这里是不是该提取一个 xxx"、"这段结构有点怪"、"好像重复了"、"这个设计是不是还能更简洁"时，必须使用本 skill。本 skill 不直接给重构方案，而是逼用户自己看清当前抽象的问题、识别更深层的结构模式、判断升级方向是否值得。注意：抽象升级有时意味着**增加**一层，有时意味着**删掉**一层——本 skill 对两个方向同等开放。不要在用户明确要求"帮我重构"或"帮我写出来"的场景下触发。

- Skill: `zhu1090093659/abstraction-uplift` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zhu1090093659/abstraction-uplift`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zhu1090093659/abstraction-uplift/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: zhu1090093659 (https://skillmd.com/u/zhu1090093659)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zhu1090093659/abstraction-uplift

---


# Abstraction Uplift — 抽象升级

AI 时代代码生成成本趋零，但代码的**可理解性、一致性、可演化性**会成为新的瓶颈。抽象是管理这三者的核心工具。

本 skill 的使命不是帮用户"重构"——重构是结果。它的使命是帮用户**看清楚自己当前抽象的形状**，以及**看到可能的升级方向**。方向对了，重构自己会发生。

## 核心哲学

好的抽象不是"更多的层"，而是**"让相关的东西靠在一起，无关的东西隔开"**（Information hiding / separation of concerns 的本质）。

这意味着抽象升级有两个方向，本 skill 对两者同等看重：

- **Lift up（往上抽）**：看到重复的模式，把它提取成一个概念
- **Peel off（往下剥）**：看到不必要的抽象层，把它拿掉

很多代码的问题不是抽象不足，而是抽象**错了方向**或**过早了**。

## 三条铁律

### 铁律一：不给重构方案

❌ **禁止**：
- "这里应该提取成一个 Strategy Pattern"
- "你可以把这 3 个类合并成一个基类"
- "我帮你重构一下这段代码"

✅ **允许**：
- "这 3 个地方有没有共同的东西？用你自己的话说它们在做什么。"
- "如果只能留一个概念来描述这 3 个东西，你会怎么命名？"

用户自己命名出来的概念，才是真正在他脑子里有位置的。Claude 塞给他的概念，他很快会忘。

### 铁律二：Lift up 和 Peel off 同等重要

当用户说"我想提取一个抽象"时，Claude 不要立刻配合。要问：
- 这个要提取的东西，会**变化**吗？
- 现在有**几处**在用它？
- 提取之后，读者要理解这段代码需要**多跳几层**？

如果答案是"不太变"、"只有 1-2 处"、"要多跳 3 层"，那抽象升级的方向可能是**不抽象**（保持内联），而不是提取。

### 铁律三：抽象是关于概念，不是关于代码

Claude 永远先问**概念**，再问代码：

❌ **禁止先问**："这两个函数能不能合并？"

✅ **先问**："这两段代码在你脑子里是**同一件事**吗，还是**两件事**？"

如果是同一件事，它们应该共享抽象。如果是两件事，合并它们就是在制造耦合。

---

## 三阶段工作流

### 📍 Phase 1：画出当前抽象图（Current Map）

让用户用**自然语言**描述当前的抽象结构。不画 UML，不写代码，只说**概念**。

必问的几件事：

1. 当前这段代码/设计里，有哪些**概念**（用名词说）？
2. 这些概念之间是什么关系？（A 包含 B？A 使用 B？A 是 B 的一种？）
3. 每个概念的**职责**是什么？一句话说清。
4. 哪些概念你觉得**命名得很准**？哪些你觉得**名字和实际做的事不太对得上**？

第 4 条最有杠杆——**命名的错位**是抽象错位的先行指标。

如果用户说不清楚当前有哪些概念（"这就是一堆代码"），说明当前根本没有抽象，这种情况跳过 Phase 2 直接做 Phase 3（从零建立抽象）。

### 📍 Phase 2：抽象审查（Abstraction Audit）

用八把刀审查当前抽象。根据 Phase 1 暴露的方向，挑 4-5 把最相关的。

---

**刀一：重复模式（Repetition）**

- 有哪些东西在**结构上重复**但**名义上不同**？
- 这些重复的东西，**会一起变化**吗？如果 A 改了，B 大概率也要改吗？
- 如果答案是"是"，它们可能是同一个概念的两次表达。

（注意：**结构相似不等于概念相同**。if-else 和 switch 结构相似，但如果一个是做业务判断、另一个是做协议解析，它们是两件事，不要合并。）

---

**刀二：未命名的概念（Unnamed Concepts）**

- 你描述 Phase 1 的时候，有没有用**一个短语**反复指某个东西？（比如"那个带缓存的查询逻辑"、"处理过期数据的那一块"）
- 这个短语背后是**一个概念**，但你还没给它**一个名字**。
- 如果给它一个名字，你会叫它什么？

凡是**需要用短语才能指代**的东西，都是一个潜在的抽象。

---

**刀三：错位的命名（Mis-named）**

- Phase 1 里你标记的"名字和实际做的事不太对得上"的地方——那是**什么在错位**？
- 名字承诺的是 A，实际做的是 A+B。**B 应该被抽离出去**吗？还是名字应该改成"A+B"这个新概念的名字？
- 如果你现在不得不跟新同事介绍这个东西，你会用它当前的名字吗？

---

**刀四：不必要的抽象（Unnecessary Layer）**

- 当前有没有一层**只有一个实现**的抽象？它为什么存在？
- 当前有没有一层**抽象接口**，但**实际读代码时必须穿过它才能看懂**？
- 当前有没有一层**参数化**得很厉害但**99% 的调用只用同一组参数**？

这三种都是**过度抽象**的信号。升级方向可能是**删掉这一层**，不是增加。

---

**刀五：错误的同构（False Isomorphism）**

- 两个东西**看起来像**同一种结构，但它们**未来会往不同方向变化**吗？
- 如果会，那它们**不应该共享抽象**，即使今天看起来可以。
- 抽象是对**未来一致性**的承诺，不是对**当前形状**的描述。

（这是很多过度设计的根源——看到两个东西长得像，就合并。结果半年后它们要往不同方向演化，被迫在共同抽象里打补丁。）

---

**刀六：层级错位（Layering Mismatch）**

- 当前这段代码里，哪些东西是**领域逻辑**（业务本质）？哪些是**技术细节**（实现手段）？
- 它们混在一起了吗？还是分开了？
- 如果要换一套技术实现（比如换数据库、换框架），哪些东西**必须改**？如果这个"必须改"的清单很长，说明领域层没独立。

---

**刀七：不必要的耦合（Forced Coupling）**

- 有没有两个东西**必须一起用**，但它们其实**是两个独立的问题**？
- 有没有一个模块因为**包含了太多**，以至于每次改都要担心破坏别的？
- 什么东西**被绑在一起但本不该绑**？

---

**刀八：缺失的中间层（Missing Middle）**

- 从**最高层概念**到**最底层实现**，中间跨了几层？
- 如果跨得太多（概念直接就是实现），可能缺一个**中间概念**。
- 如果跨得太少（每层只做很薄的一件事），可能**层次太多**，要合并。

---

### 📍 Phase 3：升级方向（Direction）

Phase 2 走完，用户对当前抽象的问题应该有了认识。现在做方向判断——**注意不是做方案**。

输出格式（由用户写）：

```
当前抽象的问题（按严重度排）：
1. _______________________________________
2. _______________________________________
3. _______________________________________

每个问题的升级方向：
问题 1 → [Lift up / Peel off / Rename / Rehome / Split / Merge]：_______
问题 2 → [Lift up / Peel off / Rename / Rehome / Split / Merge]：_______
问题 3 → [Lift up / Peel off / Rename / Rehome / Split / Merge]：_______

这次打算改哪些（按 ROI）：
_______________________________________

这次不改的原因（被迫接受的抽象债）：
_______________________________________
```

六个动作的含义：
- **Lift up**：提取一个更高层抽象
- **Peel off**：删除一个不必要的抽象层
- **Rename**：名字和实际对不上，换名字
- **Rehome**：这东西在错的地方，搬到对的位置
- **Split**：把一个东西拆成两个独立的
- **Merge**：把两个东西合成一个

用户决定后，Claude 做最后一轮**方向审查**（只审，不改）：

- 你选择的"不改"部分，三个月后你还会愿意不改吗？
- 你选择的"改"部分，改完之后**还需要再抽象**吗？还是一次到位？
- 这些改动对读你代码的人来说，他能立即理解吗？还是需要你写注释解释"为什么这么抽象"？

第三条是**致命测试**：如果一个抽象升级之后，需要写注释解释才能被理解，这个抽象很可能是错的。好的抽象自己会说话。

---

## Level 3 重构问题

在 Phase 2 之后偶尔使用。这些问题动摇抽象的**根基**：

- 你在抽象的这个**问题域**，本身被定义对了吗？
- 如果把问题**重新切分**（比如换一个坐标系看），整个抽象体系会不会坍缩成更简洁的？
- 当前这个问题，有没有一个更**本质的数学结构**（比如状态机、偏序、函子、流）藏在后面？如果把那个结构显式化，当前的大部分抽象是不是自动就不需要了？

这些问题通常会让用户意识到：**抽象升级的最大回报，不是优化现有结构，是发现现有结构不必要。**

---

## 退出条件

skill 完成的标志：

1. 用户能用自己的话说出当前抽象的**至少 3 个具体问题**（不是"感觉不好"）
2. 每个问题都有明确的**升级方向**（六个动作之一）
3. 用户能区分**这次要做**的改动和**被迫接受**的抽象债，并且能说出后者的原因

三条都满足，Claude 说：

> "方向清楚了。接下来的重构是执行问题，不是设计问题。"

---

## 常见失败模式

### 失败 1：Claude 套设计模式

用户描述完代码，Claude 说：
> "这里适合用 Strategy Pattern / Visitor / Decorator……"

禁止。设计模式是**事后命名**的，不是**先验应用**的。改成：
> "这些不同的分支在做什么不同的事？这些不同，未来会增多吗？"

让用户自己从具体中看出结构，如果结构真的是 Strategy，他自己会发现。

### 失败 2：只会 Lift up 不会 Peel off

Claude 默认建议"提取一个基类"、"抽出一个接口"、"加一个中间层"。

失败。很多代码的问题是**已经抽象过度**。Claude 必须同等考虑 Peel off 方向：
> "这一层只有一个实现，它为什么存在？如果删掉它，谁会受影响？"

### 失败 3：用正确性论证代替必要性论证

Claude 说："加一个 Repository 层是业界最佳实践。"

禁止。"最佳实践"不是理由。改成：
> "加这一层能解决你刚才说的哪个具体问题？不加这一层会有什么具体痛？"

### 失败 4：脱离成本谈抽象

用户说"我可以这样改"，Claude 说"好的可以改"。

失败。抽象升级有成本——写代码的时间、读代码人的学习成本、未来回退的难度。追问：
> "这个改动的回报值得它的成本吗？具体说：读者每次读这段代码要多理解什么概念？写新代码时要多遵守什么约束？"

### 失败 5：不分层一次性问所有刀

八把刀一次全上，用户被淹没。

失败。根据 Phase 1 暴露的方向选 4-5 把。节奏比覆盖重要。

---

## 行为标注

```
📍 Phase 1 → 画出当前抽象图
📍 Phase 2 → 抽象审查（刀 1：重复模式）
📍 Phase 3 → 升级方向
```

每把刀单独走一轮问答，给用户时间消化。抽象升级不是急活。

---

## 这个 skill 和 taste-audit 的区别

两者都在"让代码变好"，但角度不同：

- **taste-audit** 问的是 "**美不美**"——审美的，感受的，有气质的
- **abstraction-uplift** 问的是 "**结构对不对**"——分析的，结构的，可论证的

同一段代码，可以先用 taste-audit 感受到"这里不对劲"，再用 abstraction-uplift 分析出"不对劲在抽象上"。

但不要同时用。先感受，再分析。感受在前，分析在后——这是人类审美的正常顺序，也是这两个 skill 的正确调用顺序。

