Claude Code artifact-diagramming 技能解析:Artifact 内联 SVG 制图的决策准则与实现机制
本文基于 system_prompts_leaks 仓库中泄露的 Claude Code artifact-diagramming 技能文档(SKILL.md),完整拆解 Claude Code 在生成 Artifact(可发布页面)时如何决定"该不该画一张图"、"画什么才算机制图",以及内联 SVG 在手写场景下的全部工程约束——viewBox 尺寸策略、currentColor 主题适配、箭头 marker 规范、无障碍标注与自包含要求。读完本文,你可以掌握一套可迁移到任意 HTML 输出场景的"机制图"画法,并理解这些约束与 Claude Code Artifact 运行时(CSP、主题系统)之间的底层对应关系。
这个技能在 Claude Code 技能体系中的位置
artifact-diagramming 是 Claude Code 内置技能集(Skills)中专门负责"图怎么画"的一条。技能的 front matter 声明如下:
name: artifact-diagramming
description: Diagramming know-how for Artifacts - when a picture earns its place,
how to draw one that shows the real mechanism, and the inline-SVG mechanics
that keep it legible in both themes.
从系统提示词的技能清单看,它与几个技能构成明确的分工。在 claude-code-fable-5.md 的 Skills 列表中:
artifact-design——"Design guidance and fundamentals for Artifacts",要求写任何 Artifact 前必须加载,负责整体视觉设计;artifact-diagramming——专门管 Artifact 中示意图的画法;dataviz(dataviz/SKILL.md)——管图表(chart/graph/dashboard)的选型、配色与校验。
也就是说,artifact-diagramming 只管"机制示意图"(数据流向、组件关系、状态迁移这类图),不接管图表(图表归 dataviz)也不接管页面整体设计(归 artifact-design)。
加载时机在 claude-code-fable-5.1.md 中有一段值得注意的例外说明:常规 Artifact 一律先加载 artifact-design;但 workshop 技能产出的文档有自己独立的两个"lane"(输出轨道),此时跳过 artifact-design,改为加载 artifact-diagramming 来负责模板页中的示意图。这条提示也解释了本文档中"lane"一词的来源——不同渲染轨道(HTML 页面 vs Markdown 页面)由不同的技能负责指定画图方式。
核心立场:像要长期维护这个决策的工程师那样画图
原文档开篇定调(SKILL.md 第 6 行):
Draw as the engineer who has to live with the decision, not as a decorator.
翻译过来就是:你是要长期为这个决策负责的工程师,不是装饰工。一张图"挣得它的位置"(earns its place)的条件是:它能让一个没有上下文的读者(cold reader)直接看到一段只能从文字里费力拼凑出来的机制——数据往哪里流、哪些组件在互相通信、两个方案之间差在哪里、一个请求经过哪些状态。
并给出一个硬性反证:如果一句话能更快说清楚,就写那句话。这条规则把"画图"从默认动作降格为例外动作,是整份技能的第一原则。
画什么:四条"机制图"准则
1. 画机制,不画名字(Depict the mechanism, not its name)
原文的核心论证是:一个标着 "cache" 的盒子,信息量还不如一段文字。真正有信息量的是——请求穿过缓存的路径、它夹在哪两个存储之间、以及当缓存被移除后消失的那根箭头。
准则要求:画出论证真正依赖的那些部分——正在被跨越的边界(boundary)、正在被新增的一跳(hop)、正在移动的数据——把无关部分全部去掉。这与"系统全景图"式画法相反:不画库存(inventory),只画决策的支点。
2. 比较方案时,画差异,不画两份清单(Comparing options? Draw the difference)
原文给出了"真比较"和"假比较"的判据:
- 真比较:两套架构并排(side by side)、before/after、每个方案各自新增或删除的那一条边(edge)——读者应该能用手指指出"我要在什么之间做选择";
- 假比较(被明确点名否决):每个方案各一个带标签的盒子、与系统之间没有任何连线——这不叫比较,这叫"把方案列表重述了一遍"。
这条规则在实操中可以直接当验收标准用:检查并排的两张图,看它们是否共享同一套系统骨架、差异是否体现在连线上,而不是两张孤立的盒子图。
3. 复杂度与赌注匹配(Match complexity to the stakes)
原文给了两个对称的锚点:
- 一跳(one-hop)问题 → 三盒子的图就够;
- 把写流量改道经过队列的迁移 → 必须画出队列、写者、读者和那根表顺序的箭头(ordering arrow)。
结论是"画到决策真正依赖的粒度为止":既不接受强行极简(forced minimalism),也不接受把整个系统列一遍(inventory of the whole system)。复杂度由"这个决策要赌什么"决定,而不是由作者的手感决定。
4. 给箭头打标签(Label the arrows)
原文的判断标准:
An unlabeled arrow is "related somehow".
无标签箭头只表达" somehow 有关系";而 writes、invalidates、polls every 30s 这种标签本身就是信息。
关于图例(legend),原文给了一条克制原则:只有当同一种编码方式(虚线、颜色、双线)在图中重复出现时,图例才值得存在;否则直接把含义写在标记本身(箭头/连线)上。这是对"每张图都配图例"惯例的反向约束。
内联 SVG 机制:手写 <svg> 的全部约束
适用前提:HTML 轨道才用内联 SVG
原文第 20 行划定了适用边界:
These mechanics apply where the page renders inline SVG natively (HTML pages); a markdown-rendered page draws its diagrams in whatever fence that lane's renderer supports, and the skill that owns the lane says which.
- HTML 页面:直接手写内联
<svg>,本文后续所有机制都适用于这一轨道; - Markdown 渲染页面:图画在该轨道渲染器支持的代码围栏(fence)里,具体用哪个围栏由"拥有该轨道的技能"指定。结合 claude-code-fable-5.md 中 Artifact 运行时的说明可以印证这一点:Artifact 原生渲染 mermaid 图——Markdown 用
```mermaid围栏、HTML 用<pre class="mermaid">块,不依赖任何外部库。
对 HTML 轨道的总要求是:手写内联 <svg>,只用原生形状(rect、circle、line、polyline、path)加 <text>——无库、无运行时、无外部图片。 这一条与 Artifact 的 CSP 约束是互相咬合的:claude-code-fable-5.md 中说明 Artifact 受严格 CSP 管控,外部请求(CDN 脚本、远程字体、远程图片、fetch/XHR)一律被拦截,所以图必须自包含;claude-code-haiku-4.5.md 也特别提醒不要把内容上传到第三方渲染工具(diagram renderers),因为上传即公开。这些运行时约束解释了为什么"无库、无运行时、无外部图片"不是风格偏好,而是硬性前提。
约束一:用 viewBox 定尺寸,交给 CSS 缩放
- 设
viewBox="0 0 W H",尺寸交给 CSS 缩放:max-width: 100%; height: auto; - W 和 H 按内容选,不按预设选——不要套 800×600 这类默认画布;
- 读向与内容对应:横向流(flow)左到右读;分层堆叠(stacked layers)上到下读。
这条的实操含义是:画布宽高比本身就是版式决策的一部分。一条"客户端 → 网关 → 队列 → 消费者"的管道图如果画成接近正方形的 viewBox,视觉读向会立刻失真。
约束二:用 currentColor 做主题适配
- 描边(strokes)、文字、箭头头部一律用
currentColor,让它同时继承浅色与深色主题下的页面前景色; - 全图只保留一个字面颜色(literal hue)给唯一承载语义的元素——被倾向的那个方案、正在讨论的那一跳——并且必须确认这个颜色在深浅两种底色上都能看清。
这条机制与 artifact-design 技能的主题系统直接对应。artifact-design/SKILL.md 规定页面按"三种状态"设计主题:用户显式选择会在根元素打 data-theme="dark" / data-theme="light" 戳,而默认"跟随系统"状态下不打任何戳,此时只有 prefers-color-scheme 能区分深浅。currentColor 方案正是针对这个三态系统的最低成本适配:只要前景色 token 在两个主题下都正确,SVG 里所有走 currentColor 的元素自动跟着换;而那唯一一个字面色则要求作者自己为"两种底色都读得清"负责——这恰好是 artifact-design 中"给第二个主题和第一个同等的用心"这条设计准则在图上的投影。
约束三:箭头头部用 marker 或 polygon,永不用图片
两种合法做法:
<defs>里定义<marker>,用marker-end="url(#arrow)"引用——注意 id 是**片段内(fragment-internal)**的,即指向本 SVG 内部的锚点;- 在线条末端直接放一个小
<polygon>。
底线是"never an image"——不引用任何图片资源,与"无外部图片"的总约束一致。一个符合本技能全部约束的最小片段大致长这样(依规则手工构造的示例,非仓库文件):
<figure>
<svg viewBox="0 0 560 120" role="img"
aria-label="请求经过网关后先查缓存,未命中再落到主库;去掉缓存后箭头直连主库"
style="max-width: 100%; height: auto;">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor"/>
</marker>
</defs>
<rect x="10" y="40" width="110" height="40" rx="4"
fill="none" stroke="currentColor"/>
<text x="65" y="65" text-anchor="middle" font-size="12">Gateway</text>
<rect x="225" y="40" width="110" height="40" rx="4"
fill="none" stroke="#c05621"/>
<text x="280" y="65" text-anchor="middle" font-size="12">Cache</text>
<rect x="440" y="40" width="110" height="40" rx="4"
fill="none" stroke="currentColor"/>
<text x="495" y="65" text-anchor="middle" font-size="12">Primary</text>
<line x1="120" y1="60" x2="220" y2="60" stroke="currentColor"
stroke-width="1.5" marker-end="url(#arrow)"/>
<line x1="335" y1="60" x2="435" y2="60" stroke="currentColor"
stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="170" y="50" text-anchor="middle" font-size="11">reads</text>
<text x="385" y="50" text-anchor="middle" font-size="11">falls through</text>
</svg>
<figcaption>缓存命中路径:Gateway 先查 Cache,未命中再写穿到主库;Cache 框用强调色标出当前讨论的对象。</figcaption>
</figure>
对照技能逐条核对:viewBox 按内容定宽(宽大于高,横向流);除 Cache 框外全部走 currentColor,唯一点缀色标出"讨论焦点";箭头头是 defs 内 marker、marker-end="url(#arrow)" 引用片段内 id;文字 11–12px 且短;标签(reads、falls through)直接写在箭头上而不是图例里;整段包在 <figure> 里,figcaption 陈述图的内容,role="img" + aria-label 带同一断言;无 <script>/<style>/<foreignObject>,无外部资源。
约束四:保持文字可读
- 按绘制尺度算,字号大约 11–13px;
- 用
text-anchor做对齐(middle/start/end); - 短标签:一个词到三个词;
- 解释性的句子放图下方的 caption 里,不放进图内。
这条把"图内信息"与"图外解释"的职责切开了:图内只承载命名与动作,叙事全部交给 <figcaption>。
约束五:对齐到网格
Shared baselines and even gaps are most of what makes a hand diagram read as deliberate; eyeballed offsets read as noise.
共享基线 + 等距间隙,是一幅手写图"看起来是刻意的"的最大来源;凭眼睛估的偏移只会读起来像噪声。实操上意味着:盒子的 y 坐标、字号、线宽都从同一小组里取值(示例里所有盒子同 y=40、同高 40,线宽统一 1.5px),而不是每个元素各偏几像素。
约束六:一图一断言(One figure, one claim)
这是把前面所有约束收拢成"文档契约"的一条:
<svg>必须包在<figure>里;<figcaption>陈述这张图展示了什么——不是"架构总览"这类空话,而是图的具体断言;- 给
<svg>加role="img",aria-label携带同一个断言,服务于看不到图(读屏)的读者。
"一图一断言"同时是内容原则(一张图只证明一件事,对应"画什么"一节里只画决策支点)和无障碍原则(figcaption 与 aria-label 内容一致,视觉读者与非视觉读者拿到的是同一个事实)。
约束七:保持自包含(Stay self-contained)
- SVG 内禁止
<script>、<style>、<foreignObject>; - 渐变(gradients)、图案(patterns)、
<use>只能引用同一片段内的 id(href="#id")——不允许跨片段或跨文档引用; - 最后一条是风格自检:"长串装饰性的 path 数据是这张图该用真正的图形工具的信号——简化,别硬画"。
这条约束呼应了两个相邻技能。artifact-design 在"Build cleanly"一节明确:生成式或装饰性图形应走 Canvas 或 WebGL,而不是手写长 SVG path(artifact-design/SKILL.md);design 技能对图标的要求则是"永不使用 emoji 或 dingbat 字符,画内联 SVG(描边式、16/20/24px 网格、风格统一)以便缩放与改色"(design/SKILL.md)。三者合起来构成 Claude Code 的图形输出谱系:数据图走 dataviz 的图表规范,机制图走 artifact-diagramming 的手写内联 SVG,装饰图形交给 Canvas/WebGL,图标用网格化描边 SVG——artifact-diagramming 恰好覆盖中间"手写 SVG"那一格,它的自包含规则正是 Artifact CSP 环境对这一格的硬约束。
Markdown 轨道:围栏(fence)替代手写 SVG
技能的"Inline SVG mechanics"一节开头就声明:这些机制只适用于原生渲染内联 SVG 的页面(HTML 页面)。Markdown 渲染页面的示意图"画在该轨道渲染器支持的围栏里,由拥有该轨道的技能指定具体围栏"。
从仓库中 Artifact 运行时的描述可以还原出这条 lane 的实际形态:Artifact 原生渲染 mermaid——Markdown 页面用 ```mermaid 围栏,HTML 页面用 <pre class="mermaid"> 块,全程无外部库(见 claude-code-fable-5.md)。这意味着:
| 轨道 | 画图手段 | 主题/尺寸 | 适用判断 |
|---|---|---|---|
| HTML 页面 | 手写内联 <svg>(原生形状 + <text>) |
viewBox + CSS 缩放,currentColor 跟主题 |
需要精确控制布局、强调色、标签位置时 |
| Markdown 页面 | 该 lane 渲染器支持的围栏(运行时原生支持 mermaid) | 由渲染器托管 | 快速表达结构关系时 |
两条轨道共同的底线是"无外部图片、无外部资源",差异只在于 HTML 轨道把主题适配与无障碍标注的责任压给作者本人(currentColor、role="img"、aria-label),而围栏轨道把这些交给渲染器。
实操自检清单
综合全文,产出一张符合该技能的 Artifact 示意图前,可以逐条过一遍:
- 该不该画:一句话能说清吗?能,就写句子。(技能第一条)
- 画的是机制不是名字:图里有没有"论证的支点"——被跨越的边界、新增/移除的那条边、移动的数据?无关组件是否都删了?
- 比较图是不是真比较:读者能否指出两方案共享的骨架与各自的差异连线?还是只是两个孤立盒子?
- 复杂度对不对:三盒子够不够?还是必须画出队列/写者/读者与顺序箭头?
- 箭头都有标签:每根无标签的箭头是否都值得存在?图例是否只在同一编码重复时才出现?
- viewBox 按内容定,宽幅对应横向流、纵向对应分层堆叠。
currentColor全覆盖 + 唯一强调色:强调色在深浅两种底色下都读得清吗?- 箭头头是 marker 或 polygon,id 引用在本 SVG 片段内。
- 文字 11–13px、一词到三词,解释句挪进 caption。
- 基线共享、间隙均等,没有凭眼睛估的偏移。
<figure>+<figcaption>+role="img"+aria-label,caption 与 aria-label 陈述同一断言。- 无
<script>/<style>/<foreignObject>,无外部资源;path 数据一长就回头简化。
参考与延伸阅读
- 本文主体文档:Anthropic/claude-code/skills/artifact-diagramming/SKILL.md
- 技能清单与加载规则:claude-code-fable-5.md、claude-code-fable-5.1.md
- 主题三态系统与自包含/CSP 约束:artifact-design/SKILL.md、claude-code-fable-5.md、claude-code-haiku-4.5.md
- 相邻图形技能(分工对照):dataviz/SKILL.md、design/SKILL.md
需要说明的适用前提:artifact-diagramming 是 Claude Code 面向 Artifact 发布场景的技能文档,其"自包含、无运行时"等约束与 Artifact 的 CSP 运行时强绑定;在普通网页或文档站中使用这些内联 SVG 技巧时,"无外部资源"一条可以从硬性约束降级为最佳实践,而 viewBox 尺寸策略、currentColor 主题化、箭头标签、网格对齐与"一图一断言"这几条则不依赖任何特定运行时,可以直接复用。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00