uxskill
Star on GitHub
博客 · 简体中文 · 2026-05-28

AI 编程设计 — 为什么每个 AI 都做出同一个 UI

任何一个让 Claude Code、Cursor、Windsurf、GitHub Copilot、Cline 或 Continue 生成过 landing page 的人,都见过那种结果:Inter 被拉到 90px 当显示字、紫到蓝的渐变铺底、横向并排三张一模一样的卡,Hero 下面那行 「Build something amazing」。问题不在工具,问题在所有这些工具都是用同一批模板训练出来的。ux-skill 用 145 条确定性正则规则,在 CI 上拦下这些默认产物。

每个 AI 都会复刻的八个视觉默认值

我们把所有指纹都整理在了 AI 设计指纹分类 里。下面这八个,几乎在每个 Hero 里都出现:

  1. 把 Inter 当显示字 — Inter 是为屏幕小字号易读性而设计的,被拉到 90px 当大标题用,正好和它的设计意图反着来。
  2. 紫到蓝的渐变#7C3AED → #3B82F6 这一族,用作第一屏的背景底色。
  3. 横向三张同款卡片 — 图标、单词标题、一句话副标题,重复三遍。
  4. 全员 fade-in-up — 每个 section 的每个直接子元素都套同一个动画,角色完全不区分。
  5. 所有内容居中 — Hero、卡片、表单,全在视觉中轴上。
  6. 泛泛的文案 — 「Build something amazing」「Beautiful experiences」「Revolutionizing X」,一个产品相关的名词都没有。
  7. 占位图 URL — 用通用占位图代替真实的产品截图。
  8. 扁平设计上压重阴影 — 「要醒目」和「扁平最潮」这两种本能撞在一起,得到一种说不清的立体感。

单独看每个默认值都不是错。问题是这八个同时出现在一张页面上时,任何人都能一眼认出「这是 AI 写的」。一个,你可以耸耸肩放过去;在同一个 above-the-fold 里凑齐四个,你甚至能猜出是哪个工具生成的。

为什么 prompt 不够用

每个团队的第一反应都是给 prompt 加约束:「别用默认渐变」「换一款真正的显示字」「别再放三张同款卡」。这一条消息内有效;到下一条,引导被稀释,上下文窗口变大,指纹又回来了。靠 prompt 引导是概率性的,而且随对话长度衰减。

我们真正需要的是确定性的兜底 — 一道在模型 写完之后 跑、回路里不再夹一个 LLM 的检查。这正是 ux-skill 填上的那块缺口:推荐器在前面收窄模型的选项,linter 在后面把漏过来的默认值打回去。

不要用随机性对抗随机性

「那就让第二个 LLM 来给第一个 LLM 打分」这个想法每隔一阵就冒出来。但 LLM 给的分数本身也是随机的:它取决于评分用的 prompt、few-shot 示例、当天用到的模型版本。CI 需要的是每次都给同一个答案的那一层。这正是正则的唯一长处,而它足够。

145 条正则、不调 LLM、跑在 CI 上

linter 扫描所有 *.tsx*.jsx*.vue*.svelte*.astro*.css*.scss*.html 文件,用 im 两个 flag 套上 145 条正则,输出 JSON,带规则 ID、严重度、文件、行号、列号、片段、建议修复。

# 本地 lint,默认拦截 high+critical
$ uxskill lint
[OK] Scanned 142 files in 412ms · 0 findings at threshold high

# 子目录 + JSON
$ uxskill lint apps/web/src --json | jq '.summary'
{
  "critical": 0,
  "high": 4,
  "medium": 11,
  "low": 3,
  "total": 18
}

0 次 LLM 调用。一个 200 文件的 Next.js 仓库平均扫描时间冷启动 380ms,热启动 90ms。完整的规则说明在 正则 linter 指南 里。

真实 Hero 的前后对比

下面是一段从 Next.js 起始模板里截出来的简化 Hero,会命中三条规则;下方是改写后能以 exit 0 通过的版本。同样的转化意图,完全不同的指纹。

// 改写前 — 命中 3 条 high
<section className="bg-gradient-to-br
  from-purple-500 via-violet-500
  to-blue-500 py-32">
  <h1 className="font-['Inter']
    text-7xl leading-none">
    Build something amazing.
  </h1>
  <div className="grid grid-cols-3 gap-6">
    <Card icon="Zap" title="Fast" />
    <Card icon="Shield" title="Safe" />
    <Card icon="Heart" title="Loved" />
  </div>
</section>

// 改写后 — 0 命中
<section className="bg-stone-50 py-28">
  <h1 className="font-['Fraunces']
    text-6xl leading-[1.04]
    tracking-tight">
    你们 TMS 一直没交付的
    那一层货运路由。
  </h1>
  <div className="grid grid-cols-12 gap-6 mt-16">
    <Card className="col-span-7"
      title="货运合并" />
    <Card className="col-span-5"
      title="承运人排名" />
  </div>
</section>

改写前命中三条规则:Inter 用在 text-7xl、AI 标志性渐变、三张同款卡的三列网格。改写后用 Fraunces (显示字) 配 Inter (正文),底色变成平的浅米色,网格换成 7-5 非对称布局。意图没变,指纹消失了。

推荐器抬高地板。Linter 压住天花板。两者缺一不可。

给 Cursor 配一套真正能用的设计系统

Cursor 是目前 AI 编程栈里最受欢迎的 composer 体验,但它本身对设计系统没有任何内置认知。Cascade 直接继承模型的默认值。ux-skill 在 Cursor 上的接入分两层:一层是 .cursorrules 文件,负责编辑器内的指令;另一层是 MCP 服务器,负责结构化工具调用。

# Cursor 接入步骤
$ pip install uxskill
$ uxskill init --target cursor
$ uxskill mcp-config --target cursor

# 生成的文件:
# .cursorrules           ← 51 条规则片段,编辑器内生效
# ~/.cursor/mcp.json     ← 14 个 MCP 工具注册
# tokens.css             ← OKLCH 调色板、字号刻度
# MASTER.md              ← 设计系统单一事实来源

接好之后,Cursor Composer 可以直接调用 14 个 ux-skill 工具:discover_briefrecommend_designlint_codebaseget_brand_spec 等等。设计决策不再只活在聊天里,而是落到仓库里的真实文件 — 之后每一次 Cursor 会话也都跟着这些文件走。

三条安装路径,一个引擎

同一个 Python 包覆盖兼容矩阵里的 17 个 IDE。挑离你的编辑器最近的那条路:

编辑器 路径 命令
Claude Code插件市场/plugin install ux@ux-skill
Cursor.cursorrules + MCPuxskill init --target cursor
Windsurf.windsurfrules + MCPuxskill init --target windsurf
GitHub Copilotcopilot-instructions.mduxskill init --target copilot
Cline / ContinueMCP 服务器uxskill mcp-config --target cline
JetBrains AI Assistant.junie/guidelines.mduxskill init --target jetbrains
ZedMCP stdiouxskill init --target zed
Codex CLI / Aider直接命令行pip install uxskill

所有路径背后都是同一组:1,182 条目录条目、145 条规则、131 条品牌规范、22 条命令、每次发版都通过的 75 个测试。

坦白的边界

规则只接得住结构,接不住品味。

linter 永远不会报「这一段节奏不对」「这句文案冷冰冰的」。那是人来做的事,或者是评审用的 LLM 来做的事。但凡能用字面 token、模式、形状表达的指纹,正则都能 稳稳地 接住 — 这恰恰是 AI 默认行为里的绝大部分,因为模型每次都跑回同一种产物。

我们故意不在 CI 上跑 LLM 评委。如果你的标准是「看起来像设计师做的」,那就是 code review,不是 lint。ux-skill 提供 ux critique 来做这一步 — 但只在编辑器里按需运行,不进 CI。

延伸阅读

安装

17 个 IDE。一个引擎。145 条规则。

推荐器、linter、MCP 服务器、22 条命令、131 条品牌规范、1,182 条目录条目一并发行。linter 在亚秒级跑完,其余按需触发。MIT,无遥测,无账号。

$ /plugin marketplace add Laith0003/ux-skill
$ /plugin install ux@ux-skill
— 或 —
$ pip install uxskill
— 或 —
$ npx uxskill@alpha init