はじめに

平素は大変お世話になっております。 クイックガードのパー子です。

皆様はシステム構成図を作成/維持されておりますでしょうか。

弊社ではお客様の多数のシステムを運用しているため、頻繁に作図/更新の機会があります。
システム構成図は一度作って終わりではなく、システムに変更が入れば追従して図に反映していく必要があります。

システム構成図の管理責任を負っている方はよくご存知だと思いますが、図の体裁を見栄え良く整えるために、将来的な変更を受け入れるための余白や遊びを削らざるを得ない場合も多いです。
その結果として、実体システムへの変更は軽微なものであっても、図のほうでは配置を大幅に変更しないといけないこともあるため、図の追従というのは見かけよりも面倒な作業なのです。

こうした作業を支援するため、AWS のシステム構成図を作図する Agent Plugin を社内向けに作成しました。
本記事では当該プラグインの設計上の工夫を紹介します。

プラグインの概要

このプラグインは、AIエージェントを使って draw.io で AWS のシステム構成図を作成/編集するためのものです。
新しい図を作る場合にも、既存の図を修正する場合にも利用できます。

draw.io の MCPサーバー (MCP Tool Server) を組み込んでおり、AIエージェントは直接的に AWS用のアイコンを検索したり draw.ioファイルのページを読み書きできるため、一気通貫で作図を完遂できます。

作図フロー

一手で図を完成させるのではなく、描画に先んじて、まず図に含める要素や接続、包含関係などの構造を中間データとして整理するようにしています。
(この考え方は、株式会社ZOZO様の先行事例 を参考にさせていただきました)

中間データでは、AWSリソースや登場人物などのノードと、ノード間の接続、リージョンやスタックなどの包含関係を YAML形式で記述します。
一方、座標や色、draw.io のアイコン形式といった見た目の情報は持たせません。
これにより、「何を描くか」と「どう見せるか」を明確に分離します。

中間データの具体例として、先日の弊社ブログ記事『Bedrock Agent で AWS Health Event をサマライズする』の構成であれば、

  • 複数の管理対象のアカウント (= 管理アカウント) と単一の集約アカウントが存在すること
  • EventBridge を経由して管理アカウントから集約アカウントに Health Event を集めること
  • 集約アカウントにおいて Bedrock でイベントを判定すること
  • etc.

などといった要素が抽出されます。

次の YAML は実際にプラグインを用いて出力した中間データです。
(スキーマの説明はしませんが、各属性の意味は何となく読み取れるかと思います)

title: Bedrock Agent で AWS Health Event をサマライズする - 全体アーキテクチャ
nodes:
  # すべての管理アカウントは同じ構成でイベントを集約アカウントへ転送する
  - { id: acct1,         type: aws.account,     label: 管理アカウント1 }
  - { id: health_event,  type: aws.health,      label: Health Event,              parent: acct1 }
  - { id: default_bus_1, type: aws.eventbridge, label: ① EventBridge Default Bus, parent: acct1 }

  - { id: acctN,         type: aws.account,     label: 管理アカウントN }
  - { id: health_event_n, type: aws.health,      label: Health Event,              parent: acctN }
  - { id: default_bus_n, type: aws.eventbridge, label: ① EventBridge Default Bus, parent: acctN }

  # 集約アカウント (判定システム)
  - { id: agg,           type: aws.account,            label: 集約アカウント }
  - { id: custom_bus,    type: aws.eventbridge_custom, label: ② EventBridge Custom Bus,  parent: agg }
  - { id: orchestrator,  type: aws.lambda,             label: ③ Lambda (オーケストレーター), parent: agg }
  - { id: bedrock_agent, type: aws.bedrock,            label: ④ Bedrock Agent,            parent: agg }
  - { id: action_group,  type: aws.lambda,             label: ⑤ Lambda (Action Group),    parent: agg }
  - { id: sns,           type: aws.sns,                label: ⑥ SNS,                      parent: agg }

  # 通知先
  - { id: staff,         type: generic.user,    label: スタッフ }

edges:
  - { from: health_event,  to: default_bus_1, label: イベント捕捉 }
  - { from: health_event_n, to: default_bus_n, label: イベント捕捉 }
  - { from: default_bus_1, to: custom_bus,    label: 転送 (クロスアカウント配信) }
  - { from: default_bus_n, to: custom_bus,    label: 転送 (クロスアカウント配信) }
  - { from: custom_bus,    to: orchestrator,  label: 起動 }
  - { from: orchestrator,  to: bedrock_agent, label: 呼び出し }
  - { from: bedrock_agent, to: action_group,  label: 実行 }
  - { from: action_group,  to: acct1,         label: リソースタグ探索 }
  - { from: action_group,  to: acctN,         label: リソースタグ探索 }
  - { from: orchestrator,  to: sns,           label: メッセージ発行 }
  - { from: sns,           to: staff,         label: 通知 }

この中間データをもとに、レイアウトやアイコン、線の経路を決めて draw.io の図に起こします。

AWSアイコンは MCPサーバーを用いて検索し、見つかったスタイルを使います。

実際に出力された図は次のようになりました。

一部で線が入り組んでいる箇所があるものの、調整なしのプロンプト一発でこの程度の図が出力されるので、使い勝手としては及第点かなと思います。

作図における工夫点

作図フローを安定させつつ繰り返し修正しやすくするため、特に次の点を工夫しました。

構造を明確なスキーマの中間データとして定義する

作図フローでも言及したように、ノードや接続、包含関係をスキーマに沿って整理し、描画に入る前に構成を確認できるようにしました。

構成の整理と描画を一度に行おうとすると、「何を描くか = AWSリソースや接続関係を正しく整理すること」と「どう見せるか = draw.io の図として要素を見やすく配置すること」を同時に判断することになります。
これらを同時並行的に扱うには、AIエージェントのキャパオーバーを感じるケースが多くありました。

そこで作図作業を 2フェーズに分けて、まず中間データで構成を整理し、確定してから次のステップで描画に専念させることにしました。
フェーズを分けることによって構造の整理と見た目の問題を別々に取り扱えるため、お互いの領分に波及することなく調整を加えやすくなったように感じます。

線とノード/ラベルの重なりを避ける

図の品質を損なう主要因として、線とノード/ラベルの重なりが挙げられます。
重なりがあると、それだけで図が壊れているように見えるため、要素が重ならないよう配置と経路の検討を重点的に行うルールをスキル定義に記述しました。

具体的には、まず接続関係に沿ってノードを配置し、線を通す余白を確保します。
そのうえで、線の交差、重なりが発生しないかを確認し、必要に応じてノードの位置や線の起点/終点、経路を調整するようにします。
線もノードやラベルと同じく図の構成要素として明確に認識させたうえで、配置計算の段階から位置関係を考慮させます。

一発で常にきれいな経路が得られるわけではありませんが、こうしたルールを明示することで、重なりをできるだけ減らすことを狙います。

その他のリファレンス

線やテキストの推奨スタイルや、オブジェクトの配置ルールといった基本的な描画ルールの他に、

  • 図の見本
  • XML (mxGraph) の構造ルール
  • スタイルのチートシート

を詳細なリファレンスとして用意しました。

draw.io の図の実体は mxGraph という仕様の XML です。
その仕様詳細をリファレンスとして参照することで、効率的に作図することができるようになります。

公式ドキュメント や MCP のリポジトリ で詳細な情報が提供されており、これらを元に必要な分を取捨してプラグイン内に持たせています。

図の背景として余白付きの矩形を配置する

(当項目は作図フローには関係なく、単に見た目の工夫に過ぎない話なのですが、)
図の背景として大きな白色矩形を明示的に配置し、その内側に適度なパディングを設けるようにしました。

draw.io は図の書き出し時にオブジェクトがぎりぎり収まるサイズで画像を出力するため、パディングを設けることで、図中のオブジェクトが出力画像の枠ぎりぎりに配置されて窮屈な印象を与えてしまうことを防ぎます。

使ってみた所感

一部の実務で実験的に利用を始めているところですが、以下の知見や改善点が得られています。

構造を中間データとして分離した効能

構造を中間データとして明示的に分離したことで、要素の追加/削除や接続関係の変更を指示しやすくなっていると感じます。

一発で狙いどおりの構成に変更できますし、構造の変化に引きずられて意図せず描画が大きく書き換わることもありません。
基本的にシステム構成は時間経過で少しずつ変化するものなので、描画面への影響を抑えながら漸進的に書き換えできる中間データ方式の採用は正解でした。

納品物としての品質には満たない

社内の運用用途で使うドキュメントとしては充分な品質の図を作成できていると感じる一方で、顧客への正式な納品物としてはまだまだ品質が足りません。
顧客への納品物として仕上げる場合は、読み手に応じた情報の取捨選択や見せ方、細部の調整を人間が手動で行う必要があります。

とはいえ、その叩き台や草稿として使えるので、すべて手動で書き起こす場合に比べて作業工数は格段に下がりました。

まとめ

draw.io を用いた AWSシステム構成図の作成/編集を支援する Agent Plugin を作成しました。

構造を中間データで整理してから描画することで、構成の検討とレイアウト調整の責務を分離しています。

  • 描画の前に、中間データで構成要素と関係性を整理する
  • 中間データをもとにノードやラベルの配置、線の経路を決める
  • 線とノード/ラベルの重なりを避けるため、配置や経路を重点的に確認する

「構成を整理してから図に書き起こす」という 2フェーズ設計とすることで、狙いどおりに図を変更しやすくなりました。

今後ともよろしくお願い申し上げます。