有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。——蒲松龄

所有 AI 做的页面,为什么长得像同一批人做的

一张你肯定见过的截图

浅灰背景。左上角一个圆角方形图标块,里面塞着一个细线条的几何图形。大标题用的是 Inter。按钮是一片从紫到蓝的渐变,圆角十六像素,底下压着一层淡淡的紫色光晕。内容区被切成三张卡片,卡片里又套着两层卡片。

这套东西不丑。它的问题在于太熟了——熟到你打开任何一个「AI 生成的落地页」,都能在第三秒猜到第七屏长什么样。

Impeccable 就是冲这件事来的。它的描述只有一句:让你的 AI harness 更懂设计的那个设计语言。

项目地址:https://github.com/pbakaus/impeccable

文档的第一行把它的构成讲得很干脆:一个 skill、24 个命令、浏览器里的实时迭代,以及 62 条针对 AI 生成前端的确定性检测规则。

四个数字,对应四种不同的干预方式。skill 是教材,命令是词汇,实时迭代是手,检测规则是尺子。

问题的根源,不在模型笨

Impeccable 对这件事的诊断,写得比大多数批评都准:

每一个模型,都是在同一批 SaaS 模板上训练的。

这句话解释了为什么不同公司的模型会犯同样的错。它们看见的世界是同一份世界——同一批用 Inter、同一批紫蓝渐变、同一批嵌套卡片的落地页。当你要它「做一个现代、简洁、专业的网站」,它给出的答案当然是那些页面的平均值。

平均值不难看,平均值只是没有观点。

所以问题不是「AI 不会设计」,而是「AI 太擅长复现平均值」。而设计这件事,恰恰是从平均值里偏出去才开始成立的。

它的出身,是一份被继承的作业

文档里有一段很坦诚的交代:Anthropic 的 frontend-design 是第一个被广泛使用的 Claude 设计技能,Impeccable 从那里出发。

「从那里出发」这四个字很重要。它没有宣称自己是凭空发明的,而是承认站在一份已有的作业上,然后往前推了一步。

推的方向也很清楚:frontend-design 给的是一套设计判断的准则,Impeccable 给的是一套可以执行、可以检查、可以复用的流程——把准则拆成命令,把品味拆成规则,把「这样不好看」拆成「第 37 条:不要在彩色背景上放灰字」。

先记住产品,再谈好看

整套流程的入口只有一个:/impeccable init。

这个命令做的事,听上去平淡,其实是整份设计里最关键的一步。它会检查项目,只问那些真正缺失的、关于产品的持久事实,然后写进一份 PRODUCT.md。

写进去的是:受众、目的、运行环境、约束、语气、证据。

这段话里有个很硬的区分:这些事实不能被混淆成表层的视觉方向。 换句话说,PRODUCT.md 回答「这是给谁用的、在什么场景下用、说话该是什么调子」,它不回答「用紫色还是用绿色」。

视觉方向被推到了后面,而且是按面逐个决定。已经存在的视觉体系、或者新建立的视觉体系,另外记在 DESIGN.md 里。

这个分层解决了一个很常见的事故:一开始就把「我们想要科技感」写进需求,然后整个项目被这句话绑死,连错误提示的文案都带着科技感。产品事实是长期的,视觉方向是每个界面自己的事,混在一起,两边都做不好。

24 个命令,一套可以吵架的词汇

命令列表很长,值得整张抄下来,因为它本身就是一份设计的工序表。

命令 做什么
craft 完整的先成形再建造流程,带视觉迭代
init 一次性设置:收集持久的产品上下文,写 PRODUCT.md,在适用时配置实时模式,推荐下一步
document 从既有项目代码生成根目录的 DESIGN.md
extract 把可复用组件与 token 抽进设计系统
shape 在写代码之前先规划 UX 与 UI
critique UX 设计评审:层级、清晰度、情绪共鸣
audit 跑技术质量检查:可访问性、性能、响应式
polish 终局打磨,对齐设计系统,准备上线
bolder 把无聊的设计放大
quieter 把过头的设计收回来
distill 剥到只剩本质
harden 错误处理、国际化、文字溢出、边界情况
onboard 首次运行流程、空状态、激活路径
animate 加入有目的的动效
colorize 引入有策略的颜色
typeset 修正字体选择、层级、字号
layout 修正布局、间距、视觉节奏
delight 加入让人开心的瞬间
overdrive 加入技术上出格的效果
clarify 改善不清楚的 UX 文案
adapt 适配不同设备
optimize 性能改进
live 视觉变体模式:在浏览器里对元素逐一迭代
generate 在实时浏览器里为指定元素生成变体,不需要手动挑选

24 个。数一遍会发现它们不是平级的,而是成组的:shape、craft 负责从零到一;critique、audit、polish 负责从一到好;bolder 和 quieter 是一对反向旋钮;distill 和 delight 是另一种反向——一个减到最少,一个加到刚好;harden、adapt、optimize 管的是「上线之后会不会出事」。

这套命名的价值不在于命令本身,而在于它给了你和 AI 一套共享词汇。以前你说「这里感觉不对」,AI 只能猜;现在你说 /impeccable quieter,它知道你要把音量调小,而不是换个配色。

指令的模糊,是 AI 设计工作里最大的隐性成本。这些命令在做的事,是把形容词换成动词。

用法也很轻。大部分命令接受一个可选的目标:

1
2
3
/impeccable audit blog           # 审博客首页和文章页
/impeccable critique landing # UX 设计评审
/impeccable polish settings # 上线前的终局打磨

或者干脆不用命令,直接用一句话描述:/impeccable redo this hero section。

如果某个命令你天天用,可以钉住它:/impeccable pin audit,之后就有独立的 /audit 快捷方式。

五条反模式,是这份技能的骨头

比 24 个命令更能说明立场的,是那份「明确不要做什么」的清单:

  • 不要用被用滥的字体,Arial、Inter、系统默认字体都在名单里
  • 不要在彩色背景上放灰色文字
  • 不要用纯黑或纯灰,永远带一点色相
  • 不要把一切包进卡片,也不要卡片套卡片
  • 不要用弹跳或弹性缓动,那感觉过时了

五条,都是具体的、可判定的。注意它们的形式——不是「要有品味」这种无法执行的劝告,而是「不要卡片套卡片」这种一眼能验的禁令。

设计指导最容易失败的地方,就是写成格言。格言很美,但 agent 没法执行。禁令可以。

它不需要运行时,只需要一个可以被调用的二进制

安装那一节里藏着一个很克制的工程决定。

这份 skill 自己不需要任何运行时。每一份 skill 副本里都带一个小小的启动器,Windows 上是 impeccable.cmd,其余平台是 scripts/impeccable。启动器去跑 Impeccable 引擎——一个自包含的二进制,要么就躺在启动器旁边,要么在第一次运行时下载一次到 ~/.impeccable/bin/。

Node 只在用 npx impeccable 安装器的时候才出现,而那个安装器也只是同一份二进制外面套的一层壳。

这个设计的意义在于:你的机器上不必为了一个设计检查工具装 Node 生态。 手动安装和 Git 子模块这两条路,完全不需要 Node。

对一个要嵌进别人仓库、跑在别人编辑器里的工具来说,依赖越少,被接受的概率越高。

五条安装路径,各有各的场合

推荐的方式是 CLI 安装器。在项目根目录跑一条命令,它会:

  1. 列出检测到的 harness 目录或已安装的 CLI,比如 ~/.claude、~/.codex、~/.grok、~/.hermes、~/.veto,或者项目本地的 .cursor
  2. 让你保留检测到的集合,或者自定义
  3. 问你是装进当前项目,还是装到全局

脚本里可以用 --providers= 和 --scope=project|global 跳过这两个选择。

在 Claude Code、Cursor、Codex、GitHub Copilot 和 Grok Build 上,它还会顺手把 provider 原生的 hook 清单装进当前项目。

第二条路是 Git 子模块,适合那种希望把 Impeccable 一起 vendor 进仓库、靠 Git 更新来管理的团队:加子模块,用 npx impeccable link 把编译好的 provider 构建链进各 harness 目录,然后一次性提交。link 会从 .impeccable/dist/universal/ 里逐个链接技能目录,而且不碰已经存在的真实技能目录,除非你加 --force。

第三条是插件市场:VS Code 里从扩展市场装,Claude Code 里加 marketplace 再装,Grok Build 用一条带 #plugin 后缀的命令装精简包。

第四条是从官网下 ZIP,第五条是从仓库手动复制——后者在文档里被明确定位为「兜底与调试用」,正常路径是 install 和 update。

五种方式摆在一起,是一种现实主义的体贴。团队规模不同、工具链不同、对供应链的信任程度不同,安装方式就该不同。

设计 hook:在你改完文件的那一刻出面

这是整套东西里最像「工具」而不是「教材」的部分。

在 Claude Code、GitHub Copilot、Codex、Cursor 和 Grok Build 上,安装或更新会带上一份 provider 原生的 hook 清单。这个 hook 会在你直接编辑 UI 文件时跑一遍设计检测器,然后把发现推回 agent 的流程里。

各家的落地位置不一样,文档列得很清楚:Claude Code 写进机器本地的 settings.local.json;Copilot 写进会提交的 .github/hooks/impeccable.json,由 CLI 和云端 agent 共用;Cursor 挂在 postToolUse 上;Codex 用 .codex/hooks.json,另配一个给 cmd.exe 的 commandWindows 兄弟项;Grok Build 需要先信任目录,而且它的发现要等到 Stop 才到达模型,不是每次编辑后。

有两条细节值得单独说。

第一条:安装器不会覆盖你原有的 hook 配置。 如果发现某份 hook 清单格式坏了,默认直接中止,加 --force 才会把坏文件备份成 .bak 再替换。一个会改别人配置的工具,最该有的品德就是这个。

第二条,也是更值得警惕的一条:在 Claude Code 里,已安装的命令 hook 独立于模型工具审批运行。所以第一次编辑或 Stop 事件,有可能在会话拒绝了模型启动器命令的情况下,仍然把引擎下载并缓存下来。文档没有把这件事说成优点,而是直说:无人值守运行之前,先审一遍装了什么 hook;要全部关掉,启动时传 --settings '{"disableAllHooks": true}'。

这种把风险主动摊开的写法,比任何安全承诺都更让人放心。

62 条规则,和一套很讲究的退出码

CLI 是可以脱离 AI 单独用的:npx impeccable 是一个小壳,跑的还是同一份引擎二进制。

检测的用法很朴素:

1
2
3
4
5
npx impeccable detect src/                # 扫一个目录
npx impeccable detect index.html # 扫一个 HTML 文件
npx impeccable detect --json . # CI 友好的 JSON 输出
npx impeccable detect --github src/ # 输出 GitHub Actions 注解
npx impeccable detect --list-rules # 列出全部规则 id、名称与描述

这 62 条确定性规则分两类。一类针对「AI 味」:侧边标签式的边框、紫色渐变、弹跳缓动、暗色光晕。另一类针对通用的设计质量:行宽过长、内边距局促、触摸目标过小、跳级使用标题,等等。

分类这件事本身就有意思。它等于承认,「AI 生成的丑」有两种:一种是模型的口音,一种是人类也会犯的基本功错误。前者需要专门针对模型,后者需要一把通用的尺子。

然后是退出码,这一段设计得相当专业:

  • 0 表示扫描完成且没有主要发现
  • 2 表示扫描完成但有主要发现
  • 1 表示至少有一个目标扫不了

把「有问题」和「扫不了」分成两个不同的非零码,是 CI 集成的分水岭。很多工具把两者都返回 1,于是流水线无法区分「代码有问题」和「工具坏了」,最后只能一律放行。

文档还留了一句让人信服的免责声明:一次干净的检测是证据,不是证明;它不能替代在相关视口下真正看一眼渲染出来的体验。

一个卖检测工具的项目,主动说检测不等于质量,这需要一点底气。

检测之外,还有一份「这个世界该长什么样」的登记

Impeccable 不只是检查你写的东西对不对,它还会在每次新设计开始时,向 impeccable.style 的 roll API 要一手「视觉世界」的牌。

这一步是功能本身,所以它总会发生。

而这里紧接着就是隐私边界。默认情况下,它会记一条匿名记录:发出了哪一手牌、哪张牌赢了。发出去的内容包括:roll key、作用域、访客模式、重摇轮次、目录版本、获胜卡片的类型与目录 id 与位置、客户端版本、这个选择来自决策页还是 agent、以及一个用来去重的随机 id。

不发出去的内容也列得很清楚:你的项目名、文件、代码、PRODUCT.md,以及你的 agent 写下的方向名字。

再往下是一个更细的设计:提交进仓库的 surface brief 里,只记录一个种子引用——用 ~/.impeccable/seed-salt 里的随机盐对 roll key 做的哈希,而不是 key 本身。如果一台机器上留不住这个盐,brief 就干脆不记种子,而不是记一个更弱的哈希。

这句话值得念两遍。宁可少记,也不记一个看起来安全的东西。

关掉的方式给了四种:一条 telemetry off 命令、两个环境变量、或者项目级的配置项。关掉之后,摇牌照常工作,只是 API 被告知不要记录。

comp 还是 code,这不是审美问题

新界面开始设计时,Impeccable 有两条路。

comp-first:先生成一张全保真的设计稿,再照着它写代码。
code-first:直接在代码里建,把野心写进 surface brief 里一份仅开发期使用的方向契约,最后再对着检查。

文档给的评价很干脆:comp-first 更有胆量,也更慢;code-first 更精简,也更快。这个选择覆盖落地页和展示型界面。而 app 内的屏幕和文档,无论选哪种,都走 code-first——因为做出来比画出来更好。

/impeccable init 会问一次,把答案记成 buildPath,只认 comp 和 code 两个值。想在某台机器上覆盖团队的选择,写进本地的 config.local.json 就行——尤其是当你的 harness 没有图像生成能力时。

而且这个选项只在有图像生成能力的地方出现。没有画笔,就没什么可 comp 的。

最贴心的一段是迁移路径:老项目不必重跑 init,也不必手动改文件。每个决策页底部都有一个开关,翻一下只对当前会话生效;如果项目还没记录过任何值,翻完之后它会问一次要不要保留,然后写下来。

记录的是默认值,不是锁。 这七个字,值得所有做配置系统的人抄一遍。

哪些文件该进 git,哪些不该

跑命令的过程中,Impeccable 会在 .impeccable/ 下写不少东西:评审和打磨的截图、实时模式的会话与预览状态、运行时缓存、每个开发者自己的配置。

大部分是临时的,不该提交。少数是共享的项目产物,应该提交。

所以文档给了一段用 # impeccable-ignore-start 和 # impeccable-ignore-end 包起来的 .gitignore 片段,前缀用 **/,这样无论 .impeccable/ 在仓库根目录还是在 apps/web/ 这样的嵌套工作区里,都能匹配上。

要保留的是五样:统一的共享配置、实时模式的框架接线、共享的设计规格、每个面的策略与方向契约、评审报告。

还有一句很实在的提醒:.gitignore 没法让 Git 停止追踪一个已经被追踪的文件。如果某个临时文件早就被提交过,得手动 git rm --cached。

这些细节跟「设计」没什么关系,但它们决定了一个工具能不能在团队里活下来。

实时模式的边界,划得很硬

实时模式改的是本地检出:通过开发服务器,或者本地静态 HTML。

而文档紧接着就把话说死了:不支持把它的 localhost HTTP 助手注入到已部署的生产站点,包括 HTTPS 站点。不要为了让它能用而关掉浏览器安全策略,也不要削弱生产环境的 CSP。

还有一条更少见的提醒:应用文案编辑时,会自动在一个 shell 里跑 package.json 里的 impeccable:manual-edit-validate 命令,用的是你的用户权限。所以在不熟悉的检出里用实时模式之前,先看看那个脚本写了什么。

想检查生产站点,就走 detect 或者浏览器扩展。它们看的是渲染后的页面,不提供实时变体编辑,也不会把改动写回源码。

这三种能力的边界划得清清楚楚:改本地、看线上、绝不动线上。

十七个工具,一份共用的话术

支持列表最后拉了很长:Cursor、Claude Code、GitHub Copilot、DeepSeek Harness、Gemini CLI、Codex CLI、Grok Build、Hermes Agent、OpenCode、Pi、Kiro、Trae、Rovo Dev、Qoder、Mistral Vibe、Veto、Google Antigravity。

十七个。这个数字说明它赌的不是某一家 harness 会赢,而是「给 agent 加技能」这件事本身会变成常态。

也说明它愿意为不同平台的差异付代价:Codex 用的是 skills 不是斜杠命令,得打 /skills 或者 $impeccable;Copilot 的技能住在 .github/skills/;Hermes 对项目本地技能有一道每仓库的信任门,因为技能是过程文档,从任何克隆下来的仓库自动加载都被视为提示注入的入口。

最后这条几乎是整份文档里最清醒的一句话。它承认了:教 agent 做事的那份文件,本身就是攻击面。

最后

回到那张截图。

那套设计不是错的,它只是在做一件很安全的事——复现训练数据里的平均值。要让结果偏出平均值,不能靠再喊一遍「要有创意」,得靠三样东西:一份记住产品事实的文档、一套双方都认的词汇、一把能量出偏差的尺子。

Impeccable 把这三样都做成了文件:PRODUCT.md 记事实,24 个命令当词汇,62 条规则当尺子。它们都在你的仓库里,可以被读、被改、被提交、被 review。

设计这件事最难自动化的部分,是品味。但品味之下有一层是可拆解的——你知道为什么这张卡片不该套在那张卡片里,你知道为什么这段灰字放在紫底上读起来是脏的。把这些拆出来,剩下的才是真正需要人的部分。

工具能做的,是把你从平均值里推出来一点点。剩下的那一步,还得你自己走。