Impeccable 的 extract 流程详解:从重复 UI 模式中提炼可复用组件与设计令牌
在 AI 辅助开发的前端项目中,重复的按钮、散落各处的硬编码颜色和字号会随迭代不断膨胀,最终演变成难以维护的样式债务。Impeccable 项目提供的 /impeccable extract 命令(对应流程文档 extract.md)定义了一套从“发现现有设计系统”到“沉淀文档”的六步标准流程,帮助 Agent 系统性地识别目标区域中值得复用的模式与令牌,并把它们合并进设计系统。读完本文,你将掌握 extract 流程的完整操作步骤、判断“该不该抽象”的量化标准,以及六条不可逾越的反模式红线,并能理解这套流程在 Impeccable 自身文档中是如何被实际落地的。
extract 在 Impeccable 命令体系中的定位
Impeccable 通过单一技能入口暴露 23 个子命令,全部经由 /impeccable 调用。在 SKILL.md 的命令表中,extract 属于 Build 类别,描述为 “Pull reusable tokens and components into design system”(把可复用的令牌与组件拉入设计系统),并支持可选的目标参数:
/impeccable extract [target]
即你可以指定要提炼的具体区域(如某个目录、某组页面),省略参数则由 Agent 自行确定扫描范围。README 中对它的概括是 “Pull reusable components and tokens into the design system”。
按照 SKILL.md 的 Setup 约定,任何命令执行前 Agent 都会先运行一次 context.mjs(位于 .agent/skills/impeccable/scripts/),加载 PRODUCT.md、DESIGN.md 与对应 surface brief 等持久化上下文——这意味着 extract 流程天然能感知项目已有的产品事实与视觉方向,而不是从零猜测。
Step 1: Discover the Design System
流程的第一步是先找,而不是先建:定位项目中现有的设计系统、组件库或共享 UI 目录,并理解它的结构,包括:
- 组件的组织方式(目录布局、分组逻辑)
- 命名约定(组件名、文件名、类名前缀)
- 设计令牌(design token)的结构
- import/export 约定
原文档在此处给出了一条 CRITICAL 级约束:如果项目中尚不存在设计系统,不要现在就创建一个。正确做法是直接向用户提问,澄清无法推断的部分——先弄清用户期望的存放位置与结构,再开始工作。从源码结构看,这一约束对应技能模板中的 {{ask_instruction}} 占位符(skill/reference/extract.md 第 9 行),即由运行时注入的具体“提问指令”,确保 Agent 在信息缺口处停下来询问,而不是自行假设。
这一步的价值在于:后续的组件命名、令牌层级、文件落位都必须与现有约定保持一致,否则提炼出的资产会成为第二套并行体系。
Step 2: Identify Patterns
在确定扫描范围后,Agent 需要在目标区域内主动搜寻六类提炼机会:
| 模式类型 | 具体表现 |
|---|---|
| Repeated components(重复组件) | 同一 UI 模式被使用 3 次及以上(按钮、卡片、输入框) |
| Hard-coded values(硬编码值) | 本应成为令牌的颜色、间距、字体、阴影 |
| Inconsistent variations(不一致的变体) | 同一概念存在多种实现 |
| Composition patterns(组合模式) | 重复出现的布局或交互模式(表单行、工具栏分组、空状态) |
| Type styles(字体样式) | 重复出现的 font-size + weight + line-height 组合 |
| Animation patterns(动画模式) | 重复出现的 easing、duration 或 keyframes 组合 |
原文档同时给出了价值评估的量化门槛:只提炼被相同意图使用 3 次以上的东西(only extract things used 3+ times with the same intent)。原文明确警告:过早抽象比重复更糟(Premature abstraction is worse than duplication)。这条 3 次规则是整篇文档中最具操作性的判断标准——它防止 Agent 把一次性实现过早上升为“组件”,也避免为了收敛而收敛。
Step 3: Plan Extraction
动手前必须先形成一份系统化的提炼计划,覆盖五个维度:
- Components to extract:哪些 UI 元素将成为可复用组件?
- Tokens to create:哪些硬编码值将转为设计令牌?
- Variants to support:每个组件需要支持哪些变体?
- Naming conventions:组件名、令牌名、prop 名如何与既有命名模式保持一致?
- Migration path:现有使用点如何重构为消费新版共享实现?
此处原文档附带一条 IMPORTANT 原则:设计系统是增量生长的——只提炼现在明确可复用的部分,而不是把所有“将来可能可复用”的东西一次性抽象出来。这与 Step 2 的 3 次规则共同构成了 extract 流程的克制哲学:设计系统的价值来自渐进式收敛,而非大爆炸式重构。
Step 4: Extract & Enrich
这一步要求构建的不再是简单拷贝,而是改进后的可复用版本。原文档按三类资产分别提出要求:
组件(Components)
- 清晰的 props API 与合理的默认值
- 针对不同使用场景的恰当变体
- 内建的无障碍支持:ARIA 属性、键盘导航、焦点管理
- 文档与使用示例
设计令牌(Design tokens)
- 清晰的命名体系,区分 primitive(原始值)与 semantic(语义值)两层
- 合理的层级与组织
- 每个令牌的“何时使用”说明
模式(Patterns)
- 该模式的适用时机
- 代码示例
- 变体与组合方式
注意“Extract & Enrich”这个动词组合:提炼不是机械搬迁,而是借迁移之机补上原本缺失的类型、无障碍与文档——这与流程末尾 NEVER 清单中“不得跳过 TypeScript 类型或 prop 文档”的要求相呼应。
Step 5: Migrate
提炼完成后,必须回写存量代码,形成闭环,包含四个动作:
- Find all instances:搜索所有被提炼模式的现有实例
- Replace systematically:逐个更新为消费共享版本
- Test thoroughly:确保视觉与功能双重一致性(parity)
- Delete dead code:删除旧实现,避免同一概念出现双份来源
其中“Delete dead code”尤为关键:若旧实现残留,团队日后仍会引用它,设计系统的单一事实来源(single source of truth)地位即刻瓦解。
Step 6: Document
最后一步是把新资产登记进设计系统文档:
- 将新组件加入组件库
- 记录令牌的取值与用法
- 补充示例与使用指南
- 更新 Storybook 或组件目录
至此,六步流程形成完整闭环:发现 → 识别 → 规划 → 提炼强化 → 迁移 → 文档化。
NEVER 红线清单
原文档以独立的 NEVER 区块列出了六条禁止行为,可作为评审 extract 产出的检查表:
- 不提炼一次性的、依赖特定上下文的实现——除非已做泛化处理;
- 不创建泛化到毫无用处的组件——过度抽象与过早抽象同样有害;
- 不无视既有设计系统约定——命名、组织方式必须对齐现状;
- 不跳过规范的 TypeScript 类型与 prop 文档;
- 不为每个值都建令牌——令牌必须具备语义意义,而非值的一一对应;
- 不提炼意图不同的东西——两个外观相似但目的不同的按钮,应当保持分离。
第 6 条与 Step 2 的“same intent”门槛互为表里:抽象的边界不是“长得像”,而是“意图相同”。
在 Impeccable 仓库中的实证:kit 消费规则
extract 流程所倡导的原则在 Impeccable 自身的文档中有着直接体现。其站点设计文档 DESIGN.md 定义了一个名为 “Neo Kinpaku” 的设计系统,把全局组件 kit 收敛在单一 CSS 文件中,由页面基类统一导入,所有页面免费获得;样式经由 kinpaku-tokens.css 中的令牌解析,组件类自动继承当前品牌值。
更值得注意的是其中“Kit Consumption Rule”(kit 消费规则)的表述,与 extract 流程的理念逐条对应:
- 构建新页面或重构现有页面时,先取用 kit 原语,再考虑发明新类。例如按钮统一用
.ks-button加变体,明令禁止再写.hero-cta-primary/.footer-cta这类“为每个场景各造一个”的 bespoke 词汇——这正是 extract 要消除的“不一致的变体”。 - 分组内容统一用
.ks-bento网格而非发明新卡片类;只有当 kit 确实覆盖不了某个形状时才允许自创,并且自创的新模式如果解决了真实的重复性需求,就应当回流进 kit,而不是留在页面级 CSS 中。这句话本质上是 extract 流程的增量生长原则(Step 3)在执行层的落地。 - 文档还专门用 “Tokens vs Classes” 一节区分两层使用方式:kit 原语消费令牌,而原语之外需要颜色、字号阶梯、easing 或透明度时直接读取令牌(如
var(--ks-kinpaku)、var(--ks-patina))——这正对应 Step 4 中 primitive 与 semantic 令牌分层的落地方式。
也就是说,/impeccable extract 的六步流程与仓库文档中“先查 kit、令牌直读、新模式回流”的规则是同一套设计系统维护哲学在不同文档里的表达:前者是执行流程,后者是执行完成后应维护的稳态。
实际运行方式与适用前提
在任意支持的技能宿主中安装 Impeccable 后(推荐方式是从项目根目录运行 npx impeccable install,详见 README 的 Installation 一节),即可在会话中直接触发该流程:
/impeccable extract # 由 Agent 确定扫描范围
/impeccable extract src/pages # 指定目标区域
适用前提与限制:
- 该命令面向已有存量代码的前端项目,其核心输入是目标区域中的重复模式;对全新空项目没有提炼对象。
- 项目中若无既有设计系统,流程会按 Step 1 的 CRITICAL 约束停在“询问用户”环节,需要你确认设计系统的目标位置与结构后才继续。
- 流程的量化判断标准(3 次以上、相同意图)是原文档明文规定,实际执行中可将其作为与 Agent 协商取舍的依据。
小结
extract.md 用六个步骤加一份 NEVER 清单,把“从代码中提炼设计系统”这一高自由度任务约束成可复核的标准作业:Step 1 的“先发现后创建”、Step 2 的 3 次使用门槛、Step 3 的增量生长、Step 4 的强化而非搬迁、Step 5 的迁移闭环与死代码清除、Step 6 的文档登记,共同保证了提炼结果既不过度抽象、也不遗漏可复用价值。对希望让 AI Agent 参与设计系统建设的团队而言,这套流程的价值在于它把抽象的“代码洁癖”翻译成了可执行、可检查、可协商的步骤与红线。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00