"Inline SVG gives the agent a real pen. Ask for the figures for a post or a flowchart of a process and get vector art you can tweak by hand or paste straight into the final document."
When to use
| User says | Which paradigm | Template |
|---|---|---|
| "draw our deploy pipeline" | Flowchart | ../../templates/flowchart.html |
| "what does the state machine look like" | Same as above | Same as above |
| "how does the request flow / data flow go" | Same as above (or refer to 01-explore 's plan data flow) |
— |
| "add a few images to this blog post" | SVG illustration set | Build your own (see below) |
Do not use mermaid / d3 / excalidraw. Write inline SVG directly — more controllable, zero dependencies, hand-editable.
Paradigm 5.1 · SVG illustration set
Spatial shape: all the diagrams a document needs are drawn on one page. Each <svg> is a separate block — readersright-click-inspect-copy outerHTML to get one image.
HTML skeleton:
<article class="figure">
<h3>Figure 1 · Token bucket</h3>
<svg viewBox="0 0 240 160" width="240" height="160">
<!-- 用基本图元:rect, circle, path, text -->
<rect x="60" y="40" width="120" height="80" rx="8"
fill="var(--ivory)" stroke="var(--slate)" stroke-width="2"/>
<!-- tokens as small circles -->
<circle cx="80" cy="100" r="6" fill="var(--clay)"/>
<circle cx="100" cy="100" r="6" fill="var(--clay)"/>
<circle cx="120" cy="100" r="6" fill="var(--clay)"/>
<!-- inflow -->
<path d="M 120 10 L 120 38" stroke="var(--success)" fill="none"
stroke-width="2" marker-end="url(#arr-down)"/>
<text x="130" y="25" font-size="11">refill rate/sec</text>
</svg>
<p class="caption">A bucket holds at most <code>burst</code> tokens; refills at <code>rate</code>/sec.</p>
</article>
<article class="figure">
<h3>Figure 2 · LRU cache eviction</h3>
<svg viewBox="0 0 320 100">...</svg>
<p class="caption">...</p>
</article>
Manual SVG coordinate calculation(don't let the LLM guess numbers):
- viewBox uses evenly divisible values:
0 0 240 160、0 0 800 400 - nodes aligned to a 20px grid
- text centered:
text-anchor="middle" dominant-baseline="middle" - colors use
var(--clay)and other baseline variables (if the SVG is not on the same page as base.css, change to hex)
No standalone template (varies by diagram).
Paradigm 5.2 · Flowchart
Spatial shape: nodes (boxes) + edges (arrows) + state colors (pass/fail) + nodes clickable to expand "what this step runs".
Typical scenarios: deploy pipeline, state machine, decision tree.
HTML skeleton:
<svg viewBox="0 0 800 400" class="flowchart">
<defs>
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5"
markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor"/>
</marker>
</defs>
<!-- 节点 -->
<g class="node process" data-detail="ci-detail" tabindex="0">
<rect x="20" y="40" width="140" height="60" rx="8"/>
<text x="90" y="68" text-anchor="middle">CI · lint+typecheck</text>
<text x="90" y="86" text-anchor="middle" class="sub">~2 min · ci.yml</text>
</g>
<g class="node decision">
<polygon points="240,40 320,70 240,100 160,70" />
<text x="240" y="74" text-anchor="middle">tests pass?</text>
</g>
<g class="node terminal success">
<rect x="500" y="40" width="140" height="60" rx="30"/>
<text x="570" y="74" text-anchor="middle">✓ Deploy complete</text>
</g>
<!-- 边:成功路径(实线) -->
<path d="M 160 70 L 200 70" class="edge success" marker-end="url(#arr)"/>
<path d="M 320 70 L 500 70" class="edge success" marker-end="url(#arr)"/>
<!-- 边:失败路径(虚线) -->
<path d="M 240 100 L 240 200 L 500 200" class="edge fail"
stroke-dasharray="6 4" marker-end="url(#arr)"/>
<!-- 图例 -->
<g class="legend" transform="translate(20, 360)">
<text font-size="11" fill="var(--gray-700)">Solid = pass · Dashed = fail</text>
</g>
</svg>
<!-- 节点详情面板(点击节点弹出) -->
<aside id="ci-detail" hidden>
<h4>CI · lint + typecheck</h4>
<p>~2 min · <code>.github/workflows/ci.yml</code>. Runs <code>eslint</code> + <code>tsc --noEmit</code>.</p>
</aside>
Key CSS:
.flowchart .node rect, .flowchart .node polygon {
fill: var(--white); stroke: var(--gray-300); stroke-width: 1.5;
}
.flowchart .node.terminal.success rect { fill: rgba(120,140,93,0.15); stroke: var(--success); }
.flowchart .node text { font-size: 12px; font-family: var(--font-sans); fill: var(--slate); }
.flowchart .node text.sub { font-size: 10px; fill: var(--gray-500); }
.flowchart .node[tabindex] { cursor: pointer; }
.flowchart .node:focus rect { stroke: var(--clay); stroke-width: 2; outline: none; }
.flowchart .edge { fill: none; stroke: var(--slate); stroke-width: 1.5; }
.flowchart .edge.fail { stroke: var(--danger); }
Key JS(node click expands details):
document.querySelectorAll('.node[data-detail]').forEach(n => {
n.onclick = () => {
const id = n.dataset.detail;
document.querySelectorAll('aside[id]').forEach(a => a.hidden = a.id !== id);
};
});
Ready-to-use template:../../templates/flowchart.html — an 11-node deploy pipeline skeleton, including three node shapes (process / decision / terminal), dual paths for success (solid line) / fail (dashed line), keyboard-accessible click-to-expand detail panel for nodes, and embedded node detail JSON.How to modify: replace the SVG node transform coordinates and text, adjust the path d routing, and replace the <script type="application/json"> detail data with your pipeline content.
Common principles
- Always use inline SVG, do not link external libs——agents should know how to use
<rect><path><text> - Failure paths must be visually distinguished——usually with
stroke-dasharray="6 4"+--dangercolor - A legend must be shown——if readers can't understand the diagram at first glance they give up
- Clickable nodes are a luxury but useful——users can check "what this step is doing"
- Node shapes have semantics: rectangle = process, diamond = decision, rounded capsule = terminal, circle = state