字节笔记本
2026年6月7日
Mermaid + Code Agent 的绝配:beautiful-mermaid 让架构图走进 agent 工作流
有一件事在悄悄发生:用 Claude Code 写代码的人,产出的文档量是以前的好几倍。
以前文档是负担,没人愿意写,写了也没人维护。现在让 Claude Code 顺手把架构说明、接口时序、模块关系一起生成,几乎零边际成本。文档多了,架构图的需求自然跟着来。
问题是,架构图一直是个麻烦事。打开 Visio 或者 draw.io,拖半小时方块和箭头,改一个字段名又要重新拖。这种工具和 AI agent 的工作流完全不兼容,一个靠鼠标,一个靠文本。
Mermaid 是这个矛盾的解法。它是一套纯文本语法,用来描述图表结构,然后由工具渲染成图。你写的不是图,是图的描述。
graph LR
用户 --> 登录页
登录页 -->|验证成功| 首页
登录页 -->|验证失败| 错误提示这段文字渲染出来就是一张流程图。改需求时改文字,不动鼠标。放进 Git 仓库做版本管理,和代码一起演进。
Mermaid 支持流程图、时序图、状态机、类图、ER 图等十几种类型,GitHub、GitLab、Notion、Obsidian 都原生渲染。在 Markdown 里写一个 mermaid 代码块,平台自动帮你画出来。
但最关键的一点是:Mermaid 是文本,AI 最擅长生成的就是文本。
以前 Mermaid 的瓶颈是"写起来麻烦",现在 Claude Code 三秒就能给你一段语法正确、结构清晰的 Mermaid 代码。生成这件事彻底不是问题了。
新的瓶颈在渲染这一侧。
Claude Code 生成 Mermaid 图从来不是问题
让它画一个 API 调用链路,三秒给你一段 sequenceDiagram。让它把数据库表关系画出来,erDiagram 语法干净、缩进整齐。这件事它做得很好,因为 Mermaid 本质上是结构化文本,而 LLM 最擅长的就是生成结构化文本。
问题出在下一步。
那段代码生成完之后,你拿它怎么办?粘进 Markdown 等 GitHub 渲染?本地跑 mmdc CLI 导出 PNG?还是扔进 Mermaid 官网的在线编辑器?
这三条路各有各的麻烦。GitHub 渲染的默认主题停留在 2017 年的审美;mmdc 需要单独装 Puppeteer 和 Chromium,光这一步就够喝一壶的;在线编辑器每次手动粘贴,在 Claude Code 这个全自动的工作流里是典型的断点。
断点意味着切换上下文、切换工具、切换窗口。对于"让 AI 帮我把文档写完"的场景,这是不可接受的摩擦。
然后我发现了 beautiful-mermaid。
它是什么
beautiful-mermaid 是 Craft 团队开源的 Mermaid 渲染库,目前 GitHub star 接近 10k。它解决的不是"Mermaid 语法"问题,而是"Mermaid 渲染"问题。
三个核心设计决策,每一个都是冲着 agent 场景去的:
同步渲染。 调用 renderMermaidSVG() 直接拿到 SVG 字符串,没有 Promise,没有 await。这件事看起来不起眼,但对于 agent 工具链来说是关键区别,后面展开说。
零 DOM 依赖。 纯 TypeScript,不依赖浏览器环境,Node 里直接跑。Claude Code 的 bash 工具可以直接执行,不需要起任何浏览器进程。
ASCII 终端输出。 不想开浏览器?renderMermaidASCII() 直接输出 Unicode 字符画,在终端里就能看架构图。
三个场景,从简到复杂
场景一:在 Node 脚本里生成 SVG 文件
Claude Code 生成完 Mermaid 代码之后,让它顺手再写一段渲染脚本并执行:
npm install beautiful-mermaid// render.mjs
import { renderMermaidSVG, THEMES } from 'beautiful-mermaid'
import { writeFileSync } from 'fs'
const diagram = `
sequenceDiagram
Client->>API: POST /orders
API->>DB: INSERT order
DB-->>API: order_id
API-->>Client: 201 Created
`
const svg = renderMermaidSVG(diagram, THEMES['tokyo-night'])
writeFileSync('arch.svg', svg)node render.mjs
# arch.svg 生成完毕整个过程 Claude Code 一步到位:写 Mermaid 代码、写渲染脚本、执行脚本、SVG 落盘。你不需要切任何窗口。
场景二:终端里直接看 ASCII 图
纯终端工作流,不想碰浏览器:
import { renderMermaidASCII } from 'beautiful-mermaid'
const result = renderMermaidASCII(`graph LR
Auth-->Gateway
Gateway-->UserService
Gateway-->OrderService`)
console.log(result)终端里直接打印出来:
┌──────┐ ┌─────────┐ ┌─────────────┐
│ Auth │────►│ Gateway │────►│ UserService │
└──────┘ └─────────┘ └─────────────┘
│
└─────────►┌──────────────┐
│ OrderService │
└──────────────┘Claude Code 在 bash 工具里直接打印给你看,不需要浏览器,不需要额外安装任何东西。
终端不支持 Unicode 或者需要走管道,加一个参数降级:
renderMermaidASCII(diagram, { useAscii: true })
// ─ 变 -, ► 变 >, ┌ 变 + ... 纯 ASCII,最大兼容性场景三:React 前端嵌入实时渲染
做文档站、内部工具,或者任何需要展示架构图的 SaaS 产品,同步渲染天然适配 useMemo():
import { renderMermaidSVG } from 'beautiful-mermaid'
function MermaidDiagram({ code }) {
const { svg, error } = React.useMemo(() => {
try {
return {
svg: renderMermaidSVG(code, {
bg: 'var(--background)',
fg: 'var(--foreground)',
transparent: true,
}),
error: null,
}
} catch (err) {
return { svg: null, error: err instanceof Error ? err : new Error(String(err)) }
}
}, [code])
if (error) return <pre style={{ color: 'red' }}>{error.message}</pre>
return <div dangerouslySetInnerHTML={{ __html: svg }} />
}注意 var(--background) 这里。SVG 内部用 CSS 自定义属性存颜色,和你的应用共享同一套 CSS 变量。用户切暗色模式,图表跟着变,不需要重新渲染,不需要写任何额外逻辑。
为什么同步渲染对 agent 场景这么重要
mermaid.js 官方库是异步的。render() 返回 Promise,因为它内部要操作 DOM。在浏览器里这很合理,但在 agent 工具链里会带来额外复杂度:异步意味着中间态,中间态意味着 agent 需要处理等待和错误恢复。
beautiful-mermaid 通过 FakeWorker 绕过了 ELK.js 布局引擎的异步调用,让整个渲染变成同步的。对 Claude Code 而言,执行一个同步的 Node 脚本就是跑完就跑完了,输出就在那里,没有任何中间状态需要协调。
mmdc CLI 依赖 Puppeteer 启动一个 Headless Chrome 来渲染,这是它慢、重、难装的根本原因。beautiful-mermaid 完全绕开了这条路。
主题系统:两个颜色推导一张图
主题系统是这个库设计得最聪明的地方。
核心思路叫"两色推导":给定背景色 bg 和前景色 fg,用 CSS color-mix() 自动推导出所有中间色。节点填充、连线颜色、标签、箭头,全部从这两个颜色派生,不需要你手动配一套完整的 token。
// 最简的自定义主题,两个颜色就够
const svg = renderMermaidSVG(diagram, {
bg: '#0f172a',
fg: '#e2e8f0',
})需要精确控制某个颜色?逐项覆盖:
const svg = renderMermaidSVG(diagram, {
bg: '#0f172a',
fg: '#e2e8f0',
accent: '#7c3aed', // 箭头和高亮
line: '#475569', // 连线
muted: '#64748b', // 次要文字
})15 套内置主题直接用名字引用:
import { THEMES } from 'beautiful-mermaid'
// Tokyo Night, Catppuccin Mocha, Nord, Dracula,
// GitHub Light/Dark, Solarized, One Dark...
const svg = renderMermaidSVG(diagram, THEMES['catppuccin-mocha'])在 Claude Code 里直接用
beautiful-mermaid 仓库里自带一个 .agents/skills/ 目录,里面就是现成的 Skill 定义文件。把这个目录克隆下来,放进 Claude Code 的 Skill 路径,它就直接具备生成并渲染 Mermaid 图的能力:
git clone https://github.com/lukilabs/beautiful-mermaid.git
cp -r beautiful-mermaid/.agents/skills/. ~/.claude/skills/重启 Claude Code 之后,直接在对话里说"画一个 sequenceDiagram,描述用户登录流程,渲染成 SVG 保存到本地",Claude Code 自动识别 Skill,调用 beautiful-mermaid 渲染,SVG 落盘,全程不需要你解释用哪个库、怎么写脚本。
支持哪些图表类型
目前六种,覆盖日常开发文档里最常见的需求:
- Flowchart 流程图,支持 TD/LR/BT/RL 四个方向
- Sequence Diagram 时序图
- State Diagram 状态机图
- Class Diagram 类图
- ER Diagram 实体关系图
- XY Chart 柱状图、折线图、组合图
和其他方案的横向对比
| mermaid.js 原生 | mmdc CLI | beautiful-mermaid | |
|---|---|---|---|
| 环境要求 | 浏览器/DOM | Node + Chromium | Node 即可 |
| 渲染方式 | 异步 | 异步(子进程) | 同步 |
| 终端 ASCII 输出 | 无 | 无 | 支持 |
| 自定义主题 | CSS 类,繁琐 | 有限 | CSS 变量,简单 |
| 内置主题数 | 少 | 少 | 15 套 |
| agent 场景适配 | 低 | 中 | 高 |
mmdc 的优势是能导出 PNG/PDF,这个 beautiful-mermaid 目前做不到。如果你的需求是生成图片文件交付给别人,mmdc 还是要用。如果你的需求是在工具链里处理架构图,beautiful-mermaid 更合适。
最后
Claude Code 生成 Mermaid 代码这件事早就不是瓶颈了。瓶颈一直在渲染这一侧,而且大多数人选择了忍受而不是解决。
beautiful-mermaid 的零 DOM 依赖、同步渲染、ASCII 输出三个特性加在一起,才是它真正契合 agent 工作流的原因。这些不是顺手加的功能,Craft 团队本来就是为了自己的 AI 编程产品才做的这个库,agent 场景是第一优先级。