AI 为主题配置流程提效实践经验分享

背景
我们设计组建立并维护了一套设计系统,并且也有一个「主题编辑器」,支持可视化配置全局/组件维度的颜色、圆角和字号等。

虽然我不是主题编辑器项目的负责人,但我对这个平台是有些感情的,因为这是我刚来这家公司不久就深度参与的设计中台项目之一,当时加班加点梳理组件 Token 明细、逐个组件编排配置面板等场景还历历在目。
当时我们设定「主题编辑器」的使用路径是这样的:
- 要基于当前 React 组件库的框架进行主题/风格的定制时;
- 在主题编辑器里对全局样式或组件配置项进行编辑;
- 发布主题后,将主题包的哈希值交付给前端开发;
- 以后前端调用组件库时,应用的是经过设计师精调的风格。

这个主题编辑器最初的构想很美好:当不同业务的产品/设计对设计风格有自定义要求,但又不想重新设计开发一套组件库,就可以通过「主题编辑器」基于当前的 React 组件库来手动配置一套样式。
网上其他品牌的组件库也有类似工具,比如:Arco / Ant Design 的主题编辑器,其实和我们公司内部是一样的东西:

思考
我自己也帮业务系统配置过主题,当时感受到一个很痛的痛点:主题配置太麻烦了,必须逐条手动修改。
目前主题编辑器主要有两个使用场景:
- 设计师在 Figma 对系统的主要设计风格进行定义、出了几个主界面的设计后,在主题编辑器里对照设计稿逐条配置;
- 产品想参考某个系统/平台的风格,但是不会进行配置(或者觉得麻烦),最终还是找设计师来帮忙。
AI 时代来临之后,公司领导常说要研究如何让 AI 为旧流程提效,我觉得这里可能有机会点。
启发
我在网上看到过有些工具是在线提取指定网站的设计风格,能把主题色、边框色和字号梯度等等都抓取下来,并生成一份 DESIGN.md。

这个工具看上去很哇塞,但是却很难进入到 B 端工作流里,原因有二:
- 无法访问要登录的站点或内网 —— 比如发一个阿里云后台的链接,在这种平台上是无法访问的;
- 输出物无法直接被内部的主题编辑器消费 —— DESIGN.md 与主题编辑器的 Schema 毫无关联。
受此启发,我们设计师也可以做个浏览器插件:
提取任意网站的设计风格,并输出一份适用于内部主题编辑器的配置参数。
当时想做成浏览器插件而不是 SKILL 的主要原因有两点:
- 绕过登录态。SKILL 里做内网登录状态相对麻烦而且细碎,插件天然长在我浏览器里,登录态现成就有;
- 稳定采集页面样式。浏览器打开看到的是渲染后的样式,而且可以直观地指定想要采集的页面风格。
这是「主题风格提取器」插件的真实使用过程录屏。如果对实现过程有兴趣,可以继续往下看。

下面就来分享下这个插件的制作过程和细节。项目里会有些纠结和取舍,也有一些我与 AI 斗智斗勇的过程,对我来说是一段宝贵的经历。
方案规划
因为是探索型项目,在做之前我也先思考了下这个功能的能力边界:我需要做到什么程度,以及可以做到什么程度。
我们当前的主题编辑器里的配置项很多很细,细到 Checkbox 里图标和文字之间的距离、Tabs 高亮指示器的粗细等等都能进行配置。

而每个网页呈现的内容不同,样式的写法也不同,事无巨细地对所有样式参数进行抓取不现实。
所以我决定仅提取目标网站上小部分对整体风格有关键影响的样式,并在此基础上推算出全量的参数配置。前期我先按以下流程进行分析:
- 将当前主题编辑器里的样式配置项梳理一遍;
- 筛选出能较大程度影响视觉风格的那些配置项;
- 插件就专门提取这些配置项,基于一套给定的推导规则把全量样式参数推出来;
- 最后输出为可导入主题编辑器的 JSON 格式。
最终我筛选出以下关键配置项:
| 类型 | 配置项名称 |
|---|---|
| 主题色 | brand-6 |
| 成功色 | success-6 |
| 警告色 | warning-6 |
| 危险色 | danger-6 |
| 中性色(文字) | neutral-text-5 |
| 中性色(填充) | neutral-fill-6 |
| 中性色(边框) | neutral-border-1 ~ 2 |
| 页面背景色 | background-layout |
| 默认字号 | font-14 |
| 默认圆角 | border-default |
明确输出物后,接下来的任务也就明确了:
- Vibe Coding 把「采集 + 输出」的插件做出来,把功能跑通;
- 找多个网页进行采集生成,将生成的内容与真实网页效果对比测试准确度。
制作插件
插件功能开发是基本上没有难度,现在的 Code Agent 开发这种项目都很轻松。整体走这样的提取路径:

- 批量采集页面上的元素样式 (Computed Styles),比如背景色
background-color、字号font-size、圆角大小border-radius等; - 数据处理:
- 合并多页:插件支持采集多个页面,用脚本把多个页面里相同的色值、字号等合并统计数量;
- 聚合相同样式:以组件维度,把相同的样式合并为同一条;
- 裁剪数据:每个类目取最多 20 条不同的样式,防止信息过载;
- 把处理后的数据打包交给 AI,让 LLM 基于样式数据 + 提示词推理出完整样式表,以 JSON 格式输出。
功能跑通后,我迫不及待找几个网站测试效果,但结果令人咋舌。

最开始我以为这件事情很简单,但是现实是:生成内容准确率非常低。举几个例子:
- 以黑白相间(或灰白相间)模块来展示内容的网站,此时输出的结果很容易有误 —— 多种 background-color 出现频率一样时,取哪个?
- 网站明明是 12px 字体风格,输出结果却是 14px —— 非文字元素也会有
font-size属性。
所以我对这个项目的理解是这样的:
采集样式和输出结果(无论是输出 JSON、DESIGN.md 还是 HTML)都不难,难的是结果的准确度。
每个样式类型都要设定更详细的规则,而这正是我这次项目花时间最多、同时收获也最多的地方。下面分享几个点,说说我是用了什么方法让输出结果更准确。
优化策略
重建颜色梯度
一套设计系统里,颜色、字号、圆角等样式 Token 都需要建立梯度,而这正是插件容易犯错的地方 —— 很难保证这些梯度里所有的参数都出现在被采集的页面上。
因为我这插件采集样式的来源是用户当前打开的页面,是基于渲染出来的前端页面来采集的。所以如果一些颜色梯度没有出现在页面上,采集器是无法感知到的。

我曾经试过扫描 CSS Variable 语义化变量名的方式,因为理想状态下,页面上所有用过的颜色都会取自于这个网站自身的颜色变量表。但我最终没有用这个方案,因为在 B 端后台的场景里,事情没有那么简单 —— 在一些历史包袱重的后台,一个系统有多份变量表的事情屡见不鲜。
最终我用了一个自己觉得比较靠谱的办法,虽然会损失一点精确度,但能确保输出物是完整、可用的。我做了一个「AI 定锚点色,算法重建梯度」的策略,具体如下:
- LLM 基于采集的数据确定锚点颜色,比如:系统主题色、一级文字色;
- 用颜色算法把完整色阶计算出来,其中:
- 主题色、有明显色彩倾向的颜色:用 Arco 开源的颜色推导算法;
- 中性色(填充、文字色):用自己捣鼓的灰度插值算法,基于我给定的步长。
这种做法可能会与目标网站的真实设计系统有些许偏差,但能大幅提升产出物的整体完整性、可信度和可解释性,并且有效避免采集错误导致色阶跳跃、步长分布不均匀等问题。

值得一提的是,无论是彩色还是中性色的色板推理,都要区分浅色/深色主题。在深色模式下,彩色色板的饱和度会稍微降低,明度稍微提亮;而中性色普遍调高明度,与浅色主题的的色板相反。
正好 Arco 的颜色生成算法会区分浅色/深色主题:同一个基准色值在两种主题下生成出来的颜色梯度会完全不同。所以插件也会识别当前站点的主题模式。
优先用脚本抓取当前网页的 CSS 属性 color-scheme,如果没有,则让 LLM 发挥它的特长。LLM 侧的方案如下:
- 采集阶段:在插件面板点击「采集」时,自动把当前网页截图下来;
- 预处理:对图片做轻微的质量压缩和分辨率控制(节省 Token);
- 生成阶段:用户点击「生成」时会将图片发送给 AI,先让其给出一个确定的回答:这个网站是浅色(或深色)主题;
- 基于 AI 给出的回答,调用颜色算法的不同功能。

按语义分类数据桶
边框色
我们的主题编辑器里定义了两种边框色:border-1 和 border-2。从语义角度,分别对应的是「默认分割线颜色」和「可交互控件的边框色」。

按我们集团的设计系统,交互控件的边框色都会比分割线颜色深,所以最开始的取值逻辑就是取出现频率最大的两个描边色,然后根据明度排序来定义 border-1 和 border-2。
测试后发现这个方式太不靠谱了,简单举个例子:一个网站页面(尤其是功能复杂的 B 端后台界面)里有可能出现 >2 种描边色,如果刚好采集的页面可交互控件比较少,就会被排到第三位,最终输出错误的边框色。或者一个平台里的边框色基本统一,这个方法就会给出明显的错误结果。
所以对于边框色,我按照语义对数据进行分类,设定一个叫「可交互控件」的桶。具体做法如下:

- 定义「可交互元素」:通过标签名 + Class 关键词 + role 属性等方式进行定义;
- 让
border-1取「非可交互元素」里出现频次最多的边框色; - 让
border-2取「可交互元素」里出现频次最多的边框色。同时:- 排除饱和度 > 12 的颜色(防止有主题色的 Ghost 按钮干扰);
- 没有采集到时用
border-1颜色作为兜底。
注:在第一步如果仅取 <button>、<input> 是不准的,因为按钮有可能是一个 <span> 改造而成,或者输入框的 CSS 样式包在上层 <div> 里。
分别在两个桶内采集数据,实测让输出准确率提升了很多。
圆角兼容处理
由于我们同样不可能准确提取到某个网站的所有控件的圆角大小,所以我们可以利用刚刚定义的「可交互元素」桶。
通过仅提取「可交互元素」的圆角尺寸,以这个尺寸作为锚点来推测出这个系统的圆角风格,并扩展到其他组件上。
下面具体分享下不同的默认圆角大小下我会怎么处理:
- 如果圆角处于正常范围,比如
2px、6px或12px。我可以将绝大部分组件的圆角(标签等小型组件除外)都统一调到提取出来的默认圆角大小,确保整体风格一致; - 如果是全圆角风格,比如采集到的参数是
1000px、9999px或50%。这时候就不能将提取出来的值应用到所有组件上了。因为在块状组件(比如多行文本框、穿梭框、折叠面板等)用这种超大的圆角会出现样式异常。

所以我也做了个特殊处理逻辑,针对「全圆角风格」的情况:
- 在中小型组件里保持使用这种全圆角样式,此时会呈现胶囊形状;
- 在块状组件里取一个主题编辑器定义的非全圆角上限:
24px,此时会呈现大圆角样式,符合整体风格。

按语义降噪
对于页面背景色,最开始插件用的是很简单的逻辑:统计网页里 background-color 的色值,取出现频率最高的。
但是这种方式正确率很低,举个例子:一个后台管理页面里,只有页面背景设为了灰色;但输入框、按钮、侧边栏等这些能盖在背景上层的元素,背景色都是纯白色。此时 AI 很容易推断出页面整体背景色就是白色。

当时基于 AI 的建议,调整了取色逻辑,取 body 或者 [id="app"] 的背景色,或者取网页 CSS 变量表里带有 bg 或 background 的颜色 Token。
但很快就被验证不靠谱了:有些后台的 body 和真实背景色不匹配,或者没有设置色值。变量表的方法同样有盲区,出现多个带有 background 关键词的变量名时,AI 未必能把正确的选出来 —— 甚至如果 body 和 --background 的颜色不同,此时又取哪个?全交给 AI,随机性太大了。
为了提高准确性,我还是用基于「背景色」的语义排除噪音的做法,具体如下:
- 排除面积小于视窗 35% 的元素:避免把输入框、卡片等背景色纳入;
- 排除干扰元素:比如
nav、aside、footer、img、path等存在背景色属性但明显与页面背景色无关的元素; - 排除绝对定位元素:
fixed、absolute。
去掉噪音后,我取了前 5 个面积最大的背景色,并且把其他比较贴合「背景色」语义的参数也一并打包进数据集里面,希望能帮助 LLM 更好地判断。
具体打包了元素的面积和 DOM 层级深度 —— 因为承载背景色的元素大概率面积会很大,而且层级深度相对浅。同时把当前页面的主题色(前文提到用 AI 视觉识别的结果)也打包进去。

此时再让 AI 推理出背景色,实测输出结果的准确度上了好几个档次。
收获
这个工具最终效果蛮不错的,前面表格里列出来的关键颜色都能准确提取出来。配合一套推算规则把全量样式参数都推出来之后,导进主题编辑器内就能快速配出一套与某站点风格高度相似的主题,省下了很多时间。
这个项目最有意思的过程是通过不断尝试,在具有不确定性的 LLM和能稳定 I/O 的脚本中找到一个能同时利用两者优点的策略,输出符合预期的结果。
整个项目耗时不到一周,前期快速搭好功能之后,就得耐心地逐个调整采集策略,不断找各种网页进行测试、改规则等等。
而且我发现 Vibe Coding 流程里有一点很累的是:组织语言。 得在对话框里组织好语言,把相关的上下文理清楚,重点关注什么,让 Agent 别往哪个方向思考等等,才能获得一个比较好的结果。
Context is everything.