用明确约束让 AI 遵守设计系统
作者建议用精简的组件使用契约替代整库粘贴,明确可导入的组件、合法属性和完成标准。通过可检查的限制,减少 AI 重造组件、硬编码样式及偏离设计规范。
AI 深度解读
把设计系统整包塞进 AI 提示词,未必能让它老老实实复用组件。作者遇到的情况是:回答变长、变慢,最后仍然冒出一个带硬编码颜色的 PrimaryButton。问题在于,模型看到了组件库,却没有把它当成必须遵守的边界。
作者给出的办法,是用一份约 80–120 行的规则速查表,明确合法组件、属性、令牌和验收条件,再加上「缺东西先停下」的要求。对经常让 AI 写页面的前端团队,这篇文章最有用的地方,是把设计系统合规从视觉判断变成可检查的约束。
为什么看过组件库,还是会另造一个按钮
作者举出的失败提示词很常见:粘贴 components/ui 下的 40 个文件,再要求 AI 做一个符合设计系统的设置表单。
结果可能出现重复实现 Card 的 SettingsCard、混在令牌导入旁边的内联样式、替代 Switch 的自制开关,以及不在间距刻度上的数值。
这些实现可能看起来像目标页面,却没有遵守现有系统。作者认为,组件目录容易被模型当成参考素材,供它挑选和改写;目录本身没有明确告诉模型:哪些东西必须用,哪些东西不能造。
组件库提供了可用能力,提示词还需要规定使用边界。
作者把合规拆成四项检查:
- 导入白名单:基础组件只能来自
@/components/ui/*等指定入口,不能建立另一套平行组件。 - 属性白名单:只能使用文档允许的
size、tone、intent等属性及取值,不能自己发明big、fancy。 - 令牌规则:颜色、间距、圆角必须来自令牌,JSX 中不能出现绕过系统的原始 hex、rgb 或随意填写的 px 数值。
- 组合规则:页面由现有基础组件拼装;新增基础组件必须获得明确的「new primitive approved」许可。
这里的基础组件(primitive),可以理解为 Button、Input、Switch 这一层积木。任务要求的是搭页面,模型却可能顺手重新设计积木,这正是需要限制的地方。
速查表应该写什么,缺组件时怎么办
作者维护的速查表约 80–120 行,并在公开 API 改变时更新。它承载的是实现时需要做出的选择,完整属性表和 Storybook 资料仍留在仓库里。
例如,Button 明确允许 primary | secondary | ghost | danger 四种 variant,以及 sm | md | lg 三种 size。Input 必须配合 Label,错误通过 error 属性表达。其余合法组件包括 Select、Switch、Checkbox、Textarea、Card、Stack、Inline、Dialog、Toast。
令牌也要具体。颜色列出 bg.default、bg.subtle、fg.default、fg.muted、border.default、accent.primary;间距限定为 1–8;圆角限定为 sm | md | lg | full。
常用组合则直接给默认值:表单使用 Stack gap={4},操作区使用 Inline justify="end" gap={2};危险操作使用 Button variant="danger" 配合确认 Dialog;空状态用 Card、Stack 和弱化文字组合。
最关键的一条指令是:缺少能力时,停止实现并指出缺口。
作者用 DatePicker 举例:白名单没有日期选择器,就应该询问使用原生 input type=date,还是另开基础组件需求。作者认为,这比交回一个 200 行的自制日历更合适。这里的「200 行」是说明风险的例子,原文没有提供对应实验记录。
作者还会保留 3–5 段违规示例,让模型看到具体边界。下面这段展示了什么叫另造组件、绕过令牌,以及合法组合:
- // illegal: new parallel primitive
- export function FancyButton(...) { ... }
- // illegal: token bypass
- <div style={{ color: '#3366ff', marginTop: 13 }}>
+ // legal: compose
+ <Button variant="primary" size="md">Save</Button>
+ <Stack gap={4}>...</Stack>
要关注的是 marginTop: 13:即使没有写出 px,这个任意数值仍然绕过了间距规则。示例里的十六进制颜色同样违规。
任务拆小之后,规则才容易检查
作者没有只调整提示词,还缩小了每次任务的范围。
「重做账单设置页并现代化 UI」给了模型太多自由。作者将其拆成先接数据和现有布局容器,再逐组替换套餐、支付方式、发票控件,最后补空状态和错误状态。每一步复用同一份速查表,评审时更容易判断改动是否越界。
验收条件也提前写进提示词:没有「new primitive」任务许可,就不能在 components/ui 下新增文件;改动文件中不能有 hex/rgb;交互元素使用 ui/* 基础组件;主路径由 Story 或 Playwright 覆盖。完成后,要求模型逐项报告通过或失败。
完整 Storybook MDX、Button 内部实现、所有状态的 Figma 截图和整份 tokens JSON,都不必默认粘贴。需要属性细节时,让模型读取 Button.tsx、类型文件或包导出;布局确实重要时,再附对应页面截图。
合并前仍要检查实际 diff:用 rg 查 hex 和 rgb(,看有无未经许可的新组件、来自 ../shared/Button 之类路径的导入,以及重复实现 Stack 间距职责的 class。发现问题后,作者会修正规则速查表,而不只是修当前代码。
我的判断
这套方法说得对的地方,是把「看起来符合设计系统」拆成了导入、属性、令牌、组合几类可核对的问题。比单纯要求 AI「参考现有风格」,它更适合代码评审,也更容易接入自动检查。
但原文没有给出模型版本、任务样本量、违规率或耗时对照。「80–120 行」「3–5 段反例」都是作者的实践选择,不能视为已经验证的最佳参数。
它也依赖组件库自身足够成熟。如果合法组件缺失、类型定义落后、令牌使用方式不统一,模型就会频繁停下来询问。白名单必须对应团队真实可用的 API,否则只是把模糊需求换成了过时规则。
提示词适合传达约束,类型检查、lint 和测试负责验证实际代码。
相比把所有文档塞进上下文,这种按需读取更节制;相比只靠提示词自报通过,仓库里的自动检查更可靠。两者可以配合使用,作者也明确表示仍然需要人工评审。
能拿来做什么
- 给日常 AI 页面任务准备一份设计系统速查表,先写清合法导入、关键属性取值、令牌用法和常见组合,并跟随公开 API 更新。
- 在任务里明确缺口处理方式:找不到合法组件时,先指出缺失能力,再决定采用已有替代方案还是新增基础组件。
- 将整页改造拆成数据接入、控件替换、状态补齐等步骤,每一步都要求复用同一套约束,并覆盖主操作路径。
- 评审 AI 生成的 diff 时,优先检查新增基础组件、异常导入和令牌绕过;反复出现的违规模式,应补进速查表和适合的自动检查中。