アーキテクチャが AI の生産性を決める
AI 駆動開発の生産性は、使っているツールの賢さよりも、コードベースの構造でほぼ決まります。同じ Claude Code や Cursor を使っても、整った構造のリポジトリでは数時間で終わる変更が、曖昧な構造のリポジトリでは何度も手戻りして半日がかりになる、ということが現場では普通に起こります。
理由はシンプルです。AI は与えられたコンテキストの範囲で推論します。境界が曖昧なコードでは「この変更がどこまで影響するか」を AI が読み切れず、安全側に倒せずに壊すか、慎重になりすぎて何も進まないかのどちらかになります。逆に、影響範囲がモジュール境界で閉じていて、入出力が型で表現され、挙動がテストで固定されていれば、AI は局所的な情報だけで正しく書けます。この構造の差が生産性にどう跳ね返るかを数字で捉える方法は AI 駆動開発の生産性をどう計測するか — KPI 設計の実務 で扱っています。
本記事では、AI が高速かつ安全にコードを書ける構造を「AI フレンドリー アーキテクチャ」と呼び、その設計指針を実務目線で整理します。前提となる AI 駆動開発そのものの進め方は 仕様駆動開発を AI で実践する で扱っているので、本記事はその土台となる「構造」に絞って深掘りします。
結論を先に言うと、押さえるべきは次の 4 つです。
- モジュール境界とディレクトリ設計で「AI が読む範囲」を小さく閉じる
- 型とインターフェースで意図を機械可読にする
- テスト容易性を設計の前提に組み込み、AI の書いたコードを自動検証する
- レガシーには「移行可能な構造」を外側から被せる
順に見ていきます。
AI が迷わないモジュール境界とディレクトリ設計
AI が最初につまずくのは「この機能を変えるには、どのファイルを読めばよいか」の判断です。関連コードがリポジトリ全体に散らばっていると、AI は探索だけでコンテキストを使い果たし、肝心の実装の精度が落ちます。
機能の凝集度を上げ、コンテキストを局所化する
有効なのは、技術レイヤーごとに横割りするのではなく、機能 (ドメイン) ごとに縦に凝集させる構成です。1 つの機能に関わるモデル・ロジック・UI・テストが近い場所にまとまっていれば、AI はそのディレクトリだけを読めば変更を完結できます。
src/
features/
billing/ # 課金に関する全てがここで完結
model.ts
service.ts
service.test.ts
ui/
notification/
...
shared/ # 機能をまたぐ共通基盤のみ
ポイントは、機能ディレクトリの内部実装を外から直接触らせないことです。billing の外から billing の内部関数を直接 import するのではなく、公開された入口 (例えば index.ts のエクスポート) だけを経由させます。こうすると AI は「billing の中身を変えても、公開インターフェースを守れば外は壊れない」と判断でき、安心して内部をリファクタできます。
依存の向きを一方向に固定する
もう 1 つ重要なのが依存方向です。機能間の依存が双方向に絡み合っていると、AI は 1 つの変更の波及先を追い切れません。shared は機能に依存しない、機能どうしは直接依存せずイベントや明示的なインターフェース経由でつなぐ、といった一方向の依存ルールを敷くと、AI が影響範囲を有限に見積もれます。
依存ルールは口頭の約束ではなく、リンタ (依存方向チェック) や CI で機械的に守らせるのが鉄則です。ルールがコードとして強制されていれば、AI が誤って境界を越える import を書いても CI で弾けます。
型とインターフェースで意図を機械可読にする
AI フレンドリー設計でもっとも費用対効果が高いのが、型です。型は AI にとって「読まなくても信じてよい仕様」として機能します。
曖昧な型は AI の推測を呼ぶ
any や、何でも入る汎用的なオブジェクト、文字列で表現された状態 (status: string) は、AI に推測を強います。status が取り得る値が "draft" | "published" | "archived" なのか文字列なら何でもよいのかが型から読めないと、AI は周辺コードを総当たりで読むか、誤った前提で実装します。
逆に、状態を直和型 (ユニオン型) で表現し、ありえない組み合わせを型レベルで排除しておくと、AI は型定義を見ただけで正しい分岐を書けます。「不正な状態を表現できない設計」は、人間のバグを減らすだけでなく、AI の推測の余地を消すという意味でも効きます。
インターフェースを先に固定する
関数やモジュールの境界では、実装より先にインターフェース (シグネチャと型) を確定させ、それを AI に渡す進め方が安定します。入出力の型と、満たすべき事前条件・事後条件が型やコメントで明示されていれば、AI は実装の中身に集中できます。これは 仕様駆動開発 における「仕様を一次情報にする」考え方を、コードレベルに落としたものと言えます。
実務では、ドメインの中心的な型 (エンティティ、値オブジェクト、API の入出力スキーマ) だけは人間がレビューして固め、その内側の実装を AI に任せる役割分担が機能します。型が安定していれば、内部実装が AI によって何度書き換わっても外への影響が型で守られます。
テスト容易性とアーキテクチャの関係
AI が書いたコードを信頼してマージできるかどうかは、テストで挙動を固定できているかにかかっています。そしてテストの書きやすさは、アーキテクチャがほぼ決めます。
副作用を端に追いやる
テストしにくいコードの典型は、ビジネスロジックの中に DB アクセスや外部 API 呼び出し、現在時刻の取得といった副作用が混ざっているものです。副作用が中心に埋まっていると、テストのたびに環境を用意する必要があり、AI も「このロジックをどう検証するか」を組み立てられません。
ロジックを純粋な関数として中心に置き、副作用を境界 (リポジトリ層やアダプタ層) に追い出すと、ロジックは入力と出力だけで検証できます。純粋な部分が広いほど、AI は副作用の準備なしにテストを書け、テストも速く安定します。AI 駆動開発における TDD の具体的な進め方は AI 駆動 TDD で詳しく扱っています。
テストを AI へのフィードバックループにする
テストが整っていれば、AI は「書く → テストを実行する → 失敗を読んで直す」というループを自分で回せます。このループが速く回るほど、人間がレビューに使う労力は減ります。逆にテストが遅い、不安定 (flaky)、あるいは存在しないと、AI は自分の出力の正しさを確認できず、人間が全行を目で追う羽目になり、AI 駆動開発の速度メリットが消えます。
ここで重要なのは、テストが「AI 生成コードを通すための品質ゲート」になっている点です。生成速度が上がっても品質を担保する仕組みがなければ意味がありません。品質保証側の設計は AI 駆動開発の品質保証 と合わせて考えると、アーキテクチャと品質ゲートが 1 つの設計として噛み合います。
大規模・レガシーで AI を効かせる構造への移行
ここまでは理想的な構造の話でしたが、現実の多くの案件は、すでに動いている既存システムを抱えています。「全部作り直さないと AI 駆動開発は使えない」というのは誤解で、実際には段階的に構造を整える方が安全で速いです。
変更頻度の高い領域から境界を作る
最初に全体を整理しようとすると終わりません。まず変更が集中している領域 (新機能が次々入る、障害が頻発する) を特定し、その領域の外側に明確なインターフェースとテストを置きます。内部がどれだけ古くても、外側の境界さえ固められれば、その内側は AI に安全に書き換えさせられます。境界の内側を整え終えたら、隣の領域へ同じことを繰り返します。
絞り込みパターンで旧コードを置き換える
レガシーをリプレイスする際は、一括で書き換えるビッグバン方式ではなく、新しい構造を旧システムの周りに被せ、機能単位で少しずつ移していく絞り込み (Strangler) パターンが定石です。新しく作る部分は最初から AI フレンドリーな構造にし、旧コードへの依存はアダプタ層で吸収します。こうすると、新規部分では AI の速度を活かしつつ、旧部分は止めずに運用を続けられます。
この進め方は、実際にレガシーシステムを刷新した レガシーシステムを半分のコストで刷新した事例 でも採った方針です。既存資産を捨てずに、構造を整えた領域から AI の効果を積み上げていくのが、現実的なリプレイスの勘所です。
AI フレンドリー設計のアンチパターン
逆に、AI 駆動開発を遅くする構造もはっきりしています。代表的なものを挙げます。
巨大で何でも入るユーティリティや「共通処理」モジュールは、依存が集中して影響範囲が読めず、AI が一箇所を変えると思わぬ場所が壊れます。共通化は便利に見えて、境界を溶かす最大の要因になりがちです。
設定や状態を暗黙のグローバル変数・シングルトンで持ち回る構造も危険です。AI は「この値がどこで書き換わるか」を追えず、再現性のないバグを生みます。状態は引数や明示的なコンテキストで渡すべきです。
ドキュメントやコメントが実態とずれている状態も、AI を積極的に誤らせます。古い前提を信じて実装するため、何も書いていないより悪い結果になることがあります。コメントやルールは CLAUDE.md のような形でコードと同じ Pull Request で更新する ことを徹底し、一次情報をずらさないことが重要です。
そして、テストのないコードへの大規模な AI 変更は最も避けるべきです。検証手段がないまま AI に広範囲を書き換えさせると、レビューのコストが生成速度を上回り、AI 駆動開発が逆に遅くなります。
FIXIT のアーキテクチャ設計とシステム刷新
FIXIT は AI 駆動開発のクリエイティブスタジオとして、新規開発だけでなく既存システムのリプレイスでも、本記事で述べた「AI が書きやすい構造」を設計の中心に置いています。具体的には、機能ごとの凝集と一方向の依存、型による意図の明示、副作用を端へ追い出したテスト容易な構造を最初から組み込み、AI と人間が安全に並走できる土台を作ります。
レガシー案件では、いきなり全面刷新するのではなく、変更頻度の高い領域から境界を切り出し、絞り込みパターンで段階的に新しい構造へ寄せていきます。構造を整えた領域から順に AI の生産性が効いてくるため、刷新の途中段階から開発速度の改善を実感できるのが特徴です。実際に半分のコストで刷新した レガシー刷新の事例 では、この設計方針が期間とコストの圧縮に直結しました。
「既存システムが古くて AI を入れにくい」「リプレイスを検討しているが進め方が分からない」という段階でこそ、アーキテクチャの設計判断が成否を分けます。現状の構造を踏まえた刷新の進め方は、システム刷新サービス からご相談ください。設計の現実的な落とし所まで含めて一緒に整理します。
システム刷新の進め方を相談したい方は、システム刷新サービス からお気軽にお問い合わせください。現状のコードベースを前提に、AI 駆動開発を効かせるためのアーキテクチャ設計と移行ステップをご提案します。

