做流程图、架构图、时序图这件事我干了十几年工具从Visio换到ProcessOn、再换到draw.io折腾一圈下来最深的感受是图形化工具把“画图”的门槛降低了却没有把“改图”的痛苦消灭。直到Mermaid这类文本化图表方案出现图形从鼠标拖拽变成了代码描述版本管理和复用才有了真正的突破口。而AI的加入等于把“从需求描述到结构化代码”这最后一道门槛也拆掉了整条链路第一次可以被普通开发完整掌控。这篇内容想聊的就是这样一条链路你用自然语言描述需求AI理解后输出Mermaid代码前端页面拿到这段代码在UI层渲染成真正的图形化图表。也就是标题里的AI → Mermaid → 图形可视化UI。它不是某个特定开源项目的使用教程而是一套可复用的工程思路。低代码平台、报表系统、流程编排、AI应用研发都可以直接参考想提升日常画图效率的朋友也能抄作业。1. 为什么是AI Mermaid组合1.1 传统画图流程的痛点先聊聊没有Mermaid之前我们是怎么活过来的。用Visio或者ProcessOn画一张流程图本身不算难真正难的是改图。需求一变牵一发而动全身所有连线重新拉一遍箭头对齐能把你逼疯。更不用说团队协作每个人用不同颜色的画笔加自己的理解最后合并出来的图比没图还危险。再退一步哪怕不画图用文字描述流程也有很大的歧义问题。“如果订单状态是已支付那么进入发货流程否则返回等待支付”——这句话不同的人理解出来的分支可能差出好几条路径。文字描述自然语言天然就不适合表达严格的结构关系。还有一个隐藏痛点版本管理。图片在Git里基本没法做有意义的内容对比你只能看到“这张图变了”但到底改了哪个分支、哪条边完全靠肉眼比对。对于强调可追溯、可审计的研发团队来说这是一件很头疼的事。1.2 Mermaid把图形变成了文本Mermaid对整个问题的改变本质上只有一句话把图形变成了文本。流程图、时序图、甘特图、状态图全部用类似代码的声明式语法描述。节点、连线、分组、方向都是可以“读”的字符而不是鼠标拖出来的像素。这就带来三个直接好处。第一图形可以进Git做diff了。文案变了哪个节点一眼扫出来。第二图形可以被动态生成。既然它是文本那么后端接口、脚本、CI流程都可以按数据拼出图表不需要人手动维护。第三图形有了明确的语法边界。结构不合法就是渲染失败不存在“画歪了但还能看”这种模糊状态。不过Mermaid本身是有学习成本的。语法虽然比SVG简单得多但分支、子图、注释、箭头方向这些细节新手还是总要翻文档。以前Mermaid没能完全普及一定程度上就是卡在这里。1.3 AI补上了最后一块短板大语言模型最擅长的事情恰好就是自然语言到结构化输出的转换。你说“给我画一个用户登录的流程包含验证码校验和密码错误锁定”它会基于对Mermaid语法的大规模预训练直接输出能被解析的代码。这件事在AI出现之前需要人来记语法、查文档在AI出现之后变成了提需求的人只要能把话说清楚。Mermaid成为AI和图形之间的“中间语言”本质上就是因为它既足够结构化让AI不容易出错又足够接近人类直觉让用户能看懂AI生成的每一行。这比直接让AI输出SVG路径或者Canvas绘制代码要可靠得多因为Mermaid是受限的声明式语言雷区少。所以AI Mermaid的组合不是赶时髦它补齐的是“需求描述 → 图形表达”这条链路上最耗人的一环。2. 整体链路的设计与拆解2.1 三个关键节点各司其职整条AI → Mermaid → UI的链路可以清晰地切成三段。第一段是AI生成端。你给大模型一段需求描述它返回Mermaid代码。这一段的成败取决于Prompt怎么写、AI对语法的掌握准不准。如果AI输出了不存在的方向关键词比如把TB写成BT或者漏了结束括号后面的渲染必然失败。第二段是Mermaid解析渲染端。拿到Mermaid代码后浏览器里跑着mermaid.js它的解析器会把这段文本变成节点、边、布局坐标最后通过SVG绘制出来。这个阶段的关键是配置初始化、主题选择、以及异常捕获。第三段是UI展示端。Mermaid渲染出来的SVG要嵌入到页面的哪个容器里如何处理加载时序、如何适配暗黑模式、如何在渲染失败时给用户一个友好的提示都是UI集成要解决的问题。三段之间通过“Mermaid代码文本”粘合好处是每一段的输入输出都明确可测。AI那段可以用接口测试覆盖渲染那段可以用单元测试覆盖UI那段可以走正常的前端联调流程。2.2 为什么中间层选Mermaid而不是别的有人可能会问为什么中间表示不选PlantUML、ECharts的option、或者直接让AI画SVG我自己的选择逻辑是这样的ECharts的option是JSON结构AI生成JSON确实准确率高但JSON的可读性太差用户想微调一个节点得看懂一长串嵌套对象。SVG更是反人类一个圆角矩形的坐标稍微算错就歪了AI输出SVG的稳定性不够。PlantUML的语法和Mermaid类似但生态和前端渲染库的成熟度不如Mermaid。Mermaid的优势在于它的语法设计就贴近人类思维。A--B就是A指向Bsubgraph就是分组几乎不需要额外“翻译”。而且mermaid.js的官方渲染能力很成熟支持懒加载、主题定制社区里还有大量编辑器插件降低了UI侧的集成成本。它不像其他方案那样需要你同时维护数据结构、图形布局、渲染引擎三套逻辑。2.3 这套链路最适合落到什么场景我自己实际落地过和看别人落地最多的场景有这么几类低代码平台。用户用自然语言描述一个审批流AI生成Mermaid前端渲染成流程画布再配合节点拖拽做二次编辑。这类场景里AI负责把用户的模糊想法变成“可以编辑的骨架”而不是直接生成不可改的图片。智能报表工具。让用户输入一句话比如“统计各城市订单量并画个饼图”AI根据Mermaid的pie语法生成图表代码展示在报表页面上。知识库/文档站。产品经理写需求文档时不再需要手动画架构图只需要写文字AI顺手补一张Mermaid图文档的阅读体验立刻提升一个档次。教学演示工具。想给学生讲清楚一段代码的调用关系用AI把代码逻辑抽成时序图比用鼠标一幅幅画快得多。这些场景的共同点都是图文内容高频变化追求“描述即所得”并且前端有现成的React/Vue页面可以嵌入。3. Mermaid语法核心让AI生成正确代码的细节3.1 常用图形类型与选型Mermaid支持的图形类型不少但AI生成时选型正确非常关键。选错类型哪怕语法全对表达效果也会很别扭。图形类型语法关键字适合表达典型场景流程图flowchart分支、顺序、判断业务流程、算法逻辑时序图sequenceDiagram角色间的消息顺序接口调用链、微服务交互甘特图gantt任务时间线、依赖关系项目排期、迭代计划状态图stateDiagram-v2状态机迁移订单状态、设备状态饼图pie占比统计数据分布实体关系图erDiagram表与表关系数据库设计类图classDiagram类的属性与方法架构设计、代码建模给AI下指令时我会在Prompt里明确写出“请用Mermaid的flowchart语法”。否则AI有时候会自由发挥比如在描述系统模块关系时输出classDiagram虽然也能看但和业务图的语义不匹配。3.2 语法细节与踩坑点即使AI很聪明它生成Mermaid的时候也会在某些细节上翻车。这里列一些我见过的高频雷区。节点ID尽量别用中文。虽然Mermaid现在能处理中文节点但如果你后续要做节点点击事件、从脚本里动态挂数据中文ID的兼容性会差一些。更好的写法是A[用户登录]这种A是节点ID[用户登录]是显示文本。箭头方向关键词要确认。flowchart里--是实线箭头---是无箭头实线-.-是虚线箭头是粗箭头。AI偶尔会把---和--搞混尤其是需求里说了“关联”而不是“流向”的时候。生成以后肉眼扫一遍常常能提前发现问题。特殊字符会直接导致渲染失败。节点文本里如果出现引号、尖括号、大括号mermaid解析器很容易报错。我遇到过一次AI生成的代码里在节点文本写了div标签渲染直接白屏。遇到这种情况要么改为普通文本要么用引号包裹。Prompt里就应该提前约束“不要使用任何HTML标签和转义字符”。subgraph的边界要留意。子图的语法是subgraph 标题开始end结束。AI偶尔会漏掉end或者把外层流程图的end和子图的end混在一起。这种错误光靠眼睛很难发现建议让AI输出后用工具直接校验。3.3 Prompt技巧让AI一次生成可用的代码我自己总结了一套相对稳定的Prompt模板极大降低了后期返工概率。请把下面的需求转换成Mermaid的flowchart代码 1. 只能用flowchart TD不要使用其它类型。 2. 节点ID使用英文字母显示文本用中文格式A[文本内容]。 3. 不要使用任何HTML标签、引号、尖括号、大括号。 4. 判断节点使用菱形 { }。 5. 如果逻辑有循环请使用返回箭头并注释说明。 6. 直接输出代码不要任何解释文字。 需求描述 ...这个模板的精髓在于第2条和第6条。第2条统一了ID和显示文本的格式既保留中文可读性又避免中文ID的兼容问题。第6条则很重要如果不加这个限制AI很容易输出一大堆“好的以下是你需要的...”之类的废话直接把代码包在Markdown代码块里增加前端解析的复杂度。另外如果AI生成的是复杂流程我会追加一句“请只用英文ID所有节点文本不要超过20个字”。节点的显示文本太长渲染出来会很拥挤UI层看起来就不够清爽。4. UI层集成把Mermaid代码变成页面里的图4.1 渲染方案怎么选Mermaid在前端的渲染主流有两条路。第一条是直接用官方npm包mermaid在React/Vue页面里手动调用初始化方法把Mermaid代码塞进DOM容器然后mermaid.run()触发渲染。这条路的优点是灵活、可控性最强适合有定制需求的业务。第二条是使用社区封装好的组件比如mermaid-js/mermaid-cli主要用于Node端出图或者针对React的mermaid-react等。这些封装适合快速上线但遇到版本升级、主题定制、事件绑定的时候你要扒开封装层去改反而更麻烦。我的建议是核心业务用官方库自己封装一层。一个页面只需要一个组件级封装逻辑不复杂而且完全在自己掌控内。封装好了以后其他页面接入只是传入一个code字符串的事。4.2 基础集成从CDN到npm快速验证阶段直接CDN引入最省事。!DOCTYPE html html langzh-CN head meta charsetUTF-8 script srchttps://cdn.jsdelivr.net/npm/mermaid10/dist/mermaid.min.js/script /head body pre classmermaid flowchart TD A[启动] -- B{检查状态} B --|正常| C[执行] B --|异常| D[告警] /pre script mermaid.initialize({ startOnLoad: true }); /script /body /html这种方式适合验证语法、调试样式。真正进入工程化项目我还是推荐npm安装并模块化引入npm install mermaid然后在组件里引入。import mermaid from mermaid;4.3 初始化参数与主题定制初始化参数直接影响渲染效果这里有几个值得设置的项。theme默认有default、dark、neutral、forest几种。如果页面有暗黑模式通常会动态切换主题或者直接自定义主题变量来适配品牌色。fontSize默认字体偏小16px可能是比较稳妥的正文大小。flowchart节点间距nodeSpacing和rankSpacing控制节点与连线之间的密度。节点多的时候适当加大间距避免全部挤成一团。我自己常用的初始化方式是这样的mermaid.initialize({ startOnLoad: false, theme: document.body.classList.contains(dark) ? dark : default, securityLevel: strict, fontFamily: PingFang SC, Microsoft YaHei, sans-serif, flowchart: { htmlLabels: true, curve: basis, nodeSpacing: 50, rankSpacing: 50 } });关于securityLevel这里要特别说明默认的strict模式会禁掉HTML标签的使用防止XSS风险。如果不需要点击事件、不需要在节点里塞HTML就让它保持strict。一旦改成loose虽然能嵌入HTML但恶意脚本也可能趁机注入外部输入的代码尤其危险。4.4 动态渲染与错误捕获startOnLoad设为false之后渲染就完全由你手动控制。推荐的做法是提供一个渲染函数输入Mermaid代码输出SVG或者渲染后的DOM节点。async function renderMermaid(code, container) { // 清除旧的渲染结果避免重复初始化 container.innerHTML ; // 创建临时div接收渲染结果 const tempDiv document.createElement(div); tempDiv.textContent code; // 关键点用textContent而不是innerHTML container.appendChild(tempDiv); try { const { svg } await mermaid.render(graph-svg, code); container.innerHTML svg; } catch (e) { container.innerHTML p stylecolor:#d33图表渲染失败${e.message}/p; } }这里有个细节容易踩坑mermaid的render方法第一个参数需要唯一的ID值。如果你渲染多次每次用同一个ID旧图表不会出问题但新渲染的图表在事件绑定上可能出现冲突。更稳妥的做法是每次用递增计数器生成一个新的ID。另一个很重要的点是我在上面的临时div上用了textContent而不是innerHTML。因为Mermaid代码来自AI本质上是不可信的字符串。用textContent写入能保证任何尖括号、脚本片段都被当作纯文本处理然后再交给mermaid解析有效降低注入风险。5. 实操实录AI生成架构图并在页面展示5.1 一个真实的需求场景我拿最近给内部系统做的“发布部署架构图”举例。需求是这样一句话“帮我画一个前端项目部署到Nginx后端接口部署到K8s数据库走云RDS监控走Prometheus加Grafana的架构图。”这种图传统流程要手动画半天现在用AI整个链路跑通不超过10分钟。5.2 给AI的Prompt与AI输出Prompt我按前面那套模板稍微演进了一下请把这个部署架构转换成Mermaid的flowchart LR代码 用户请求 - Nginx - 前端静态资源 用户请求 - Nginx - 后端网关 - K8s Pod业务服务 K8s服务 - 云RDS数据库 Prometheus采集K8s和业务服务指标 - Grafana展示 要求 1. 只使用flowchart LR 2. 节点ID用英文显示文本用中文 3. 不要输出任何解释AI输出的代码大概是这样flowchart LR User[用户请求] -- Nginx[Nginx 入口] Nginx -- Static[前端静态资源] Nginx -- Gateway[后端网关] Gateway -- Pod[K8s Pod 业务服务] Pod -- DB[(云 RDS 数据库)] Prom[Prometheus] --|采集指标| K8s[K8s 集群] K8s -- Grafana[Grafana 展示]这段代码可以看到几个细节节点ID是User、Nginx这样的英文显示文本用了[用户请求]这种中括号格式--箭头方向也符合从用户到后端的请求流向。不过我拿到之后还是做了两处微调一是把Pod -- DB改成了Pod -.- DB因为业务服务对数据库的访问不是核心请求链路用虚线更合适二是给整体加了一个subgroup把K8s相关节点收进一个“容器环境”的分组里让架构层次更清晰。5.3 前端渲染的完整代码页面端我用的是Vue 3 Vite但核心逻辑和框架无关。完整组件大致长这样template div classchart-container div refchartRef/div /div /template script setup import { ref, onMounted } from vue; import mermaid from mermaid; const props defineProps({ code: { type: String, required: true } }); const chartRef ref(null); let renderId 0; async function renderChart() { if (!chartRef.value) return; chartRef.value.innerHTML ; const code props.code; const tempDiv document.createElement(div); tempDiv.textContent code; chartRef.value.appendChild(tempDiv); try { renderId 1; const { svg } await mermaid.render(mermaid- renderId, code); chartRef.value.innerHTML svg; } catch (e) { chartRef.value.innerHTML p classerror渲染失败请检查Mermaid语法/p; console.error(e); } } onMounted(() { mermaid.initialize({ startOnLoad: false, theme: default, securityLevel: strict }); renderChart(); }); /script这段代码里的几个决定我解释一下原因用props.code接收父组件传进来的Mermaid字符串组件内部完全不需要关心数据来自AI还是用户手动输入职责单一。临时div先textContent再追加是为了确保Mermaid解析器拿到的不是已被浏览器解析过的HTML实体。每次渲染用自增renderId是为了避免同一个页面多个实例冲突。5.4 效果检查与常见微调我实际跑出来的效果里最常见的问题反而不是渲染报错而是布局太宽或太窄。Flowchart默认从上到下但部署架构这种适合从左到右所以Prompt里特意指定了LR方向。这个方向选择在生成前想清楚比生成后再改省事得多。如果节点多、连线乱还有个微调技巧在flowchart配置里设nodeSpacing: 60, rankSpacing: 80间距拉开后整个图的层次感会好很多。如果字体模糊优先检查浏览器的缩放配置以及fontFamily里中文字体是否排在第一位。默认的sans-serif在Windows下显示中文时渲染出来的字体边缘会有一种“灰蒙蒙”的感觉把PingFang SC, Microsoft YaHei显式写进去就正常了。6. 常见问题与独家排查技巧6.1 问题速查表问题表现可能原因解决方案页面白屏且控制台报Error: Parse error on line XMermaid语法错误用mermaid.live快速定位检查AI输出中的箭头、end关键字中文节点显示为乱码方块浏览器字体不支持中文或charset错误显式设置fontFamily为中文字体确认HTML文档charset是UTF-8图表渲染出来节点拥挤成一团节点间距参数太小调大nodeSpacing和rankSpacing或者改用LR方向大量图表在同一页面卡顿同时渲染的SVG数量过多懒加载滚动到视口再渲染或渲染为图片缓存动态调用mermaid.render时报ID重复多次渲染用了同一个ID用计数器或时间戳生成唯一IDAI代码里含有或符号导致解析失败节点文本里出现HTML标签在Prompt中禁止HTML标签必要时用引号包裹文本6.2 独家避坑经验先说一条最重要的经验不要让用户直接编辑AI生成的代码。AI的输出虽然能渲染但代码风格并不统一用户手动改很容易改坏。更合理的做法是把“AI生成→图形预览”当成实时预览流用户改的是自然语言描述AI重新生成而不是让用户去改Mermaid源码。这个交互设计上的取舍能帮你省掉大量错误反馈工单。第二Mermaid版本很关键。mermaid.js的语法在版本间有细微变化尤其是状态图的stateDiagram和stateDiagram-v2。如果你的项目锁定的mermaid包版本和AI训练数据里的版本不一致可能出现“AI生成的代码在官网编辑器里能跑在自己项目里报错”的情况。解决方式是在项目里固定mermaid版本同时提示AI“基于Mermaid v10语法生成”。第三外部输入一定要走securityLevel: strict。我见过有人为了高亮节点文本把securityLevel调成loose结果是从接口拿来的Mermaid代码里被塞了script标签虽然Mermaid不一定执行它但渲染引擎把HTML插进DOM的这个过程本身就是风险。坚持strict模式本质上是在帮你拦截一类安全风险。第四长图场景建议渲染成图片再展示。当流程图节点超过100个时浏览器渲染SVG的时间会明显上升用户拖动页面也会卡顿。实际项目中我会在后端用mermaid-cli把Mermaid代码渲染成PNG/SVG前端直接展示图片。AI全链路仍然保留但UI层只是冰山一角页面性能不会因为图表变大而崩掉。6.3 后续还能怎么玩这套链路稳定后我可以拓展出不少有意思的方向。比如AI多轮修改。用户在第一版图上说“把数据库节点换成橙色高亮”AI识别出针对某个节点的修改意图只生成增量更新而不是整张图重新渲染。配合mermaid的动态切换体验非常接近“对话式画图”。再比如交互式图表。Mermaid渲染出的SVG本身可以绑定点击事件让节点跳转到详情页、展开子图、或者联动其他组件。AI生成代码时在节点ID上做文章前端就能根据ID映射到业务对象。还有多图表联动。AI一次性生成一套互相引用的图表比如架构图加时序图加部署图通过公共节点ID串联用户点架构图中的服务节点旁边的时序图就切换到该服务的调用链。这个组合在运维排查场景里非常实用。我在实际项目里的体会是AI → Mermaid → UI这套东西真正的价值不是省掉画图那几分钟而是把“图”从一次性产物变成了可以被程序理解、修改、复用的数据资产。只要中间表示是文本它就能参与代码评审、能进自动化测试、能被搜索引擎索引、能被AI继续加工。沿着这个方向往下做可发挥的空间比大多数人想象中大得多。最后再分享一个小技巧写Prompt的时候别只说“画个图”一定要给AI一个“图形类型和方向的默认值”。我自己是把flowchart TD当成默认因为从上到下的流程符合大多数人的阅读习惯需要左右布局时再临时指定LR。这个默认值能显著提高AI第一次输出的可用率减少无效沟通。整条链路跑顺之后你会发现自己已经在用一种更接近产品经理的视角画图了。