AIによるアーキテクチャ自動発見:その仕組み
昨年、ドキュメントがゼロのコードベースを引き継ぎました。15のサービスにまたがる200,000行のコードで、すでに去ったチームが書いたものでした。私のタスクは、新しい決済統合を追加できるほど十分に理解することでした。会社はアーキテクチャの把握だけで2〜3週間かかると見積もっていました。
その経験こそが、ArchylのAI発見機能を構築した理由です。そして、大規模言語モデルを使ってコードを分析する作業に数ヶ月を費やした今、何が本当に機能し、何が機能しないのか、そしてなぜAI駆動のアーキテクチャ発見が強力だが魔法ではないのかを共有したいと思います。
手動発見の問題点
AIに入る前に、なぜそもそもこれが必要なのかを確認しましょう。
あのドキュメントのないコードベースに直面したとき、私の発見プロセスはこのようなものでした:
第1週:コード内をgrepでキーワード検索。メインのエントリーポイントを見つける。ホワイトボードにいくつかの箱を描く。サービス境界を誤解していたことに気づく。消して描き直す。
第2週:歴史を覚えているほど長くいる唯一のエンジニアにインタビュー。彼の話の半分はコードで見つけたこととは矛盾していた。実は変更があったが、誰も彼のメンタルモデルを更新していなかった。
第3週:ようやくシステムを十分に理解し、変更を加えられると感じる。ドキュメントを作成し、必ず更新すると誓う。(ネタバレ:しなかった。)
このプロセスは遅く、エラーが起きやすく、スケールしません。新しいチームメンバーは全員、同じ苦痛な発見プロセスを経験します。ドキュメントは数ヶ月で古くなります。
AI発見の実際の仕組み
リポジトリをArchylに接続して発見を実行すると、内部ではこのようなことが起きています:
ステップ1:リポジトリスキャン
まず、コードベースのマップを構築します。これはまだAIではありません — 単純なファイルシステムの走査です:
- すべてのファイルとディレクトリをリスト化
- 設定ファイルの識別(package.json、go.mod、docker-compose.yml)
- エントリーポイントの発見(main関数、indexファイル、APIルート)
- インポートからの依存関係グラフの構築
これでスケルトンが得られます。どんなファイルが存在し、互いにどう参照しているかはわかります。しかし、それらが何を_するのか_はまだわかりません。
ステップ2:チャンク分析
ここでLLMが登場し、同時に難しくなるところです。
現代の言語モデルにはコンテキストの制限があります。GPT-4は約128Kトークン、Claudeは200Kを処理できます。多く聞こえますが、中規模のコードベースでも簡単にこの制限を超えます。つまり、コードベース全体をプロンプトに入れて「これは何?」と聞くことはできません。
代わりに、コードベースを消化可能な塊に分割します:
- ディレクトリやモジュールごとにファイルをグループ化
- 各チャンクをプロジェクト内の位置のコンテキストとともにLLMに送信
- モデルに識別を依頼:このコードは何を担当しているか?どんなパターンを使っているか?どの外部システムと対話しているか?
レスポンスは構造化データとして返ってきます — システム、コンテナ、コンポーネントとその関係を記述するJSONです。
ステップ3:集約と調整
これが最も難しい部分であり、開発時間の大半を費やしたところです。
各チャンク分析は部分的なビューを提供します。ユーザーサービスのチャンクはユーザーデータベースについて知っています。決済のチャンクはStripeについて知っています。しかし、どちらも全体像は知りません。
これらの部分的なビューを調整する必要があります:
- 重複エンティティのマージ(「UserDB」と「users_database」は同じものか?)
- チャンク間の関係の推論(注文サービスはユーザーサービスを呼び出すが、別々に分析された)
- 矛盾の解決(あるチャンクはPostgreSQLを使っていると言い、別のチャンクはMySQLと言う — どちらが正しい?)
この調整には、もう一ラウンドのLLM分析に加え、一般的なパターンに基づくヒューリスティクスを使用します。完璧ではありません。AIが間違えることもあります。だからこそ、発見は最終的なドキュメントではなく、人間がレビューする_提案_を生成するのです。
ステップ4:C4モデル生成
最後に、発見されたエンティティをC4モデル要素にマッピングします:
- 外部システム(サードパーティAPI、管理していないデータベース)
- コンテナ(デプロイ可能なユニット)
- コンポーネント(コンテナ内の主要モジュール)
- 関係(誰が誰を呼び出すか、データがどこに流れるか)
結果として、AIがあなたのアーキテクチャを理解した内容を反映するC4図のドラフトセットが得られます。
AIが正しく行うこと
開発中に数十のコードベースで発見を実行した後、印象に残った点は以下の通りです:
テクノロジースタックの検出
LLMはプロジェクトが使用しているテクノロジーの特定において驚くほど優れています。フレームワークのパターン、ライブラリのイディオム、設定ファイルのフォーマットを認識します。GPTが@Controllerアノテーションを見ると、Springを使っていることがわかります。fiber.New()を見ると、Go Fiberを使っていることがわかります。
サービス境界の検出
マイクロサービスアーキテクチャでは、AIはサービス境界を確実に識別します。/services/user/のコードが/services/order/とは別のサービスである可能性が高いことを理解します。Docker Composeファイルをサービストポロジーの指標として認識します。
一般的なパターンの認識
AIはトレーニングデータで数百万のコードベースを見ています。リポジトリパターン、MVC構造、イベント駆動アーキテクチャ、APIゲートウェイのセットアップを認識します。コードが一般的なパターンに従っている場合、AIはそれらを素早く特定します。
外部統合の発見
すべてのAPIキー定数、webhook URL、またはSDKインポートは、外部統合に関する手がかりです。AIはこれらのほとんどを捕捉し、システムがどのサードパーティサービスに依存しているかの全体像を構築します。
AIが間違えること
ここで現実的な期待を設定する必要がありました:
カスタムドメインロジック
AIはあなたのビジネスドメインを理解しません。processOrder関数があることはわかりますが、あなたの特定のビジネスコンテキストで「注文を処理する」とは何を意味するかは知りません。ドメイン固有のコンポーネントの目的を誤って特定する可能性があります。
非定型アーキテクチャ
アーキテクチャが一般的なパターンに従わない場合、AIは苦戦します。カスタムプラグインシステム、非伝統的なフォルダ構造、自社開発のフレームワークはAIを混乱させます。AIはRailsアプリがRailsアプリらしく見えることを期待しています。
隠れた依存関係
すべての依存関係がコードで明示的に示されているわけではありません。サービスが本番環境にのみ存在する特定バージョンのRedisを必要としているかもしれません。AIが見ることのないサイドカーコンテナがあるかもしれません。ランタイム依存関係は静的分析には見えないことが多いです。
古いコードパス
AIは、どのコードがアクティブに使用されていて、どのコードが何年も誰も触れていないレガシーなものかを知りません。コードベースにはまだ残っているが、もうデプロイされていない非推奨のサービスを目立たせてしまうかもしれません。
AI発見をより良くする方法
試行錯誤を通じて、発見の精度を向上させる方法を見つけました:
コンテキストを提供する
発見を実行する前に、AIにシステムについて伝えましょう。「これは決済処理機能を持つeコマースプラットフォームです」という情報がモデルに参照枠を与えます。コンテキストがなければ、盲目的に推測するだけです。
構造から始める
既存のドキュメントがあれば — たとえ大まかなアーキテクチャスケッチがあるREADMEでも — 提供してください。AIはこれを事前情報として分析のガイドに使用します。
段階的にレビューする
コードベース全体に対して一度に発見を実行しないでください。1つのサービスから始めましょう。結果をレビューし、修正します。次に、次のサービスに拡張します。あなたが行った修正が将来の分析に反映されます。
信頼しつつ検証する
AIの提案は出発点であり、最終的な答えではないと考えてください。AIの精度は80%程度かもしれません。残りの20%を検証する必要があります。ソースコードのリンクをクリックし、関係が妥当かどうかを確認し、間違いを修正してください。
技術的な詳細
実装に興味のある方へ:
チャンク戦略
固定サイズのチャンクではなく、セマンティックチャンキングを使用しています。チャンクは通常、1つのモジュール、1つのサービス、または1つのディレクトリツリーです。これにより関連するコードがまとまり、AIの理解が向上します。
プロンプトエンジニアリング
プロンプトは大幅に進化しました。初期バージョンは冗長で物語的な説明を生成していました。現在のプロンプトは特定のフィールドを持つ構造化された出力を要求します。期待されるフォーマットを示すためにfew-shotの例を使用しています。
並行処理
大規模なコードベースには何千ものファイルがあります。順次処理では膨大な時間がかかります。APIレート制限を回避するための設定可能な並行性制限を持ちながら、チャンクを並行して分析します。
モデル選択
異なるモデルには異なる強みがあります。GPT-4はより正確な分析を生成しますが、コストが高くなります。Claudeは構造化された出力要件に従うのが得意です。両方をサポートし、さらにコードを外部APIに送信できないチーム向けにOllamaによるローカルモデルもサポートしています。
AI駆動発見の未来
今日あるのはバージョン1です。以下は私が目指している方向です:
継続的な発見
一回限りの分析ではなく、コードベースを継続的に監視します。コードが変更されたとき、関連する図を自動的に更新します。アーキテクチャのドリフトが問題になる前に検出します。
より深い理解
現在の分析は主に構造的なものです。将来のバージョンでは振る舞いを理解できるようになるかもしれません:「このエンドポイントは入力を検証し、決済サービスを呼び出し、確認メールを送信します。」コードから生成されるシーケンス図。
リポジトリ横断分析
ほとんどの組織は複数のリポジトリを持っています。発見はそれらがどのように接続されているかを理解すべきです — リポジトリAのどのサービスがリポジトリBのサービスを呼び出しているか。
信頼度スコアリング
すべての発見が同じ確度を持つわけではありません。どの提案をより慎重に精査すべきかがわかるよう、信頼度スコアを追加しています。
まとめ
AI駆動のアーキテクチャ発見は魔法ではありません。コードベースを理解する中での面倒な部分を加速するツールであり、ニュアンスのある部分には依然として人間の判断が必要です。
今日あの20万行のコードベースで発見を実行すると、3週間ではなく10分でアーキテクチャ図のドラフトが得られます。完璧ではありません — まだレビューと修正が必要です。しかし、空白のホワイトボードよりも劇的に良い出発点です。
ドキュメントのないコードに埋もれているなら、AI発見を試してみてください。現実的な期待を持って臨みましょう:ビジネスドメインは理解しませんし、珍しいパターンを見逃すかもしれませんし、人間のレビューは間違いなく必要です。しかし、はるかに短い時間で80%のところまで到達できます。
もっと学びたいですか?AI発見が生成するC4モデルの紹介をご覧いただくか、そもそもなぜアーキテクチャドキュメントが重要なのかをお読みください。