31 个 skill、72 个 system:Open Design 库是怎么运作的
带你走一遍让 Open Design 可组合的四个原语:skill、system、adapter 和 daemon。并用具体例子说明一个 Markdown 文件如何变成一份像素级精确的交付物。
从机制上看,Open Design 就是四个原语层层叠起来:
- Skill——agent 应该做什么
- System——输出应该长成什么样
- Adapter——由哪个 agent 来干活
- daemon——把它们串接起来的那个循环
每个原语都是一个装着文件的文件夹。它们谁都不需要数据库、插件运行时或托管服务。这就是整个库的全部——没有藏在登录墙后面的第五个概念。这篇文章会逐一走过它们,并展示当你把 agent 指向一份真实的 brief 时会发生什么。如果你想在了解「怎么做」之前先了解我们为什么把它塑造成这个样子,请从 我们为什么把 Open Design 构建成一个 skill 层、而不是一款产品 读起。
Skill:能力的基本单位
一个 skill 就是一个文件夹,里面装着一个 SKILL.md 以及零个或多个辅助文件。这个 Markdown 文件是 agent 的契约——文件夹里其余的一切都是为了帮助 agent 兑现它。
一个 skill 文件夹的解剖
一个典型的 skill 长这样:
skills/
guizang-ppt/
SKILL.md
templates/
magazine.html
examples/
product-launch.html
pitch-deck.html
SKILL.md 声明了这个 skill 的名字、触发条件、输入形态、输出形态,以及给 agent 的任何内联指引。templates/ 和 examples/ 文件夹是可选的,但分量很重:example 是已知良好的产物,agent 可以拿它来做模式匹配,这正是「给我做一套 deck」到底是产出一个连贯的东西,还是产出一个临场拼凑的东西,二者之间的区别。
front matter 是 daemon 读来登记 skill 的部分;正文则是 agent 读来执行它的部分:
---
name: guizang-ppt
trigger: a deck, slide presentation, or pitch
output: HTML (exportable to PDF, PPTX)
---
Build a horizontal slide deck. One idea per slide.
Lead with a cover, close with a call to action.
Respect the locked-in design system for color, type, and spacing.
Pattern-match against examples/ for layout density and rhythm.
为什么这个文件本身就是注册表
当 daemon 启动时,它会扫描 skills/,并把每一个含有 SKILL.md 的文件夹登记进来。没有插件清单。没有版本字段。没有上传步骤,没有审核队列,没有构建。只有这个文件,而这个文件就是事实源。丢进一个新文件夹,重启 daemon,这个 skill 就出现在选择器里。删掉它,它就没了——不会留下一条指向已不存在代码的孤儿注册项。
我们目前内置 31 个 skill。有些是 deck 生成器,有些产出移动端原型,有些构建编辑风页面,有些撰写办公文档(Word、Excel、PowerPoint)。每一个都是你可以 fork、编辑或替换的文件夹。因为契约就是纯文本,「写一个 skill」和「读一个 skill 来理解它做什么」是同一件事——你审查它的方式就是打开它。
System:审美的基本单位
如果说 skill 描述的是做什么,那么 system 描述的是它应该长成什么样。一个 system 就是一个 DESIGN.md 文件,外加可选的参考资源。它用机器可读的形式描述一套视觉识别:
- Color——前景、背景、强调色、错误色等的 OKLch 取值
- Type——字体栈、字重、字号阶梯、行高约定
- Space——基础单位、间距阶梯、容器宽度、栏间距规则
- Layout posture——网格选择、非对称规则、密度偏好
- Voice——文字的「排版」:语气、用词、句子节奏
DESIGN.md 是一份契约,不是组件库
实践中,一个 DESIGN.md 读起来像一份简短、有主见、agent 不可能误读的品牌 brief:
## Color
--bg: oklch(98% 0.01 95);
--ink: oklch(20% 0.02 260);
--accent: oklch(72% 0.19 35);
## Type
Display — Albert Sans, 600, -0.02em
Body — Albert Sans, 400, 1.7 line-height
## Posture
Generous whitespace. One accent, used sparingly. No drop shadows.
这些颜色之所以用 OKLch,是为了让它们在明暗表面上都保持知觉上的均匀;字号阶梯是一架 agent 不会偏离的梯子;而 posture 规则正是「十个生成出来的屏幕感觉像同一个产品」与「十个屏幕感觉像十个不同实习生做的」之间的差别。agent 读一遍这份契约,然后在整个任务里都遵守它。
一个 system 不是 Figma 库。这里没有组件、没有变体、没有嵌套实例、没有横在你和规则之间的二进制格式。它是一份任何 agent 都能读、任何人类都能审查的契约。我们开箱内置 72 个 system,包括 Linear、Vercel、Stripe、Apple、Cursor、Figma 的可移植版本,以及一长串编辑风与品牌 system。
混搭、fork、拥有
因为一个 system 不过是文本,你可以 fork 一个并就地编辑、交付一个变体,或者用大约 30 分钟的专注工作从头写一个自己的。你甚至可以在项目进行中混搭多个 system——排版取自 Linear、配色逻辑取自 Vercel、版式取自一份内部规范——因为没有任何东西被锁进专有的二进制里。skills/ 和 design-systems/ 两个文件夹的拆分是刻意的:能力与审美是正交的,所以任何 skill 都能在任何 system 下运行,任何 system 也都能驱动任何 skill。
Adapter:agent 的基本单位
skill 和 system 是惰性的文本。adapter 则是把它们连接到真正干活的 agent 的那一小段代码。一个 adapter 是 adapters/ 里一个简短的 TypeScript 文件,它懂得如何:
- 检测该 agent 是否已安装在用户的
$PATH上 - 用该 agent 开启一个会话
- 把一次 skill 调用喂进去
- 把输出收集回来
我们今天为 12 个 agent 提供了 adapter:Claude、Codex、Gemini、Cursor、Copilot、OpenCode、Devin、Hermes、Pi、Kimi、Kiro、Qwen。daemon 会自动检测哪些已存在,并在首次启动时以下拉菜单的形式提供它们——你什么都不用配置,只会看到你已经拥有的那些 agent。
| 原语 | 位于 | 文件 | 事实源 |
|---|---|---|---|
| Skill | skills/ | SKILL.md | 磁盘上的那个文件 |
| System | design-systems/ | DESIGN.md | 磁盘上的那个文件 |
| Adapter | adapters/ | 一个 .ts 文件 | 一次 register() 调用 |
如果你想新增一个 adapter,那个文件大约是 80 行 TypeScript 加一次 register() 调用。没有要学的 SDK,没有要申请的权限,没有要发布到的中心注册表。你笔记本上早已信任的那个 agent,就成了引擎——Open Design 从不取代它。(姊妹篇 BYOK 设计工作流 走了一遍如何把一个 adapter 指向你自己的密钥。)
daemon:把一切系在一起的循环
daemon 是系统里唯一在运行的进程。它是你用 pnpm tools-dev 启动的一个小小的 Node 进程,依次做四件事:
- Detect(检测)——启动时扫描
$PATH查已安装的 agent、扫描skills/查已安装的 skill - Discover(探询)——打开一个交互式提问表单,为当前 brief 锁定载体、受众、语气、规模和品牌上下文
- Direct(定向)——给出 5 个确定性的视觉方向(OKLch 配色、字体栈、版式 posture 提示),让用户挑一个
- Deliver(交付)——用锁定的 system 调起选中的 skill,让 agent 写到磁盘,并在沙箱化的 iframe 里预览输出
整个循环大约 1500 行代码就装得下。它是刻意做小的。聪明之处在 skill 里,而不在运行时——daemon 的工作就是扫描文件夹、把一份 brief 路由过这四步,然后让到一边。这种小正是要点所在:这里几乎没有什么会腐坏的东西,也几乎没有什么能把你的工作扣作人质。
实践中它是什么感受
假设你想为一个新产品功能做一套发布 deck。流程是这样的:
- 你在终端里运行
pnpm tools-dev。daemon 在localhost:7780上启动。 - 你打开这个 URL。daemon 给你看它找到了哪些 agent(例如 Claude、Cursor、Codex)。
- 你从 skill 列表里挑选
guizang-ppt。 - 弹出一个 30 秒的提问表单:受众是谁、语气是什么、品牌上下文是什么。
- 你被展示了 5 个视觉方向——不同的配色、字体搭配、版式 posture。你挑一个。
- agent 写到磁盘。一个沙箱化的 iframe 显示出结果。你可以导出为 HTML、PDF、PPTX、ZIP 或 Markdown。
顺着这些原语回溯,整件事就一目了然:第 3 步选了一个 skill,第 5 步锁定了一个 system,背后的那个 agent 是通过一个 adapter 接进来的,而 daemon 跑完了这四步循环。输出是真实的。文件是你的。你可以在任何编辑器里改它们,把它们交给一位设计师,或者把它们重新喂回另一个 skill。
为什么用文件,而不是数据库
每一个原语——skill、system、adapter——都是一个装着文本文件的文件夹。没有中心数据库。没有「Open Design 账户」。没有那种必须一直运转、你的工作才能一直运转的托管服务。
这是一笔刻意的交换。我们放弃了做花哨的跨用户分析、跨项目记忆或托管协作的能力。换回来的是:可移植性、长寿、可审查性,以及任何人都能 fork 整个库并交付自己变体的能力。今天写下的一个 SKILL.md,两年后对一个 agent 读起来一模一样,对一个手头没有任何工具的人类也读起来一模一样——而一个被钉死在去年某个 API 上的插件可做不到这一点。
如果你曾眼看着一代又一代设计工具死去、还把你的文件一并带走,你就会明白这笔交换为什么值得。
延伸阅读
- 我们为什么把 Open Design 构建成一个 skill 层、而不是一款产品——这四个原语背后的赌注
- BYOK 设计工作流:用你自己的密钥运行 Claude、Codex 或 Qwen——adapter 如何连接到你早已付费的那个 agent
- 画布曾经藏起来的那一层版式——为什么 DESIGN.md 里的 posture 规则胜过在画布上拖框