AIによるコード生成ツールの進化は、私たちの開発スタイルを劇的に変えつつあります。
簡単な指示を出すだけで、驚くほど高速にアプリケーションの雛形が完成するようになりました。
しかし、その手軽さの裏側で、新たな課題に直面している方も多いのではないでしょうか。
それは、AIが生成したコードが、しばしば「スパゲッティコード」になってしまう問題です。
一見すると動いているように見えても、コンポーネントが巨大すぎたり、命名が不統一だったり、同じような処理が至る所に散らばっていたり…。
このようなコードは保守性が低く、将来の機能追加やバグ修正の際に大きな足かせとなります。
この記事では、そんなAIが書いたスパゲッティコードを、AIソフトウェアエンジニア「Lovable(ラバブル)」を使って「きれいなコード」にリファクタリングしていくための、具体的な指示術(プロンプト)を徹底解説します。
AIを単なるコード生成係ではなく、優秀なペアプログラマーとして育て上げ、保守性と拡張性の高いアプリケーションを効率的に構築するテクニックを身につけましょう。
なぜAIは「スパゲッティコード」を書いてしまうのか?
AI、特に大規模言語モデル(LLM)がなぜ読みにくく、メンテナンスしにくい「スパゲッティコード」を生成してしまうのでしょうか。その原因は、AIの思考プロセスと特性にあります。
1. 文脈理解の限界と短期的な最適化
AIは与えられたプロンプトに対して、その場で最も確率の高い「正解」を出力しようとします。しかし、プロジェクト全体の設計思想や将来の拡張性といった、コードに明記されていない長期的な視点を持つことは苦手です。例えば、「ユーザー一覧ページを作って」と指示すれば、その機能を最短で実装することに集中します。その結果、とりあえず1つの巨大なコンポーネントに全てのロジックを詰め込んでしまう、といったことが起こりがちです。これは、人間が短期的な締め切りに追われて場当たり的な実装をしてしまうのと似ています。
2. 具体的なスパゲッティコードの例
AIが生成しがちなコードには、いくつかの典型的なパターンがあります。
- 巨大なコンポーネント: 1つのファイルに数千行のコードが記述され、UI、ビジネスロジック、状態管理が密結合している。
- 命名の不統一: ある場所では`userList`、別の場所では`usersData`のように、同じ意味の変数名や関数名が統一されていない。
- マジックナンバー・マジックストリング: `if (status === 2)` や `const TAX_RATE = 0.1;` のような、意味が自明でない数値や文字列がコード中に直接記述されている。
- ロジックの重複(Don’t Repeat Yourself原則の違反): 複数のコンポーネントで、APIからデータを取得する処理など、同じようなコードがコピー&ペーストされている。
これらのコードは、書いた直後は問題なく動作するかもしれません。しかし、数ヶ月後に「消費税率を変更したい」となった時、プロジェクト内のすべての「0.1」を探し出して修正する必要があるとしたら…その大変さは想像に難くないでしょう。
3. スパゲッティコードを放置するリスク
このようなコードを放置することは、技術的負債を増大させ、プロジェクトの健全性を著しく損ないます。
- バグの温床になる: コードの見通しが悪いため、修正による思わぬ副作用(デグレード)が発生しやすくなります。
- 機能追加が困難になる: 既存のロジックとの依存関係が複雑なため、新しい機能を追加するたびに大規模な修正が必要になります。
- チーム開発の妨げになる: 新しく参加したメンバーがコードの全体像を理解するのに膨大な時間がかかり、生産性が低下します。
AIによる開発の初期速度というメリットは、保守性の低さというデメリットによって、あっという間に相殺されてしまうのです。だからこそ、AIと対話しながらコードを洗練させていく「リファクタリング」のスキルが、これからのエンジニアにとって不可欠となります。そして、その対話型開発に特化して設計されたツールが、今回ご紹介する「Lovable」なのです。
Lovableで実践する「きれいなコード」へのリファクタリング基本戦略
Lovableは、単にコードを生成するだけでなく、対話を通じてアプリケーションを育てていくことを得意としています。AIが生成した初期コードを「素材」と捉え、ここから人間が「設計者」として介入し、きれいなコードへと導くための基本戦略を見ていきましょう。
LovableはデフォルトでReact 18, TypeScript, Vite, Tailwind CSS, shadcn/uiといったモダンな技術スタックを採用しており、リファクタリングを行う上で非常に堅牢な土台を提供してくれます。この土台を活かすことが重要です。
戦略1:まず「設計思想」という名の憲法を制定する
家を建てる前に設計図を描くように、コードを書き始める前に「どのようなルールでコードを書くか」という設計思想をAIに与えることが最も重要です。これを最初にインプットすることで、以降のAIの生成物の品質が劇的に向上します。
具体的なプロンプト例:
「これから〇〇という目的のWebアプリケーションを開発します。以下のコーディング規約を厳守してください。
1. 技術スタック: React, TypeScript, Tailwind CSSを使用します。
2. コンポーネント設計: Atomic Designの思想に基づき、`components/atoms`, `components/molecules`, `components/organisms` のようにディレクトリを分け、再利用性を意識して設計します。
3. 状態管理: シンプルな状態は`useState`、コンポーネント間で共有する複雑な状態は`Zustand`を使用します。
4. 命名規則: コンポーネントはPascalCase(例: `UserProfile`)、関数や変数はcamelCase(例: `fetchUserData`)で統一します。
5. 定数管理: 色のコードやAPIのエンドポイントなど、再利用する値は`src/constants`ディレクトリ内のファイルで定数として管理します。」
このように、プロジェクトの「憲法」を最初に定義することで、AIは闇雲にコードを生成するのではなく、一貫性のあるルールに従ってくれるようになります。
戦略2:一度に一つずつ、小さく具体的に指示する
「ECサイトを作って」のような漠然とした大きな指示は、AIがスパゲッティコードを生む原因になります。Lovableが提唱する「vibe coding」の思想に則り、人間がタスクを分解し、一つずつ具体的に指示していくことが成功の鍵です。
悪い例: 「ユーザー管理と商品管理と決済機能があるECサイトを作って」
良い例(ステップ・バイ・ステップ):
1. 「まず、Supabase(Lovable Cloud)を使ったメールアドレスとパスワードでのサインアップ・ログイン機能を作成してください。」(→確認・修正)
2. 「次に、ログインしたユーザーが自分のプロフィール情報を編集できるページを作成してください。」(→確認・修正)
3. 「続いて、商品のCRUD(作成・読み取り・更新・削除)ができる管理画面を作成します。商品テーブルのスキーマは…」(→確認・修正)
このように、一つの機能が完成するごとに挙動を確認し、必要であればその場でリファクタリングを指示します。この反復的なプロセスが、プロジェクトが混沌に陥るのを防ぎます。
戦略3:Lovableの機能を使い分け、AIと人間の役割を分担する
Lovableの強みは、すべてをプロンプトで解決しようとしない点にあります。適切な場面で適切な機能を使い分けることで、より効率的に開発を進められます。
- プロンプト: 機能追加、ロジック構築、全体的なリファクタリングなど、構造的な変更に使用します。
- Visual Edits: ボタンの色やマージン、テキストの変更といったUIの微調整に使います。これにより、見た目の修正のためにプロンプトの履歴を汚すことなく、直感的にデザインを整えられます。
- Code Mode: 複雑なアルゴリズムや、AIではうまく生成できない特殊なロジックを実装する際に、人間が直接コードを記述します。
AIに全体の8割の骨格を作らせ、デザインの最後の仕上げと、特に重要なロジックの2割を人間が担当する。このハイブリッドな開発スタイルこそ、Lovableが目指す新しい開発の形です。
【具体例】Lovableへのリファクタリング指示術(プロンプト例付き)
それでは、AIが生成しがちな典型的なスパゲッティコードを、Lovableを使ってどのようにリファクタリングしていくか、具体的なプロンプト例を交えて見ていきましょう。ここでのポイントは、「何をしてほしいか」だけでなく「なぜそうするのか」という設計意図も伝えることです。
ケース1:巨大化したコンポーネントを分割する
AIはしばしば、関連する機能をすべて1つのファイルに詰め込んでしまいます。これを「関心の分離」の原則に基づいて分割させます。
ありがちなコード(リファクタリング前):
`Dashboard.tsx`というファイルに、ユーザー情報の表示、最近のアクティビティ一覧、統計グラフの表示ロジックがすべて混在している状態。
悪い指示例:
「このコンポーネントを分割して。」
→ これでは、AIがどのような基準で分割すれば良いか判断できません。
良い指示例(設計意図を伝える):
「現在の`Dashboard.tsx`は機能が多く、見通しが悪くなっています。関心の分離を行うため、以下の3つの子コンポーネントに分割してください。
1. `UserProfileCard.tsx`: ユーザーのプロフィール情報を表示する部分。
2. `RecentActivityFeed.tsx`: 最近のアクティビティ一覧を表示する部分。
3. `StatisticsChart.tsx`: 統計グラフを表示する部分。
これらのコンポーネントを`src/components/organisms/dashboard/`ディレクトリに作成し、`Dashboard.tsx`からはこれらのコンポーネントを呼び出すだけのシンプルな形にリファクタリングしてください。必要なpropsは適切に渡してください。」
このように、新しいコンポーネント名やディレクトリ構成まで具体的に指示することで、AIは設計者の意図を正確に汲み取り、理想的な構造に変更してくれます。
ケース2:マジックナンバーをなくし、可読性を向上させる
コード内に直接書かれた意味不明な数値(マジックナンバー)は、将来のバグの元です。これらを意味のある定数に置き換えるよう指示します。
ありがちなコード(リファクタリング前):
`setTimeout(doSomething, 3600000);`
`if (user.role === 1) { … }`
悪い指示例:
「コードを読みやすくして。」
→ AIは何を改善すべきか分かりません。
良い指示例(ルールを定義する):
「プロジェクト全体の可読性を向上させるため、マジックナンバーとマジックストリングを排除します。以下のルールに従ってコードを修正してください。
1. `src/constants/`ディレクトリに`time.ts`ファイルを作成し、`ONE_HOUR_IN_MS = 3600000` のような時間に関する定数を定義してください。
2. 同じく`src/constants/`に`roles.ts`ファイルを作成し、`USER_ROLES = { ADMIN: 1, GUEST: 2 }` のようなユーザー権限に関する定数を定義してください。
3. プロジェクト内のすべてのマジックナンバーを、これらの定数をインポートして使用するように置き換えてください。」
この指示により、`if (user.role === USER_ROLES.ADMIN)` のように、コードが自己説明的になり、誰が読んでも意味が理解できる「きれいなコード」に変わります。
ケース3:ロジックを抽出し、再利用可能なカスタムフックを作成する
複数のコンポーネントで同じような処理が繰り返されている場合、それはロジックを共通化するサインです。Reactではカスタムフックを作成することで、効率的にロジックを再利用できます。
ありがちなコード(リファクタリング前):
`ComponentA.tsx`と`ComponentB.tsx`の両方で、`useState`と`useEffect`を使ってAPIからデータをフェッチするほぼ同じコードが記述されている。
悪い指示例:
「重複したコードをまとめて。」
→ どうまとめるかの選択肢が多すぎます。
良い指示例(具体的な実装方法を指定する):
「複数のコンポーネントでAPI通信ロジックが重複しています。DRY(Don’t Repeat Yourself)原則に従い、これを再利用可能なカスタムフックに抽出します。
– `src/hooks/`ディレクトリに`useFetch.ts`という名前でファイルを作成してください。
– このカスタムフック`useFetch`は、APIのURLを引数として受け取ります。
– 内部で`data`, `isLoading`, `error`の3つの状態を管理し、それらを返り値としてください。
– `useEffect`を使って、URLが変更された際に非同期通信を実行するように実装してください。
– 最後に、重複しているコンポーネントのロジックを、この`useFetch`フックを使用するように書き換えてください。」
この指示は、AIに「作業者」としてだけでなく、Reactのベストプラクティスを理解した「設計者」としての振る舞いを求めています。ここまで具体的に指示することで、AIはその能力を最大限に発揮し、アプリケーションの品質を飛躍的に向上させることができるのです。
まとめ:AIを「育てる」という新しい開発スタイルへ
本記事では、AIが生成しがちな「スパゲッティコード」を、AI開発プラットフォーム「Lovable」を使って保守性の高い「きれいなコード」にリファクタリングするための具体的な指示術を解説しました。
重要なポイントをまとめます。
- 最初に設計思想を伝える: プロジェクトのルールを最初に定義することで、AIの生成物の一貫性を保つ。
- 小さく、具体的に指示する: 一度に大きなタスクを任せず、ステップ・バイ・ステップで確認と修正を繰り返す。
- 設計意図を明確にする: 「なぜそうするのか」という背景を伝えることで、AIはより的確なコードを生成する。
- AIと人間のハイブリッド開発: Lovableの機能を使い分け、それぞれの得意な領域で能力を発揮させる。
AIによるコード生成は、もはや魔法ではありません。それは強力なツールですが、使いこなすには乗り手である人間のスキルが求められます。AIにただコードを書かせるのではなく、対話を通じてコードを「育て上げ」、より良い設計へと導いていく。Lovableは、まさにそんな新しい時代の開発スタイルを体現するプラットフォームです。
AIとのペアプログラミングを通じて、開発の生産性とコードの品質を両立させる。そんな未来の開発を、あなたも体験してみませんか?Lovableはクレジットカード不要で、無料で始めることができます。(2026年2月時点の情報)
また、Lovableの料金プランやアカウント作成方法、さらに詳しい機能については、こちらの完全ガイド記事で網羅的に解説していますので、ぜひ合わせてご覧ください。
