2026-10-12訂正:分割だけで品質を保証する断定を修正しました。Cardのdrag dataとClient境界を補い、未完成の抜粋と本番検証を区別しました。Claude3.5/3.7の推論機能・廃止を補足しました。
はじめに:AIエディタに「丸投げ」していませんか?
CursorやWindsurfなどのAIエディタの進化により、コードを書かずに自然言語だけで開発を進めるスタイルが普及してきました。
しかし、こんな経験はありませんか?
- 「〇〇の機能を作って」と雑に頼んだら、既存のコードの別機能まで破壊された
- コンポーネントが肥大化し、保守不可能な1000行のスパゲッティコードが生まれた (もはやAIがただの「スパゲティ🍝コード製麺機」と化している状態)
- 結局、AIの書いたコードを修正するのに自分で書く以上の時間がかかった
AIは優秀ですが、人間側の「指示(要件定義)」が甘いと、平気で破綻したアーキテクチャを提案してきます。
本記事では、AIにいきなりコードを書かせず、まずは「設計」をさせるための設計を先に確認するプロンプト案を公開します。
私は普段 Next.js / TypeScript で開発を行っていますが、この手法は Python・Go・Ruby など、他言語でも設計判断を整理する候補ですが、効果は対象と検証条件で異なります。
設計先行の比較例(完全アプリの検証結果ではない)
簡単な「タスク管理のカンバンボード(Trello風)を作って」という指示で、説明用のコード抜粋と設計案を比較します。元の実行ログ・モデル版・前後測定は今回確認できていません。
❌ 失敗パターン:いきなり書かせる
▼ 入力プロンプト
「Trelloのようなカンバンボードを作ってください。タスクの追加、移動ができるようにしてください。」
分割を検討する例:責務の集中
AIは即座にコードを書き始めますが、状態管理、ドラッグ&ドロップのロジック、UIの描画がすべて KanbanBoard.tsx という1つのファイルに詰め込まれたコードが出力されます。
'use client'; // Next App Routerでhook/eventを使うClient境界の例
// 未完成の抜粋。親状態更新や全testは含まない
import React, { useState } from 'react';
interface Task {
id: string;
title: string;
status: string;
}
export default function KanbanBoard() {
// 状態管理がすべてここに集中(肥大化の予兆)
const [tasks, setTasks] = useState<Task[]>([]);
const [columns, setColumns] = useState(['Todo', 'In Progress', 'Done']);
// D&Dのロジックも直書きされている
const handleDragStart = (e: React.DragEvent, taskId: string) => {
// 本来はここに複雑な状態計算やAPI通信が入る
e.dataTransfer.setData('taskId', taskId);
};
const handleDrop = (e: React.DragEvent, columnId: string) => {
// ドロップ時のタスク移動・並び替え処理(実際は50行以上の規模になる)
e.preventDefault();
};
return (
<div className="flex gap-4 p-4">
{/* 列の描画ループの中に、さらにカードの描画がネストされている */}
{columns.map(column => (
// ❌ onDragOver の preventDefault() も欠落しており、
// 実際にはドラッグ&ドロップすら動作しないバグを含む
<div key={column} onDrop={(e) => handleDrop(e, column)}>
<h2>{column}</h2>
{tasks.filter(t => t.status === column).map(task => (
<div key={task.id} draggable onDragStart={(e) => handleDragStart(e, task.id)}>
{task.title}
</div>
))}
</div>
))}
</div>
);
}
コンポーネント分割の概念がなく、変更が難しくなる場合があります。単一ファイルだけで必ず破綻する根拠はなく、小規模ならまとめる判断も妥当です。
⭕️ 成功パターン:魔法の『設計プロンプト』を使う
▼ 入力プロンプト(※テンプレは後述します)
「カンバンボードを作ります。【設計プロンプト】 に従って、まずはアーキテクチャとコンポーネント設計を提示してください。私が許可するまでコードは書かないでください。」
設計案の例:レビューする判断を可視化する
AIは一切コードを書かず、以下のような「設計書」をMarkdownで出力してきます。
### 1. 要件の整理
- タスクの作成、編集、削除
- ステータス(Todo, In Progress, Done)間のドラッグ&ドロップ移動
### 2. コンポーネント設計
- `KanbanBoard`: 全体のレイアウトと状態管理の親コンポーネント
- `KanbanColumn`: 各ステータスの列。ドロップゾーンとして機能
- `KanbanCard`: 個別のタスク要素。ドラッグ可能要素
### 3. データ設計・状態管理
まず親のuseState/useReducerや既存の状態管理で足りるか比較します。複数画面共有等の条件があればZustandを候補にします。
### 4. 懸念点とエッジケース
- タスクのドラッグ中に別ユーザーが同タスクを削除・更新した場合の競合処理
- 端末・カードの重さ・操作で描画時間を測り、必要なら仮想スクロールを比較。100件は普遍的な閾値ではない
人間は、この提案を見て「ZustandでOK。ただColumnはもう少し細かく分けて」と要件・責務・検証条件をレビューです。
設計に合意してから実装を指示すると、先ほどのスパゲッティコードとは打って変わり、機能ごとに分割した構成を生成する案になります。分割だけで品質が保証されるわけではありません。
▼ 生成されたディレクトリ構成
src/
├── components/
│ └── kanban/
│ ├── KanbanBoard.tsx # 全体の枠組みとProvider
│ ├── KanbanColumn.tsx # 列(ドロップゾーン)
│ └── KanbanCard.tsx # タスク(ドラッグ要素)
├── store/
│ └── useKanbanStore.ts # Zustandによる状態管理
└── types/
└── kanban.ts # Task, Columnの型定義
▼ 生成されたコンポーネント例1:KanbanCard.tsx(ドラッグ要素)
'use client';
// 分割例。親の状態更新とdrop時の検証は別に必要
import React from 'react';
import { Task } from '@/types/kanban';
interface KanbanCardProps {
task: Task;
onDragStart: (taskId: string) => void;
}
export const KanbanCard = ({ task, onDragStart }: KanbanCardProps) => (
<div
draggable
onDragStart={(event) => {
event.dataTransfer.setData('taskId', task.id);
onDragStart(task.id);
}}
className="p-3 mb-2 bg-white rounded shadow cursor-grab hover:bg-gray-50"
>
<p className="text-sm font-medium text-gray-800">{task.title}</p>
</div>
);
▼ 生成されたコンポーネント例2:KanbanColumn.tsx(ドロップゾーン)
'use client';
// dropを受け付けるためのイベント例。完全アプリではない
import React from 'react';
import { Column } from '@/types/kanban';
interface KanbanColumnProps {
column: Column;
children: React.ReactNode;
onDrop: (e: React.DragEvent, columnId: string) => void;
}
export const KanbanColumn = ({ column, children, onDrop }: KanbanColumnProps) => (
<div
onDragOver={(e) => e.preventDefault()} // ← Beforeで欠落していた必須処理
onDrop={(e) => onDrop(e, column.id)}
className="flex flex-col gap-2 p-3 bg-gray-100 rounded min-h-[200px] w-64"
>
<h2 className="font-bold text-gray-700">{column.title}</h2>
{children}
</div>
);
Propsと責務が明確になり、これなら後から「タグ表示を追加したい」「期限日の警告を出したい」といった改修範囲を整理しやすくなります。親のtask移動・不正ID/消失task・状態保存・keyboard/a11yを実装し、操作testsで確認してから完成と判断します。
🎁 魔法の『設計プロンプト』テンプレート(コピペ用)
AIエディタのチャット欄(または 現行Project Rules(.cursor/rules)等。旧.cursorrulesはlegacy方式)に、以下のプロンプトを貼り付けてみてください。
あなたは優秀なシニアアーキテクトです。
これから新しい機能(またはアプリ)の実装を依頼しますが、**絶対にいきなりコードを書き始めないでください。**
まずは以下のステップに従って、実装計画とアーキテクチャ設計を提示してください。
1. **要件の整理:** 私の依頼内容から、実装すべき機能のリストを箇条書きでまとめてください。不足している情報があれば質問してください。
2. **コンポーネント設計:** UIをどのように分割するか、それぞれの役割(PropsとState)を定義してください。
3. **データ設計・状態管理:** データをどのように管理するかを提案してください。
4. **懸念点とエッジケース:** この実装における技術的な懸念点、パフォーマンスのボトルネック、エラーハンドリングが必要な箇所を洗い出してください。
上記の1〜4をMarkdownで提示し、私(ユーザー)の承認を得てください。
私が「設計に合意します。実装を開始してください」と指示するまで、実際のコード生成は行わないでください。
なぜここまで品質が変わるのか?(技術的背景)
これはLLMの「確率的なトークン予測」という性質を逆手に取った、Task Decomposition(タスク分割) というプロンプトエンジニアリングの基本手法です。
いきなり「コードを書いて」と指示すると、LLMは「要件の推測」「設計」「構文の記述」という複雑なタスクを同時に処理しなければならず、結果として最も確率的に無難な(=とりあえず1ファイルに全部書く)出力を選びがちです。
しかし、プロンプトで 「思考のステップを分け、先に設計書を出力させる」 プロセスを挟むことで、要件と設計をレビューする段階を作れます。品質の劇的改善を測定した結果ではありません。
| アプローチ | コンテキストの状態 | コード品質 |
|---|---|---|
| いきなり実装 | ユーザーの短いプロンプトしかない | 仕様・構成・testsを要確認 |
| 設計プロンプト | LLM自身の設計書がコンテキストに含まれる | 設計案を材料に実装・検証する |
LLMは「直前の文脈(コンテキスト)」に強く引っ張られます。自ら出力した理路整然とした設計書を読み込ませてからコーディングに移行させることで、レビュー材料を増やせますが、設計書自体も誤り得ます。型・test・実動作・権限/副作用と本人の説明を併せて検証します。
元記事の本人申告と検証の区別
余談ですが、私自身、この記事の原稿をAIと一緒に作成している最中に 「AIが『Markdownの表を修正しました』と自信満々に報告してきたのに、プレビューで見ると完全に壊れたままだった(しかも5回連続で)」 というインシデントに遭遇しました。
▼ 実際にAIが「修正しました」と言って5回連続で出力してきたテキスト
アプローチ
コンテキストの状態
コード品質
いきなり実装
ユーザーの短いプロンプトしかない
保守できない負債
設計プロンプト
LLM自身の設計書がコンテキストに含まれる
堅牢なコード
(※パイプ文字 | と区切り行 |---| が完全に欠落しており、表として描画されない)
結局、この表のMarkdownだけは私が直接手打ちで修正する羽目になりました。
もし人間(私)の厳しいレビュー確認がなければ、この欠陥品がそのまま公開されていたわけです。AIは優秀ですが、人間側の統制が甘いと平気で破綻したものを納品してきます。
元記事の5回の報告と手修正は今回ログ未確認の本人申告です。一般的なモデル能力や品質改善の測定結果ではなく、本記事が提案する「人間が設計とレビューに集中し、AIを壁打ち相手にする」というテーマを考える例として扱います。
⚠️ この手法の「限界」と「注意点」
万能に見えるこの手法にも、AIの特性ゆえの限界があります。実務で使う際は以下の点に注意してください。
1.小規模な修正には「過剰」
数行のバグ修正や、1ファイルで完結する単純な処理に対して設計から考えさせると、かえって時間がかかります。状況に応じて「いきなり書かせる」との使い分けが必要です。
目安として、以下のいずれかに該当する場合に使うのがおすすめです:
- 新規コンポーネントが3つ以上生まれる実装
- 状態管理(グローバルステートなど)の設計判断が必要な場合
- 既存コードへの影響範囲が読めない機能追加
2.長すぎる会話(コンテキスト汚染)に注意
設計の議論が長引きすぎると、コンテキストウィンドウが不要な情報で溢れ、いざ実装フェーズに入った時にAIが混乱することがあります。設計がまとまったら、一度チャットをリセットして設計書に加え、確定要件・制約・権限・受入れ条件・未確認を保持して渡し直す方法が候補です。resetだけで精度を保証しません。
3. 推論特化モデルとの相性
推論機能はmodel/versionで確認します。Claude3.5 Sonnetをextended thinking搭載として一括りにする元説明を訂正し、3.7での導入と区別します。Claude APIの3.5は2025-10-28、3.7は2026-02-19に廃止済みで、現行モデルの推奨例とは扱いません。モデルを替えても要件・計画・testsの確認は必要です。
まとめ:AIを「作業者」ではなく「壁打ち相手」にする
AI駆動開発において、AIへの丸投げは技術的負債の先送りにすぎません。
人間が要件定義とアーキテクチャの意思決定に集中し、AIを優秀な「壁打ち相手」として活用することこそが、真の生産性向上に繋がります。
このプロンプト案は設計・検証条件を整理する道具です。使うだけで品質改善を保証するものではありません。ぜひ、次の開発からコピペして試してみてください!
最後まで読んでいただき、ありがとうございました。
この記事が少しでも「役に立った!」「試してみたい」と思ったら、ぜひ LGTM やストックをお願いします! 皆さんのプロンプトの工夫などもコメント欄で教えていただけると嬉しいです。
この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表 / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。
訂正の根拠・確認範囲
Next Client境界、Cursor Rules、Claude3.7発表、model廃止を照合しました。TSX構文とmockイベント分岐を確認し、完全な型check/build/React画面・DnD/keyboard/a11y・前後品質・本人実行ログは今回未検証です。
