> ## 文章索引
> 在这里获取全部文章的索引：https://lrd.im/blog/llms.txt
> 这是 lrd.im 的个人博客，记录设计、技术与思考。

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

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/01.png)

## 背景

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

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/02.png)

虽然我不是主题编辑器项目的负责人，但我对这个平台是有些感情的，因为这是我刚来这家公司不久就深度参与的设计中台项目之一，当时加班加点梳理组件 Token 明细、逐个组件编排配置面板等场景还历历在目。

当时我们设定「主题编辑器」的使用路径是这样的：

1. 要基于当前 React 组件库的框架进行主题/风格的定制时；
2. 在主题编辑器里对全局样式或组件配置项进行编辑；
3. 发布主题后，将主题包的哈希值交付给前端开发；
4. 以后前端调用组件库时，应用的是经过设计师精调的风格。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/03.png)

这个主题编辑器最初的构想很美好：当不同业务的产品/设计对设计风格有自定义要求，但又不想重新设计开发一套组件库，就可以通过「主题编辑器」基于当前的 React 组件库来手动配置一套样式。

网上其他品牌的组件库也有类似工具，比如：Arco / Ant Design 的主题编辑器，其实和我们公司内部是一样的东西：

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/04.png)

### 思考

我自己也帮业务系统配置过主题，当时感受到一个很痛的痛点：主题配置太麻烦了，必须逐条手动修改。

目前主题编辑器主要有两个使用场景：

1. 设计师在 Figma 对系统的主要设计风格进行定义、出了几个主界面的设计后，在主题编辑器里对照设计稿逐条配置；
2. 产品想参考某个系统/平台的风格，但是不会进行配置（或者觉得麻烦），最终还是找设计师来帮忙。

AI 时代来临之后，公司领导常说要研究如何让 AI 为旧流程提效，我觉得这里可能有机会点。

### 启发

我在网上看到过[有些工具](https://www.context.dev/free-tools/design-md-generator)是在线提取指定网站的设计风格，能把主题色、边框色和字号梯度等等都抓取下来，并生成一份 DESIGN.md。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/05.png)

这个工具看上去很哇塞，但是却很难进入到 B 端工作流里，原因有二：

1. 无法访问要登录的站点或内网 —— 比如发一个阿里云后台的链接，在这种平台上是无法访问的；
2. 输出物无法直接被内部的主题编辑器消费 —— DESIGN.md 与主题编辑器的 Schema 毫无关联。

受此启发，我们设计师也可以做个浏览器插件：

> 提取任意网站的设计风格，并输出一份**适用于内部主题编辑器的配置参数**。

当时想做成浏览器插件而不是 SKILL 的主要原因有两点：
1. 绕过登录态。SKILL 里做内网登录状态相对麻烦而且细碎，插件天然长在我浏览器里，登录态现成就有；
2. 稳定采集页面样式。浏览器打开看到的是渲染后的样式，而且可以直观地指定想要采集的页面风格。

这是「主题风格提取器」插件的真实使用过程录屏。如果对实现过程有兴趣，可以继续往下看。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/06.png)

<video alt="主题风格提取器的使用链路示意图和真实使用过程的操作录屏" src="https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/07.mp4">

下面就来分享下这个插件的制作过程和细节。项目里会有些纠结和取舍，也有一些我与 AI 斗智斗勇的过程，对我来说是一段宝贵的经历。

## 方案规划

因为是探索型项目，在做之前我也先思考了下这个功能的能力边界：我**需要做到什么程度**，以及**可以做到什么程度**。

我们当前的主题编辑器里的配置项很多很细，细到 Checkbox 里图标和文字之间的距离、Tabs 高亮指示器的粗细等等都能进行配置。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/08.png)

而每个网页呈现的内容不同，样式的写法也不同，事无巨细地对所有样式参数进行抓取**不现实**。

所以我决定仅提取目标网站上小部分对整体风格有关键影响的样式，并在此基础上推算出全量的参数配置。前期我先按以下流程进行分析：

1. 将当前主题编辑器里的样式配置项梳理一遍；
2. 筛选出能较大程度影响视觉风格的那些配置项；
3. 插件就专门提取这些配置项，基于一套给定的推导规则把全量样式参数推出来；
4. 最后输出为可导入主题编辑器的 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` |

明确输出物后，接下来的任务也就明确了：

1. Vibe Coding 把「采集 + 输出」的插件做出来，把功能跑通；
2. 找多个网页进行采集生成，将**生成的内容**与**真实网页效果**对比测试准确度。

## 制作插件

插件功能开发是基本上没有难度，现在的 Code Agent 开发这种项目都很轻松。整体走这样的提取路径：

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/09.png)

1. 批量采集页面上的元素样式 (Computed Styles)，比如背景色 `background-color`、字号 `font-size`、圆角大小 `border-radius` 等；
2. 数据处理：
    1. 合并多页：插件支持采集多个页面，用脚本把多个页面里相同的色值、字号等合并统计数量；
    2. 聚合相同样式：以组件维度，把相同的样式合并为同一条；
    3. 裁剪数据：每个类目取最多 20 条不同的样式，防止信息过载；
3. 把处理后的数据打包交给 AI，让 LLM 基于样式数据 + 提示词推理出完整样式表，以 JSON 格式输出。

功能跑通后，我迫不及待找几个网站测试效果，但结果令人咋舌。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/10.png)

最开始我以为这件事情很简单，但是现实是：**生成内容准确率非常低**。举几个例子：

1. 以黑白相间（或灰白相间）模块来展示内容的网站，此时输出的结果很容易有误 —— 多种 background-color 出现频率一样时，取哪个？
2. 网站明明是 12px 字体风格，输出结果却是 14px —— 非文字元素也会有 `font-size` 属性。

所以我对这个项目的理解是这样的：

> 采集样式和输出结果（无论是输出 JSON、DESIGN.md 还是 HTML）都不难，难的是结果的准确度。

每个样式类型都要设定更详细的规则，而这正是我这次项目花时间最多、同时收获也最多的地方。下面分享几个点，说说我是用了什么方法让输出结果更准确。

## 优化策略

### 重建颜色梯度

一套设计系统里，颜色、字号、圆角等样式 Token 都需要建立梯度，而这正是插件容易犯错的地方 —— 很难保证这些梯度里所有的参数都出现在被采集的页面上。

因为我这插件采集样式的来源是用户当前打开的页面，是基于渲染出来的前端页面来采集的。所以如果一些颜色梯度没有出现在页面上，采集器是无法感知到的。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/11.png)

我曾经试过扫描 CSS Variable 语义化变量名的方式，因为理想状态下，页面上所有用过的颜色都会取自于这个网站自身的颜色变量表。但我最终没有用这个方案，因为在 B 端后台的场景里，事情没有那么简单 —— 在一些历史包袱重的后台，一个系统有多份变量表的事情屡见不鲜。

最终我用了一个自己觉得比较靠谱的办法，虽然会损失一点精确度，但能确保输出物是完整、可用的。我做了一个「AI 定锚点色，算法重建梯度」的策略，具体如下：

1. LLM 基于采集的数据确定锚点颜色，比如：系统主题色、一级文字色；
2. 用颜色算法把完整色阶计算出来，其中：
    1. 主题色、有明显色彩倾向的颜色：用 [Arco](https://github.com/arco-design/color) 开源的颜色推导算法；
    2. 中性色（填充、文字色）：用自己捣鼓的灰度插值算法，基于我给定的步长。

这种做法可能会与目标网站的真实设计系统有些许偏差，但能大幅提升产出物的整体完整性、可信度和可解释性，并且有效避免采集错误导致色阶跳跃、步长分布不均匀等问题。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/12.png)

值得一提的是，无论是彩色还是中性色的色板推理，都要区分浅色/深色主题。在深色模式下，彩色色板的饱和度会稍微降低，明度稍微提亮；而中性色普遍调高明度，与浅色主题的的色板相反。

正好 Arco 的颜色生成算法会区分浅色/深色主题：同一个基准色值在两种主题下生成出来的颜色梯度会完全不同。所以插件也会**识别当前站点的主题模式**。

优先用脚本抓取当前网页的 CSS 属性 `color-scheme`，如果没有，则让 LLM 发挥它的特长。LLM 侧的方案如下：

1. 采集阶段：在插件面板点击「采集」时，自动把当前网页截图下来；
2. 预处理：对图片做轻微的质量压缩和分辨率控制（节省 Token）；
3. 生成阶段：用户点击「生成」时会将图片发送给 AI，先让其给出一个确定的回答：这个网站是浅色（或深色）主题；
4. 基于 AI 给出的回答，调用颜色算法的不同功能。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/13.png)

### 按语义分类数据桶

#### 边框色

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

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/14.png)

按我们集团的设计系统，交互控件的边框色都会比分割线颜色深，所以最开始的取值逻辑就是取出现频率最大的两个描边色，然后根据明度排序来定义 `border-1` 和 `border-2`。

测试后发现这个方式太不靠谱了，简单举个例子：一个网站页面（尤其是功能复杂的 B 端后台界面）里有可能出现 >2 种描边色，如果刚好采集的页面可交互控件比较少，就会被排到第三位，最终输出错误的边框色。或者一个平台里的边框色基本统一，这个方法就会给出明显的错误结果。

所以对于边框色，我按照语义对数据进行分类，设定一个叫「可交互控件」的桶。具体做法如下：

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/15.png)

1. 定义「可交互元素」：通过标签名 + Class 关键词 + role 属性等方式进行定义；
2. 让 `border-1` 取「非可交互元素」里出现频次最多的边框色；
3. 让 `border-2` 取「可交互元素」里出现频次最多的边框色。同时：
    1. 排除饱和度 > 12 的颜色（防止有主题色的 Ghost 按钮干扰）；
    2. 没有采集到时用 `border-1` 颜色作为兜底。

_注：在第一步如果仅取 `<button>`、`<input>` 是不准的，因为按钮有可能是一个 `<span>` 改造而成，或者输入框的 CSS 样式包在上层 `<div>` 里。_

分别在两个桶内采集数据，实测让输出准确率提升了很多。

### 圆角兼容处理

由于我们同样不可能准确提取到某个网站的所有控件的圆角大小，所以我们可以利用刚刚定义的「可交互元素」桶。

通过仅提取「可交互元素」的圆角尺寸，以这个尺寸作为锚点来推测出这个系统的圆角风格，并扩展到其他组件上。

下面具体分享下不同的默认圆角大小下我会怎么处理：

1. 如果圆角处于正常范围，比如 `2px`、`6px` 或 `12px`。我可以将绝大部分组件的圆角（标签等小型组件除外）都统一调到提取出来的默认圆角大小，确保整体风格一致；
2. 如果是全圆角风格，比如采集到的参数是 `1000px`、`9999px` 或 `50%`。这时候就不能将提取出来的值应用到所有组件上了。因为在块状组件（比如多行文本框、穿梭框、折叠面板等）用这种超大的圆角会出现样式异常。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/16.png)

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

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/17.png)

### 按语义降噪

对于页面背景色，最开始插件用的是很简单的逻辑：统计网页里 `background-color` 的色值，取出现频率最高的。

但是这种方式正确率很低，举个例子：一个后台管理页面里，只有页面背景设为了灰色；但输入框、按钮、侧边栏等这些能盖在背景上层的元素，背景色都是纯白色。此时 AI 很容易推断出页面整体背景色就是白色。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/18.png)

当时基于 AI 的建议，调整了取色逻辑，取 `body` 或者 `[id="app"]` 的背景色，或者取网页 CSS 变量表里带有 `bg` 或 `background` 的颜色 Token。

但很快就被验证不靠谱了：有些后台的 `body` 和真实背景色不匹配，或者没有设置色值。变量表的方法同样有盲区，出现多个带有 `background` 关键词的变量名时，AI 未必能把正确的选出来 —— 甚至如果 `body` 和 `--background` 的颜色不同，此时又取哪个？全交给 AI，随机性太大了。

为了提高准确性，我还是用基于「背景色」的语义排除噪音的做法，具体如下：

1. 排除面积小于视窗 35% 的元素：避免把输入框、卡片等背景色纳入；
2. 排除干扰元素：比如 `nav`、`aside`、`footer`、`img`、`path` 等存在背景色属性但明显与页面背景色无关的元素；
3. 排除绝对定位元素：`fixed`、`absolute`。

去掉噪音后，我取了前 5 个面积最大的背景色，并且把其他比较贴合「背景色」语义的参数也一并打包进数据集里面，希望能帮助 LLM 更好地判断。

具体打包了元素的**面积**和 **DOM 层级深度** —— 因为承载背景色的元素大概率面积会很大，而且层级深度相对浅。同时把当前页面的主题色（前文提到用 AI 视觉识别的结果）也打包进去。

![](https://lrdim.oss-accelerate.aliyuncs.com/blogimg/2026-09-29/19.png)

此时再让 AI 推理出背景色，实测输出结果的准确度上了好几个档次。

## 收获

这个工具最终效果蛮不错的，前面表格里列出来的关键颜色都能准确提取出来。配合一套推算规则把全量样式参数都推出来之后，导进主题编辑器内就能快速配出一套与某站点风格高度相似的主题，省下了很多时间。

这个项目最有意思的过程是通过不断尝试，在**具有不确定性的 LLM**和**能稳定 I/O 的脚本**中找到一个能同时利用两者优点的策略，输出符合预期的结果。

整个项目耗时不到一周，前期快速搭好功能之后，就得耐心地逐个调整采集策略，不断找各种网页进行测试、改规则等等。

而且我发现 Vibe Coding 流程里有一点很累的是：**组织语言。** 得在对话框里组织好语言，把相关的上下文理清楚，重点关注什么，让 Agent 别往哪个方向思考等等，才能获得一个比较好的结果。

Context is everything.