Skip to content
←返回开源项目

OPEN SOURCE DEEP DIVE

AgentSkillDiagramDesignSVG

Diagram Design:给 agent 用的编辑级图表设计 skill

MIT 开源的 agent skill,把 Claude Code/Codex/Factory Droid/Pi 变成图表设计工具:44 种视觉类型、211 个自包含 HTML 示例、语义模式与版式正交的结构,首次运行强制校验品牌 token 以免默认皮肤污染品牌站,渲染 lint 以像素 diff 抓 SVG 被裁。

cathrynlavery/diagram-design45kHTMLMIT5 min read

一句话定位

diagram-design 是一个给 coding agent 用的图表设计 skill——把它装进 Claude Code、Codex、Factory Droid 或 Pi,agent 就会产出自包含的 HTML + 内联 SVG 图表,而不是那种「一堆圆角灰盒子加连线」的东西。它自述为「你那位设计师不会讨厌的编辑级图表」,目前在 GitHub 上 44,982 星 / 2,889 fork,MIT 许可。它的产品定位就是一句话:把「让 agent 画图」这件事从「能跑」推到「能直接放进官网」。

数据面

项值
仓库cathrynlavery/diagram-design(MIT,HTML 主语言)
Stars / Forks / Watchers44,982 / 2,889 / 128
建仓 / 最后提交2026-04-16 / 2026-10-08(仍在活跃更新)
视觉类型44 种(references/type-*.md 恰好 44 个文件,逐类型一份参考文档)
预置示例assets/ 下 211 个 HTML,每种类型三档静态变体(minimal light / minimal dark / full-editorial)
参考文档references/ 共 62 份:44 份类型文档 + 语义模式 + 风格指南 + 导入导出 + 原语规范 + 布局预算等
脚本scripts/ 下 174 个文件,含皮肤 lint、渲染 lint、缩略图生成、插件打包等
支持的 agent 宿主Claude Code(.claude-plugin)、Codex(.codex-plugin)、Factory Droid(.factory-plugin)、Pi,以及任何兼容 Agent Skills 的宿主

它到底解决什么问题

作者 Cathryn Lavery 的动机写得很直白。她在 littlemight.com 写文章、做 BestSelf.co,每次需要一张架构图或流程图,就去问 Claude,拿回来的是一张千篇一律的圆角盒子图,和站点的其余视觉完全不搭。她的选择只有两个:跟 Figma 死磕半小时,或者干脆不画图。

于是有了这个 skill。README 里有一句话把它整个设计哲学说完了:「最高质量的动作通常是做删除。」展开成四条硬规则:

  • 每个节点代表一个独立的想法——总是同进同出的两个节点应该合并成一个;
  • 每条连线都要承载信息——如果关系从布局里已经看得出来,就把线删掉;
  • 珊瑚色(accent)是编辑性的,不是标记——每张图最多 1–2 个焦点节点,用在 5 个节点上就把信号抹平了;
  • 目标密度 4/10——技术上都齐了,但不至于需要一份讲解。超过 9 个节点,通常应该拆成两张图。

还有一句写在 README 顶部的话值得单独拎出来:「不用 Figma,不用泛泛的圆角盒子,不用花 30 分钟挑颜色。」这三句「不用」精确地圈出了它的边界——它不替代设计工具,它替代的是「让一个通用 LLM 在没有品牌上下文的情况下画出能看的东西」这件事。

核心设计一:语义模式与视觉类型正交

这是整个项目最有价值的架构决定,README 里的说法是:语义模式描述系统「做什么」,44 种视觉类型描述信息「怎么排」。

为什么必须拆开?因为行为、状态、执行点、风险这四类信息才是图表要讲的东西,而它们跟「用泳道还是用分层」是正交的。举几个真实的路由例子:

读者要理解什么语义模式最近的视觉类型
多个入口争抢有限的服务容量Fan-in queue / bottleneckData flow
两条规则链的判定差异与首次分叉点Paired policy-evaluation tracesFlowchart
哪些路径穿过信任边界、哪些被禁止Secure paved roadArchitecture
控制措施分别在哪个执行面上生效Governance / control catalogLayer stack
防御层如何逐级降险、残余风险如何传播Compensating security layersLayer stack
系统如何分解为可独立引用的子块并追溯到实现Traceable block decompositionTree
一个主体在阶段间推进、等待、重试、取消Lifecycle phase mapState Machine

这个拆分解决的是一个很实际的问题:它让「扩展行为」不再需要新增类型。一个队列、一个策略链、一条信任边界,都能借用最接近的既有版式来画,而不必为每种新行为往类型表里加一项。README 里把它写成一句设计意图:「语义模式独立于版式描述行为,所以队列、策略追踪或信任边界可以使用最接近的既有类型,而无需扩展类型数量。」

语义模式本身的写法也很严谨。每个模式都定义了五件事:选择触发条件(什么情况下该用它)、必需的原语(画出来必须包含什么)、复杂度预算(硬上限,比如 fan-in queue 是「≤5 个源、≤5 个队列槽、1 个瓶颈、2 种结局、≤9 个主节点」)、反模式(明确禁止画法,比如「等宽流水线掩盖了竞争」「箭头在可追溯之前就合并」「容量只用盒子大小暗示」)、以及静态回退方案(动画失效时静态帧要能讲清同一件事)。

「静态回退」这一条是很多同类项目会漏的:既然默认输出是静态 HTML,那么任何依赖动画才能看懂的信息就算设计失败。语义模式文档里明确要求「标签与结局在静态帧里必须完整」。

核心设计二:风格从网站反推,且有强制门禁

references/style-guide.md 被明确标注为「颜色、排版与 token 的唯一真源」——所有类型文档都只说 accent,不写 #eb6c36 这种十六进制值。默认皮肤是一套冷调编辑风配色:白烟纸背景 #f5f5f5、-jet 黑墨色 #2d3142、原子橘强调色 #eb6c36、蓝灰弱化色 #4f5d75,另加银灰 #bfc0c0,正好是作者自己站点的品牌色。

token 是按语义角色定义的,不是按色值——paper、paper-2、ink、ink-strong、muted、soft、rule、rule-solid、accent、accent-tint、link。这个设计带来一条很好用的规则:浅色转深色时,任何 rgba(28,25,23, X) 在深色下变成 rgba(250,247,242, X),透明度不变、RGB 翻转,强调色则轻微提亮偏移以适应深色纸面。

更值得注意的是首次运行的风格门禁。SKILL.md 的第 0 节写着:在新项目里画第一张图之前,必须先确认风格指南是否已定制;如果还是出厂默认值(纸 #f5f5f5、墨 #2d3142、强调 #eb6c36),agent 必须停下来问用户——选项包括给一个网站 URL、给一个已安装的 skill、给本地设计系统目录、直接粘贴 token、保持默认、或载入已保存的 profile。原文的措辞是「不要悄悄把默认皮肤的图表塞进一个品牌化项目里」。

这个「主动停下来问」的设计,比事后换色重要得多——图表一旦嵌进页面就很难整体重做。配套的 references/onboarding.md 负责从网站 URL 反推品牌色,references/profiles.md 负责把定制结果存成具名 profile,下次直接跳过门禁(项目里有 .diagram-design 标记或 profile 头时自动生效)。

核心设计三:导入是「重画」,不是「转换」

这个 skill 也能吃 draw.io、Mermaid、Excalidraw 的源文件,但处理方式在 SKILL.md 里写得很硬:「重画——绝不转换。」来源或渲染器的坐标、颜色、字体、形状怪癖全部丢弃,保留的只是内容:组件、关系、分组、方向。然后它要求输出一份保真度账本——合并了什么、压扁了什么、丢了什么。

还有两条约束值得记:导入受源文件限制,不得为填满版式而虚构组件,也不得静默丢弃组件;以及 「绝不转换」这条规则意味着 Mermaid 的 slop(那种一眼就是自动生成的味道)不会传染进来——因为没有坐标被继承。仓库描述里那句「No Mermaid slop」是字面意义的。

导入前要先设四个旋钮(dial):

旋钮选项默认
格式html · svg · png · html+pnghtml
尺寸doc-inline · doc-wide · slide-16x9 · slide-4x3 · social-og · social-square · print-a4/a3/letter-landscape · fitdoc-inline
细节度faithful(≤24 节点,分区) · balanced(≤12) · simplified(≤7)balanced
受众engineer · mixed · executive——决定用词而非节点数mixed

尺寸预设同时设定 viewBox 和字号阶梯——这是很多同类工具会忽略的一环:同一张图放进文档内联和放进 16:9 幻灯片,字号必须跟着变。规则里还写明 faithful 是唯一可以突破 9 节点预算的档位(超过 24 个必须拆图),但连接线规则永不放松。

核心设计四:lint 分两层,浏览器是唯一裁判

scripts/ 下 174 个文件里,最有工程价值的是两个 lint,它们抓的是完全不同的两类 bug。

lint-skin.py 读 HTML,检查源码层面的问题:内联的十六进制色值(应该走语义 token)、rgb(0,0,0) 纯黑、指向外部 http(s) 的图片引用(违反自包含原则)、以及 <script> 标签(无 JavaScript 是这个项目的基本承诺)。它还有个基线机制——2.0 之前的示例可能合理地不通过,因为它们是在更早的皮肤下建的,可以用 --all --baseline 跳过这些有据可查的历史文件。

lint-render.py 渲染后检查,抓的是源码里看不出来的破损。脚本自己的文档字符串解释了它为什么必须这么做,这段推理本身就很有价值:

Chromium 的 getBoundingClientRect() 在 SVG 子元素上报告的是几何而不是实际绘制——它不含描边宽度、marker 和滤镜溢出(所以一段 40px 的描边溢出到视口外,量出来仍在里面),而且它无视 clip-path、opacity: 0 的祖先和 overflow: visible(所以安全的内容反而量出来在外面)。这两个方向的错误都在 Chromium 里被复现过,所以这里不用任何几何模型。

它改用浏览器作为裁判:按作者写法截一次视口图,再放开 overflow 截第二次,diff 两张图——多出来的墨迹就意味着有绘制被裁掉了。「墨就是墨」,描边、marker、滤镜溢出都算;而 clip-path、不可见内容和本来就可见的内容都不会产生新墨。裁切检测还分多级释放,因为一张图可能在不止一层被裁,每一级释放各自重绘它自己的盒子。

这个「不信任几何 API、只相信像素 diff」的思路,是把「自包含 SVG 会不会在别人环境里被裁掉」这个部署期问题变成 CI 里可复现检查的最好办法。

核心设计五:动效是可选增强,且必须先在静态帧里讲完

2.3 加入了动效,但它被框定得非常严格——references/animation.md 开头第一句就是约束:「动效解释的是一张已经完整的静态图,它永不提供缺失的含义。」只有当用户明确要求、或者动效能实质性澄清顺序/累积/求值/包含/传播这几类关系时才加载这份文档,否则一律用 none 模式交付静态 HTML。

模式只有四种,其中一个关键限制是只有 loop 可以重复播放——队列状态、打字过程、字段取值、策略结论、包含关系、审计条目一律用 reveal 或 step,并且必须播完并停在完整状态。用动效表现顺序是允许的,用动效暗示「还没说完」是不允许的。

「静态优先增强契约」有八条,核心是前三条:① 源码本身是完整的——每个语义节点、标签、连接线、状态、结局在增强之前就已经在 HTML/SVG 里可见,只有 .motion-ready 选择器下的元素可以被隐藏或变形;② 稳定捕获——data-frame="static"、?motion=static、打印、无 JS、独立 SVG 导出这五种路径都必须暴露完整帧并隐藏控件,且不允许在任意延迟后截图;③ 表现归 CSS——出现与位移用 CSS 过渡和关键帧,内联 JS 只允许绑定显式控件、更新步骤/状态属性、排定确定性步骤、更新专用 live-status 区,禁止 fetch、禁止注入标记、禁止测量路径、禁止改动语义标签或取值。

另外几条同样具体:统一时钟用 --motion-fast: 160ms、--motion-step: 480ms、--motion-hold: 720ms、--motion-total ≤ 8000ms,延迟从整数步推导,不许随机、不许弹簧、不许依赖 transition 事件计时;步骤是 1–8 的整数且每步最多进两个元素;控件只作用于最近的 [data-motion-root],ID、计时器、live region 与步骤状态不跨图边界;最后 JavaScript 只有在控件绑定完成且首次渲染成功后才添加 .motion-ready 类——在此之前脚本出错,完整源码依然可见。

这整套条款的共同点是:动效被当成一个可能失效的增强层来设计,而不是当成内容本身。任何一条被违反,图表在打印、截图、无 JS 环境或导出时就会残缺。

核心设计六:原语层与版式纪律

参考文档里除了 44 份类型文档,还有 6 份原语规范,它们是所有类型共用的词汇表。

4px 栅格被规定为强制几何:节点原点、宽高、间距、内边距必须能被 4 整除,并给出允许值表——节点宽高限定在 {80, 96, 112, 120, 128, 140, 144, 160, 180, 200, 240, 320},节点间距 {20, 24, 32, 40, 48},盒内边距 {8, 12, 16},圆角 {4, 6, 8}。同时明确列出了故意不在栅格上的东西:字号阶梯、圆角本身、数据驱动的位置、文本基线、箭头 marker、为了让 1px 描边保持锐利而用的 .5 偏移、描边宽度、不透明度,以及 22×22 的点阵纹理。

这种「哪些必须对齐、哪些必须不对齐」的明确切分,比单纯说一句「对齐网格」有用得多——否则 agent 会把文本基线也吸到网格上,反而把版面弄脏。

复杂度预算是分层收紧的:SKILL.md 里的普适限制(9 个节点、12 条箭头或转移、2 个珊瑚色元素、2 个注释标注)对所有类型生效;类型文档可以更严但不能更松;语义模式自己的预算只能进一步收紧。比如架构 delta 的上限是 8 个独特组件 / 10 条关系 / 8 条账本条目,时序图最多 5 条生命线。

还有两个可选原语值得一提。手绘滤镜是一个 SVG 位移滤镜,让任何 minimal 变体变成手绘「编辑感」而不改布局——文档给出的语法是 feTurbulence fractalNoise baseFrequency 0.02 numOctaves 2 seed 4 接 feDisplacementMap scale 1.5,并注明用于配随笔文章而非技术文档。终端窗口是一套独立皮肤,把任意图表包进假终端窗(三点标题栏、$ 提示符行、全等宽字体),用于开发者工具发布、CLI 产品帖与技术社交卡片;它不继承品牌 token、不参与浅深色翻转,无论宿主站点品牌如何,九个 token 恒定不变。

导出则是纯手动、绝不主动执行(references/export.md 用的是 all-caps):只在你调用 /diagram-design:export-diagram 斜杠命令、或用自然语言明确要求导出 SVG/PNG 时才加载。它支持斜杠命令与自然语言两条入口,两者走同一套流程。

工程规模与活跃度

635 个文件、22MB。skill 本体 30KB 的 SKILL.md、62 份参考文档、44 种类型各自的版式文档、211 个预置示例 HTML(每种类型三档静态变体,可直接浏览器打开,无构建步骤、无 JavaScript、无外部图片依赖)。宿主适配通过四套插件清单完成:.claude-plugin/、.codex-plugin/、.factory-plugin/、.agents/plugins/,另有 scripts/build-openai-plugin-zip.py 处理 OpenAI 侧的打包。

版本节奏很密,README 顶部就挂着几条近期变更:2.0 引入 Loop(带共享记忆中枢的飞轮,虚线是回写路径);2.3 加入语义系统模式与可选的无障碍动效,静态输出仍是默认;2.5.10 又加十种版式语法——Sankey、鱼骨图、Wardley map、看板、用户旅程、部署、依赖图、UML 类图、故事地图、数据库 schema。当前 SKILL.md 的元数据标 version: "2.6"。仓库还有 .maintainer-policy.json、CONTRIBUTING.md(31KB)、SECURITY.md、PRIVACY.md 与 THIRD_PARTY_LICENSES.md,以及 plugin_version_history.py 这类版本一致性检查脚本。

适合谁,不适合谁

适合:写技术博客或文档、需要成批产出「能直接放进页面」的架构图/流程图/时序图的人;希望 agent 产出自包含文件而不是依赖外部图片和 CDN 的人;已经在用 Claude Code / Codex / Factory Droid / Pi 并愿意把品牌 token 一次性配置好的人;以及需要一个有强约束的图表规范去统一团队文档视觉的团队。

不适合:想要自由拖拽编辑的人(它生成静态文件,不提供编辑器);需要实时协作或交互式图表的人(动效是可选的辅助解释,默认输出是静态);追求 3D 或照片级视觉的人(它明确反对阴影、反对拟物、反对 Mermaid 风格);以及不愿意花五分钟配一次品牌 token 的用户——门禁会拦住他们,而这不是 bug,是它刻意的设计。

一句话结论

diagram-design 的真正贡献不是「44 种图表模板」,而是给 agent 装上了一条设计纪律:密度 4/10、强调色最多 1–2 个、无阴影无外链、能减的节点就减。这条纪律之所以能被执行,是因为作者同时提供了语义模式与版式正交的结构(扩展行为不必扩类型)、语义角色的 token 体系(换肤只改一个文件)、强制停下来问的风格门禁(避免默认皮肤污染品牌),以及以像素 diff 为裁判的渲染 lint(自包含 SVG 不会在别人环境里悄悄被裁)。

换句话说,它把「让 LLM 画图」从一件碰运气的事,变成了一条有验收标准的产线。这大概是任何 agent skill 想要达到的更高形态——交付物不只是结果,还有结果为什么该被信任的证据链。

作为亚马逊联盟会员,我们可能从符合条件的购买中获得佣金。