システム構成図、もう手で描くのやめました ── Claude Codeで構成図を自動生成・自動更新する仕組み

システム構成図、もう手で描くのやめました ── Claude Codeで構成図を自動生成・自動更新する仕組み

はじめに

こんにちは、ブランドソリューション開発本部ZOZOMO部FBZブロックの座間です。2025年4月にZOZOへ新卒入社し、現在はFulfillment by ZOZO(以下、FBZ)のバックエンド開発を担当しています。最近はチームメンバーの影響でビリヤニにハマっています。

今回は、Claude Codeを活用してFBZのシステム構成図を自動生成・自動更新する仕組みを構築した事例を紹介します。

目次

背景

FBZのシステムはAWS上に構築されており、500以上のLambdaをはじめ、SQS、S3、DynamoDBなどのフルマネージドサービスで構成された、イベント駆動型アーキテクチャです。詳しいシステム構成については、以下のブログ記事で紹介されています。

techblog.zozo.com

イベント駆動型アーキテクチャでは、システムの処理の流れを追うときや、システムの全体像を把握するうえで、システム構成図(以下、構成図)が非常に重要な役割を果たします。

これは、1つの機能を実現するために複数のリソースが連鎖的に関わっているためです。処理の全体像を頭の中だけで把握するのが難しいからこそ、リソース間の繋がりを俯瞰的に可視化する構成図が重要になります。

具体的には以下のようなシーンで活用されています。

  • 障害発生時
  • 新機能開発の設計
  • システムのリファクタリング
  • 新人教育

これらのシーンで構成図が役立った経験のある方も多いのではないでしょうか。構成図は、多くの場面でその価値を発揮します。自分自身も1年前にチームへジョインした際、構成図はシステムの理解に大いに役立ちました。

FBZチームでは以下のような構成図がMiroのボード上で運用されていました。

既存のシステム構成図

課題

しかし、上記のような構成図は運用する上でいくつかの課題がありました。

作成に時間がかかる

構成図を作成した経験がある方はお分かりかもしれませんが、手動での構成図の作成にはそれなりに時間がかかります。特にシステムの全体像を把握していない状態での作成は骨の折れる作業であり、規模が大きくなるほどこのコストは重くなります。このような理由により、しばしば構成図の作成は後回しにされ、結果として構成図が作成されにくく、更新も滞るという状況が生まれていました。

ルールや要件が明文化されていない

構成図の作成にあたり、どのようなルールで図を作成すべきか明文化されていないことも課題でした。図を眺めているとそこには確かにルールが存在するように感じるものの、明文化されていないため作成者ごとに表現方法が異なり、図の統一感が失われていました。また、新規参入者はルールが不明瞭であるため図の作成に時間を要するという問題も生まれていました。

ソースを修正しても構成図が更新されず、陳腐化することがあった

ソースを修正し本番リリースをしたにもかかわらず、変更内容が構成図へ反映されないまま放置され、陳腐化してしまうことがありました。その結果、ミスリードを引き起こし、構成図の信頼性を損なうことがありました。実際、私も入社した当初、更新されていない構成図を鵜呑みにしてしまい、タスクに必要以上の時間がかかってしまったことがありました。

Claude Codeを使った図の作成を試してみる

まず、構成図の作成に時間がかかるという課題を解決するために、Claude Codeを使った図の作成を試してみました。draw.ioのような形式であればClaude Codeを使って直接図を生成できるため、手動で作成するよりも短時間で図を作成できました。

Claude Codeを使ったシステム構成図の直接生成のフロー

しかしこの直接生成する方法では、AIによって作成された図が、どのような指示・要件を根拠に生成されたのかを参照できません。また、システム構造をどのように捉え、図に落とし込んだのかについても明確ではありません。つまり、依然としてルールが明文化されていないという課題は解決されていませんでした。ルールが図の中に情報として埋め込まれたままブラックボックス化してしまい、何が図を生成するうえでの要件だったのかが曖昧になってしまっていたと言えます。

ソースと構成図の間に中間ファイルを挟む

上記の課題を解決するために、構成図に含まれる、人間の与える要件・チームの慣習といった「規約」と、構成図の「構造」を構成図の生成前にファイルとして出力する方法をとりました。このようなファイル群を中間ファイルと呼ぶことにします。以下で中間ファイルの詳細を説明します。

中間ファイルを挟んだシステム構成図の生成のフロー

中間ファイルその1: 規約ファイル

まず、中間ファイルの1つとして、要件を明文化したファイルを挟むことにしました。このようなファイルを規約ファイルと呼ぶことにします。規約ファイルには、構成図の規約・要件などの情報を記述します。例えば以下のようなものです。

  • アイコンのルール
  • 図全体のフローの向き
  • 矢印の種類と持たせる意味
  • ラベルの位置

プロンプトをファイルとして保存しておくイメージに近いです。

規約ファイルは全体に適用されるものと個別の構成図にのみ適用されるものとに分離しました。ディレクトリ構成は以下のようになります。

.
├── conventions.md              # 全図共通の表現ルール
└── views/
    ├── <view1>/
    │   └── conventions.md      # view1固有の表現ルール
    └── <view2>/
        └── conventions.md      # view2固有の表現ルール

プロジェクトルートに配置されるconventions.mdは全図共通のルールです。各View(1枚の構成図)のディレクトリ配下に配置されているものは、その図にのみ適用される規約です。

このように中間ファイルとして規約ファイルを生成過程に挟むことで、以下のメリットがあります。

  • 図がどのような要件をもって生成されたのかが明確になる
  • 図を作成するうえでの指示が蓄積される

規約ファイルには、過去に与えられた要件が蓄積されていき、図は蓄積された規約ファイルの内容をもとに生成されます。仮にその図についての要件を把握していない人であっても、過去のルールを踏襲して図の修正が行えるようになり、結果として安定した図を生成できます。

中間ファイルその2: 構造ファイル

また、構造についてのファイルも中間へ挟むようにしました。ここでいう構造とはノードとエッジのグラフ構造およびその付随情報のことです。このファイルを構造ファイルと呼ぶことにします。構造ファイルは例えば以下のような情報を持ちます。

  • どのリソースが存在するか
  • それぞれのリソースの物理名
  • 何が何に繋がるか
  • どのような関係として繋がるか

また、ディレクトリ構成は以下のようになります。

.
├── structure-spec.md              # structure.yaml の仕様定義
├── conventions.md                 # 全図共通の表現ルール
└── views/
    ├── <view1>/
    │   ├── structure.yaml         # view1 の構造情報
    │   └── conventions.md         # view1 固有の表現ルール
    └── <view2>/
        ├── structure.yaml         # view2 の構造情報
        └── conventions.md         # view2 固有の表現ルール

構造ファイルの本体はstructure.yamlであり、各Viewでファイルを持ちます。また、構造ファイル自体の構造を定義したファイルはstructure-spec.mdであり、プロジェクトルートに配置され、Claude Codeが構造ファイルを生成する際に参照されます。例えば以下のような内容を定義します。

  • トップレベル構造:reposviewdescriptionmetadatanodesedgesの各フィールドの定義
  • nodesの仕様:id(snake_case、一意)、type(CloudFormationのType名)、name(図に表示する名前)、description(任意、補足メモ)
  • typeに使う値:AWS::Lambda::FunctionAWS::S3::BucketAWS::SQS::Queue等の一覧。AWS外はExternal
  • edgesの仕様:fromto(nodesのidを参照)、trigger(列挙値)、label(任意、矢印ラベル)
  • triggerの列挙値:schedules3_eventsendpollstreaminvokewritereadapi_call
  • 制約・ルール:捏造禁止、idはファイル内で一意、同じ物理リソースはビューをまたいで同じid

これはあくまで一例であり、開発チームのニーズや要件に即した構成を定義できます。例えば、FBZのシステムでは複数のリポジトリにまたがる処理が多く、そのような処理の構成図を書くケースが想定されるため、reposキーの値は配列を受けるように定義しています。

また余談ですが、.claude/rules配下にstructure-spec.mdのsymlinkを配置することで、Claudeにルールとして構造ファイルの定義を与えることができます。

この定義をもって出力されたファイルは例えば以下のようになります。

repos:
  - my-api-repo
view: order_processing
description: 注文データを受け取り、在庫確認・決済処理を経てDBに保存するフロー

nodes:
  - id: api_gateway
    type: AWS::ApiGateway::RestApi
    name: 注文受付API
  - id: process_order
    type: AWS::Lambda::Function
    name: "{stage}-process-order"
  - id: sqs_payment
    type: AWS::SQS::Queue
    name: "{stage}-payment-queue"
  - id: execute_payment
    type: AWS::Lambda::Function
    name: "{stage}-execute-payment"
  - id: dynamo_orders
    type: AWS::DynamoDB::Table
    name: "{stage}-Orders"
  - id: payment_service
    type: External
    name: 決済サービス

edges:
  - from: api_gateway
    to: process_order
    trigger: api_call
  - from: process_order
    to: sqs_payment
    trigger: send
  - from: sqs_payment
    to: execute_payment
    trigger: poll
  - from: execute_payment
    to: payment_service
    trigger: api_call
  - from: execute_payment
    to: dynamo_orders
    trigger: write

このように構造をファイルとして分離することで、図がどのような構造をもって生成されたかを明文化できます。さらに、処理の流れをAIにコンテキストとして与えるケースなどで、ノイズを減らせます。

その他のメリット

ここまでの中間ファイルの導入を振り返ると、これは構成図が持つ情報を責務ごとに分離した構造と捉えられます。構成図は以下のように表現できます。

システム構成図 = 構造情報 + 規約情報 + その他の情報(レイアウト情報)

構造情報と規約情報は人間が管理すべき情報です。一方、座標やノードのサイズといったその他の情報は人間が管理すべきでなく、レンダラやAIが補完すべき情報です。このように扱うべき情報を分離することは、さまざまなメリットをもたらします。

まず、変更の局所化です。構造の変更はstructure.yaml、規約の変更はconventions.mdのみに閉じるため、変更の影響範囲が明確になります。これにより、レビューが容易になり、構成図の作成・更新を促進することが期待されます。

次に、特定のレンダラとの密結合を回避できるという点です。構造情報と規約情報は特定のレンダラに依存しないため、容易にレンダラの差し替えが可能になります。レンダラは種類ごとにメリットとデメリットが異なり、構成図を見る人や目的・シーンに応じて最善のものを選択することで効果を最大化できるため、この利点は大きいと考えています。以下にレンダラの一例と形式・メリット・デメリットについてまとめます。

レンダラ 形式 メリット デメリット
draw.io XML GUI編集可能、AWS等のアイコン豊富 座標・サイズの制御が必要、差分レビューしにくい
D2 テキストDSL テキストベースで差分が見やすい、自動レイアウト アイコンのカスタマイズが限定的、普及度が低い
Mermaid テキストDSL Markdown内に埋め込める、GitHub等で直接レンダリング レイアウト制御が弱い、複雑な図には不向き

レンダラの疎結合化の概念図

CIによる自動更新

構成図の陳腐化を防ぐための方法として、リリース時に構成図を自動更新する仕組みをGitHub Actionsで構築しました。

特定のリポジトリでリリースが行われると、GitHub APIのrepository_dispatchを使って構成図管理リポジトリにイベントが送信されます。イベントを受け取った側では、Claude Code Action(Bedrock経由)が起動し、以下の流れで構成図を自動更新します。

  1. 対象ビューの絞り込み — 各ビューのstructure.yamlのreposフィールドを見て、リリースされたリポジトリに関係するビューだけを対象にする
  2. 差分の分析 — リリースタグ間のGit diffを取得し、structure.yamlのノード(id, name)と突き合わせて構成図への影響を判断する
  3. 構成図の更新 — 影響があるビューについて、IaCやハンドラーのコードを読み、structure.yamlを修正したうえで構成図を更新する
  4. PRの作成 — 変更内容をブランチにpushし、更新後のPNG画像を埋め込んだPRを自動作成する

この自動更新においては、構造ファイルが効果を発揮します。画像やD2ファイルを直接管理していた場合、diffとの突き合わせは困難です。しかしstructure.yamlのノード情報があれば、図のファイルを直接参照せずとも「この変更はどのビューに影響するか」を判断できます。

Skillsの活用

構成図の生成・更新のワークフローは、Claude Codeのスキル機能を活用して create-diagram というスキルにまとめました。/create-diagram と入力するだけで、以下のステップが自動で実行されます(D2使用前提)。

Step やること
1 対象リポジトリのパス・範囲をユーザーに確認する。
2 IaC・アプリコードを読解してノード(リソース)とエッジ(接続・トリガー)を抽出し、構造情報を structure.yaml に書き出してユーザーにレビューをリクエストする。
3 ユーザーが指示した表現の要件(方向、グルーピング等)を conventions.md に記録する。
4 structure.yaml + conventions.md から D2 を生成し、PNGにレンダリングする。生成したPNGをAI自身がチェックし、問題があれば修正して再生成する。

Skillsを使用することで、コード読解から中間ファイル生成、図のレンダリングまでの流れを1つのスキルにワークフロー化できます。これにより、規約ファイル・構造ファイルを経由して構成図が生成されるという手順を自然に誘導できます。

実際に作ってみる

FBZの商品連携の構成図をClaude Codeに生成させてみます。Miro上で運用されていた現状の構成図は以下です(ラベルはダミーとしています)。

従来の商品連携の構成図

テキストベースの図表記言語であるD2を用いて構成図を作成させてみます。なお、既存の構成図はClaude Codeに入力として与えません。最終的に生成された図は以下のとおりです(ラベルはダミーとしています)。

商品連携の構成図

既存の構成図と構造自体は大きく変わりませんが、より整理された形で構成図が生成されています。また、規約ファイルに以下のような指示を入れたため、図の矢印が意味をもって表現されています。

## エッジ(trigger → 色・線種)

矢印は「色」で**役割**を、「線種」で**種別**を表す。

| trigger                                                                                  | 役割                             | 色                   | 線種 |
| ---------------------------------------------------------------------------------------- | -------------------------------- | -------------------- | ---- |
| `schedule` / `s3_event` / `poll` / `invoke` / `stream` / `webhook_event` / `api_request` | 制御フロー(処理を起動する主動線) | 黒 `#000000`         | 実線 |
| `send` / `write`                                                                         | データの書き込み・送信           | グレー `#888888`     | 実線 |
| `read`                                                                                   | データの読み取り(参照のみ)       | 薄いグレー `#aaaaaa` | 実線 |
| `api_call`                                                                               | 外部 API 呼び出し                | 黒 `#000000`         | 破線 |

得られた効果・知見

冒頭で挙げた3つの課題に対して、本記事で紹介した仕組みがそれぞれどのように作用したかを振り返ります。

作成時間の短縮

Claude Codeによるコード読解と構造ファイルの自動生成、さらにスキルを活用したワークフロー化により、構成図の作成時間を大幅に短縮できました。以前はシステムの処理の流れを把握し、手動で図に起こすまでに1時間以上要するケースもありましたが、現在は微調整も含め10分程度で対応できるようになり、従来のおよそ6分の1の作業時間の短縮を実現しました。

ルール・要件の明文化

規約ファイル(conventions.md)を中間ファイルとして導入したことで、図の作成ルールが明文化されるようになりました。これにより、作成者ごとに表現方法がばらつくという問題が解消され、誰が作成・更新しても一貫した図を生成できるようになりました。また、生成した図の失敗パターンを規約に追記して育てていくことで、同じミスを繰り返さない仕組みが自然と構築されていきました。

陳腐化の防止

GitHub Actionsによる自動更新の仕組みを導入したことで、リリースのたびに構成図が自動的に更新されるようになりました。構造ファイル(structure.yaml)にリポジトリ情報が紐づいているため、どのビューに影響があるかを自動判定でき、更新漏れを防止できます。これにより、構成図が実態と乖離するリスクが大幅に低減しました。

また、知見として以下が得られました。

一発で完璧な図を作れることはほとんどない

指示の曖昧さやClaude Codeの誤認により、細かい部分が誤った図になることは珍しくありませんでした。対話的に規約ファイルや構造ファイルを育てていく中で、理想とする構成図を完成させるケースが大半でした。また、全図にまたがる規約ファイルにも、要件や頻発する失敗パターンを明記することで、次回以降の生成品質が着実に向上していきました。

自動レイアウトツールとの相性がいい

draw.ioのように座標を指定して図を定義するツールでは、どうしても微調整に多くの時間がかかりました。D2のようにレイアウトを自動で行うツールはその煩わしさから解放してくれ、安定した図を生成できることが多かったです。

新規の機能開発の設計に役立つ

従来、構成図は開発後に作成するドキュメントとして扱われることが大半でした。しかし、この仕組みを活用すれば、実装前に構造ファイルを作成し、構成図を設計書として運用することも可能になります。構造ファイルはYAMLで記述されたノードとエッジの定義であり、draw.ioのXMLのようなレイアウト情報を含みません。そのため、別のAIエージェントに設計意図をコンテキストとして与える際にも、ノイズの少ない効率的なインプットとして機能します。

まとめ

本記事ではClaude Codeを活用して構成図を自動更新する仕組みを構築した事例を紹介しました。この取り組みを通じて感じたのは、AIに仕事を任せるには「何を人間が管理し、何をAIに委ねるか」の境界設計が重要だということです。中間ファイルによる責務の分離は、まさにその境界を明確にする手段であり、これにより諸課題を解決できました。

ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。

corp.zozo.com

カテゴリー