「AIコーディングは前半速いけど、後半になると途端に遅くなる」
この感覚、あなたにもないだろうか。筆者自身も確かにそう感じることがある。最初の数画面はスラスラ作れるのに、機能が増えてくると「あれ、なんかAIの提案が微妙になってきた」「修正するたびに別の箇所が壊れる」という状態になる。
ただし、少し立ち止まって考えてほしい。
この「後半遅い」という問題、AIコーディングが原因なのだろうか?
「後半遅い」はAI以前から言われていた
実は、ソフトウェア開発が後半になるにつれて生産性が落ちていくという問題は、AIコーディングの登場より遥か以前から指摘されてきた。
最も有名な例のひとつが、Robert C. Martin(通称 Uncle Bob)の著書 「Clean Architecture」 だ1。
この本の冒頭には、衝撃的なグラフや主張が載っている2。
「普通に開発を進めると、リリースを重ねるごとに1リリースあたりのコスト(=エンジニアの時間)が増加していき、やがてソフトウェアは維持不可能になる」
2010年代にすでにこの指摘があった。Uncle Bob はこの問題を「技術的負債」「複雑性の爆発」として説明し、それに対抗するための技術として SOLID原則 や クリーンアーキテクチャ を提唱した。
ここで少し視点を変えてみる。ソフトウェアエンジニアリングには、実は(少なくとも)2つの側面がある。機能を実現することと、ソフトウェアのエントロピーを低く保つことだ。ここでいうエントロピーとは、「変更を加えたとき、どこが影響を受けるか読めない状態」のことだ。機能は目に見えるが、エントロピーは見えない。Uncle Bob が指摘した「後半の遅さ」は、エントロピーを抑える努力を怠った結果、複雑性が制御不能になった状態そのものだ。SOLID やクリーンアーキテクチャは、機能実現の方法論というよりも、エントロピー低減のための技術体系と捉えると本質がよく見える。
つまり、「後半遅い」はAIコーディングが生み出した新しい問題ではない。AIコーディング以前から存在していた、古典的なソフトウェア工学の問題なのだ。
では、なぜいまになって「AIコーディングが後半遅い」という評判が広がっているのか?
2025〜2026年:「後半遅い」は実際に観測されている
この問題は仮説にとどまらない。2025〜2026年の現場でも、実際のデータとして現れはじめている。
AIコーディング(Vibe Coding)の普及を追った業界分析によれば、AI主導で高速開発したプロダクトの多くで、典型的な失速パターンが報告されている3。
- ベロシティの急上昇(初期は2〜5倍)
- 一貫性の崩壊(コード重複が4倍に膨れ上がる)
- レビュー疲弊(テストカバレッジが50%以下に低下)
- 障害の加速(未レビューの脆弱性が本番に流れ込む)
- ベロシティの崩壊(初期比50〜70%低下が6〜12ヶ月以内に訪れる)
Uncle Bob が指摘した「リリースを重ねるごとに生産性が下がる」曲線が、AIによって圧縮された形で現れているように見える。この5段階はそのまま、エントロピーが制御されずに増大し続けた結果とも読める。
もう一つ興味深いデータがある。AI安全性研究機関 METR が2025年7月に発表したRCT(ランダム化比較試験)では、経験豊富なオープンソース開発者16名を対象にした実験で、AI使用時のほうが平均19%遅くなったという結果が出ている4。さらに注目すべきは、開発者自身は「AIで20%速くなった」と感じていたという点だ。感覚と実態の乖離が約40ポイントに達していた。
この2つのデータは文脈が異なる(前者はプロダクト全体の技術的負債の蓄積、後者は個別タスクの実験)。ただし共通して示しているのは、「AIコーディングの効果を自分たちは過大評価しがち」 という現実だ。
では、なぜこういったことが起きるのか。「AIがダメだから」で片づけてしまうのは少し早い気がしている。
仮説:AIは「後半遅い」を生み出したのではなく、前倒しした
筆者の根本的な仮説はシンプルだ。
AIコーディングが「後半遅い」を生み出したのではなく、「後半遅い」の到来を前倒しした。
人間だけで開発していたとき、多くのエンジニアは「後半の遅さ」にたどり着く前に、そもそも機能を作り終えていた(あるいはプロジェクト自体が終わっていた)。AIを使うと、同じ時間でより多くの機能が実装される。その分、コードベースの複雑性が早期に爆発する。
では本題だ。「前倒しされた後半の遅さ」を、誰がどう体験しているか。 それによって、解決策がまったく変わってくる。
体験の仕方は2つに分かれる
パターン1:AIで初めて「後半の重さ」にぶつかった人
AIコーディングの登場によって、今まで「後半の遅さ」を感じる余地すらなかったエンジニアが、初めてその壁にぶつかるようになっているのではないか。
以前であれば、機能が増える前にスプリントが終わっていた。コードベースが複雑化する前にリリースが完了していた。PMやリーダー層は感じていても、現場のエンジニアには届いていなかった「後半の重さ」が、AIによる加速で現場にまで降りてきた。
この場合、エンジニア自身が「後半の遅さを回避する技術」をそもそも知らない・未経験である可能性が高い。
必要なのは、アーキテクト視点の習得だ。言い換えれば、ソフトウェアのエントロピーを低く保つという目的意識と、そのための技術を身につけることだ。SOLID原則や依存関係の管理、レイヤリング設計は、どれも「エントロピーを上げない」ための手段である。AIが速く走れるようになったからこそ、エントロピーを制御するレールを敷く技術がより重要になる。
パターン2:設計習慣があるのにAIで詰まった人
もう一つは、今まで「後半の遅さ」を意識的・無意識的に回避してきたエンジニアのケースだ。
こういったエンジニアは、設計を意識しながらコードを書いてきた。インターフェースを切り、依存方向を制御し、テストを書く。それが自然な習慣だった。
ところが、AIコーディングを使い始めると、ある感覚が芽生える。
「AIならそこまで考えてコードを書いてくれるはず……だよな?」
しかし現実はそうではない。AIは、明示的な指示がない限り、設計(クリーンアーキテクチャ本の語彙で言うと、「構造」)上の考慮をほぼ行わない。 理由も違った意味で構造的だ。AIは「変更容易性」ではなく「即時動作」を最適化する。そして最適化の範囲は目の前のファイルやプロンプトに閉じており、プロジェクト全体の依存構造を俯瞰する視点を持たない。つまり局所最適に寄る。プロンプトに「SOLIDに従え」「依存を逆転させろ」「この層は触るな」と書かなければ、AIはただ機能を実装するだけだ。
そして、プロンプトだけでは実は不十分だ。プロンプトは「お願い」に過ぎない。AIはそれを無視できるし、文脈が長くなれば忘れる。
今まで「人間の頭の中」にあった設計の文脈をAIに渡すには、「言葉で伝える」だけでなく「物理的に違反できない状態を作る」 必要がある。具体的には、依存方向の静的解析(例:dependency-cruiser)や lintルール、CIでのチェックといった機械的な強制機構をプロジェクトに組み込み、AIがどれだけ雑なコードを生成しようとも構造的に壊れない仕組みにすることが求められる。
必要なのは、エージェントへの設計意図の注入 + 機械的強制だ。プロンプト・ルール・スキル・プレイブックで「どう書くべきか」を伝えつつ、lintや静的解析で「違反したらCIで落とす」環境を整える。パターン1 とは異なり、AIの仕組み・プロンプト設計・ツールチェーンの三つを同時に扱う技術が求められる。
エンジニアは不要にはならないが、進化が必要だ
筆者は、少なくとも2026年から数年の間、AIコーディング時代に突然「エンジニアが不要になる」ことはないと考えている。
しかし求められるスキルセットは、静かに、しかし確実に変化している。
パターン1(この問題をまだ体験していない人)に必要なのは、今まで体験できなかった「後半の遅さ」と初めて向き合うための設計の知識だ。SOLID を知り、アーキテクチャを学ぶことが、AIを持続的に使いこなす土台になる。
パターン2(すでに回避習慣を持っていた人)に必要なのは、今まで頭の中にあった設計の文脈をAIに伝える技術だ。知識はすでにある。ただ、それをプロンプトやルールに落とし込む一歩が必要になる。
SOLID原則は「後半遅い」に対する人間のための解だった。これからは、その解をAIに伝える技術が、新たなエンジニアリングの核になるのではないかと思っている。
Uncle Bob が本の冒頭で示した問題は、今も変わらず有効だ。ただ、プレイヤーが増えた。だからこそ、構造を守る責任のあり方も変わる。
ここで一つ、現状への違和感も共有したい。AIコーディングをめぐる議論の多くは、「機能をいかに速く実現するか」 に集中しており、「エントロピーをいかに低く保つか」 という話題はほぼ出てこない。しかしソフトウェア構築とは、この2つを同時に行うことだ。後者を無視して前者だけを加速させるのは、基礎を省いて壁だけ急いで建てるようなものである。AIコーディングが普及した今こそ、エントロピー低減の技術と文化をどう維持するかを、エンジニア自身が意識的に議題に乗せていく必要がある。
AI時代に必要なのは、"速く書く技術"ではなく、"壊れないように速く書かせる技術"だ。
アーキテクト視点の一例
ここで、一つ「アーキテクト視点の一例」を具体的に記述しておく。抽象的な話だけで終わらせず、イメージを掴みやすくするためだ。
あえてソフトウェアとは違う話で書く。「電源直結文明 vs コンセント文明」だ。
電力はどちらの文明にもある。違うのは、機器と電源をつなぐ規格(コンセント)があるかどうかだ。
直結文明では、機器ごとに電源用の線が2本ぶら下がったまま売られている。購入後、居室の電源盤から線を引き、必要な変圧器を介して機器に電流を供給すると、とりあえず動く。必要な変圧器は機器(機種)ごとに違う。だから例えば冷蔵庫を替えようとすると、壁の配線を工事しなければならない。変圧器も変えなければいけないかもしれない。電子レンジが増えると、また別の工事が必要だ。ドライバーやニッパや半田ごて、場合によっては資格も必要になり、変更のたびに周辺が巻き込まれる。大工事になる。
コンセント文明では、統一規格の電源と機器側が 「この形で接続する」という契約(規格) を持っている。直流/交流、電圧、周波数といった電気的規格から、「差し込む」部分と「差し込まれる」部分の物理的形状まで規格で決まっている。電流供給側と消費側の機器は、 お互いに依存していない。それぞれが「100V50HzのJIS規格コンセント」という 「契約(contract)」に依存しているだけ だ。だから、早い。機器の設置場所を変えるのも簡単だし、機器変更も簡単だし、売ったり買ったりも最小限のコストで行える。
後半遅くならないソフトウェアは、どちらの方式で構築されるべきだろうか?
答えは明白だ。しかし、AIエージェントのコードは、何も言わなければデフォルトで直結する。「動けばいい」という最短経路を選ぶので、契約を経由しない配線を平気で引く。最初は問題ない。しかし機能が増えるにつれ、変更のたびに工事が発生し、後半の重さになって返ってくる。
コンセントのようなもの(契約)をどこに置くかを人間が決め、AIにそれを守らせる。 それがアーキテクト視点の第一歩だ。
実践編
実践編として、アーキテクト視点が「ない」AIコーディングと、「ある」AIコーディングの端的な例も挙げておく。もちろん、アーキテクト視点は一朝一夕で身につくものではないし、この記事で網羅的に語ったりすることは不可能(そもそも筆者がそれを網羅的に語る知識を持っていない)ため、あくまで「サンプル」ではあるが、なんとなくのイメージは掴んでいただけるのではないかと思う。
(例1)「後半確実に遅くなる」AIコーディング
AIコーディングツール、例えば Cursor を開き、新しいプロジェクト(フォルダ・リポ)でAIエージェントにこう指示する。(node は別途インストールされている想定)
時刻に応じてコンソールにあいさつ文を表示するプログラムを TypeScript で書いて。必要な依存関係はインストールして。
そうすると例えばエージェントはこんなプログラムを書いてくれる。
function greetingForHour(hour: number): string {
// hour は 0–23(ローカル時刻)
if (hour >= 5 && hour < 12) {
return "おはようございます";
}
if (hour >= 12 && hour < 17) {
return "こんにちは";
}
if (hour >= 17 && hour < 22) {
return "こんばんは";
}
return "遅い時間ですね。お疲れさまです";
}
const now = new Date();
const hour = now.getHours();
const timeStr = now.toLocaleTimeString("ja-JP", { hour: "2-digit", minute: "2-digit" });
console.log(`現在は ${timeStr} です。${greetingForHour(hour)}`);
うん、確かに動く。AIテクノロジーで自動プログラミングだ。素晴らしい。
ただ、「将来の要求仕様変更」に耐えられるかという視点で見ると少し怪しい。特定の環境やユーザーに対して挨拶文や出しわけロジックを変更することになったら?、コンソール以外にも同様の挨拶を出力することになったら?・・・etc
(例2)「もしかすると将来の礎になるかもしれない」AIコーディング
例1と同様、新規フォルダでAIエージェントに次のような指示をする。
時刻に応じてコンソールにあいさつ文を表示するプログラムを TypeScript で書いて。必要な依存関係はインストールして
-
SOLID原則を意識してレイヤリングする
-
フォルダ構成は以下のように番号プレフィックスで依存方向を明確化
- 0100_contracts/ → インターフェース・型定義のみ
- 0200_domain/ → 挨拶ロジック本体(時間判定・優先度など)
- 0300_output/ → コンソール出力などの具象
- 0400_entrypoint/ → メイン + DIコンテナ
-
依存ルール:数字が**大きい方から小さい方(内側)**だけを参照可能。小さい数字から大きい数字への依存は禁止。
-
depcruise でこの依存ルールを自動検査できるように設定して
-
DIはコンストラクタインジェクションでシンプルに(Container系ライブラリはまだ使わない)
-
各モジュールはSingle Responsibilityを守ること
一体何ができるであろうか。ぜひ試してみてほしい。(なかなかの構成になるのでここには結果を掲載しない。)
結果を掲載しない代わりに、後者の実装後、実装を担ったエージェントに次のような質問をしてみる。
↓のプログラムが「直結・日曜大工実装」だとしたら今の実装は「コンセント型・マンションレベルの建築に耐えられる」レベルかな?将来的な仕様変更に対する耐性や「プロジェクトの後半、実装が遅くなるかどうか」視点で教えて。
function greetingForHour(hour: number): string {
// hour は 0–23(ローカル時刻)
if (hour >= 5 && hour < 12) {
return "おはようございます";
}
if (hour >= 12 && hour < 17) {
return "こんにちは";
}
if (hour >= 17 && hour < 22) {
return "こんばんは";
}
return "遅い時間ですね。お疲れさまです";
}
const now = new Date();
const hour = now.getHours();
const timeStr = now.toLocaleTimeString("ja-JP", { hour: "2-digit", minute: "2-digit" });
console.log(`現在は ${timeStr} です。${greetingForHour(hour)}`);
エージェントからの回答
結論から言うと、「マンション級の構造の枠組みには届いているが、“マンションとして引き渡し可能”という意味の完成度までは言わない」のが正直な位置づけです。レイヤーと depcruise は後半に効くガードレールになりますが、プロジェクトの規模とチームの運営次第で効き方が変わります。
直結スクリプト(日曜大工)の強みと限界
一本の流れは最初の実装は速いし、要件が「1ファイルで出力だけ」なら十分です。
一方で、要件が増えると次のようなものが同じ関数/同じブロックに吸い込まれやすく、後から触るたびに全体を読み直す時間が伸びます。
- 時刻の取り方(テスト用の固定時刻、TZ、サーバー時刻)
- 文言の差し替え(locale、利用者セグメント、機能フラグ)
- 出力先の追加(ログ、HTTP、メッセージキュー)
- 表示フォーマット(
toLocaleTimeStringのオプション、テストでのスナップショット)
また「Date と console に直結」しているので、自動テストで振る舞いを安定させにくいのも、後半のボトルネックになりやすい点です。
いまの実装が「コンセント型」=マンション級か
できていること(マンションでよくやる“配線の分離”に近い)
- 時刻取得とドメイン判定と出力の責務が分かれている
-
内側への依存だけに寄せてあり、
depcruiseで配線ミスを自動で検知できる - 仕様の核(何時を朝とみなすか・文言)は、
time_of_day/greeting_messageに寄せやすい
ここまでは、「あとから差し替え・テスト・増築」しやすいコンセント(差し込み口)を先に決めた実装と言ってよいです。
まだ「マンション完成」ではない典型理由
- 本番運用では、だいたい テスト、設定、エラー方針、観測(ログ/メトリクス)、CIでdepcruise固定 などがセットになります。フォルダを分けただけでは「耐震・防火・管理組合の規約」までは含みません。
- チームがルールを無視して
anyや「とりあえず上位レイヤに import」などをすると、すぐ日曜大工に戻る。差は depcruise を CI で回すかどうかでかなり変わります。
仕様変更への耐性(ざっくり比較)
| 変更の種類 | 直結スクリプト | レイヤー+depcruise |
|---|---|---|
| 境界時刻や文言だけ変える | 早い(1か所) | ややファイルが分かれるが、変更箇所は明確 |
| テストで時刻を固定したい | 手が入りやすい | Clock を差し替えればやりやすい |
| 出力やフォーマットが増える | 同一ファイル肥大 | Writer 側だけ増やしやすい |
| ルールが複雑化(祝日・勤務地TZ) | 同じ関数が神になる | domain に閉じて増築しやすい(設計の質次第) |
「境界と文言だけ」の変更なら、直結でもレイヤーでも手間は近いことが多いです。差が開くのは、差し替え・テスト・複数出口・チープな増築が続くときです。
「後半、実装が遅くなるか」という視点
- レイヤーありは、最初はファイル数と認知負荷で遅く感じることがあります。
- ただし中長期では、(1) 壊れ方が予測しやすい、(2) レビューで「どこを直すか」が定まる、(3) 禁止依存を機械検査できる ため、手戻りと読み直しコストを下げる方向に働くことが多いです。
- 逆に、小さなツールを永久に1人で触るだけなら、レイヤー分けは純粋なオーバーヘッドになり得ます。
まとめ: いまの実装は、「配線をコンセントにして、配線ルールを機械で見る」という意味ではマンション寄りの土台です。一方で、テストや CI、運用上の約束事まで含めてプロとしての完成度と呼ぶには一段足りません。
チームで長く育てる/要件が増える見込みが高いならこの方向性は合理的で、短命の単発スクリプトなら、あなたが貼った直結版の方が総コストは低いことが多い、という整理になります。
AIは「設計を守れる」——ただし、守るべき設計が存在するなら
例2の実践が示していることは、AIへの批判ではなく、むしろその逆だ。
適切な設計意図を伝えれば、AIはその設計に見合った品質のコードを書く。レイヤーを明示し、依存ルールを定義し、それを機械的に検査する仕組みを整えれば、AIはユーザーの意図を汲み取った構成を生成し、そのルールの中で動き続ける。
問題は「AIが設計できない」ことではなく、「設計の文脈が存在しない状態でAIを走らせている」ことだ。電源とランプを渡して「ランプを点灯して」と言えば、普通の作業者は電源とランプを直結する。それが「指示に従った作業」だ。「ランプが切れたら簡単に交換できるようにして」「電源が壊れてないか確認できるメーターをつけて」「簡単にON/OFFできるスイッチをつけて」といった指示が必要なら、指示者がきちんと言語化する必要がある。
設計の文脈を作るのは人間の仕事だ。 それさえあれば、AIは想像以上に忠実にその設計を実装してくれる。
おわりに
「後半遅い」をAIのせいにするのは、大きな勘違いかもしれない。
AIは問題を生み出したわけではない。長年、僕たちが目を背けてきた 古典的なソフトウェア工学の問題——複雑性の増大と技術的負債の蓄積—— を、ただ容赦なく前倒しにして見せつけただけだ。AIという加速装置を手に入れたことで、従来は「まあいいか」でやり過ごせていた エントロピーの崩壊が、誰の目にも明らかな形で早期に露呈するようになった。これは危機ではなく、むしろ絶好の機会だ。
AIコーディングが普及した今こそ、エンジニアは「速く書く技術」から 「壊れないように速く書かせる技術」 へと、本質的なシフトを迫られている。アーキテクチャを意識し、エントロピーを低く保つ仕組みを設計し、それをAIに強制的に守らせる。プロンプトだけに頼る時代は終わり、設計意図をコードの構造とツールチェーンで物理的に担保する時代が始まっている。Uncle Bobが2010年代に警告した曲線は、今、AIによって圧縮されて目の前に突きつけられた。
このサインを見逃さず、真正面から向き合えるかどうかが、これからのエンジニアの価値を分ける。
機能やロジックを実装するのはAIに任せられるかもしれない。
しかし、ソフトウェアを長く健全に生き続けさせる責任は、2026年現在のところ、人間にしか負えない。AI時代に本当に必要なのは、ただの速いコーダーではなく、エントロピーを制御するアーキテクトだ。その覚悟を決めた者にこそ、AIは真の生産性と創造性を与えてくれるだろう。
-
Robert C. Martin (著), 角 征典・高木 正弘 (訳). Clean Architecture 達人に学ぶソフトウェアの構造と設計. 初版, ドワンゴ (KADOKAWA), 2018. ↩
-
この記事にはグラフ自体は掲載(引用)しませんが、例えば Amazon の「サンプルを読む」で、該当の「部」である「第I部 イントロダクション」は全て公開されているようです。(2026年4月8日確認) ↩
-
The Vibe Coding Crisis: How AI-Generated Technical Debt Is Costing Companies Millions(Kyros, 2025) ↩
-
Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity(METR, 2025) ↩