AIでコードは速く書けるようになった。でも“壊れやすさ”も増えた
Cursor や Copilot、Codex のような AI コーディングツールによって、実装速度は大きく変わった。
簡単な CRUD や API 実装であれば、数分でそれらしいコードが生成される。
テストコードや DTO、Repository 実装まで自動生成されることも珍しくない。
実際、以前より「コードを書く速度」は明らかに上がっている。
しかしその一方で、
「コード全体の構成が崩れやすくなる」
という問題も感じるようになった。
例えば、
- 修正したら別の箇所が壊れる
- 類似実装が増殖する
- 責務が曖昧になる
- Domain に Infra の知識が漏れる
- Utility クラスが肥大化する
- UseCase が何でもやり始める
- 同一概念の表記揺れや不統一
といったことが起きやすい。
一見すると実装速度は上がっている。
しかし長期的に見ると、
コード全体の構造が徐々に崩壊していく感覚がある。
これは単純に「AI の精度が低い」という話ではない。
むしろ、
AI がコードを生成する仕組みそのものが、
こうした問題を起こしやすいのではないかと感じている。
AIは“局所最適化”が得意
AI コーディングツールは非常に優秀だ。
既存コードを参考にしながら、
必要な実装を高速に生成してくれる。
例えば、
- Repository 実装
- DTO
- CRUD
- テストコード
- API エンドポイント
などは、かなり高い精度で生成できる。
しかし、ここで重要なのは、
AI は「システム全体を完全理解している」わけではない
という点だ。
多くの場合 AI は、
- 周辺ファイル
- import
- 命名
- 既存実装
- 類似パターン
などを参考にしながら、
「この場所にありそうなコード」
を推論して生成している。
つまり、AI は非常に強力な「局所最適化」を行っている。
これは逆に言うと、
構造が曖昧なコードでは、
その曖昧さをそのまま増幅しやすいということでもある。
例えば、
- UserService
- UserManager
- UserHandler
のように、似た責務のクラスが複数存在している場合、
人間であれば「なんとなく同じ概念だな」と理解できる。
しかし AI は、
それぞれを別概念として扱いやすい。
結果として、
- 同じ責務の実装が増える
- 微妙に異なる実装が量産される
- 類似ロジックが散乱する
- 命名規則が崩壊する
といったことが起きやすくなる。
また、既存コードに責務漏れが存在すると、
AI はそれも既存パターンとして踏襲しながら実装を広げていく。
つまり AI は、
良い構造も悪い構造も、そのまま増幅する。
実際、自分でも似たようなことを感じている。
最初にある程度レイヤ構造や責務を整理した状態で AI に実装を任せると、
出力されるコードの一貫性は比較的高かった。
例えば、
- UseCase の責務が揃う
- Repository の使い方が統一される
- DTO や Validator の配置が揃う
など、
既存の構造に沿った形で実装されやすかった。
一方で、
最初から広い範囲を AI に任せると、
徐々に構造が崩れていくことも多かった。
例えば、
- 同じ責務なのに別名クラスが増える
- Utility に処理が集まり始める
- Domain と Infra の境界が曖昧になる
- Repository を経由したりしなかったりする
といった状態が起きやすかった。
少なくとも現時点では、
「AI にコードを書かせる」
以前に、
「AI が既存パターンを踏襲しやすい構造を作る」
ことが重要なのではないかと感じている。
なぜClean ArchitectureはAI時代と相性が良いのか
では、AI が推論しやすい構造とは何なのだろうか。
その一つが、
Clean Architecture のような「責務境界を明確に分離する構造」だと感じている。
従来、Clean Architecture は主に、
- 保守性
- テスト容易性
- 変更容易性
のために語られることが多かった。
しかし AI コーディング時代では、
別の価値も出始めている。
それは、
AI がコードを推論しやすくなる
という点だ。
責務境界が明確になる
例えば、
- UseCase はアプリケーションの処理を行う
- Repository はデータ取得を行う
- Domain はビジネスルールを持つ
といったように責務が整理されていると、
AI は「この場所に書くべきコード」を推測しやすくなる。
逆に責務が曖昧だと、
- Repository にビジネスロジックを書く
- UseCase に DB 操作を書く
- Utility に何でも押し込む
といった実装が発生しやすい。
コンテキストが小さくなる
AI は巨大なコードベース全体を完全に理解しているわけではない。
多くの場合、
- 周辺ファイル
- import
- 近い実装
などを参考にしながら推論している。
そのため、
1ファイルの責務が小さいほど、
AI はそのコードを推論しやすくなる。
例えば、
- 「この UseCase を修正する」
- 「この Repository を追加する」
- 「この Validator を実装する」
のように、
局所的な変更として扱いやすくなる。
これは AI コーディングとの相性がかなり良い。
依存方向が固定される
Clean Architecture では、
依存方向がある程度決まっている。
例えば、
- Domain は Infra を知らない
- UseCase は Repository Interface に依存する
といったルールがある。
これによって、
AI が無秩序に依存関係を広げにくくなる。
AI は既存実装や周辺コンテキストを参考にしながらコード生成する傾向があるため、
依存方向が曖昧だと責務漏れが発生しやすい。
構造ルールが明確であるほど、
AI の生成も安定しやすい。
Clean Architectureの“欠点”はAIで弱まりつつある
従来の Clean Architecture は、
実装コストの高さが問題だった。
例えば、
- Interface
- DTO
- Mapper
- DI
- テスト雛形
など、
ボイラープレートが増えやすい。
しかし AI 時代では、
- 雛形生成
- DTO 作成
- Mapper 作成
- テストコード生成
などを AI が高速に肩代わりしてくれる。
つまり、
「責務分離そのもの」ではなく、
「責務分離によって増える実装量」
が従来の大きなコストだった。
そしてそのコストは、
AI によってかなり弱まりつつある。
Clean Architectureなら何でも良いわけではない
ここまで、
AI 時代では責務分離された構造の価値が上がっている、
という話を書いてきた。
しかし、
だからといって「とにかく Clean Architecture にすれば良い」
という話ではない。
むしろ、
形式的に分離しすぎた構造は、
逆に AI の推論コストを上げることもある。
過抽象化はAI時代でも問題になる
例えば、
- Interface が大量に存在する
- 1メソッドしか持たない Wrapper が増える
- 意味の薄い DTO が乱立する
- Repository が細かく分かれすぎる
- レイヤが深くなりすぎる
といった構造は、
人間にとっても読みづらい。
そしてこれは、
AI にとっても同様だ。
AI は既存コードや周辺コンテキストを参考に推論するため、
構造が過剰に複雑になると、
どこに何を書くべきかを判断しづらくなる。
重要なのは“形式”ではなく“一貫性”
重要なのは、
「Clean Architecture という名前の構造」を採用することではない。
本当に重要なのは、
- 命名規則
- 責務境界
- 依存方向
- レイヤの役割
などが、
システム全体で一貫していることだ。
例えば、
- UseCase は何をする層なのか
- Repository はどこまで責務を持つのか
- Domain に何を書いて良いのか
がチーム内で統一されていると、
AI も既存パターンを踏襲しやすくなる。
逆に、
同じ概念に複数の書き方が存在すると、
AI はその揺れをそのまま増幅しやすい。
AI時代は“推論しやすさ”も設計品質になる
従来の設計では、
- 保守しやすいか
- テストしやすいか
- 変更しやすいか
といった観点が重視されていた。
もちろんそれらは今でも重要だ。
しかし AI コーディング時代では、
それに加えて、「AI が推論しやすいか」という観点も、設計品質の一部になり始めているように感じる。
例えば、
- 責務が明確
- 命名が統一されている
- 依存方向が整理されている
- パターンが揃っている
といった構造は、
AI が既存実装を踏襲しながらコード生成しやすい。
つまり今後は、「人間が理解しやすい構造」だけではなく、「AI が一貫性を保ちながら推論しやすい構造」も重要になっていくのではないかと思っている。
まとめ
AI がコードを書く時代において、
「本当に人間が読みやすいコードを書く必要があるのか」
という議論は今後増えていくと思う。
実際、
AI がコード生成・修正を行うのであれば、
人間が細かい実装を直接読む機会は減っていく可能性もある。
極端な話をすれば、
- 人間は仕様だけを書く
- AI が実装する
- 人間は結果だけ確認する
という開発スタイルも、
少しずつ現実味を帯び始めている。
一方で、
現時点の AI はシステム全体を完全理解しているわけではなく、
既存構造や周辺コンテキストを参考にしながら推論している。
そのため、
- 命名
- 責務境界
- 依存方向
- 実装パターン
などが整理されているほど、
AI の生成も安定しやすい。
そして面白いのは、
AI が推論しやすい構造を目指していくと、
結果的に人間にとっても読みやすい構造になりやすいことだ。
責務が整理され、
命名が統一され、
依存関係が明確になったコードは、
人間にとっても理解しやすい。
つまり今後は、
「人間のための設計」と
「AI のための設計」
が対立するのではなく、
むしろ近づいていくのかもしれない。
少なくとも現時点では、
AI にコードを書かせるほど、
構造設計や一貫性の重要性はむしろ上がっているように感じている。