AI 驱动的设计 Token 智能推导:从设计稿中自动提取语义化设计变量
一、引言:当设计师说"这个蓝有点不一样",我们在调试什么
在美院学习色彩时,我的老师曾让我们做一个练习:用同一色相的不同明度,画出一天中光线变化的氛围。从清晨的灰蓝到正午的鲜蓝,再到黄昏的暖蓝——它们之间看似只有"一点点不一样",但就是这"一点点",决定了画面的情绪和呼吸感。
转到前端后,我发现设计系统中的色彩管理,和这幅"光线变化练习"有着惊人的相似。设计师会指着设计稿说:"这个主色在 hover 状态时要暗 8%"、"这个背景色在深色模式下要偏暖一点"——这些微调,本质上是设计 Token 体系中的语义化变量在起作用。
但现实很骨感。大多数团队的设计 Token 管理,仍然停留在"手动提取 Figma 样式 → 粘贴到代码中的变量文件"的原始阶段。这个过程不仅耗时,而且极易出错:
- 命名不一致:设计师叫它"Primary Blue",开发在代码里写成 –color-main,另一个项目里又变成了 –primary-500。
- 语义丢失:从设计稿中提取的 #1890FF,失去了它作为"品牌主色"的语义,变成一个冰冷的十六进制值。
- 多主题适配成本高:当需要扩展深色模式、品牌定制模式时,需要手动为每个 Token 创建映射关系。
AI 驱动的设计 Token 智能推导,正是在这个痛点上的一种新尝试。它能够"读懂"设计稿中的颜色、间距、字号的使用规律,自动推导出语义化的 Token 命名,并构建多主题下的变量映射关系。
更重要的是,AI 在推导过程中不仅能够识别"这个值是什么"(如 #1890FF),还能够理解"这个值在设计系统中的作用"(如"这是品牌主色,hover 时应该使用它的暗色变体")。这种"语义级"的理解,是传统手工提取无法企及的。
本篇文章,我将从自己的实践出发,拆解 AI 如何自动化地完成设计 Token 的提取、命名和映射,分享其中的技术原理、实现方案,以及落地过程中的真实踩坑经验。
二、底层机制:AI 如何"理解"设计系统中的 Token 语义
要让 AI 从设计稿中推导出设计 Token,核心挑战在于:如何让机器理解"为什么这个值是这个",而不仅仅是"这个值是什么"。
设计规律的检测器:从"值"到"规律"
AI 在分析设计稿时,首先会检测其中的设计规律。这些规律是推导语义化 Token 的基础:
1. 色彩规律检测
AI 会分析设计稿中所有颜色值,检测是否存在以下规律:
- 品牌色系:是否存在一个主色,以及它的明度阶梯变体(如 primary-100 到 primary-900)?
- 功能色系:是否存在语义明确的功能色(如 success、warning、error)?
- 中性色系:是否存在从白到黑的灰色阶梯?
如果检测到这些规律,AI 就可以自动为颜色值分配语义化名称。
2. 间距规律检测
大多数设计系统都遵循"间距阶梯"原则(如 4px、8px、12px、16px、24px、32px…)。AI 会检测设计稿中使用的所有间距值,判断它们是否符合某个基础单位的整数倍规律。
例如:如果设计稿中的间距值都是 8 的倍数(8、16、24、32、48…),AI 可以推断基础间距单位为 8px,并生成相应的 Token(–spacing-1: 8px、–spacing-2: 16px…)。
3. 字体阶梯检测
类似的,AI 会检测设计稿中的字号分布,判断是否存在"字体阶梯"(如 12px、14px、16px、20px、24px、32px…)。如果检测到规律,可以自动生成 font-size-sm、font-size-base、font-size-lg 等 Token。
Token 语义标注:从"规律"到"命名"
检测到设计规律后,AI 需要为这些规律分配语义化的名称。这一步涉及"角色推断":
- 品牌主色的推断:出现频率最高、且被用于 CTA 按钮和关键导航链接的颜色,通常被推断为"品牌主色"。
- 功能色的推断:被用于提醒、警告、错误提示等特定场景的颜色,会被标注为对应的功能色。
- 中性色的推断:被用于背景、边框、辅助文本的颜色,通常被标注为中性色。
三、生产级实现:智能 Token 提取与导出管线
下面展示一个实际的实现方案,它能够从 Figma 设计稿中提取设计 Token,并导出为多格式的输出。
/**
* AI 辅助设计 Token 提取器
*
* 核心功能:
* 1. 从 Figma API 获取设计稿的样式信息
* 2. 检测设计规律(色彩阶梯、间距规律、字体阶梯)
* 3. 推导语义化 Token 命名
* 4. 导出为 Style Dictionary / CSS Variables / TS 类型
*/
// ============ 核心数据类型 ============
interface DesignToken {
/** Token 的名称(语义化) */
name: string;
/** Token 的值 */
value: string;
/** Token 的类型 */
type: 'color' | 'spacing' | 'fontSize' | 'lineHeight' | 'fontWeight' | 'borderRadius';
/** Token 的角色标签 */
role: 'brand' | 'functional' | 'neutral' | 'semantic';
/** 所属的主题(如 'light'、'dark'、'brand-a') */
theme?: string;
/** 引用的底层 Token(如 –color-primary-500 引用 –color-primary-base) */
ref?: string;
}
interface DesignSystemPattern {
/** 检测到的色彩阶梯 */
colorRamps: ColorRamp[];
/** 检测到的间距阶梯 */
spacingScale: number[];
/** 检测到的字体阶梯 */
fontSizeScale: number[];
}
interface ColorRamp {
/** 色系的基础色相 */
baseHue: number;
/** 该色系的 Token 前缀(如 'primary'、'success') */
tokenPrefix: string;
/** 明度阶梯(100, 200, …, 900) */
steps: { step: number; hex: string }[];
}
// ============ 主提取器类 ============
class SmartTokenExtractor {
private figmaFileKey: string;
private accessToken: string;
private detectedPatterns: DesignSystemPattern;
constructor(figmaFileKey: string, accessToken: string) {
this.figmaFileKey = figmaFileKey;
this.accessToken = accessToken;
}
/**
* 主入口:提取设计 Token 并导出
*/
async extractAndExport(): Promise<{
tokens: DesignToken[];
exportFiles: Record<string, string>;
}> {
// Step 1: 从 Figma API 获取样式信息
const rawStyles = await this.fetchFigmaStyles();
// Step 2: 检测设计规律
this.detectedPatterns = this.detectDesignPatterns(rawStyles);
// Step 3: 推导语义化 Token
const tokens = this.deriveSemanticTokens(rawStyles, this.detectedPatterns);
// Step 4: 导出为多格式
const exportFiles = this.exportTokens(tokens);
return { tokens, exportFiles };
}
/**
* 从 Figma API 获取样式
*/
private async fetchFigmaStyles(): Promise<FigmaStyle[]> {
const response = await fetch(
`https://api.figma.com/v1/files/${this.figmaFileKey}/styles`,
{
headers: {
'X-Figma-Token': this.accessToken,
},
}
);
if (!response.ok) {
throw new Error(`Figma API 错误:${response.statusText}`);
}
const data = await response.json();
return data.meta.styles; // 返回样式列表
}
/**
* 检测设计规律:色彩阶梯、间距阶梯、字体阶梯
*/
private detectDesignPatterns(styles: FigmaStyle[]): DesignSystemPattern {
const colorValues = styles
.filter(s => s.style_type === 'FILL')
.map(s => s.description); // 简化处理,实际应该解析颜色值
// 简化实现:检测是否颜色值可以形成阶梯
const colorRamps = this.detectColorRamps(colorValues);
// 检测间距规律
const spacingScale = this.detectSpacingScale(styles);
// 检测字体阶梯
const fontSizeScale = this.detectFontSizeScale(styles);
return { colorRamps, spacingScale, fontSizeScale };
}
/**
* 推导语义化 Token 名称
*
* 核心逻辑:
* 1. 根据颜色值的分布,推断角色(品牌主色 / 功能色 / 中性色)
* 2. 根据在设计稿中的使用频率,确定 Token 的重要性
* 3. 生成符合行业惯例的 Token 名称
*/
private deriveSemanticTokens(
styles: FigmaStyle[],
patterns: DesignSystemPattern
): DesignToken[] {
const tokens: DesignToken[] = [];
for (const style of styles) {
const token = this.deriveTokenForStyle(style, patterns);
if (token) {
tokens.push(token);
}
}
return tokens;
}
private deriveTokenForStyle(
style: FigmaStyle,
patterns: DesignSystemPattern
): DesignToken | null {
// 简化实现:根据 style 的名称和属性,推导 Token
if (style.style_type === 'FILL') {
// 检查这个颜色是否属于某个检测到的色彩阶梯
for (const ramp of patterns.colorRamps) {
const matchedStep = ramp.steps.find(s => s.hex === style.description);
if (matchedStep) {
return {
name: `–color-${ramp.tokenPrefix}-${matchedStep.step}`,
value: matchedStep.hex,
type: 'color',
role: ramp.tokenPrefix === 'primary' ? 'brand' : 'functional',
};
}
}
}
return null; // 实际实现需要处理更多类型
}
/**
* 导出 Token 为多格式文件
*/
private exportTokens(tokens: DesignToken[]): Record<string, string> {
const files: Record<string, string> = {};
// 导出为 Style Dictionary JSON 格式
files['tokens.json'] = JSON.stringify(
this.convertToStyleDictionaryFormat(tokens),
null,
2
);
// 导出为 CSS Custom Properties
files['tokens.css'] = this.generateCSSVariables(tokens);
// 导出为 TypeScript 类型定义
files['tokens.ts'] = this.generateTSTypes(tokens);
return files;
}
// ============ 规律检测的简化实现 ============
private detectColorRamps(colorValues: string[]): ColorRamp[] {
// 实际实现需要使用颜色科学库(如 chroma.js)来分析色相、明度、饱和度
// 这里返回简化示例
return [
{
baseHue: 210,
tokenPrefix: 'primary',
steps: [
{ step: 100, hex: '#E6F7FF' },
{ step: 500, hex: '#1890FF' },
{ step: 900, hex: '#003A8C' },
],
},
];
}
private detectSpacingScale(styles: FigmaStyle[]): number[] {
// 简化:假设检测到 8px 倍数规律
return [4, 8, 12, 16, 24, 32, 48, 64];
}
private detectFontSizeScale(styles: FigmaStyle[]): number[] {
// 简化:假设检测到字体阶梯
return [12, 14, 16, 20, 24, 32, 40];
}
// ============ 导出格式的简化实现 ============
private convertToStyleDictionaryFormat(tokens: DesignToken[]): object {
// 转换为 Style Dictionary 的 JSON 格式
const result: Record<string, any> = {};
for (const token of tokens) {
result[token.name] = { value: token.value, type: token.type };
}
return result;
}
private generateCSSVariables(tokens: DesignToken[]): string {
let css = ':root {\\n';
for (const token of tokens) {
css += ` ${token.name}: ${token.value};\\n`;
}
css += '}';
return css;
}
private generateTSTypes(tokens: DesignToken[]): string {
let ts = 'export const tokens = {\\n';
for (const token of tokens) {
ts += ` '${token.name}': '${token.value}',\\n`;
}
ts += '} as const;';
return ts;
}
}
四、边界分析:AI 推导 Token 的局限与人工审核的必要性
尽管 AI 在设计 Token 推导上展现出了很高的效率,但我们必须清醒地认识到:AI 生成的 Token 体系,目前还无法做到"完全无需人工审核"。
4.1 语义理解的模糊边界
AI 可以检测到"这个颜色出现了 15 次,且被用于关键按钮",但它很难判断"这个颜色是否应该被提升为品牌主色,还是仅仅是一个『高频使用的功能色』"。
这种判断,往往涉及品牌策略、设计语言和产品定位——这些"上层决策",目前仍需要人类设计师的参与。
4.2 设计企图的识别误差
有时候,设计稿中的某个"异常值"(如一个偏离色彩阶梯的颜色),可能是设计师有意为之(为了突出重点、创造视觉张力)。但 AI 可能会将其"纠正"为符合规律的色值,从而丢失了设计的微妙之处。
4.3 Token 命名的主观性
即使 AI 能够准确识别 Token 的角色,但"如何命名"仍然是一个主观性很强的问题。不同的团队可能有不同的命名惯例(如 –color-primary vs –brand-blue vs –blue-500)。AI 生成的命名可能需要根据团队的偏好进行调整。
适用场景建议
基于以上分析,我建议将 AI 驱动的设计 Token 推导定位为"智能辅助工具",而非"全自动解决方案":
- ✅ 设计系统从 0 到 1 阶段:AI 可以快速生成初始的 Token 体系,作为讨论和修改的基础。
- ✅ 设计稿的批量标准化:当团队有大量的历史设计稿需要提取 Token 时,AI 可以大幅提高效率和一致性。
- ⚠️ 品牌重塑或设计语言升级:需要高度定制化的 Token 策略时,AI 的生成结果可能需要大量人工调整。
- ❌ 完全替代设计师的 Token 决策:AI 可以成为强大的助手,但最终的 Token 体系仍然需要人类设计师的审美和策略判断。
五、总结
AI 驱动的设计 Token 智能推导,本质上是将"设计规律识别"和"语义化命名"这两个高度模式化的任务自动化。它不会替代设计师在 Token 体系中的策略性决策,但它能够将那些重复性高、规律明确的提取和命名工作接管过来,让我们把精力投入到更具创造性的设计决策中。
从实践来看,这套方案的落地关键在于:AI 生成 + 人工审核的协作模式。AI 负责"从设计稿中提取规律、生成初版 Token",人类设计师负责"审核 Token 的语义准确性、调整命名惯例、确保与品牌策略一致"。
对于团队而言,我的建议是先从小规模、模式化强的设计模块开始试点(如后台系统的基础组件库),积累经验后再逐步扩展到更复杂的品牌设计系统中。设计系统的 Token 化管理,是一条值得投入的长期主义道路;而 AI 的加入,可以让这条路走得更轻盈、更稳健。
规律可以被学习,但美学的判断,仍然需要人类的眼睛和心灵。


