abstraction-uplift

star 20

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

zhu1090093659 By zhu1090093659 schedule Updated 4/17/2026

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

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 的正确调用顺序。

Install via CLI
npx skills add https://github.com/zhu1090093659/growth --skill abstraction-uplift
Repository Details
star Stars 20
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator
zhu1090093659
zhu1090093659 Explore all skills →