はじめに
「AIにアーキ図を書かせたい」
→「アーキ図を画像としても、プロンプト用にテキストとしても扱いたい」
→「そういえば .drawio.png ってなんで画像としてもdraw.ioで編集もできるんだ?」
という流れで調べていくうちに、AIにXMLで draw.io の図を描かせ、 .drawio.png からXMLを取り出してAIに構成情報を把握・編集させることが可能だと知り、便利だったため記事にします。
1. 本題
draw.io(diagrams.net)のファイル(.drawio)の中身はXMLです。つまり、AIにXMLを書かせれば draw.io の図を作ることも編集することもできます。さらに言えば、アーキ図の画像ではなくXMLを読み込ませることで、図の情報をAIに網羅させることが可能になります。
実践
記事用に一般的なWebアプリの3層構成をサンプルとして用意し、実際にdrawioを生成させてみました。
Claude に次のように依頼してAWSのアーキ図を生成させています。
以下の構成のAWSアーキテクチャ図を draw.io 形式(.drawio)で作成してください。
アイコンは draw.io 標準のAWSシェイプ(mxgraph.aws4)を使ってください。
## 構成
- ユーザー → Route 53 → CloudFront → ALB → ECS(Fargate) → RDS
- CloudFront から S3 へのアクセス(静的ファイル配信)
- ECS からのログを CloudWatch に送る
## 配置
- AWS Cloud の枠の中に Region の枠、その中に VPC の枠を描く
- VPC の中は 2 つの AZ に分け、それぞれに以下のサブネットを置く
- パブリックサブネット:ALB, NAT Gateway
- プライベートサブネット:ECS(Fargate)
- DBサブネット:RDS(AZ-a にプライマリ、AZ-c にスタンバイ)
- Route 53, CloudFront, S3, CloudWatch は VPC の外に置く
- 処理の流れが左から右に読めるように配置する
生成された図が以下です。
AWS公式のアイコンが使われ、AWS Cloud → Region → VPC → AZ → サブネットの入れ子の枠も指示どおりに描かれています。RDSのプライマリ/スタンバイ間の同期レプリケーションなど、指示していない線まで補ってくれました。
もちろんちゃんと確認すると修正点もいくつかありますが、手で簡単に直せる程度になっています。(ラベルが重なっている、ALBの位置調整が必要、線が重なっている、など)
2. .drawio.png:画像なのに編集できる仕組み
draw.io には、図をPNGで書き出すときに図のデータ(XML)をPNGファイルの中に埋め込む機能があります。拡張子を .drawio.png にしておくと、
- 普通の画像ビューアやGitHub上ではただのPNG画像として表示される
- VSCodeの拡張機能「Draw.io Integration」で開くと、そのまま draw.io の図として編集できる
という、1つのファイルで両方の役割をこなしてくれます。書き出し用の画像と編集用のファイルを別々に管理しなくてよいのが大きな利点です。
XMLはどこに入っているのか
PNGファイルは「チャンク」と呼ばれるブロックの集まりでできていて、画像データ以外にテキストを保存するためのチャンク(tEXt / zTXt)を持つことができます。draw.io はここに図のXMLを入れています。
PNGファイル
├─ IHDR … 画像サイズなどの情報
├─ tEXt … ★ここに draw.io のXML(キーワード "mxfile")
├─ IDAT … 画像データ本体
└─ IEND … ファイルの終わり
見た目の画像(IDAT)と、図のデータ(tEXt)が同じファイルの中に並んで入っているイメージです。
draw.io のバージョンや設定によっては、XMLが圧縮(deflate+Base64)された状態で入っていることがあります。また、画像共有サービスなどにアップロードすると、このテキスト部分が削除されて編集できなくなることがあるので注意してください。
3. AIに .drawio.png を「テキストとして」読ませる
.drawio.png をそのままAIに渡すと、恐らく大抵は画像として読み込まれます。画像として読ませると、AIは細かい文字や線のつながりを読み違えることが多く、構成を正確に理解してくれません。
そこで、PNGの中からXMLを取り出してAIに渡します。次のPythonスクリプトは標準ライブラリだけで動きます。
import base64
import re
import struct
import sys
import urllib.parse
import zlib
def read_chunks(path):
with open(path, "rb") as f:
data = f.read()
if data[:8] != b"\x89PNG\r\n\x1a\n":
raise ValueError("PNGファイルではありません")
pos = 8
while pos < len(data):
length, ctype = struct.unpack(">I4s", data[pos:pos + 8])
yield ctype, data[pos + 8:pos + 8 + length]
pos += 12 + length
def find_mxfile(path):
for ctype, body in read_chunks(path):
if ctype == b"tEXt":
key, _, text = body.partition(b"\x00")
if key == b"mxfile":
return urllib.parse.unquote(text.decode("latin-1"))
elif ctype == b"zTXt":
key, _, rest = body.partition(b"\x00")
if key in (b"mxfile", b"mxGraphModel"):
# rest[0] は圧縮方式(0=deflate)
text = zlib.decompress(rest[1:]).decode("latin-1")
return urllib.parse.unquote(text)
raise ValueError("drawioのデータが見つかりません")
def decompress_diagrams(xml):
# <diagram>の中身が圧縮されている場合(base64 → raw deflate → URLエンコード)に展開する
def repl(m):
body = m.group(2).strip()
if body.startswith("<"):
return m.group(0)
raw = zlib.decompress(base64.b64decode(body), -15).decode("utf-8")
return m.group(1) + urllib.parse.unquote(raw) + m.group(3)
return re.sub(r"(<diagram[^>]*>)(.*?)(</diagram>)", repl, xml, flags=re.S)
if __name__ == "__main__":
xml = decompress_diagrams(find_mxfile(sys.argv[1]))
# Windowsでも文字化けしないよう、UTF-8でファイルに書き出す
with open(sys.argv[2], "w", encoding="utf-8") as f:
f.write(xml)
python extract_drawio_xml.py aws-architecture.drawio.png aws-architecture.drawio
取り出したXMLには、たとえば次のように各リソースの名前・種類・位置・つながりがすべてテキストで入っています(先ほどの図から抜粋し、style は一部省略しています)。
<mxCell id="ecs-a" parent="pri-a" value="Amazon ECS<br>(Fargate)" vertex="1"
style="...shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.fargate;">
<mxGeometry height="60" width="60" x="95" y="95" as="geometry" />
</mxCell>
<mxCell id="e-alb-ecsa" edge="1" parent="1" source="alb" target="ecs-a" style="..." value="">
...
</mxCell>
これならAIは「ECS はプライベートサブネットの中にあり、ALB から線がつながっている」ことをXMLから抽出した事実として読み取ることが可能です。
Claude Code のようにコマンドを実行できるAIエージェントなら、スクリプトを用意しなくても「PNGに埋め込まれたXMLを取り出して読んで」と頼むだけで、取り出しから読み込みまでやってくれます(後述の修正例でも、取り出し方は指示していません)。上のスクリプトは、自分で中身を確認したいときや、コマンドを実行できないAIにXMLを貼り付けて渡したいときにお使いください。
XMLの部分だけを書き換えた場合、PNGの見た目(画像データ)は更新されません。見た目を更新するには、draw.io(VSCode拡張など)で開いて保存し直すか、draw.io デスクトップ版をインストールしてコマンドライン書き出しまでAIに任せるなど追加手順が必要になります。
修正実践
先ほどの aws-architecture.drawio.png に、キャッシュとして ElastiCache を追加させてみます。Claude Code に次のように依頼しました。
aws-architecture.drawio.png は draw.io の図で、PNGの中に図のXMLが埋め込まれています。
画像として読むのではなく、埋め込まれたXMLを取り出して構成を把握してください。
そのうえで、以下の修正をしてください。
## 修正内容
- ECS がデータを参照するときのキャッシュとして、Amazon ElastiCache(Redis)を追加する
- ElastiCache は各AZのDBサブネットに配置し、AZ a にプライマリ、AZ c にレプリカを置く
- ECS → ElastiCache の線を追加する(ECS → RDS の線はそのまま残す)
- プライマリとレプリカの間にレプリケーションの線を引く
- アイコンは draw.io 標準のAWSシェイプ(mxgraph.aws4)を使う
- 既存のアイコンやラベルと重ならないよう、必要に応じてサブネットの枠を広げる
## 出力
- 元ファイルのXMLに修正したXMLを反映してください。
修正された aws-architecture.drawio.png を VSCode で開いて画像情報を更新したものが以下になります。
XMLの取り出し方は指定していませんが、PNGからXMLを取り出すところから自分で行い、元の構成を正しく理解したうえで修正してくれました。
- ElastiCache が各AZのDBサブネットに、プライマリ/レプリカとして配置されている
- ECS → RDS の線を残したまま、ECS → ElastiCache の線が追加されている
- ElastiCache のレプリケーションには「非同期」と付いていて、RDS の「同期」と区別されている
- 新しいアイコンが収まるように、サブネットから AWS Cloud までの枠がすべて広げられている
前の項での実践と同じように多少の修正点はありますが、許容範囲内でしょう。
4. その他の方法
今回は draw.io しか試していませんが、図をテキストで書く方法は他にもたくさんあるらしいので、もっといい方法があればコメントなどで共有いただけるとうれしいです。
Claudeが教えてくれた一覧
- PlantUML:シーケンス図やクラス図を含め、UMLの図の種類が豊富
- D2:レイアウトの見た目がきれいな図をテキストで描ける
- diagrams(Python):Pythonのコードでクラウド構成図を描けるライブラリ
5. まとめ
元々 draw.io は使っていましたが .drawio.png がなぜ画像としてもVSCodeの拡張機能などで draw.io のファイルとして編集できるのかは知りませんでした。色々調べていくうちに勉強にもなって面白かったです。

