UI 逆向工程(UI Reverse Engineering)
将任意 UI 视觉稿逆向还原为结构化 DSL,Agent 可直接消费并生成生产级前端代码。
工作流(6 个阶段)
阶段一 — 图像读取与多轮视觉分析
Agent 具备视觉能力(read_file 支持 PNG / JPG / GIF / WebP),可直接"看"图片。但并非所有模型都支持多模态:当 read_file 返回 "当前模型不支持图片 / Content filtered" 之类提示时,说明本模型无法看图。此时禁止反复重试读取图片,必须立即切换到下方的【备选方案】用文本手段完成图像识别,再继续 4 轮分析。
不要只读一次就下结论,必须执行 4 轮聚焦分析,每轮带着不同的问题去观察同一张图(或同一份文本分析报告)。
> ## ★ 精准还原红线(必须遵守)
>
> 本技能的目标是像素级、逐元素还原 UI,严禁凭经验猜测或自由发挥。任何无法从图像/报告中确定的内容,都必须显式标记,绝不能编造。
>
> 1. 文字必须真实:所有标签、按钮、表头、占位符、文案,必须来自视觉 API 报告 / OCR 结果 / 用户补充,禁止凭"常见用法"杜撰。
> 2. 配色必须取样:所有颜色(主色、文字、边框、背景、语义色)必须来自 palette 或像素采样,禁止套用组件库默认值(如 Ant 的 #1890ff)而自称还原。
> 3. 尺寸必须测量:间距、圆角、字号、列宽等须基于网格/像素推断,标注为"约 Xpx",禁止随意填数。
> 4. 看不清就问:当关键文本或视觉属性无法确认时,必须停下来向用户索取(图片原文、设计标注、或补充截图),而不是硬编一个接近的版本。
> 5. 无视觉能力时不得裸生成:若模型不支持看图,且 VISION_API_KEY 未配置、本地脚本/OCR 也不可用,则禁止输出代码,先按红线第 4 条向用户求助。
> 6. 输出须附置信度:最终代码或 DSL 中,对每个区域标注信息来源(已确认 / 推断 / 待确认),让用户一眼看出哪些需要复核。
1.0 预处理
| 输入类型 | 处理方式 |
|---|---|
| PNG / JPG / WebP / GIF | 直接用 read_file 读取,无需转换 |
| 截图 | 用 read_file 读取,注意排除系统 UI(状态栏、窗口边框) |
| Figma 导出图 | 用 read_file 读取,注意 Auto Layout 信号(等间距、对齐方式更明显) |
| PDF 页面 | 先用 pdf skill 将页面转为高分辨率 PNG,再用 read_file 读取 |
能力自检(必须先做):第一次尝试 read_file 读取图片后,检查返回内容:
- 若成功看到图像内容 → 走下方 1.1 ~ 1.4 的常规 4 轮视觉分析。
- 若返回"不支持图片 / 已过滤"等 → 走 1.0.1 备选方案,用脚本把图像转成结构化文本,再基于文本做 4 轮分析。
1.0.1 备选方案 — 当模型不支持多模态时(图像识别)
目标:在不依赖模型"看图"的前提下,把图像转换为结构化的文本报告,使后续 4 轮分析照常进行。使用以下路径:
路径 A — 调用外部视觉模型 API(推荐,识别最完整)
本技能内置 scripts/vision-api.py:把图片 base64 发送给一个支持视觉的模型(OpenAI 兼容接口,如 GPT-4o / Claude / 本地兼容端点),由其返回结构化的 UI 文字描述。
# 在项目中配置密钥(及可选端点 / 模型)
export VISION_API_KEY="sk-..."
export VISION_API_BASE="https://api.openai.com/v1" # 可选
export VISION_MODEL="gpt-4o" # 可选
python3 scripts/vision-api.py /path/to/screenshot.png
脚本会打印一份中文结构化报告(布局区域、组件清单、可见文本、Design Token、交互语义)。把这份报告作为"图像内容"代入 1.1~1.4 进行 4 轮分析即可。
路径决策:
1. 一律使用路径 A(视觉 API)。若未配置 VISION_API_KEY,见下方兜底硬规则。
2. 仍无法确定关键文本时,向用户索要图片中文字内容的补充说明,而不是直接编造。
> ### ⛔ 兜底硬规则(无能力且无视觉 API 时禁止裸生成)
> 若满足以下条件,必须停止并求助,不得输出任何代码:
> - 模型 read_file 返回"不支持图片 / 已过滤";且
> - 未配置 VISION_API_KEY(路径 A 不可用)。
>
> 此时向用户明确说明受限原因,并求助:让用户提供 VISION_API_KEY,或让用户直接粘贴图片中的文字内容(标签、表头、按钮、占位符)。
>
> 收到视觉 API 报告或用户粘贴的文本后,方可继续 4 轮分析与代码生成,且生成内容须严格遵守上方【精准还原红线】。
1.1 第 1 轮 — 整体布局扫描(鸟瞰)
用 read_file 读取图片,专注回答:
- 页面分为几个大区域?(Header / Sidebar / Content / Footer / Modal)
- 整体布局方向是?顶部导航还是侧边导航?
- 是否有浮层/弹窗覆盖?
- 页面大致的内容密度(密集表格 vs 简洁卡片)
记录:画出页面区域划分的 ASCII 草图。
1.2 第 2 轮 — 组件识别(逐区域)
再次用 read_file 读取同一张图,逐区域识别:
- 每个区域内的 UI 组件类型(按钮、表格、表单、卡片、菜单...)
- 组件的父子嵌套关系
- 重复模式(列表项、表格行、卡片网格)
- 识别到的文本内容(标签、标题、按钮文字)
记录:构建初步的 componentTree JSON。
1.3 第 3 轮 — Design Token 采样(像素级)
再次用 read_file 读取,聚焦视觉属性:
- 颜色:主色、背景色、文字色、边框色、语义色(成功/警告/错误)
- 字体:标题大小 vs 正文大小、字重差异(粗体/常规)
- 间距:各区域内的留白大小、组件间距
- 圆角:按钮/卡片/输入框的圆角半径
- 阴影:卡片/弹窗是否有阴影,深度如何
记录:填充 designTokens 对象。
1.4 第 4 轮 — 交互语义推断
再次用 read_file 读取,关注交互线索:
- 哪些元素可点击?(按钮样式、下划线文字、图标暗示)
- 排序/筛选/搜索的标识
- 表单必填标识 (*)、校验状态
- 可展开/折叠的箭头或
...按钮 - 导航高亮状态(当前激活的菜单项)
记录:补充 interactions 数组。
> 为什么不一次读完? 4 轮分别聚焦不同维度,每轮的观察结果作为下一轮的上下文约束。单轮分析容易遗漏细节或产生幻觉。
阶段二 — 布局拆解
自上而下分析界面:
- 识别页面区域:Header(顶栏)、Sidebar(侧栏)、Main Content(主内容)、Footer(底栏)、Overlay/Modal(浮层/弹窗)。
- 确定每层布局方向:
horizontal(水平/row)、vertical(垂直/column)、grid(网格)。 - 检测响应式模式:固定宽度区域、自适应区域、断点提示。
阶段三 — 组件树构建
对每个视觉元素进行分类,构建父子层级关系树。
元素分类体系 — 完整 8 大类别详见 REFERENCE.md(容器类、导航类、数据展示类、表单控件类、反馈类、操作类、排版类、媒体类)。
输出格式:
{
"type": "Page",
"layout": "vertical",
"children": [
{ "type": "Header", "layout": "horizontal", "children": [
{ "type": "Logo" },
{ "type": "Navigation", "component": "Menu", "mode": "horizontal" }
]},
{ "type": "MainContent", "layout": "horizontal", "children": [
{ "type": "Sidebar", "children": [...] },
{ "type": "ContentArea", "children": [
{ "type": "Breadcrumb" },
{ "type": "SearchBar", "component": "Input.Search" },
{ "type": "DataTable", "component": "Table" }
]}
]}
]
}
阶段四 — Design Token 提取
提取并规范化视觉属性为结构化 Token。
必须提取的类别(详细规范见 REFERENCE.md):
- 色彩体系 — 主色、成功色、警告色、错误色、文字层级、边框色、背景色、表面色
- 字体排版 — 标题级别、正文、辅助文字、字体族、字重、行高
- 间距系统 — xs/sm/md/lg/xl 梯度
- 圆角 — sm/md/lg/round(圆形)
- 阴影 — sm/md/lg 层级
所有 Token 值使用 CSS 兼容格式输出(px、rem、hex、rgba)。
阶段五 — 组件库匹配
将识别出的组件映射到目标组件库。向用户确认或从项目上下文中推断:
核心映射(完整映射表见 REFERENCE.md):
| 模式 | Ant Design | Element Plus | MUI | Shadcn/ui | Naive UI |
|---|---|---|---|---|---|
| 主按钮 | Button type="primary" |
el-button type="primary" |
Button variant="contained" |
Button |
n-button type="primary" |
| 表格 | Table |
el-table |
DataGrid |
Table |
n-data-table |
| 弹窗 | Modal |
el-dialog |
Dialog |
Dialog |
n-modal |
| 表单 | Form |
el-form |
Box component="form" |
Form |
n-form |
| 输入框 | Input |
el-input |
TextField |
Input |
n-input |
| 选择器 | Select |
el-select |
Select |
Select |
n-select |
| 标签页 | Tabs |
el-tabs |
Tabs |
Tabs |
n-tabs |
| 卡片 | Card |
el-card |
Card |
Card |
n-card |
| 菜单 | Menu |
el-menu |
Drawer/List |
NavigationMenu |
n-menu |
| 分页 | Pagination |
el-pagination |
Pagination |
Pagination |
n-pagination |
阶段六 — DSL 输出与代码生成
6.1 生成完整的 UIR DSL
推荐输出 YAML 格式(可读性更好),也可输出 JSON。DSL Schema 包含以下顶层字段:
version: "1.0"
metadata: # 来源、目标组件库、框架、时间戳
designTokens: # 颜色、字体、间距、圆角、阴影
layout: # 顶层布局方向和区域划分
componentTree: # 递归的组件节点(含 props、children、interactions)
interactions: # 事件绑定:触发 → 动作 → 目标
完整 DSL 示例见 REFERENCE.md。
6.2 从 DSL 生成前端代码
- 确认目标技术栈:框架(React/Vue/Flutter/Angular)、组件库、CSS 方案。
- 渲染组件树:转换为框架对应的 JSX/模板语法。
- 输出 Design Token:生成为 CSS 自定义属性或主题配置。
- 绑定交互事件:使用框架的事件处理模式。
- 准备数据绑定:为动态内容生成占位 state/props。
交互语义推断规则
分析交互元素时,根据视觉线索推断行为:
| 视觉线索 | 推断行为 |
|---|---|
标签末尾有 ... |
打开对话框/弹窗 |
| 箭头 / 展开图标 | 可展开或可导航 |
| 加号 (+) 图标 | 创建 / 新增操作 |
| 垃圾桶图标 | 删除操作 |
| 铅笔图标 | 编辑操作 |
| 放大镜图标 | 搜索 |
| 齿轮图标 | 设置 |
| 漏斗 / 筛选图标 | 筛选操作 |
| 排序箭头 (▲▼) | 可排序列 |
| 外链图标 | 新标签页打开 |
常见 UI 模式(快速识别)
- 表格模式:表头行 + 排序标识 + 行复选框 + 操作列 + 分页
- 表单模式:标签-输入对 + 必填标识 (*) + 提交/重置 + 校验信息
- 卡片网格模式:等宽卡片排列 + 缩略图 + 操作按钮
- 筛选+列表模式:筛选栏 + 搜索 + 标签切换 + 排序下拉 + 结果列表
- 仪表盘模式:统计卡片行 + 图表区 + 数据表格 + KPI 趋势箭头
输出要求
每次分析必须产出:
- YAML DSL — 规范的结构化表示(主产物)
- 摘要 — 页面区域数、组件总数、唯一颜色数、字体梯度
- 建议 — 推荐匹配的组件库、响应式策略、标记需要用户确认的歧义项