第41章:DESIGN.md:给 Agent 的设计系统说明书
"模型有审美,没有记忆。你的品牌长什么样,得你自己写成文件。"
第 40 章讲了六个前端 Skill,把 AI 生成界面从 Slop 拉回有品味。但 Skill 管的是怎么设计,不管设计成什么。Agent 生成的界面确实好看,按钮却是蓝色的,你的品牌色是橘色。字体、圆角、间距,全都对不上。
这不怪模型。你的品牌只存在于设计师的脑子里和 Figma 的画布里,Agent 每次开工都得靠你口头转述。转述就有损耗,这次说 #2563eb,下次它生成 #3b82f6,肉眼一看:颜色不对,重来。
2026 年,Google Labs 把这个问题做成了格式规范:DESIGN.md。一句话说清楚它:给编码 Agent 看的视觉身份说明书。放在项目根目录,Apache-2.0 开源,如今 28k star。
41.1 思路:README 给人,DESIGN.md 给 Agent
这个词你听着耳熟。AGENTS.md 是给 Agent 看的 README:构建命令、测试命令、代码规范。README.md 服务人,AGENTS.md 服务 Agent,两边各看各的,互不干扰。
DESIGN.md 是同一个思路在视觉领域的落地。它只装一件事:你的设计系统长什么样。Agent 读过它,生成的每个按钮、每段文字、每张卡片,自动落在你的品牌规范里。
关键在"持久"两个字。口头转述是会话级的,这个会话说完下个会话就忘。DESIGN.md 是文件级的,跟着仓库走,所有 Agent、所有人、所有工具,读到的都是同一份。
41.2 格式:一半给机器,一半给人
一个 DESIGN.md 文件分两层。开头是 YAML front matter,装机器可读的 design token。后面是 markdown 正文,装人可读的设计理由。官方 README 的示例项目叫 Heritage,精简后长这样:
---
name: Heritage
colors:
primary: "#1A1C1E"
tertiary: "#B8422E"
neutral: "#F7F5F2"
typography:
h1:
fontFamily: Public Sans
fontSize: 3rem
label-caps:
fontFamily: Space Grotesk
fontSize: 0.75rem
rounded:
sm: 4px
md: 8px
---
## Colors
The palette is rooted in high-contrast neutrals and a single accent color.
- **Primary (#1A1C1E):** Deep ink for headlines and core text.
- **Tertiary (#B8422E):** "Boston Clay", the sole driver for interaction.
- **Neutral (#F7F5F2):** Warm limestone, softer than pure white.
token 给 Agent 精确的值。正文告诉它为什么:Boston Clay 是唯一的交互色,只用在主按钮上;石灰白比纯白温和,做页面底色。Agent 读完这个文件,生成的界面就是深墨色标题、Public Sans 字体、波士顿黏土色的按钮。
这个分工有主次。spec 里写明:token 是规范值,正文只是上下文。两者冲突时,以 token 为准。正文可以写"Midnight Forest Green"这种有画面感的名字,对应的 token 还是老老实实叫 primary。
token 的类型不多,五个就够:
| 类型 | 格式 | 示例 |
|---|---|---|
| Color | 任意 CSS 颜色 | "#1A1C1E"、oklch(62% 0.18 250) |
| Dimension | 数字加单位 | 48px、-0.02em |
| Typography | 七个字体属性的对象 | fontFamily、fontSize、fontWeight、lineHeight 等 |
| Token 引用 | {path.to.token} |
{colors.primary} |
| 组件属性 | 八个固定键 | backgroundColor、textColor、rounded、padding 等 |
颜色支持全套 CSS 写法,hex、rgb、hsl、oklch 都行,内部统一转成 sRGB 做对比度检查。引用语法从 W3C Design Token Format 借来的,{colors.primary} 指向别处定义的值,改一处,全项目跟着变。
还有一个 omitted 字段,声明哪些章节是故意不写的,可附原因。没有它,linter 会把缺失的章节当问题报出来。
41.3 章节结构:八个段落,顺序固定
markdown 正文按 ## 分节。章节可以省略,但写了就必须按这个顺序排:
| 顺序 | 章节 | 装什么 |
|---|---|---|
| 1 | Overview | 品牌气质,UI 该给人什么感觉 |
| 2 | Colors | 色板,至少定义 primary |
| 3 | Typography | 字体层级,主流系统有 9 到 15 级 |
| 4 | Layout | 布局策略和间距节奏 |
| 5 | Elevation & Depth | 阴影层级,扁平设计写替代方案 |
| 6 | Shapes | 圆角和形状语言 |
| 7 | Components | 按钮、输入框这些组件的样式 |
| 8 | Do's and Don'ts | 禁忌清单 |
Overview 是给 Agent 的"审美底色"。具体规则没覆盖到的地方,Agent 靠这段话做判断:这个产品该显得稳重还是活泼,紧凑还是疏朗。
Do's and Don'ts 值得照抄一段感受一下:
- Do use the primary color only for the single most important action per screen
- Don't mix rounded and sharp corners in the same view
- Do maintain WCAG AA contrast ratios (4.5:1 for normal text)
- Don't use more than two font weights on a single screen
每屏只让一个动作用主色、同一视图别混圆角和直角、单屏别超过两种字重。全是设计师踩过坑才知道的禁忌,写下来,Agent 就不会再踩。
规范对未知内容很宽容:没见过的章节标题,保留不报错;没见过的 token 名,只要值合法就接受。唯一零容忍的是重复章节,两个 ## Colors 直接拒绝整个文件。
41.4 组件 token 与变体
Components 章节把抽象色板落到具体组件。每个组件是一组子 token,值可以是字面量,也可以引用前面的 token:
components:
button-primary:
backgroundColor: "{colors.tertiary}"
textColor: "{colors.on-tertiary}"
rounded: "{rounded.sm}"
padding: 12px
button-primary-hover:
backgroundColor: "{colors.tertiary-container}"
组件属性有八个:backgroundColor、textColor、typography、rounded、padding、size、height、width。悬停、按下这些状态变体,用相关联的 key 表示,button-primary-hover、button-primary-active,Agent 自己会关联。
组件里还有个特殊待遇:别的引用必须指向原始值,只有组件里可以引用复合值,比如 {typography.label-md} 整个拿一套字体规格来用。
这一层也顺带解决无障碍问题。规范会把组件的前景色和背景色两两配对,算对比度,低于 WCAG AA 的 4.5:1 就报一条 warning。
41.5 CLI 四件套:lint、diff、export、spec
格式规范配上官方 CLI(npm 包 @google/design.md),才能进真实的工程流程。
41.5.1 lint:十一条规则
npx @google/design.md lint DESIGN.md
输出结构化 JSON,Agent 拿到就能直接修。十一条规则里几条最有意思:
broken-ref(error):{colors.primary}指向一个不存在的 token。这是唯一的 error 级。contrast-ratio(warning):组件配色低于 WCAG AA 的 4.5:1。missing-primary(warning):定义了颜色却没有 primary,Agent 会自己编一个。orphaned-tokens(warning):定义了颜色却没有任何组件用它。unknown-key(warning):顶层 key 疑似拼写错误,colours:提醒你是不是想写colors:。token-like-ignored(warning):某个不认识的顶层 key 里装着 hex 色值和字号,多半是名字写错了,整段值没生效。
看得出这份规则表是拿真实事故换的:拼写错、值丢了、引用断了、对比度不够,每条都对应一种常见的烂法。
41.5.2 diff:给设计系统做回归测试
npx @google/design.md diff DESIGN.md DESIGN-v2.md
报告两个版本之间 token 级的增、删、改,按 colors、typography、rounded、spacing、components 分组列出,再对比两版的 lint 结果。改完问题变多了,退出码给 1。挂进 CI,谁改设计系统改出回归,谁就被挡在合入之前。
41.5.3 export:接到现有工具链
npx @google/design.md export --format css-tailwind DESIGN.md > theme.css
三种导出目标:Tailwind v3 的 theme.extend 配置、Tailwind v4 的 @theme CSS 变量块、W3C DTCG 格式的 tokens.json。你现有项目用的是 Style Dictionary 还是 Figma variables,都不用推倒重来。
41.5.4 spec:把规范喂给 Agent
npx @google/design.md spec --rules
输出整份格式规范,可以原样注入 Agent 的提示词。Agent 读你的 DESIGN.md,也读它要遵守的格式本身。
41.6 生态与定位
DESIGN.md 2026 年 6 月登上 GitHub Trending,一天涨了 1500 多 star。围绕它长出了一个小生态:
- designmd.app 收了 759 份现成的 DESIGN.md,挑一个风格,复制进项目就能用。
- 按 designmd.app 的说法,Claude Code、Cursor、Kiro、Windsurf 都直接可用。文件放进根目录,Agent 读项目时就会带上。
- 推荐用法是和 CLAUDE.md 搭配:在 CLAUDE.md 里加一句"生成任何 UI 代码前先读 DESIGN.md,色值照抄,不许自己估"。
它和现有设计 token 体系是互补关系。W3C DTCG 和 Style Dictionary 面向生产流水线,JSON 格式,要解析器、要构建步骤。DESIGN.md 是人和 Agent 的那一层:markdown 写的,不构建、不编译,打开就能读,改完就能用。正式的 token 流水线照跑,DESIGN.md 坐在上游,当人和 Agent 共用的那层入口。
规范目前是 alpha 版,schema 和 CLI 都还在演进,格式变动要有预期。
41.7 与全书方法论的对接
- 第 40 章:Skill 管行为,DESIGN.md 管事实。Skill 告诉 Agent"设计要有记忆点",DESIGN.md 告诉它"记忆点是波士顿黏土色"。前者是动词,后者是名词,缺一个都生成不出对的东西。
- AGENTS.md 谱系:AGENTS.md 管构建和规范,DESIGN.md 管视觉身份。上下文文件这个模式每细化一个领域,Agent 的自由发挥空间就少一分。
- 第 22 章:UML 把代码结构画给 AI 看,DESIGN.md 把视觉约束写给 AI 看。路数相同:把隐性知识显式化,写成模型读得懂的文件。
- 第 31 章:PRD 和 SPEC 约束行为需求,DESIGN.md 约束视觉需求。一份完整的"给 Agent 的合约",这两半缺一不可。
- 第 25 章:lint 和 diff 都是收尾关卡思想。设计系统的回归测试,和代码的回归测试应该是同一道闸门。
41.8 本章小结
- DESIGN.md 用一个文件解决"Agent 不知道你的品牌":YAML token 给精确值,markdown prose 给理由和禁忌。
- 八个章节顺序固定,token 是规范值,正文是上下文,冲突以 token 为准。
- CLI 四件套把格式接进工程流程:lint 查断链和对比度,diff 做设计系统的回归测试,export 对接 Tailwind 和 W3C DTCG,spec 把规范喂给 Agent。
- 它是 AGENTS.md 思想在视觉领域的落地,与 Skill 体系互补:Skill 管怎么设计,DESIGN.md 管设计成什么。
- 文件级的持久上下文胜过会话级的口头转述。品牌规范写成文件,才谈得上跨会话、跨工具、跨人的一致。
下一章看设计工具:Claude Design、open design 这些产品解决从零生成设计的问题。DESIGN.md 解决的是另一半:设计怎么持久、怎么被遵守。