1. 从“impeccable”这个词说起:它到底想解决什么问题
第一次看到“impeccable”这个项目名,我脑子里蹦出来的不是词典释义,而是一个很具体的场景:你让 AI coding agent 帮你改一个前端页面,它噼里啪啦输出了一大段代码,逻辑上好像没问题,但你就是觉得哪里不对劲——间距忽大忽小、颜色对比度怪怪的、按钮的圆角跟旁边卡片不统一、移动端一缩小就错位。你说不出具体哪里错,但一眼就知道“不够 impeccable”。
这个项目瞄准的就是这个痛点。它不是一个通用的大模型,也不是一个完整的 IDE,而是一个围绕AI coding agents 的前端设计质量层。核心形态是CLI 工具 + 浏览器扩展的组合:CLI 负责把设计规范、检查规则、上下文喂给 agent,浏览器扩展负责在真实渲染环境里做视觉校验和反馈闭环。说白了,它想让 AI 写出来的前端代码,不只是“能跑”,而是“经得起看”。
适合谁来参考?三类人最该关注。第一类是天天用 codex cli、zcode cli 这类命令行 agent 干活的前端工程师,你们最清楚 agent 生成的 UI 有多“将就”;第二类是正在搭内部 AI 工作流的技术负责人,需要一个可插拔的设计质量关卡;第三类是对前端设计有洁癖、但又被 AI 生成速度绑架的独立开发者。哪怕你只是刚装完 codex cli、还在研究/compact/model/resume这些命令怎么用,这篇文章里的思路也能帮你少走弯路。
我先把结论摆前面:impeccable 这类工具的价值,不在于它替你写代码,而在于它把“设计品味”这件很虚的事,拆成了 agent 能理解、能执行、能自检的具体规则。下面我按实际落地的顺序,一层层拆开讲。
2. 整体设计思路:为什么是 CLI 加浏览器扩展这套组合
2.1 纯 CLI 方案的先天短板
现在主流的 AI coding agent 交互方式基本都是 CLI,codex cli、zcode cli、openspec cli、minimax cli 都是这个路子。CLI 的好处是快、可脚本化、容易接进 CI。但它有个绕不过去的硬伤:它看不见渲染结果。
Agent 在终端里能读到你的 JSX、CSS、Tailwind class,但它没法真正知道这个padding: 12px在 375px 宽的屏幕上会不会挤成一团,也没法判断两个相邻的#3B82F6和#2563EB放在一起对比度够不够。它只能靠“猜”和“模式匹配”。这就是为什么很多 agent 生成的页面,代码 review 挑不出毛病,一打开浏览器就露馅。
我实测过一个很典型的例子:让 agent 给一个卡片列表加 hover 效果,它写了transition: all 0.3s ease。语法完全正确,但实际用起来,鼠标划过时卡片的阴影、位移、边框颜色全都在动,视觉上非常吵。这种问题,纯文本层面的 lint 根本抓不到,只有真实渲染 + 视觉规则才能发现。
2.2 浏览器扩展补上的那块拼图
impeccable 用浏览器扩展来补这块拼图,逻辑很顺。扩展运行在真实 DOM 和真实 CSSOM 之上,能拿到计算后的样式(computed style)、能测量元素的实际盒模型、能截图做像素级对比。它相当于给 agent 装了一双“眼睛”。
具体来说,扩展承担三件事。第一是采集:把当前页面的关键设计 token 抽出来——间距序列、字号阶梯、颜色分布、圆角值集合、阴影层级。第二是校验:拿这些实际值和 CLI 侧下发的设计规范做比对,找出偏离项。第三是回传:把偏离项整理成结构化的反馈,通过本地通道送回 CLI,让 agent 在下一轮修改里有据可依。
注意:这里的关键是“结构化反馈”。如果扩展只是截个图丢给 agent,agent 还是不知道该改哪。必须把问题定位到具体的选择器、具体的属性、具体的期望值,agent 才能精准修复。
2.3 为什么不做成纯浏览器插件
有人会问,既然扩展这么强,为什么不干脆全放浏览器里?答案是上下文和规范需要版本化管理。设计规范不是拍脑袋定的,它得跟着项目走、跟着分支走、能 diff、能 review。这些东西天然属于代码仓库,属于 CLI 的管辖范围。扩展是“执行末端”,CLI 是“规则源头”,两者分工明确,才能既灵活又可控。
这套架构还有一个隐性好处:它天然适配各种 agent。不管你用的是 codex cli 还是别的什么 cli,只要它能读文件、能执行命令、能接收标准输入,就能接进这套流程。工具不该绑定某一个 agent,这是我在选型时特别看重的一点。
3. 核心细节拆解:设计规范怎么变成 agent 能懂的规则
3.1 把“设计品味”翻译成可量化约束
“好看”这件事听起来主观,但拆到足够细,大部分是可以量化的。impeccable 的思路是建立一套design token 约束集,把模糊的审美判断转成明确的数值区间和枚举值。
我拿间距举例。一个页面里如果出现了 4px、7px、13px、18px、23px 这种毫无规律的间距,视觉上就会显得“脏”。规范的做法是定义一套间距阶梯,比如4 / 8 / 12 / 16 / 24 / 32 / 48 / 64,所有间距必须落在这个集合里。扩展采集到实际间距后,一比对就能发现 7px、13px 这些“野值”。
颜色也是同理。与其让 agent 自由发挥,不如限定一个调色板:主色、辅色、中性色各几个色阶,语义色(成功/警告/错误)固定。扩展可以统计页面上所有用到的颜色,凡是超出调色板的就标红。字号、圆角、阴影、行高,都可以用同样的方式约束。
| 设计维度 | 可量化约束 | 常见“野值”表现 |
|---|---|---|
| 间距 | 固定阶梯集合 | 7px、13px、23px 等非阶梯值 |
| 颜色 | 限定调色板 | 随手写的十六进制色 |
| 字号 | 类型比例阶梯 | 15px、17px 混用 |
| 圆角 | 枚举值集合 | 3px、5px、7px 并存 |
| 阴影 | 层级化定义 | 每个组件各写一套阴影 |
| 行高 | 与字号挂钩的比例 | 固定 px 导致大字号拥挤 |
这张表是我自己整理项目规范时常用的框架,impeccable 的约束集基本也是这个维度。你把这套东西写进配置文件,CLI 读进去,扩展执行校验,整条链路就通了。
3.2 规则文件的结构设计
规则文件我建议用 YAML 或 JSON,别用太花哨的 DSL。原因很简单:agent 读 YAML 的准确率远高于读自定义语法,而且 YAML 能直接被各种工具解析,扩展和 CLI 都能用同一份。
一个最小可用的规则文件大概长这样:
design_tokens: spacing: scale: [4, 8, 12, 16, 24, 32, 48, 64] tolerance: 0 colors: palette: primary: ["#2563EB", "#3B82F6", "#60A5FA"] neutral: ["#111827", "#6B7280", "#E5E7EB", "#F9FAFB"] allow_alpha: true radius: scale: [0, 4, 8, 12, 9999] typography: scale: [12, 14, 16, 20, 24, 32, 48] line_height_ratio: [1.4, 1.5, 1.6] rules: - id: spacing-scale severity: error message: "间距必须落在设计阶梯内" - id: color-palette severity: warning message: "颜色超出调色板范围" - id: transition-scope severity: warning message: "避免 transition: all,请指定具体属性"tolerance这个字段很关键。有些项目允许 1px 的误差(比如为了对齐图标),设成 0 会误报一堆。我一般间距设 0,因为间距是最容易标准化的;但字号可能设 1,因为不同字体的渲染基线会有细微差异。
3.3 严重级别与阻断策略
规则不能一视同仁。全是 error 会让 agent 陷入无休止的修复循环,全是 warning 又起不到约束作用。我的经验是分三级:
- error:硬性违规,比如用了调色板外的颜色、间距完全失控。这类必须修,CLI 可以配置成“不修完不让提交”。
- warning:建议性偏离,比如
transition: all、阴影层级不统一。agent 应该修,但不阻断流程。 - info:提示性信息,比如某个组件可以复用已有的 token。给 agent 参考,不强制。
实操心得:刚开始接入时,把所有规则都设成 warning,跑一周看看误报率。误报太高的规则要么调参数,要么直接删掉。规则集不是越多越好,能稳定执行的十几条,比一百条天天误报的强得多。
4. 实操过程:从零把 impeccable 接进你的 agent 工作流
4.1 环境准备与 CLI 安装
先说环境。Node 环境是基础,如果你装 codex cli 时觉得慢,多半是网络源的问题,换成国内镜像会快很多。impeccable 的 CLI 本身依赖不重,装起来很快。
# 确认 node 版本,建议 18 以上 node -v # 全局安装(假设包名为 impeccable-cli,实际以官方为准) npm install -g impeccable-cli # 验证安装 impeccable --version装完之后第一件事是初始化配置:
impeccable init这个命令会在项目根目录生成impeccable.config.yaml和.impeccable/目录。前者是规则文件,后者放扩展的本地通信配置和缓存。我建议把impeccable.config.yaml提交进仓库,.impeccable/加进.gitignore,因为缓存是本地的,不同机器不一样。
4.2 浏览器扩展的加载与配对
扩展的安装分两种场景。开发调试用“加载已解压的扩展”,正式用走商店。我重点说开发场景,因为你要改规则、要看反馈,开发模式更灵活。
加载步骤:打开浏览器的扩展管理页,开启开发者模式,选择“加载已解压的扩展程序”,指向.impeccable/extension目录。加载成功后,扩展图标会出现,点开能看到配对状态。
配对的关键是本地通信端口。CLI 启动时会监听一个本地端口,扩展通过这个端口和 CLI 通信。你需要在扩展的设置里填入 CLI 输出的配对码或端口号。这一步如果卡住,八成是端口被占用或者防火墙拦了,换个端口重试基本能解决。
# 启动 CLI 的监听模式,会输出配对信息 impeccable watch --port 7777配对成功后,扩展图标会变成激活状态。这时候你打开项目的本地开发页面,扩展就开始采集数据了。
4.3 让 agent 读取规则并执行修复
这是整条链路的核心。你要让 agent 知道两件事:规则在哪、怎么用。最直接的方式是在 agent 的上下文里注入一段说明。
如果你用的是 codex cli,可以在项目根目录放一个AGENTS.md,里面写清楚:
## 前端设计规范 本项目使用 impeccable 管理设计规范。 - 规则文件:`impeccable.config.yaml` - 校验命令:`impeccable check` - 修复建议:`impeccable suggest` 修改任何前端样式前,请先阅读规则文件,确保使用的间距、颜色、字号、圆角都在规范内。然后在实际修改时,让 agent 先跑校验:
impeccable check --format json输出的 JSON 会列出所有违规项,每项包含选择器、属性、当前值、期望值。agent 拿到这个就能精准修复,而不是瞎猜。
我实测下来,这套流程对 agent 的修复准确率提升非常明显。以前让 agent 改样式,它经常改一处坏一处;现在有了明确的违规清单,它基本能一次改对。
4.4 参数计算:间距阶梯怎么定才合理
间距阶梯不是随便拍脑袋定的。我一般用4 的倍数作为基础,因为绝大多数屏幕的像素密度和 4 对齐良好,缩放时不容易出现半像素模糊。然后按近似等比的方式扩展:
- 小间距:4、8、12、16(步长 4)
- 中间距:24、32(步长 8)
- 大间距:48、64(步长 16)
为什么步长要变?因为小间距需要精细控制,大间距差几个像素肉眼看不出来,没必要那么密。如果全用 4 的步长,阶梯会太长,agent 选择困难;如果全用 16 的步长,小间距又不够用。
字号阶梯同理,但基准不同。正文一般 16px,往上按 1.25 或 1.333 的比例放大:
- 16 × 1.25 = 20
- 20 × 1.25 = 25(取整 24)
- 24 × 1.25 = 30(取整 32)
往下:16 ÷ 1.25 ≈ 12.8(取整 12 或 14)。这套比例能让字号之间有清晰的层级感,又不会太跳跃。
注意:阶梯一旦定下来,就别频繁改。agent 会记住这套规则,你改一次它要重新适应。真要改,走一次完整的校验-修复流程,确保全项目统一。
5. 常见问题与排查技巧实录
5.1 扩展采集不到数据怎么办
这是接入初期最常见的问题。排查顺序我总结成一张表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 扩展图标灰色 | 未配对或端口不通 | 检查 CLI 是否在 watch 模式 |
| 图标正常但无数据 | 页面未在监听列表 | 确认当前域名在配置的白名单里 |
| 数据时有时无 | 页面用了 iframe | 检查 iframe 是否同源 |
| 采集到旧数据 | 缓存未刷新 | 清.impeccable/cache后重试 |
| 部分元素缺失 | 动态渲染未触发 | 手动触发一次重渲染 |
我踩过最深的一个坑是iframe 跨域。有些项目把预览页面嵌在 iframe 里,扩展默认拿不到跨域 iframe 的内容。解决办法是在配置里显式声明允许的源,或者干脆把预览页单独开一个标签页。
5.2 agent 反复修不好同一个问题
这种情况通常是规则描述太模糊。比如你写“间距要合理”,agent 根本不知道什么叫合理。改成“间距必须落在 [4,8,12,16,24,32,48,64] 集合内”,它立刻就懂了。
还有一种情况是规则冲突。比如你既要求“卡片内边距统一 16px”,又要求“卡片高度自适应内容”,当内容很少时,16px 内边距会让卡片显得很空,agent 就会试图改内边距来“优化”,结果违反第一条规则。这种时候要明确优先级:哪条是硬约束,哪条可以让步。
我的做法是给每条规则加一个priority字段,数字越小优先级越高。冲突时高优先级规则胜出,agent 就不会来回改了。
5.3 校验太慢影响开发体验
全量校验确实慢,尤其是大项目。我的优化策略是增量校验:只校验本次改动涉及的文件和组件。impeccable 支持通过--changed参数只检查 git diff 里的文件。
# 只校验改动过的文件 impeccable check --changed # 只校验某个目录 impeccable check --path src/components另外,把校验接进编辑器的保存钩子,每次保存只跑增量,体验会顺滑很多。全量校验留给 CI,提交前跑一次就行。
5.4 设计 token 和现有代码冲突
老项目接入新规范,必然有一堆历史遗留的“野值”。这时候别想着一次性全改,会累死。我的策略是新代码严格、老代码宽容:
- 新增文件必须 100% 符合规范
- 修改老文件时,顺手把涉及的那部分改规范
- 纯历史遗留、近期不动的代码,加进白名单,暂时跳过
白名单机制很重要,它让规范能渐进式落地,而不是一刀切导致项目瘫痪。
exemptions: - path: "src/legacy/**" reason: "历史代码,逐步迁移" - path: "src/vendor/**" reason: "第三方组件,不修改"6. 工具选型与生态衔接的一些思考
6.1 为什么这套思路能跨 agent 复用
我前面强调过,impeccable 的价值在于它不绑定具体 agent。规则文件是标准的 YAML,校验命令是标准的 CLI 调用,反馈是标准的 JSON。这意味着你今天用 codex cli,明天换成别的 cli,规则和流程都不用重写。
这一点在选型时特别重要。AI 工具迭代太快了,今天好用的 agent 明天可能就被替代。如果你的设计规范绑死在某个 agent 的私有格式上,迁移成本会非常高。把规范抽出来,做成 agent 无关的中间层,才是长久之计。
6.2 和现有 lint 工具的关系
有人会问,ESLint、Stylelint 不也能查样式问题吗?为什么还要 impeccable?
区别在于关注点不同。ESLint 和 Stylelint 关注的是代码层面的正确性和一致性,比如有没有用未定义的变量、属性顺序对不对。impeccable 关注的是渲染后的视觉一致性,比如实际间距是不是落在阶梯里、颜色是不是在调色板内。前者是静态的、文本层面的,后者是动态的、视觉层面的。
两者不冲突,是互补的。我的项目里两个都跑:Stylelint 管代码规范,impeccable 管视觉规范。CI 里两个都过才算通过。
6.3 浏览器扩展的权限边界
扩展要读取页面样式,必然需要一定的权限。我的建议是最小权限原则:只申请必要的权限,只在你指定的域名上激活。别图省事申请“所有网站”,那既不安全也不专业。
配置里可以明确列出允许的域名:
extension: allowed_origins: - "http://localhost:3000" - "http://localhost:5173" - "https://staging.yourproject.com"这样扩展只在开发环境和预发环境激活,生产环境不介入,既保证了开发体验,又避免了线上风险。
7. 我在实际项目里踩过的几个坑
第一个坑是过度约束。刚接入时我特别兴奋,把能想到的规则全加上了,结果 agent 每改一处就触发一堆 warning,修复循环停不下来。后来砍到只剩十几条核心规则,效率反而高了。规则的价值在于被执行,不在于数量。
第二个坑是忽略响应式。同一套间距在桌面端没问题,到移动端就太宽了。后来我在规则里加了断点维度,不同断点用不同的间距阶梯。移动端用小阶梯,桌面端用大阶梯,这样才合理。
第三个坑是忘了给 agent 留创作空间。规范是为了保证底线,不是为了扼杀所有变化。有些地方 agent 想用一点非常规的处理来突出重点,只要不破坏整体一致性,应该允许。我在规则里加了allow_override字段,特定组件可以申请豁免,但要在代码里注明原因。这样既保持了规范,又保留了灵活性。
最后一个心得:规范要跟着项目演进。项目初期规则可以松一点,快速迭代;项目稳定后规则收紧,保证质量。别一开始就上最严的规则,那会拖慢整个团队的节奏。impeccable 这类工具最大的意义,是让“设计质量”这件事从依赖个人品味,变成可配置、可执行、可传承的工程能力。你把这套东西搭起来,后面不管换什么 agent、招什么人,底线都在那儿。