用设计令牌约束 AI 生成界面
文章将颜色、间距、圆角等设计值集中为令牌,通过 AGENTS.md 统一约束 Cursor 和 Claude Code,并让 CLAUDE.md 引用同一规则。随后用两条搜索命令检查生成代码中擅自添加的样式值。
AI 深度解读
让 Cursor 或 Claude Code 写页面,最容易出现的偏差往往很细:品牌色是青绿色,按钮却用了 bg-blue-500;卡片间距基本统一,某一块突然多出 2px。页面能跑,也不算难看,但设计规范已经开始失效。
作者给出的办法很直接:先把设计值收进代码,再用一份共享规则约束 Agent,最后搜索违规输出。值得借鉴的不是某段提示词,而是让设计要求有出处、有边界,也有检查入口。
为什么只告诉 AI「遵守设计规范」不够
作者认为,模型不知道项目的设计约束时,会采用训练材料中常见的写法。在聊天里纠正一次,只能影响当前上下文;下一次任务,类似问题还可能重来。
因此,第一步是建立设计令牌(Design Tokens):把颜色、间距、圆角、阴影、字体都变成有名字的值。组件引用名字,具体数值集中维护。
原文的普通 CSS 示例把主色定义为 --color-primary: #0f766e,悬停色单独定义为 --color-primary-hover: #115e59,焦点环使用 --color-focus-ring: #14b8a6。间距则有 --space-2: 8px、--space-4: 16px、--space-6: 24px,中等圆角为 --radius-md: 10px。
这里最实用的是把交互状态提前补齐。缺少 hover 颜色,Agent 就可能临时调出一个「深一点」的色值。
暗色模式也沿用相同名字:在 [data-theme="dark"] 下,把文字从 #0f172a 改为 #f1f5f9,背景从 #ffffff 改为 #0f172a。组件不必各自选择暗色值。不过,原文只展示了部分覆盖项,不能把它当作完整的暗色主题。

Tailwind 加了品牌色,为什么还会冒出蓝色按钮
因为默认调色板还在。
只增加 primary,并不会阻止模型继续生成熟悉的 bg-blue-500。作者在 Tailwind v4 中先清空相关默认命名空间,再声明项目允许的值:
@import "tailwindcss";
@theme {
--color-*: initial;
--font-*: initial;
--radius-*: initial;
--shadow-*: initial;
--color-primary: #0f766e;
--color-primary-hover: #115e59;
--color-text: #0f172a;
--color-text-muted: #475569;
--font-sans: "Inter", system-ui, sans-serif;
--radius-md: 10px;
}
重点看 --color-*: initial;:它先移除默认颜色,再开放自定义颜色。按原文的设置,bg-blue-500 将不再提供对应样式,错误更容易暴露。字体、圆角和阴影也采用同样的限制方式。
Tailwind v3 的对应做法,是把颜色放进 theme.colors,而不是 theme.extend.colors,后者会保留默认调色板。
间距则保留 Tailwind 原有的 4px 步进,再通过规则限制可用档位。原文允许的是 4、8、16、24、32、48、64px,禁止夹在中间的数值,并提到了另一份 8pt 网格方案,但没有在这里展开。
缩小可选范围,比反复提醒模型别选错更有约束力。
不过,清空默认主题也会影响已有组件。存量项目应先确认哪些样式依赖这些默认值,不能直接照抄后就认定迁移完成。
一份规则怎么同时约束多个工具
作者把约束集中放进项目根目录的 AGENTS.md,并要求规则能通过代码检查。
「界面简洁现代」没有明确验收标准;「tokens.css 之外禁止 hex、rgb、hsl」就可以搜索。规则还要求使用 var(--color-*)、var(--space-*)、var(--radius-*) 或对应 Tailwind 类,禁止 p-[18px]、bg-[#0f766e],也禁止用 dark: 颜色类绕过主题令牌。
交互要求同样要写清:按钮使用主色和悬停色,每个可交互元素都有可见焦点样式。
最关键的一条是缺值处理:找不到合适令牌时,先选最接近的值,在回复里说明;新增令牌前先询问。它把 Agent 的临时决定变成团队可见的设计取舍。
工具入口则按原文描述统一:Cursor 读取根目录的 AGENTS.md,以及 .cursor/rules/ 下的 .mdc 文件;该目录里的普通 .md 会被忽略,旧 .cursorrules 属于兼容格式。Claude Code 每次会话读取 CLAUDE.md,因此里面只需写一行 @AGENTS.md。原文也将 Copilot、Codex 列为支持 AGENTS.md 的工具,但没有给出具体版本和兼容范围。

如果不想让后端任务加载设计规则,可以限定文件范围。Cursor 使用 .cursor/rules/design-system.mdc,配置 description: Design system rules for UI code、globs: src/components/**/*.tsx, src/styles/**/*.css 和 alwaysApply: false;Claude Code 则在 .claude/rules/ 文件顶部用 paths 列出这两个路径模式。
规则要短。原文转述的建议是,每份 CLAUDE.md 约控制在 200 行以内,Cursor 每条规则控制在 500 行以内。这些是工具文档建议,文章没有提供长度与遵循率的对照实验。
我的判断
这套方案最有价值的地方,是没有把规则文件当成验收结果。
作者建议先让 Agent 生成一个包含三档方案、中间档突出的定价区,再用下面两条命令检查硬编码颜色和部分 Tailwind 任意值:
grep -rnE "#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(" src --include=*.tsx --include=*.jsx --include=*.css | grep -v tokens.css
grep -rnE -- "-\[(#|[0-9.]+(px|rem))" src
第一条排除令牌文件,第二条匹配以颜色或 px、rem 数值开头的任意值。要留意第一条末尾的 grep -v tokens.css:它按输出文本过滤,并不是精确的文件路径排除。
搜索没有输出,只能说明这些模式没有命中。
它们查不出所有违规值,也无法判断令牌用得是否合适。例如主标题用了弱化文字颜色,代码仍然可能全部合规。Tab 检查焦点、切换暗色模式、实际看页面,仍然必要。作者建议连续通过几次后接入 pre-commit hook,但没有展示 hook 实现或错误率数据,所以效果应视为实践经验。
相比只写提示词,这套方法增加了代码层的限制;相比完整的静态检查,它的覆盖范围有限,但接入成本较低。
维护成本也不能忽略。令牌重命名必须同步更新规则,原文建议在同一次 commit 中修改,并暂时保留 --color-brand: var(--color-primary); 这样的别名,确认没有引用后再删除;大改后开启新聊天,避免旧上下文继续引用旧名字。
作者还介绍了 Google Labs 尚处 alpha 的 DESIGN.md:顶部放 YAML 令牌,下面解释设计理由。文章提醒,并非所有工具都会自动读取它,需要从规则引用,或在 CLAUDE.md 添加 @DESIGN.md。我认同其中的维护原则:不要在它和 CSS 中重复保存同一份 hex 值。
最后,作者推广了自己的 Constrainly,可导出 CSS、Tailwind v4/v3 主题及配套规则;Design Language Studio 可一次处理颜色、字体、间距、圆角和阴影。原文称其免费且无需账号,但没有提供对照数据,不能据此判断它优于手工维护。
能拿来做什么
- 给现有前端项目先补齐主色、hover、focus、文字和背景令牌,再让 Agent 修改一个真实组件,检查它是否还需要临时造值。
- 在同时使用 Cursor、Claude Code 或 Codex 的仓库里集中维护
AGENTS.md,并核对各工具实际加载的规则,避免修改多份副本。 - 把两条搜索作为 AI 生成 UI 后的初筛,再用 Tab 和暗色模式验证交互;若同一种缺失颜色反复出现,再决定补令牌还是收紧规则。
- 对前后端同仓的项目按组件和样式路径加载设计约束,并把令牌与规则的同步修改纳入代码审查。