拓冰建站拓冰建站
首页 / 资讯中心 / 正文

告别截图拖拽:AI+Mermaid+命令行一键生成流程图实践

这半年来我反复折腾一件事怎么让 AI 帮我画流程图。结论很直接——别截图别在可视化编辑器里“点点点”把画流程图的动作收敛成一条命令让 AI 读完代码或描述后直接产出图。“一行命令出流程图”听起来有点玄实际上就是把三件事串起来AI 负责理解业务逻辑Mermaid 负责定义图的结构渲染引擎负责把定义画成图片。整个过程不依赖鼠标不看截图命令敲完图就出来了。这篇文章适合被画图折磨过的开发者、写文档写到崩溃的技术博主以及想在团队里推行“流程图即代码”的人。我会把整套方案拆开讲清楚为什么截图给 AI 看是低效的命令行方案背后的分工逻辑一个可以直接用的 CLI 脚本以及我实测中踩过的坑和优化思路。如果你只想拿一段能跑的代码可以直接跳到第 3 节如果你想知道为什么这么设计我建议从头看。1. 截图给 AI 看是最笨的用法画图的效率瓶颈在输入先聊聊大多数人用 AI 画流程图的姿势。拿一段业务代码或者一个模块设计文档截图丢给 AI让它“看看这个流程”AI 挤牙膏一样回一段流程描述你再手动拖拽画图工具把节点一个个摆好。这个流程的问题不在 AI而在输入方式。截图这种输入方式天然有信息损耗。一张图片里代码的缩进、作用域、方法调用关系全部被扁平化成像素AI 能看到的只有节点的相对位置和文字。更麻烦的是很多业务逻辑根本不在界面上而在方法调用链、异常分支、事务边界里。截图丢给 AI它只能猜猜出来的流程自然是残缺的。我用半个月时间验证这个结论凡是截图喂出来的流程图基本都要人工重画一遍凡是直接把文本喂给 AI 的一次成图率反而高很多。那个背后的原理其实很朴素。大模型对文本的解析能力远强于图像解析尤其是代码和结构化的技术文档。你把源码给它它能准确识别出 if-else 分支、循环、异常捕获、事务提交点你把截图给它它还得先做一轮 OCR 和版面识别这中间不仅丢信息还增加了幻觉的概率。所以效率瓶颈从来不是 AI也不是画图工具而是输入方式。把 AI 的输入从“截图”改成“原始文本材料”把输出从“一段文字描述”改成“声明式图定义”这个流程立刻顺了。明确了这一点方案就变成我准备好文本材料AI 基于材料生成 Mermaid 语法渲染引擎把语法画成图片。材料可以是单个源码文件、目录结构、Git 提交记录、数据库表结构甚至是一句自然语言描述。AI 只负责判断流程和结构画图交给引擎。就像设计师出设计稿打印机负责打印两者互不干扰。2. 工具链选型为什么是 Mermaid 加命令行渲染而不是手动拖拽既然要让“一行命令出图”工具链必须满足三个条件AI 能稳定生成它的语法、命令行能直接调用渲染、渲染结果能嵌入文档和代码仓库。我对比了一轮最终定格在 Mermaid mermaid-cli。2.1 Mermaid 在结构化文本上的优势Mermaid 是目前唯一让我觉得“AI 生成成功率足够高”的图形定义语言。原因在于它的语法极度接近自然语言的描述习惯。graph TD Start([开始]) -- Login[用户输入账号密码] Login -- Check{账号有效?} Check --|是| Home[进入首页] Check --|否| Error[提示错误] Error -- Login看一眼这段文本不需要任何学习成本人脑就能还原出图的模样。AI 对这种语法特别擅长因为它在海量文本里见过太多类似的结构化表达。相比之下PlantUML 的语法更繁琐Graphviz 的 dot 语言优先级符号太多AI 生成时的出错率明显更高。我实测过同一个提示词分别生成三种格式Mermaid 一次渲染通过率大概在九成Graphviz 得人工修布局参数。为什么这么强调“一次生成通过”因为命令行场景下没有可视化编辑器帮你报错语法错了渲染就直接失败你需要把报错信息丢回给 AI 让它改多了一轮交互。选一个 AI 最容易生成对的语法是整条链路稳定性的基石。2.2 mermaid-cli从语法文本到高清图片Mermaid 官方提供了命令行工具mermaid-js/mermaid-cli命令名是mmdc。它的原理是启动一个无头浏览器加载 Mermaid 库解析语法然后把渲染结果导出成 PNG、SVG 或 PDF。安装非常简单npm install -g mermaid-js/mermaid-cli装完就能用。举个例子我把上面那段流程定义存成login.mmd然后执行mmdc -i login.mmd -o login.png -b transparent -s 2它就会在当前目录生成一张 2 倍分辨率的透明背景 PNG。-s 2是 scale 参数表示放大两倍这样流程图放进文档里依然清晰锐利。SVG 格式更是天然支持无级缩放适合嵌到内部 Wiki 里。这个工具唯一的坑是首次运行会下载一个浏览器内核文件比较大根据网络情况可能要等几分钟。我第一次跑的时候卡在下载进度条上一度以为脚本坏了。这个事放到第 5 节细说。2.3 为什么还是绕不开命令行的形式有人问我直接用 Mermaid Live Editor 网页版把 AI 生成的语法粘进去不也能出图吗能但手工复制粘贴这一步就违背了我们“去掉点点点”的初衷。命令行最大的价值在于可编程、可批量、可复用。一次封装以后团队所有人都能用一个命令出图还能接到 Git 钩子或 CI 流水线里让流程图随代码更新自动重新生成。这些是网页编辑器做不到的。3. 手写一个 aiflow 命令从材料到流程图的完整封装工具链准备好了接下来就是把“AI 生成 Mermaid 语法”和“mmdc 渲染图片”这两步封装成一个命令。我写了一个叫aiflow的 Bash 脚本放在~/bin/aiflow全局可调用。3.1 完整脚本#!/usr/bin/env bash set -euo pipefail # 可配置区 AI_ENDPOINT${AI_ENDPOINT:-https://api.example.com/v1/chat/completions} AI_MODEL${AI_MODEL:-gpt-4o-mini} AI_KEY${AI_KEY:-sk-please-set-me} FLOW_OUT_DIR${FLOW_OUT_DIR:-./flows} FLOW_FORMAT${FLOW_FORMAT:-png} FLOW_FONT${FLOW_FONT:-PingFang SC,Microsoft YaHei,sans-serif} # usage() { cat EOF 用法: aiflow 文件路径 根据单个代码/文档文件生成流程图 aiflow 目录路径 生成该目录整体模块流程图 aiflow -p 描述文字 直接用一句描述生成流程图 aiflow --help 查看帮助 选项: -p, --prompt 文本 直接传入流程描述 -o, --output 名称 指定输出文件名不带后缀 EOF exit 0 } collect_input() { local input$1 if [[ -f $input ]]; then cat $input elif [[ -d $input ]]; then { echo 项目目录$input echo --- 文件清单 --- find $input -maxdepth 3 -type f \ \( -name *.java -o -name *.py -o -name *.js \ -o -name *.go -o -name *.sql -o -name *.md -o -name *.ts \) \ | head -80 echo --- 关键文件内容摘要 --- for f in $(find $input -maxdepth 2 -type f \ \( -name README* -o -name pom.xml -o -name package.json \ -o -name *.sql -o -name *Controller* -o -name *Service* \) | head -20); do echo $f head -100 $f done } else echo $input fi } build_prompt() { cat EOF 你是一名资深软件架构师与流程图专家。请仔细阅读下面的材料根据材料生成 Mermaid 流程图。 输出要求 1. 只输出一个 Mermaid 代码块不要输出任何解释文字。 2. 默认 graph TD 自上而下布局若存在明显并行分支可改用 graph LR。 3. 节点 ID 用英文驼峰节点文字用中文格式NodeId[中文描述]。 4. 必须包含明确的开始节点 Start([开始]) 和结束节点 End([结束])。 5. 条件判断一律使用菱形节点 A{条件}分支线上标注条件文本例如 A --|条件为真| B。 6. 模块边界使用 subgraph 子图。 7. 只画材料中真实存在的流程不得臆造若材料不足以完整画图只在代码块外一句话说明缺失信息。 8. 节点总数控制在 8~25 个之间。 9. 不要写任何解释、不要用外链、不要画时序图或类图只画流程图。 材料如下 EOF } call_ai() { local prompt$1 local payload payload$(jq -n \ --arg model $AI_MODEL \ --arg content $prompt \ {model:$model, temperature:0.2, messages:[{role:user,content:$content}]}) curl -sS --max-time 120 $AI_ENDPOINT \ -H Authorization: Bearer $AI_KEY \ -H Content-Type: application/json \ -d $payload } extract_mermaid() { local content content$(jq -r .choices[0].message.content // .choices[0].text // empty $1 2/dev/null || true) [[ -z $content ]] { echo AI 响应异常原始响应见 /tmp/aiflow_last.json 2; exit 1; } local extracted extracted$(printf %s\n $content | awk BEGIN{inblock0} /^/{inblock!inblock; next} inblock{print} ) if [[ -z $extracted ]]; then extracted$content fi printf %s\n $extracted } main() { local input output prompt_text while [[ $# -gt 0 ]]; do case $1 in -p|--prompt) prompt_text$2; shift 2;; -o|--output) output$2; shift 2;; --help) usage;; *) input$1; shift;; esac done if [[ -z $prompt_text -z $input ]]; then usage fi mkdir -p $FLOW_OUT_DIR local material if [[ -n $prompt_text ]]; then material$prompt_text output${output:-manual} else material$(collect_input $input) output${output:-$(basename $input | sed s/\.[^.]*$// | tr / __)} fi local prompt prompt$(build_prompt) prompt${prompt}$\n\n${material} local tmp_json/tmp/aiflow_response_$$.json local tmp_mmd/tmp/aiflow_$$.mmd echo 正在请求 AI 生成流程图定义... call_ai $prompt $tmp_json extract_mermaid $tmp_json $tmp_mmd local mmd_line mmd_line$(wc -l $tmp_mmd) echo AI 返回 $mmd_line 行 Mermaid 语法开始渲染... cat /tmp/aiflow_mmdc_config_$$.json EOF { theme: neutral, fontFamily: $FLOW_FONT, themeVariables: { primaryColor: #e8f0fe, primaryBorderColor: #1a73e8, lineColor: #333333, fontSize: 14px } } EOF local out_path$FLOW_OUT_DIR/$output.$FLOW_FORMAT mmdc -i $tmp_mmd -o $out_path \ -b transparent -s 2 \ --configFile /tmp/aiflow_mmdc_config_$$.json rm -f $tmp_json $tmp_mmd echo 已生成: $out_path } main $保存后给执行权限chmod x ~/bin/aiflow3.2 这段脚本的关键设计脚本里几个看似平淡的点都是我踩过坑之后加进去的。第一为什么提示词里强制约束节点 ID 用英文、节点文字用中文因为 Mermaid 的语法解析里节点 ID 如果带空格、括号或中文有时候能渲染有时候就报错全看语法解析器心情。而节点文本写在双引号里就非常安全中文照常显示。让 AI 把 ID 和展示文本分开是降低渲染失败率最有效的一招。第二为什么temperature设成 0.2因为画流程图是结构任务不是创意任务。温度太高AI 容易“自由发挥”多画一些材料里根本没有的分支调低之后它会更老实严格贴着输入材料来。这是我在同一个项目上对比测试得出的经验。第三为什么对 AI 响应做了兜底提取有的模型服务商返回的是 OpenA 格式的choices[0].message.content有的是老的choices[0].text用jq -r的//语法让两边都能兼容。另外 AI 偶尔会不输出代码块标记直接裸返回 Mermaid 文本。所以提取逻辑是先抓代码块里的内容抓不到就把全文当 Mermaid 语法用。这个兜底让命令的可用性提升了不少。第四配置文件的fontFamily是中文渲染的关键。Mermaid 默认字体对中文不友好直接渲染经常出现方块字。我把它强制设成了苹方和微软雅黑同时在操作系统的字体环境里兜底了 sans-serif。这一行配置解决了我遇到过的最难看的问题。4. 三个实战场景源码、Git 记录、表结构都能直接出图脚本封好了光说不练没用。我拿三个真实场景跑过效果都还不错每个场景的用法略有差异。4.1 从 Java 源码生成业务流程图我手头有个用户管理模块核心是一个 userService 的注册方法里面涉及参数校验、验证码、密码加密、数据库落库、异常回滚。这种代码是最适合出流程图的因为它分支明确事务边界清晰。命令很直接aiflow src/main/java/com/example/service/UserService.java -o 用户注册流程脚本会把整个文件内容塞给 AIAI 生成 Mermaid 语法mmdc 渲染到flows/用户注册流程.png。流程图里会明确画出校验失败回退、验证码过期重发、数据库异常回滚等分支。我拿它和我手动在 ProcessOn 上画的对比了一下AI 生成的图在异常分支上几乎没有遗漏。这就是直接喂源码的好处——代码里每一个 catch 块和throw语句AI 都能准确识别。4.2 从 Git 提交记录生成发布流程图第二个场景是团队协作里很实用的从 Git 历史生成发布流程图。比如我负责维护一个发布分支想知道一个 feature 从开发分支到测试分支再到主干的合并路径传统做法是git log --graph看一堆符号或者打开 GitLab 的可视化面板。用 aiflow 可以这样先把提交记录导成文本再喂给脚本。git log --graph --oneline --all --decorate /tmp/git_log.txt aiflow /tmp/git_log.txt -o 分支合并流程AI 会读这段提交记录里的分支合并信息生成一张分支整合流程图。当然这个场景里的提交记录信息量和代码文件没法比AI 画出来的是“分支合并关系的流程图”而不是完全精确的 Git 拓扑。如果你需要非常精确的拓扑Mermaid 的gitGraph语法比通用 flowchart 更合适——这个语法本身也在 Mermaid 支持范围内AI 同样能生成。只要在提示词里加一句“使用 gitGraph 语法”就能切换。4.3 从数据库表结构生成数据流程图还有一个高频场景是画数据流转图。运营那边总问我用户下单之后订单数据到底经过了哪几张表与其翻数据库文档我直接把 schema 喂给命令。mysqldump -u root -p --no-data mydb /tmp/schema.sql aiflow /tmp/schema.sql -o 核心表数据流AI 读完建表语句之后会画出核心表之间的主外键关联和依赖关系。数据量少的时候也就是七八张表生成的图一眼就能看懂。需要注意的是这个场景 AI 输出的是数据关系图更接近 ER 图所以提示词里“流程图、开始、结束”那套要求就不太适用。我的处理是写了一个schema分支提示词换成“请根据建表语句生成 Mermaid erDiagram 语法标注表名和字段关联”。同一个脚本场景不同提示词微调一下效果天差地别。5. 实测中的翻车现场与修复思路命令好用归好用实际跑起来还是会遇到各种破事。我把碰到过的问题按发生频率排个序。5.1 语法报错AI 生成的 Mermaid 偶尔不被解析器接受频率最高的问题。Mermaid 语法本身不算复杂但 AI 偶尔会写出一些“看起来很对、渲染器不认”的东西。最常见的是节点文本里放了没转义的引号或者条件分支标签里写了特殊字符。我现在的处理是让脚本走一个“自我修复回路”如果mmdc渲染失败就把报错信息连同 AI 生成的 Mermaid 文本一起重新发给 AI告诉它“渲染器报错如下请修正语法后重新输出”。这一步自动化之后一次成图率从原来的九成提到了接近满分。虽然多了一次 API 调用但整个过程依然是全自动的没人需要在中间介入。5.2 中文字体变方块遇到过一次所有节点文字全部变成方框。查下来是配置里的字体名称写错了或者当前系统没有安装指定的字体。Linux 服务器上没有苹方和微软雅黑所以我加了 fallback 到 sans-serif。桌面端 macOS 和 Windows 上倒是没出过问题。这个属于环境问题配置调整一次就好。5.3 图太大渲染溢出成空白有次拿一个 40 多个方法的服务类去生成AI 输出了一张节点巨多的图渲染完整个 PNG 是空白一片。原因是图表超出了浏览器的可渲染范围节点全被挤到画布外面去了。解决方案有三个一是在提示词里控制节点数量我现在默认限制 25 个二是超大型模块让它先按 subgraph 划分好区域再分别渲染三是生成 SVG 而不是 PNGSVG 的视口可以滚动溢出问题会好一些。用下来组合拳最有效先让 AI 分层再逐层渲染最后用 SVG 兜底。5.4 首次运行 mmdc 卡在下载浏览器内核前面提到过mermaid-cli 第一次跑的时候要下载 Chromium体量很大很多人卡在这一步以为工具坏了。我后来在脚本里加了一个判断执行渲染前先检查本地有没有缓存没有的话打印一条友好提示“首次运行需要下载浏览器内核大约需要几分钟”。另外如果你本来就装了 Chromium 或 Chrome可以用环境变量让 mermaid-cli 直接用系统浏览器省掉下载这一步。具体变量名是PUPPETEER_EXECUTABLE_PATH指向你的 Chrome 可执行文件路径就行。5.5 提示词对输出类型的影响大于想象这个算“隐性坑”。同样的代码提示词里写“生成流程图”和“生成时序图”AI 输出完全不同提示词里写“重点标注异常分支”和“重点标注核心路径”AI 输出的分支取舍也不一样。所以我把提示词做成了模板按场景拆成flowchart、gitGraph、erDiagram、sequence四类脚本里通过--type参数选择。模板一旦稳定输出质量就非常稳定这也是我最后悔没有在第一个版本就做的事。6. 把 aiflow 变成团队基础设施批量、变更检测、CI 集成单机版跑通了接下来价值更大的方向是把这套命令沉淀成团队效率工具。6.1 批量生成项目文档对老项目做技术盘点的时候批量出图非常爽。一行命令把核心 Service 目录下的所有 Java 文件过一遍每个类生成一张流程图代码评审之前先看图很快就能定位到一个方法流程是不是过长、分支是不是过多。批量逻辑其实不需要改造脚本用一个 shell 循环就能解决for f in src/main/java/**/*Service.java; do aiflow $f -o docs/flow-$(basename $f .java) done跑完就是一堆按类名命名的图片。放到 mkdocs 或语雀里直接引用。6.2 让流程图跟着 Git 变更走流程图的头号敌人是“代码改了、图没更新”。我在本地加了一个 git 钩子每次 commit 之前自动执行一次aiflow只对变更过的文件生成新图覆盖到 docs 目录。这样每次提交代码流程图都会和代码一起变不会再出现文档里躺着半年前旧图的尴尬。更进阶一点的玩法是让 AI 读git diff生成“本次变更影响了哪些环节”的链路图。代码评审的时候先看这张图比直接看 diff 快很多。6.3 接入 CIPR 描述里自动带图如果你想把这个能力分享给整个团队让每个人都用命令是不现实的。更靠谱的路径是接入 CI在 PR 触发的流水线里跑一次aiflow把生成的图片传到制品库然后把图片地址自动拼到 PR 描述里。评审人打开 PR 一眼就看清逻辑主线比让每个人自己装环境、配密钥靠谱得多。CI 里跑和图钉跑没什么本质区别无非是保证 Node 环境可用、AI 密钥通过环境变量注入、输出目录固定。有一点要注意把 API Key 配在 CI 的 Secret 里别写死在脚本中。6.4 团队流程图风格统一当所有人都开始用命令出图流程图风格自然就统一了。因为配置里的主题色、字体、布局方向是同一套不存在你用红色、他用蓝色的问题。这是命令行方案对比可视化编辑器最隐蔽的一个优势——规范是硬约束在配置里的不是靠团队自觉执行的。最后分享一点我的小心得用这个方案跑了几个月之后我越来越觉得流程图的真正价值不在图本身而在生成图的过程。每次让 AI 重新读代码生成流程图我都会被迫重新审视一遍这段代码的逻辑是否合理、是否有冗余分支。写这篇文的时候我顺手对项目里的一个老服务跑了aiflow结果 AI 画出了一条我一直没注意到的兜底流程——那个分支隐藏在一个很深的catch块里平时看代码根本注意不到。所以最后给个小技巧别把这个命令当成画图工具把它当成代码审查的辅助工具可能才是它真正值钱的地方。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门