・ AI / 設計
アーキテクチャ図をAIに毎回同じ品質で描かせる 📐🤖
この記事について 📖
対象読者: 構成図の更新が追いつかなくなっている方、AI に図を描かせて毎回結果が変わる問題に当たった方
この記事で扱うこと: テキストから構成図を生成する手順を、レイアウトの揺れを止める設計と、実際に詰まった4箇所まで含めて解説いたします。
はじめに 👋
こんにちは!H×H のセンリツ大好きエンジニアです!✌️
構成図には、書いた瞬間から古くなるという性質があります。手で描いた図は更新が面倒で、面倒なものは放置され、放置された図は嘘をつき始める。
かといって AI に「構成図を描いて」と頼むと、今度は別の問題が出ます。頼むたびにレイアウトが変わり、粒度が変わり、色が変わる。前回と比較できないので、どこが変わったのかも分からない。
この記事では、その揺れを止めるために組んだ手順を共有いたします。土台にしたのは ZOZO TECH BLOG の記事で紹介されていた「中間ファイルを挟む」という考え方です。
この記事はおよそ 3000 字なので、6 分で読めます!
※この記事は AI と 2 人 3 脚で執筆されています
目次 📚
1. なぜ毎回違う図になるのか 🌀
「指示が自然文だと、解釈の余地がそのまま揺れになります」
「構成図を描いて」という依頼には、構造と見た目が混ざっています。どのノードを載せるか、どの向きに流すか、何色を使うか。これらが全部その場の判断に委ねられるため、同じ依頼でも出力が一致しません。
出力形式にも原因があります。Mermaid は手軽ですが、ノードにアイコンを置けず、レイアウトの制御も効きません。結果として文字の箱が並ぶだけの図になり、全体像を掴む役に立たない。
今回はテキストベースの図表記言語 D2 を使いました。アイコンを埋め込め、レイアウトエンジンを選べます。
brew install d2
2. 中間ファイルを2つ挟む 📄
「構造と見た目を、別のファイルに分けて置きます」
ソースからいきなり D2 を書かせません。あいだに2つ挟みます。
structure.yaml— ノードとエッジだけconventions.md— 形・色・向きの規約だけarchitecture.d2— 上の2つから生成する
structure.yaml には見た目を一切書きません。書くのはグラフの構造だけです。
nodes:
- {id: fetch, group: collect, type: process, name: "並列取得"}
- {id: jsonl, group: collect, type: store, name: "normalized.jsonl"}
- {id: line, group: deliver, type: output, name: "LINE カード5枚"}
# ... 他13ノード
edges:
- {from: fetch, to: jsonl, label: "約400件"}
- {from: jsonl, to: filter, label: "プロセスを分ける"}
conventions.md には逆に、構造を一切書きません。
| 種別 | 形 | 意味 |
|---|---|---|
| external | cylinder | 外部の情報源。自分で制御できないもの |
| store | page | リポジトリに残るファイル・状態 |
| guard | hexagon | 失敗を検知して止める仕組み |
- フローの向きは左→右
- アクセント色は1つだけ。強調したい経路にのみ使う
この分離が効きます。構造が変わったら structure.yaml を直し、見た目を変えたくなったら conventions.md を直す。 D2 を手で直すと、次の再生成で戻るので触りません。
そして structure.yaml は人がレビューできます。ノードとエッジの一覧なら、図を描く前に「この粒度で合っているか」を確認できる。ここで一度止めるだけで、描き直しが激減しました。
3. アイコンをノードにする 🎨
「文字の箱が並ぶ図は、結局読まれません」
外部サービスはブランドアイコンをノードにします。Simple Icons の CDN から取得できます。
mkdir -p diagrams/icons
for s in line github googlecloud claude reddit ycombinator rss; do
curl -sS "https://cdn.simpleicons.org/$s/24292f" -o "diagrams/icons/$s.svg"
done
D2 側の指定は shape: image だけです。
classes: {
icon: { shape: image; width: 66; height: 66 }
}
src: "情報源" {
rss: "RSS" { class: icon; icon: ./icons/rss.svg }
gh: "GitHub" { class: icon; icon: ./icons/github.svg }
}
アイコンはローカルに落としてから参照してください。 D2 はローカル画像を data URI として SVG に埋め込むため、出力が自己完結する。CDN の URL を直接書くと、閲覧側のコンテンツセキュリティポリシーで画像だけ表示されない事故が起きます。
実際に生成した図がこちらです。
4. 生成と自己確認 🔍
「AI に自分で見させるところまでが1セットです」
生成は SVG で行います。
d2 --layout elk diagrams/architecture.d2 diagrams/architecture.svg
ここで終わりにしません。SVG のままでは AI が中身を目視できないので、PNG に焼いてから読み込ませます。
chrome --headless --window-size=$W,$H \
--default-background-color=ffffffff \
--screenshot=architecture.png file://$PWD/architecture.svg
ウィンドウサイズには SVG の実寸を使います。固定サイズで撮ると余白だらけの画像になる。
そのうえで、生成した PNG を開いて次を確認させます。
- 最終的な表示幅で読めるか
- 文字が枠からはみ出していないか
- 線が交差しすぎていないか
- アクセント色が散っていないか
直すのは1回に1箇所だけ。まとめて変えると、どの修正が効いたのか分からなくなります。
5. 実際に詰まった4箇所 🕳️
「どれも動かして初めて分かるものでした」
PNG を指定すると固まる
D2 に PNG 出力を頼むと、レンダリング用の Chromium を入れようとして対話プロンプトを出します。自動実行では入力が返らないため、そのまま止まる。
D2 needs to install Chromium v149.0.7827.55 to render non-SVG images. Continue? (y/N):
err: chromium installation cancelled by user
素で叩くと failed to read user input: EOF で落ちます。SVG で出力し、変換は手元の Chrome で行うのが早い。
既定のレイアウトが散らかる
D2 の既定は dagre です。これで生成したところ、グループが斜めに並び、長い交差エッジが大量に出ました。
--layout elk に変えると、左から右へ整った層構造になります。階層のある構成図では elk を使ってください。
横に伸びすぎて読めなくなる
横向きで生成したところ、縦横比が 4.4 対 1 になりました。この比率は本文幅 700px に収めた時点で高さが 160px しかなく、66px のアイコンが 14px まで潰れます。
対処として向きを変えたくなりますが、先に疑うべきはノードの数でした。保存系のノードを2つ畳んだところ 3.85 対 1 まで下がり、読める大きさに収まっています。図に載せる粒度が細かすぎたのが原因です。
暗い図は貼り先で浮く
最初はダークな配色で作りました。単体で見ると格好いいのですが、白背景のブログに貼ると図だけが浮きます。
明るい配色を既定にしてください。 貼り先を選ばない図の方が、結局は使い回せます。
まとめ 🎊
- 構造と見た目を別ファイルに分ける
structure.yamlは生成前に人がレビューする- 外部サービスはアイコンをノードにする
- アイコンはローカルに落として埋め込む
- レイアウトは elk
- 出力は SVG、確認用に PNG へ焼く
- 横に伸びたらノードを減らす
- 配色は明るい方を既定にする
AI に図を描かせるとき、揺れの原因は指示の量ではありません。構造と見た目が同じ依頼に混ざっていることが原因でした。
分けて置くだけで、変更したい方だけを変更できます。そして structure.yaml を先にレビューできるようになったことで、描き直しの回数そのものが減りました。
この手順は create-diagram という名前で手順書に落としてあり、次に図が必要になったときは同じ順番をなぞるだけで済みます。
参考リンク 🔗
手法
- Claude Codeでアーキテクチャ図を作る(ZOZO TECH BLOG) — 中間ファイルを挟むという考え方の出典
ツール
- D2 — テキストから図を生成する言語
- Simple Icons — ブランドアイコンの配布元