首页
/ OpenDesign 四原语解析:31 个 Skill、72 个 System 的库是如何运作的

OpenDesign 四原语解析:31 个 Skill、72 个 System 的库是如何运作的

2026-09-04 17:51:36作者:毕习沙Eudora

OpenDesign 从机制上看是四个层层叠加的原语:Skill 决定 agent 做什么,System 决定输出长什么样,Adapter 决定由哪个本地 agent 干活,daemon 则是把它们串接起来的循环。本文逐一拆解这四个原语的文件形态与注册机制,并结合 skills/design-systems/apps/daemon/src/runtimes/ 的真实源码说明一个 Markdown 文件如何变成一份可导出的交付物,读完你可以完整理解 OpenDesign 的"文件即注册表"设计,并知道如何 fork、混搭或扩展这个库。

四个原语一览

每个原语都是一个装着文件的文件夹,谁都不需要数据库、插件运行时或托管服务。这就是整个库的全部——没有藏在登录墙后面的第五个概念。

原语 位于 文件 事实源
Skill skills/ SKILL.md 磁盘上的那个文件
System design-systems/ DESIGN.md 磁盘上的那个文件
Adapter apps/daemon/src/runtimes/defs/ 一个 .ts 文件 一次注册(registry 数组中的一条 def)

原文档写作时内置 31 个 skill、72 个 system、25 个 CLI runtime 的 adapter;以当前仓库快照看,skills/ 下已有 162 个 skill 文件夹,design-systems/ 下有 150 余个 system 包,runtimes/defs 目录内置了 27 个 CLI 定义——库本身在持续增长,但原语的形态没有变。

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.

结合仓库中的 Skills Protocol 规范 可以看到实际的前置语法:SKILL.md 沿用 Claude Code 的 Agent Skills 约定,基础字段包括 namedescriptiontriggers(触发关键词列表),正文则是描述 agent 应遵循工作流的自由 Markdown,通常是编号步骤加原则。在此基础上 OpenDesign 提供可选的 od: 扩展字段来解锁产品 UI,例如:

od:
  mode: deck                 # prototype | deck | template | design-system | image | video | audio
  surface: web                # web | image | video | audio
  scenario: marketing         # 画廊/过滤提示
  category: presentations     # 自由格式的小写过滤 slug
  example_prompt: "Create a magazine-style web deck from my content."
  design_system:
    requires: true            # 组合完整的激活 design-system 上下文
  craft:
    requires: [typography, color, anti-ai-slop]
  critique:
    policy: opt-in            # required | opt-in | opt-out

所有 od: 字段都是可选的,缺失时回退到合理默认值;skills 目录 下的每个 skill 文件夹(例如 skills/deck-guizang-editorial/skills/faq-page/skills/mobile-onboarding 对应的模板类 skill)都可以按同一套约定阅读和编写。

为什么文件本身就是注册表

当 daemon 启动时,它会扫描 skills/,并把每一个含有 SKILL.md 的文件夹登记进来。没有插件清单、没有版本字段、没有上传步骤、没有审核队列、没有构建。只有这个文件,而这个文件就是事实源。丢进一个新文件夹,重启 daemon,这个 skill 就出现在选择器里;删掉它,它就没了——不会留下一条指向已不存在代码的孤儿注册项。

内置 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 都能读、任何人类都能审查的契约。开箱内置的 system 包括 Linear、Vercel、Stripe、Apple、Cursor、Figma 的可移植版本,以及一长串编辑风与品牌 system。

仓库里一个真实 system 包的结构

从源码结构看,当前仓库中每个 system 已经长成一套完整但仍是纯文本/纯 JSON 的包。以 Linear 的 design system 为例,目录包含:

  • DESIGN.md——主契约。开篇即声明"Design System Inspired by Linear",随后分章节描述视觉主题与氛围(dark-mode-native 的 #08090a 画布、Inter Variable 的 cv01/ss03 特性、标志性的 510 字重、72px 处 -1.584px 的负字距等)与完整的颜色角色表;
  • manifest.json——机读清单,声明 schemaVersion: "od-design-system-project/v1"、包 id、分类,以及 files 字段把 DESIGN.md、tokens.css、design-tokens.json、tailwind-v4.css、components.html 各自指出来,schema 定义在 design-systems/_schema/ 中;
  • USAGE.mdtokens.cssdesign-tokens.jsontailwind-v4.csscomponents.html 及其 components.manifest.json——分别承担用法说明、CSS 变量、JSON token、Tailwind v4 主题与组件参考。

default system 是未指定品牌时的回退包,结构完全一致。这印证了原文的论断:system 是契约加参考资产,而不是组件库——components.html 是供 agent 模式匹配的参考,而非需要实例化的二进制组件。

混搭、fork、拥有

因为一个 system 不过是文本,你可以 fork 一个并就地编辑、交付一个变体,或者用大约 30 分钟的专注工作从头写一个自己的。你甚至可以在项目进行中混搭多个 system——排版取自 Linear、配色逻辑取自 Vercel、版式取自一份内部规范——因为没有任何东西被锁进专有的二进制里。skills/design-systems/ 两个文件夹的拆分是刻意的:能力与审美是正交的,所以任何 skill 都能在任何 system 下运行,任何 system 也都能驱动任何 skill。

Adapter:agent 的基本单位

skill 和 system 是惰性的文本。adapter 则是把它们连接到真正干活的 agent 的那一小段代码。一个 adapter 懂得如何:

  • 检测该 agent 是否已安装在用户的 $PATH
  • 用该 agent 开启一个会话
  • 把一次 skill 调用喂进去
  • 把输出收集回来

daemon 会自动检测哪些 agent 已存在,并在首次启动时以下拉菜单的形式提供它们——你什么都不用配置,只会看到你已经拥有的那些 agent。

源码级:RuntimeAgentDef 是数据规范,不是类

结合 Agent Adapters 设计文档 与源码,adapter 层的实现比"80 行 TypeScript"还要更刻意地小。从源码结构看,adapter 不是一个实现了 agent 循环的类,而是一个纯数据对象——每个 CLI 对应一个 RuntimeAgentDef 对象字面量,声明"如何与这个 CLI 对话":探测哪个二进制(bin / fallbackBins)、如何构造版本探测参数(versionArgs)、如何为单轮构造 argv(buildArgs)、流式输出走哪种格式(streamFormat,如 claude-stream-jsonacp-json-rpcplain)、prompt 走 stdin 还是文件,等等。完整的类型定义在 runtimes/types.ts

每个字段都是数据或纯参数构造函数——没有 run()、没有 cancel()、没有子类。检测、启动、调用、流解析全部由通用引擎驱动这些声明完成。关键代码的分布:

  • 每个 CLI 一个 def 文件runtimes/defs/ 下的 claude.tscodex.tscursor-agent.tsdevin.tshermes.tsqwen.ts 等,每个导出一个对象字面量;
  • 注册表是一个 id 唯一的数组runtimes/registry.ts 把所有 def 收集进 SHIPPED_AGENT_DEFS,启动时的循环会在任何重复 id 上直接抛错,AGENT_DEFS 再追加用户自定义的本地 profile。

这意味着新增一个 CLI 是单文件改动:丢一个 runtimes/defs/<cli>.ts 进目录、在 registry 数组里加一行,引擎就能探测、启动、调用并流式解析它——没有引擎编辑、没有新类、没有方法覆写。只有当出现全新的 wire 格式时,才需要额外加一个 *-stream.ts 解析器。内置的 27 个 def 覆盖了 Claude Code、Codex、Cursor Agent、Copilot、OpenCode、Devin、Hermes、Kimi、Kiro、Qwen、DeepSeek、DeepSeek Harness、Aider 等本地 CLI runtime。

如果你只是想新增一个 adapter,"没有要学的 SDK、没有要申请的权限、没有要发布到的中心注册表"——你笔记本上早已信任的那个 agent 就成了引擎,OpenDesign 从不取代它。

daemon:把一切系在一起的循环

daemon 是系统里唯一在运行的进程,是一个用 pnpm tools-dev 启动的 Node 进程(根 package.json 中该脚本指向 workspace 包 @open-design/tools-dev,实现位于 tools/dev/),依次做四件事:

  1. Detect(检测)——启动时扫描 $PATH 查已安装的 agent、扫描 skills/ 查已安装的 skill;
  2. Discover(探询)——打开一个交互式提问表单,为当前 brief 锁定载体、受众、语气、规模和品牌上下文;
  3. Direct(定向)——给出 5 个确定性的视觉方向(OKLch 配色、字体栈、版式 posture 提示),让用户挑一个;
  4. Deliver(交付)——用锁定的 system 调起选中的 skill,让 agent 写到磁盘,并在沙箱化的 iframe 里预览输出。

原文档强调这个循环刻意做小:聪明之处在 skill 里,而不在运行时——daemon 的工作就是扫描文件夹、把一份 brief 路由过这四步,然后让到一边。以当前仓库快照看,daemon 进程(apps/daemon/src/)已经长成一个规模可观的服务端代码库,但"文件是事实源、agent 循环全部委托给用户的 CLI"这一架构承诺没有变——检测、调用、流式解析仍全部由上面描述的通用引擎加数据 def 驱动。

实践中它是什么感受

假设你想为一个新产品功能做一套发布 deck,流程是这样的:

  1. 你在终端里运行 pnpm tools-dev。daemon 在本地端口启动(原文档给出的地址为 localhost:7780)。
  2. 你打开这个 URL。daemon 给你看它找到了哪些 agent(例如 Claude、Cursor、Codex)。
  3. 你从 skill 列表里挑选一个 deck 生成器(如 guizang-ppt 对应的 skill)。
  4. 弹出一个 30 秒的提问表单:受众是谁、语气是什么、品牌上下文是什么。
  5. 你被展示了 5 个视觉方向——不同的配色、字体搭配、版式 posture。你挑一个。
  6. agent 写到磁盘。一个沙箱化的 iframe 显示出结果。你可以导出为 HTML、PDF、PPTX、ZIP 或 Markdown。

顺着这些原语回溯,整件事就一目了然:第 3 步选了一个 skill,第 5 步锁定了一个 system,背后的那个 agent 是通过一个 adapter 接进来的,而 daemon 跑完了这四步循环。输出是真实的,文件是你的——你可以在任何编辑器里改它们,把它们交给一位设计师,或者把它们重新喂回另一个 skill。

为什么用文件,而不是数据库

每一个原语——skill、system、adapter——都是一个装着文本文件的文件夹。没有中心数据库,没有"OpenDesign 账户",没有那种必须一直运转、你的工作才能一直运转的托管服务。

这是一笔刻意的交换。它放弃了做花哨的跨用户分析、跨项目记忆或托管协作的能力,换回来的是:可移植性、长寿、可审查性,以及任何人都能 fork 整个库并交付自己变体的能力。今天写下的一个 SKILL.md,两年后对一个 agent 读起来一模一样,对一个手头没有任何工具的人类也读起来一模一样——而一个被钉死在去年某个 API 上的插件可做不到这一点。

如何在仓库中继续深入

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
903
1.82 K
docsdocs
暂无描述
Markdown
888
5.78 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.51 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.17 K
341