Kuboyage

・ AI / 設計

アーキテクチャ図をAIに毎回同じ品質で描かせる 📐🤖

アーキテクチャ図をAIに毎回同じ品質で描かせる 📐🤖

この記事について 📖

対象読者: 構成図の更新が追いつかなくなっている方、AI に図を描かせて毎回結果が変わる問題に当たった方

この記事で扱うこと: テキストから構成図を生成する手順を、レイアウトの揺れを止める設計と、実際に詰まった4箇所まで含めて解説いたします。

はじめに 👋

こんにちは!H×H のセンリツ大好きエンジニアです!✌️

構成図には、書いた瞬間から古くなるという性質があります。手で描いた図は更新が面倒で、面倒なものは放置され、放置された図は嘘をつき始める。

かといって AI に「構成図を描いて」と頼むと、今度は別の問題が出ます。頼むたびにレイアウトが変わり、粒度が変わり、色が変わる。前回と比較できないので、どこが変わったのかも分からない。

この記事では、その揺れを止めるために組んだ手順を共有いたします。土台にしたのは ZOZO TECH BLOG の記事で紹介されていた「中間ファイルを挟む」という考え方です。

この記事はおよそ 3000 字なので、6 分で読めます!

※この記事は AI と 2 人 3 脚で執筆されています

目次 📚

  1. なぜ毎回違う図になるのか
  2. 中間ファイルを2つ挟む
  3. アイコンをノードにする
  4. 生成と自己確認
  5. 実際に詰まった4箇所
  6. まとめ

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 を直接書くと、閲覧側のコンテンツセキュリティポリシーで画像だけ表示されない事故が起きます。

実際に生成した図がこちらです。

収集から配信までの構成図。左の情報源からアイコンが並び、収集・選別生成を経て LINE・HTML・Issue の3経路へ流れる

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 という名前で手順書に落としてあり、次に図が必要になったときは同じ順番をなぞるだけで済みます。

参考リンク 🔗

手法

ツール

  • D2 — テキストから図を生成する言語
  • Simple Icons — ブランドアイコンの配布元

ブログの記事一覧へ