蓝图架构图 是做什么的?
像工程图纸一样绘制的系统图:网格化的蓝图(或浅色“白图”),每个组件按类型显示为带标签的形状,实线箭头表示请求,虚线箭头表示事件,虚线区域表示分组,配有图例和标题块。你(或使用者)将系统描述为 diagram.json;一个脚本使用 dagre(已内置,无需安装)进行布局并绘制:
out/index.html:带有沿每条连接移动的点和流动的事件线的图表。可从磁盘打开,自动缩放以适应窗口。out/diagram.svg:不带动画的相同图形,适用于文档、Wiki 和幻灯片。out/diagram.png:两倍大小的静态图,由 headless Chrome 生成,适用于任何需要图片的地方。
前提条件
- Node.js 18 或更新版本。构建过程无需其他依赖。
- Chrome、Chromium 或 Edge 用于生成 PNG。脚本会在常见位置查找;如果找不到,请设置
CHROME_PATH。 - 打开或导出图表时需要互联网连接,用于从 Google Fonts 获取 JetBrains Mono 字体(若无法访问则回退到系统等宽字体)。
此技能的文件夹是 <skill> 以下路径:即此 SKILL.md 所在的文件夹。
步骤
1. 了解系统
当使用者描述系统时,使用他们的原话。当你被要求读取仓库时,请在绘制之前收集证据,并且只绘制你找到的内容:
- 可部署项:
docker-compose*.yml中的服务、KubernetesDeployment、Helm 图表、Procfile、无服务器配置(serverless.yml、vercel.json、wrangler.toml)、Terraform 资源以及单体仓库中的应用(apps/、services/、带有启动脚本的packages/*)。 - 数据存储和消息代理:镜像和托管资源(postgres、mysql、mongo、redis、kafka、rabbitmq、sqs、s3)以及连接设置,如
DATABASE_URL、REDIS_URL、KAFKA_BROKERS、存储桶名称。 - 连接:指向其他服务的 HTTP 客户端和基础 URL、gRPC 存根、队列生产者和消费者(主题和队列名称)、
depends_on、对第三方服务(Stripe、LLM API、邮件提供商)的出站调用。 - 调用者:Web 和移动应用、CLI、定时任务、Webhook。
保持 5 到 20 个节点。将副本和小助手合并到它们所属的服务中;如果节点过多,可以拆分为多个图纸("sheet": "02 / 03")而不是强行塞入。记录任何你推断而非直接找到的内容,并告知使用者。
2. 编写 diagram.json
{
"title": "订单服务 · v2",
"subtitle": "系统架构 · 来自 /services 和 docker-compose.yml · 2026年10月21日",
"sheet": "01 / 01",
"direction": "LR",
"theme": "blueprint",
"groups": [{ "id": "core", "label": "订单平台" }],
"nodes": [
{
"id": "gateway",
"label": "API 网关",
"sub": "认证 · 限流",
"kind": "service"
},
{
"id": "orders",
"label": "订单服务",
"sub": "v2 · Go · 6 个 Pod",
"kind": "service",
"group": "core",
"focus": true
},
{
"id": "db",
"label": "Postgres",
"sub": "orders · stock",
"kind": "database"
},
{
"id": "bus",
"label": "事件总线",
"sub": "Kafka · 3 个主题",
"kind": "queue"
}
],
"edges": [
{ "from": "gateway", "to": "orders", "label": "POST /orders" },
{ "from": "orders", "to": "db", "label": "SQL" },
{ "from": "orders", "to": "bus", "label": "order.created", "async": true }
]
}
| 字段 | 说明 | 限制 |
|---|---|---|
title | 系统或视图的名称(必填);也会显示在标题块中 | 60 |
subtitle | 图表展示的内容及其来源:源文件路径和日期 | 100 |
sheet | 标题块中的图纸编号,例如 "02 / 03"(默认为 01 / 01) | – |
direction | LR 从左到右(默认,适合请求流)或 TB 从上到下(适合管道流) | – |
theme | blueprint(深蓝,默认)、whiteprint(浅色)或自定义颜色:{ "paper", "line", "accent", "dim" } 以十六进制表示 | – |
groups | 围绕节点绘制的虚线区域:{ "id", "label" } | – |
nodes[].id | 字母、数字、- 或 _;边通过它引用(必填) | – |
nodes[].label | 节点上的名称(必填) | 28 |
nodes[].sub | 第二行:语言、运行时、规模、包含的内容 | 36 |
nodes[].kind | 形状:service(默认)、client、database、queue、cache、storage、function、external(第三方,虚线) | – |
nodes[].group | 所属的分组 ID | – |
nodes[].focus | true 会以强调色绘制该节点:表示图表的核心主题 | – |
edges[] | { "from", "to" } 节点 ID,方向表示数据或控制流方向 | – |
edges[].label | 协议、端点、主题或动词:HTTPS、POST /orders、order.created | 24 |
edges[].async | true 表示事件、队列以及任何即发即忘(fire-and-forget)的消息(虚线,带有流动动画) | – |
提示:
- 用实际传输的内容标记边:端点、主题、表名或动词。只有当标签没有任何意义时才省略它。
- 边的方向应与请求的方向一致(调用者到被调用者),以及事件的方向(生产者到队列再到消费者)。
- 最多只能标记一个节点为
focus。 - 最多允许 40 个节点,但超过大约 20 个后,图形会变得难以阅读。
3. 构建并检查
node <skill>/scripts/build.mjs diagram.json out
它会检查文件并一次性列出所有问题(例如连接到不存在节点的边、超出限制的标签),然后写入 out/index.html 和 out/diagram.svg。打开 out/index.html 并检查:
- 步骤 1 中的每个节点都在图中,且没有出现你未发现的内容,
- 边的方向正确且标签可读,
- 分组包含正确的节点。
如果布局混乱,可以尝试另一种 direction,或者重新排列 nodes 和 edges 的顺序:布局从它们的顺序开始。
4. 导出 PNG
node <skill>/scripts/export-png.mjs out/index.html
它会以图形两倍的大小写入 out/diagram.png;添加 --scale=1 以生成实际大小。
5. 交付成果
向使用者提供 out/index.html(带动画)、out/diagram.svg 和 out/diagram.png,以及 diagram.json,以便在系统发生变化时可以更新图形:编辑 JSON 并重新运行步骤 3 和 4。如果图形属于仓库的一部分,则一个包含 JSON 和 SVG 的 docs/architecture/ 文件夹是个好选择;SVG 可以在 GitHub 和大多数 Wiki 中渲染。
故障排除
build: fix diagram.json first:每一行都会指出需要修改的节点或边以及修改内容。- PNG 步骤提示未找到 Chrome:设置
CHROME_PATH,或打开out/index.html并截图。 - 文本显示为不同的等宽字体:页面无法访问 Google Fonts。安装 JetBrains Mono(免费)以在离线时匹配。
- 边交叉过多:切换
direction,将混乱的节点在nodes列表中提前或延后,或者将系统拆分为两个图纸。
文件
scripts/build.mjs:检查diagram.json,进行布局并绘制 HTML 和 SVG。无需安装依赖。scripts/export-png.mjs:使用 headless Chrome 保存 PNG。vendor/dagre.esm.js:dagre 图布局库(MIT 协议),已内置,无需安装;其许可证在vendor/LICENSE-dagre.txt中。examples/order-service/(蓝图,从左到右)和examples/rag-pipeline/(白图,从上到下):完整的diagram.json文件。Lookbk 上的预览图正是基于这些示例绘制的。NOTICE.md:此技能使用的第三方软件和字体信息。