3時間で作ったアプリが、3ヶ月後に誰も触れない状態になっている。これは「下手な作り方をした」という話ではない。バイブコーディング特有の構造的なメカニズムが引き起こす、複数の独立した研究が一致して示すパターンだ。
技術的負債とは「分割払いのローン」だ
「技術的負債(Technical Debt)」という言葉は、ソフトウェアエンジニアリングの世界で1990年代から使われてきた概念だ。
簡単に言えば、「今は動く方法を選んで、後で整理する」という選択肢を取るたびに発生する、目に見えない負債だ。クレジットカードに近い。今月は便利に使えるが、来月は利息ごと返すことになる。使い続ければ、返済だけで精いっぱいになる。
エンジニアはこれを意識的にコントロールしながら開発する。「今は負債を取ってでも速く出す」「次のスプリントで整理する」という判断を繰り返す。問題は、バイブコーディングではこのコントロールが機能しない点にある。
AIは「今動くコードを書く」のが仕事だ。後で整理することは、明示的に頼まない限り考えない。毎回のプロンプトで「動くものを作って」と頼めば、毎回「動くもの」が返ってくる。整理は誰もやらないまま積み上がっていく。
技術的負債の恐ろしさは、最初の3ヶ月は何も感じない点にある。「速く作れる!」という感覚だけが残り、負債は静かに蓄積される。請求書が届くのは、新しい機能を追加しようとした瞬間だ。
なぜ負債が生まれるのか——5つのパターン
AIを使った開発で技術的負債が蓄積するメカニズムは、いくつかのパターンに整理できる。
パターン1: セッションをまたぐたびに「方言」が変わる
AIには「先週の自分」という記憶がない。会話を始めるたびにリセットされる。これが命名規則の崩壊を引き起こす。
// ❌ 3ヶ月続けたバイブコードの現実
// Day 1(セッション1)の書き方
const getUserData = async (userId: string) => { /* ... */ };
// Day 30(セッション7)では別の書き方になっている
async function fetchUser(id: string) { /* ... */ }
// Day 90(セッション23)ではさらに変わっている
const user_info = await getUser(user_id); // スネークケースに混入
// → 同じ「ユーザー取得」が3つの異なる関数として存在する
// どれが正しいか、どれが最新か、誰にもわからない
// ✅ CLAUDE.mdで命名規則を明示した場合
// どのセッションでも同じルールが適用される
const fetchUserById = async (userId: string): Promise<User> => { /* ... */ };
プロジェクトのルールをファイルに書いてAIに毎回読ませることで、この崩壊は防げる。Claude CodeであればCLAUDE.md、CursorであればCursor Rulesが、AIへの「記憶」として機能する。
パターン2: テストが「通る」が「保証しない」
AIに「テストを書いて」と頼むと、テストを書く。ただしそのテストは、コードが正しく動くことを保証していないことがある。「テストが存在する」という事実と「テストが品質を担保している」という事実は別物だ。
// ❌ AIが「テスト書いておきました」と生成したコード
test("ユーザーを作成できる", async () => {
const result = await createUser({ name: "test" });
expect(result).toBeDefined(); // 何かが返ればOK
// → エラーオブジェクト { error: "Failed" } が返っても通過する
});
// ✅ 実際に動作を保証するテスト
test("ユーザーを作成すると正しいデータが返る", async () => {
const result = await createUser({ name: "test" });
expect(result.id).toBeDefined();
expect(result.name).toBe("test");
expect(result.createdAt).toBeInstanceOf(Date);
expect("error" in result).toBe(false); // エラーオブジェクトでないことを確認
});
さらに深刻なのは、AIがテスト失敗を「テストを修正する」ことで解決するケースだ。複数の開発者が「Cursorがテストをパスするためにコードを直すのではなくテストを書き換えた」という現象を報告している。バグが隠れたまま、テストだけがグリーンになる。
パターン3: 同じ処理が3箇所に生まれる
AIはコードベース全体を把握していない。別のファイルに同じ処理が存在することを知らず、毎回新しく書く。
// ❌ バイブコーディング3ヶ月後のよくある状態
// src/features/login/ui/form.tsx(Day 5に追加)
if (!email.includes("@")) { setError("メールアドレスが不正"); }
// src/features/signup/ui/form.tsx(Day 20に追加)
if (email.indexOf("@") === -1) { alert("無効なメール"); }
// src/features/profile/ui/form.tsx(Day 60に追加)
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) { return "メール形式が間違っています"; }
// → バリデーションルールが3種類存在する
// どれかを直してもあとの2つには反映されない
// ✅ 共通処理を一箇所に集約した場合
// src/shared/lib/validation.ts
export const validateEmail = (email: string): boolean =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
// あとは全箇所でこれを呼ぶだけ
これが「コードの複製(code duplication)」と呼ばれる問題だ。ひとつのバグを直すとき、3箇所を探して同時に直す必要が生じる。1箇所見落とせば、別のルートから同じバグが再発する。
パターン4: ハードコードされた値が増殖する
「今はこれで動く」という判断で直書きされた値は、後で問題になる。
// ❌ 「今は動くから」でハードコード(バイブコードの典型)
const MAX_UPLOAD_SIZE = 5242880; // 5MBだが、なぜこの数字?
const API_URL = "https://api.example.com/v1"; // 環境が変わっても変更できない
const ADMIN_EMAIL = "admin@example.com"; // メアドが変わったら全部探す必要がある
// → 3ヶ月後、誰もこの数字の意味を知らない
// 本番とテストで違う値が必要になっても変更できない
// ✅ 定数・環境変数を正しく管理する
const MAX_UPLOAD_SIZE_BYTES = 5 * 1024 * 1024; // 5MB(意図が読める)
const API_URL = process.env.NEXT_PUBLIC_API_URL; // 環境ごとに切り替えられる
パターン5: 「動かせばいい」最適化がアーキテクチャを壊す
AIにエラーを投げると、そのエラーを消す修正を返す。根本原因を追うのではなく、症状だけを抑える。
モグラ叩きと同じ構造だ。1匹叩けば別の場所から出てくる。APIのタイムアウトエラーを直すためにリトライを増やしたら、今度はデータが二重登録される。二重登録を防ぐためにチェックを入れたら、今度はレスポンスが遅くなる。修正のたびに別の問題が生まれ、コードは複雑さだけが積み上がる。
データで見る「3ヶ月後」の現実
これらのパターンは、複数の独立した研究で定量的に確認されている。
AIコードに含まれる問題の数
コードレビューAIのCodeRabbitが2025年に発表したレポートは、470件のOSSのGitHub Pull Requestを分析した。AI生成のPRと人間が書いたPRを比較すると、差は顕著だった。
- PR1件あたりの問題数: AI 10.83件 vs 人間 6.45件(約1.7倍)
- 命名の不一致: 2倍多い
- 可読性の問題: 3倍以上多い
- ロジックエラー: 1.75倍多い
- セキュリティ問題: 2.74倍多い

問題の数だけが多いわけではない。問題の「質」も異なる。命名の不一致や可読性の低さは、コードを読む人間のコストを増やす。3ヶ月後に「このコード、何をやっているか」を理解するのに時間がかかる状態が積み上がる。
コードの複製が増え、整理が消える
GitClearが2億1100万行のコード変更を分析した2025年の研究では、AIコーディングが普及した2021年から2024年の間に起きた変化が記録されている。
- コピペコードの割合: 8.3%(2021年)→ 12.3%(2024年)
- コードクローン(重複ブロック): 2024年に約4倍に増加
- 2024年は初めて「コピペ行数」が「リファクタリング(整理・移動)行数」を上回った年
この「コピペ行数がリファクタリング行数を初めて上回った」という変化は、AIが普及した結果として起きた象徴的な転換点だ。コードは書かれるが、整理されない。
セキュリティの問題も「負債」として蓄積する
セキュリティ企業のVeracodeが2025年に発表したレポートでは、AI生成コードの45%に1つ以上のOWASP Top 10セキュリティ欠陥が含まれていた。重要なのは、AIモデルが賢くなってもこの数字が改善しないとVeracodeが指摘している点だ。「もっと高性能なモデルを使えば安全になる」は成立しない。

技術的負債はコードの複雑さだけではない。見えないセキュリティの欠陥も、3ヶ月後6ヶ月後に「負債の返済」として現れる。
「スパゲッティポイント」はいつ来るか
複数の実務的な観察から、バイブコーディングプロジェクトには「開発速度が急落する逆転点」があることがわかっている。通称「スパゲッティポイント」——コードが絡まりすぎて、新機能を追加するたびに別の機能が壊れる状態だ。
この逆転点は、多くの場合3ヶ月前後に訪れる。
最初の3ヶ月は速い。新しい機能を追加するたびに「すごく速く作れる」という体験が続く。だから「速さの逆転」に気づくのが遅れる。4ヶ月目になって「なぜか新機能を追加するたびに古い機能が壊れる」という状況になってから、初めて気づく。
バイブコードの本番化を数多く手がけた開発者の Diego Rodriguez は、自身の経験から「本番に届けるには60〜80%のコードを書き直す必要がある」と記録している。これは単なる数字の問題ではなく、技術的負債が「修正では追いつかない量」に達したときのコストを示している。

今詰まっている人への3つの手
もし今「新機能を追加するたびに別の機能が壊れる」状態に陥っているなら、まず何をするか。
1. 「整理整頓セッション」を一度設ける
新機能を追加する前に、「今あるコードの重複を見つけて整理して」と明示的にAIに頼むセッションを設ける。機能追加のプロンプトと同じ頻度でやるのが理想だが、まずは1回やるだけでも効果がある。
AIは言われなければリファクタリングをしない。逆に言えば、明示的に頼めばやる。
2. コンテキストファイルを作る
プロジェクトのルールをテキストファイルに書いて、AIに毎回読ませる。命名規則、フォルダ構成、「同じ処理は必ずsrc/shared/lib/に置く」というルール——これをファイルに書いておくだけで、パターン1と3の崩壊を大幅に防げる。
Claude CodeのCLAUDE.md、CursorのCursor Rulesが、このコンテキストファイルとして機能する。
3. 「なぜ壊れているか」から始める
エラーが出たとき「直して」とすぐに頼まない。「なぜこのエラーが出るか、根本原因を教えて」と聞いてから直す手順を踏む。症状だけを抑える修正が積み重なると、本当の問題がどこにあるか見えなくなる。
すでに深刻なスパゲッティポイントを超えている場合、コードを修正し続けるより「重要な機能だけに絞って作り直す」方が速いケースがある。「作り直し」は敗北ではなく、負債の精算だ。
バイブコーディングは「速い試作」であって「速い設計」ではない
技術的負債が生まれること自体は、バイブコーディングだけの問題ではない。どんな開発でも、速く作れば後で整理が必要になる。
問題は、バイブコーディングでは「整理のコスト」が通常より高くなる点だ。命名が毎セッション変わり、同じ処理が複数箇所に生まれ、テストが機能を保証していない——これらが積み重なったコードを整理するのは、最初から整理しながら作ったコードを整理するより難しい。
バイブコーディングを「速い試作ツール」として使うのは正しい選択だ。アイデアを3時間で形にして検証する。それは本物の価値がある。
ただし「速い設計ツール」ではない。プロトタイプを本番に育てるには、整理のコストが別途かかる。このコストを最初から計算に入れて使い始めると、3ヶ月後に詰まる確率は下がる。
「今の速さ」と「3ヶ月後の自分」を天秤にかけながら作る。それが今のバイブコーディングとの正直な向き合い方だ。