如何用AI绘制架构图:Prompt工程一线实践进阶指南
时间:2026-08-18 | 作者:星际追番人 | 阅读:0一个反直觉的开场
先说个反直觉的结论:让 LLM 画出一张「能用」的架构图,最不重要的就是模型本身。
我第一次做这功能的时候,思路特别朴素。Draw.io 的文件不就是个 XML 吗?我把一个完整的 .drawio 文件丢给模型当样例,说「照这个格式,把项目架构画出来」。
结果你猜怎么着?十次里有六次是废的。要么 id="0" 这个根节点忘了写,要么连线穿过中间的方块,几条线挤在一起糊成一团,要么干脆 XML 都没闭合。
我一度以为是模型不行。直到我换了三家模型,发现失败模式一模一样,我才反应过来:不是模型笨,是我把活儿派错了。
模型擅长「这块放哪、连到谁」这种创意决策。但你让它去抠 XML 嵌套层级、平衡画布坐标、给每条线算绕行路径,这其实是在拿它的短板硬刚。
后面这套从 40% 到 90% 的演化,核心就一句话:把机械的活儿交给代码,把创意的活儿留给模型,然后用 Prompt 把两者之间的接口对齐。下面一步步拆。
1. Draw.io XML:一个 650 行才出一张图的格式
先看清楚对手。Draw.io(现在叫 diagrams.net)底层是 mxGraph XML——一套描述图形节点、连线、布局的标记语言。一个完整文件长这样:
真正承载「信息」的就是那几个 。外面套了 → → → 四层壳,外加两个雷打不动的根节点。
一张基础三层架构图,完整 XML 能写到 650 行。其中六成是每次都长一个样的模板。
你让模型从头到尾生成这整坨,等于让它在四层嵌套里不出一个错。这不现实。
2. 「反向剔除」:让代码做 boilerplate,让模型做创意
这是整个设计里我最想安利的一个洞察。
大多数人的 Prompt 思路是正向的:把完整输出格式摆给模型,让它照抄。但面对 Draw.io 这种壳比肉多的格式,这条路是死胡同。
你抄得越全,出错点越多。
catbuddy 的做法正好相反——从完整 XML 里,把模型不需要操心的部分全部剔掉。
代码承担包装层。 display_diagram 工具收到模型吐出来的裸 mxCell 片段后,自动包成一个完整文件:
function ensureMxFile(xml: string): string {const trimmed = xml.trim()if (trimmed.startsWith('
三个分支覆盖了模型可能的三种输出。有的模型「自作聪明」加了点壳,有的没加。不管哪种,代码都能兜住。
模型只负责裸 。Skill 文件里这句话写得很白:
Generate ONLY bare elements — 别带任何壳标签,系统会自动包成合法的 .drawio。
再配三条铁规则:
- ID 从
"2"开始递增("0"/"1"系统占了); - 所有
mxCell是平级兄弟不许嵌套; - 顶层元素
parent="1"。
这样一来,你压根不用告诉模型什么是 。它只要关心「这块放哪、连到谁」。
为什么这条路走得通
- 认知负担小:模型只需理解
一种元素,不用扛五层嵌套的模板; - 错误面小:每层壳都是潜在出错点,剔掉四层壳就消灭了四类错误;
- token 省:生成的 XML 缩短约 40%,同样的上下文窗口能画更复杂的图。
一句话:别教模型生成完整 XML,让代码去补它不擅长的机械部分。
3. 四轮迭代:可用率 40% → 90% 是怎么磨出来的
「反向剔除」解决了「壳」的问题。但「肉」本身,也就是布局、连线,还是模型生成。
这部分纯靠 Prompt 打磨。我们一共迭代了四轮。
每一档的提升,全都来自从失败案例里提炼具体规则,而不是把「请画得好看一点」这种废话说得更大声。
第 1 版:零约束,可用率 40%
最初的 Prompt 极简——「你是 Draw.io 图表专家,请分析架构生成 XML」,附一个三节点示例。
结果约 40% 可用。主要翻车点包括:
- 忘根节点;
- 容器内子元素
parent指错; - 连线漏了
source/target; - XML 特殊字符没转义。
第 2 版:加布局约束,可用率 55%
这一版加了空间规则:所有元素 x=0~800, y=0~600、起点 x=40,y=40、相邻间距 150~200px。
结果提升到 55%。布局不再挤成一坨了,但连线还是灾难——多条线重叠、双向连线互相穿过。
第 3 版:连线五规则,突破到 75%
这是我们投入最多的一版。盯着上百个失败案例看,最后提炼出 5 条连线规则,写进 Skill:
## Edge Routing — 5 Rules1. 平行连线错开:同两节点间的线用 exitY=0.3 / exitY=0.7 岔开。2. 双向连线:A→B 从右出(exitX=1),B→A 从左出(exitX=0)。3. 每条边都显式设 exitX/exitY/entryX/entryY。4. 用 waypoint 绕开障碍:在起点终点之间的图形旁边绕路。5. 连在边的中点,别连角落(不要 entryX=1,entryY=1)。
第 4 条 waypoint 绕行,专治「连线穿过中间节点」这个高频毛病。给模型一个带 拐点的示例,它就知道怎么让线绕开挡路的方块。
结果跳到 75%。连线质量已经到了「基本不用手动调」的水平。
第 4 版(当前):完整 Skill + 工具链,90%
当前版把整套规范沉淀成一个可插拔的 Skill 包。关键又加了四样:
- 分层颜色表:前端蓝
#dae8fc、后端绿#d5e8d4、数据橙#ffe6cc、基础设施紫、外部红——模型不用「猜」配色,查表就行; - Swimlane 完整示例:游泳道是出错率最高的元素,给整段示例,避免「子元素 parent 指错容器」;
- 三种连线示例:基础连线、容器连线、带 waypoint 绕行,覆盖九成场景;
- 工具链衔接:明确写「下一步 Call
display_diagram({ xml })」,告诉模型生成完该干嘛。
当前约 90%。剩下 10% 的锅,主要是超复杂图(20+ 节点)撞 ID 冲突或超出画布。
这里最关键的一句话是:这四轮迭代背后真正的方法论,其实是告诉模型「不要做什么」,很多时候比告诉它「要做什么」还管用。
原因也不复杂。模型的默认动作,往往正是最容易出问题的那一套。它会下意识把平行线画成重叠状态,也会默认让连线走直线,直接穿过方块。
与其费劲去正向描绘一个“理想结果”,不如先把那条最容易跑偏的路堵死。
像「连在中点,别连角落」「双向线一个从左出一个从右出」这样的要求,本质上都是在做反向剔除。不是不断叠加新规则,而是在有针对性地清理模型的坏习惯。
4. 三个工具的「委托式」分工
Prompt 只是一半,另一半是工具链。catbuddy 给画图配了三个独立的 Agent Tool,分工干净得像流水线。
display_diagram ——造。适合中等复杂度(10~15 节点以内)一次成图。它入口处有个有意思的校验,不是用 XML parser,而是直接看开头字符:
function looksLikeDrawioXml(xml: string): boolean {const trimmed = xml.trim()return trimmed.startsWith('
这比 XML 解析宽容,比不校验严格。万一模型脑子一抽吐出 Mermaid 或 Markdown 表格,直接拒了并给明确指引,而不是把一坨非法 XML 写进文件。
append_diagram ——续。大项目 30+ 节点的图,模型一次输出会被上下文窗口截断。这个工具允许分片追加,每片都先抽出完整 再逐条验证:
function validateCells(existingXml: string, cells: string[]): string | null {if (cells.length === 0) return 'No complete
ID 缺失、撞根节点、片内重复、跟已有图重复——四种情况各给一句人话错误,模型一看就知道哪错了。
edit_diagram ——改。图出来后用户常要微调。它做的是基于 ID 的精确增删改,核心是个用 lookahead 断言的正则:
function cellRegex(cellId: string): RegExp {const id = escapeRegExp(cellId)return new RegExp(`
用 lookahead 而非捕获组,保证只命中目标 ID 那个 cell,绝不误伤别人。删除时还会级联清掉引用它的连线,不留悬空的线头。
三个工具各管一摊:
display负责造;append负责续;edit负责改。
每个工具的 description 里都带完整示例和错误指引,模型自己就能判断什么时候用哪个。
5. get_shape_library:按需加载的「图例手册」
画云架构图(AWS、K8s),你要的不只是方块和连线——你要 EC2 图标、S3 图标、Lambda 图标。Draw.io 内置 1000+ 专业图标,但每个的 style 语法都不一样。
如果把所有图标语法全塞进 System Prompt,不光烧 token,还会在模型根本用不到的时候硬塞给它,干扰判断。
catbuddy 的做法是按需加载——get_shape_library 工具让模型需要时主动查:
const safe = sanitizeName(raw)const filePath = path.join(libDir, `${safe}.md`)const resolved = path.resolve(filePath)// 路径遍历防护:防模型用 ../../ 读到系统文件if (!resolved.startsWith(path.resolve(libDir))) {return 'Error: invalid library path.'}const content = fs.readFileSync(filePath, 'utf-8')return content
这个图标库本质上并不复杂。说白了,就是一组纯 Markdown 文件,比如 aws4.md、kubernetes.md、flowchart.md。
每个文件里主要放两类信息:一类是对应服务的 shape 名称,另一类是 style 语法说明。
除此之外,还配了一份包含 100+ 条目的分类清单。像 Compute(ec2、lambda…)、Storage(s3、efs…)、Database(rds、dynamodb…)、Networking(vpc、api_gateway…)这些都在里面。
整体设计的三个关键点
- 文件即图例:不用改代码,加个
.md就支持新图标库; - 路径遍历防护:
sanitizeName+startsWith双保险,堵死../../; - 友好降级:库不存在时返回的是可用库列表,而不是干巴巴一句「not found」。
6. 三层校验:不靠「解析→报错→重生成」循环
你可能以为,画错了就「生成 → 解析 XML → 失败 → 把错误喂回模型 → 重画」对吧?catbuddy 偏偏没有这个循环。
取而代之的是三层渐进式校验。
第一层:Prompt 约束
这一层是预防性的。在模型动笔前,就先消掉最常见的歪路。
- 「只生成裸 mxCell」灭包装错误;
- 「ID 从 2 递增」灭 ID 冲突;
- 「转义
<>」灭转义错误。
第二层:工具校验
这一层负责拦截。注意 display_diagram 那句错误消息的措辞——它不只说「格式错误」,而是把模型最容易犯的替代方案点名列出来:
if (!looksLikeDrawioXml(rawXml)) {return 'Error: display_diagram.xml must be actual Draw.io XML. ' +'Do not pass Markdown, ASCII diagrams, Mermaid, or plain text. ' +'Generate valid Draw.io XML and retry.'}
这给了模型足够上下文去「理解自己错在哪」,然后在下一次 tool call 里改对。
第三层:正则校验
这一层负责核实。edit_diagram 不信任模型传来的 cell_id 一定存在,每次都做真实性检查。
找不到就回「cell 不存在,建议先用 read_file 读 .drawio 看实际有哪些 ID」。
为什么不用「解析→修正」循环?因为把解析器错误喂回模型,效率太低。
XML parser 报的是「line 47: unexpected token」,模型很难从这反推出「哦是我第 12 个 mxCell 的 parent 写错了」。
三层校验的策略反过来——让每一层的错误消息本身就是一个微型修正 Prompt:发生了什么 + 可能原因 + 下一步建议,全用人话写,前缀统一 Error: 方便模型判断这是错误而非正常结果。
7. 顺手总结:可复用的四条 Prompt 工程原则
这套画图实践里,有四条原则其实跟「画图」无关。换个结构化生成场景,照样能用:
- 反向剔除:系统做 boilerplate,模型做 creative。生成 JSON 别让它写外层壳、只写
items;模板里 60% 是机械重复的,那部分就不该模型生成。 - 示例密度:一个好示例 > 十条文字规则。Skill 里近一半篇幅是示例,每种元素都给样例;模型从示例提模式的能力远强于从规则推导。
- 错误即微 Prompt:报错是给模型看的,不是给人看的。每条错误带「发生什么 + 可能原因 + 下一步」,统一
Error:前缀。 - 分层约束:别堆一个巨型 System Prompt。Skill(全局知识)+ Tool description(局部)+ Shape Library(领域)+ 错误消息(反馈),每次 tool call 只看相关那部分。
最后这条尤其想强调:catbuddy 的画图能力是四个信息来源拼起来的,不是一坨 2000 字的 System Prompt。
模型决策时综合这四层,但每次只需要看到当下相关的那一层。这样比塞一个巨无霸 Prompt 高效得多,也好维护得多。
这篇讲了什么?
- 让 AI 画架构图,靠的是工具链 + Prompt 工程,不是特殊模型能力。核心哲学是「反向剔除」——代码用
ensureMxFile()补全//根节点这些机械模板,模型只生成核心的,错误面和 token 都砍掉约 40%。 - Prompt 迭代四轮,可用率 40%→55%→75%→90%。每次提升都来自从失败案例里提炼具体规则(连线错开
exitY=0.3/0.7、waypoint 绕行),而非笼统喊「画好看点」。方法论是「告诉模型不要做什么」——因为它的默认行为往往就是你不想要的那种。 - 三个工具分工 + 三层校验兜底。
display_diagram(造)/append_diagram(续)/edit_diagram(改)形成完整工具链,get_shape_library按需加载 100+ 云图标语法;校验不走「解析→重生成」循环,而是 Prompt 预防 → 工具拦截 → 正则核实三层,每条错误消息都是一个微型修正 Prompt。
下一篇预告:进阶应用到这儿就收尾了——harness 的核心器官(心脏、手脚、眼睛、记忆、韧性、进阶)我们全拆完了。从第 13 篇起,整个系列转入产品化:怎么把这套 harness 变成桌面、Web、手机都能用的产品。
先看最基础的一环——一条消息的旅程:同一条消息,在磁盘里、在网络上、在你屏幕上,其实是三张完全不同的面孔,为什么要这么设计?再聊流式渲染怎么做到丝滑不卡顿。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- 打破多年惯例!小米18缺席9月发布会 卢伟冰:不会让大家等太久
- 时间:2026-08-25
-
- C# 里字段(Field)和属性(Property)到底怎么区分?一篇讲清职责、写法与选型
- 时间:2026-08-24
-
- 突破500万分、十核全大核设计!小米晒玄戒O3性能:领先苹果A19 Pro
- 时间:2026-08-24
-
- 红米Note12 Pro扩容内存必须获取root权限吗
- 时间:2026-08-24
-
- 华硕天选7 Pro与Max游戏本发布 售价10399元起
- 时间:2026-08-23
-
- 红米K20 Pro微信悬浮窗开启方法与使用教程
- 时间:2026-08-23
-
- 红米Note12 Pro与Note12续航对比实测
- 时间:2026-08-23
-
- 红米Note12T Pro电池容量与详细配置参数介绍
- 时间:2026-08-23
精选合集
更多大家都在玩
大家都在看
更多-
- 为什么湿头发更容易断裂 蚂蚁庄园今日答案9.15
- 时间:2026-09-14
-
- 蚂蚁庄园今天答题答案2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园答题今日答案2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园小课堂2026年9月15日最新题目答案
- 时间:2026-09-14
-
- 小鸡答题今天的答案是什么2026年9月15日
- 时间:2026-09-14
-
- 蚂蚁庄园每日答题答案2026年9月15日
- 时间:2026-09-14
-
- 糖尿病患者禁食所有含糖食物吗 蚂蚁庄园今日答案9月15日
- 时间:2026-09-14
-
- 2026年9月14日蚂蚁新村答案
- 时间:2026-09-14