AIが10倍賢くなる魔法の言葉!プロンプトの書き方完全ガイド
同じAIを使っているのに、なぜか他の人の方が良いコードを生成している。そんな経験はありませんか?
実は、AIから高品質なコードを引き出せるかどうかは、「何を指示するか」で99%決まります。
この記事では、プロの開発者が実践している「AIを賢く使うプロンプトの書き方」を、初心者でもすぐに実践できる形で徹底解説します。読み終わる頃には、あなたのAIが別人のように賢くなっているはずです。
衝撃の事実:同じAI、指示の差で結果は100倍変わる
まず、実例をお見せします。同じAI(Claude 3.5 Sonnet)に、異なる指示を出した結果です。
❌ 悪いプロンプトの例
あなたの指示:
ログイン機能を作って
AIの出力:
// 超シンプルな、使い物にならないコード
function login(username, password) {
if (username === "admin" && password === "password") {
return true;
}
return false;
}
問題点:
- パスワードが平文で比較されている(セキュリティ最悪)
- データベースに接続していない
- エラーハンドリングがない
- 実際のアプリでは使えない
✅ 良いプロンプトの例
あなたの指示:
ログイン機能を実装してください。
【要件】
- フレームワーク: Express.js
- データベース: PostgreSQL
- 認証方式: JWT トークン
- パスワード: bcrypt でハッシュ化して保存
- ログイン失敗は3回まで、それ以上は30分間アカウントロック
- CSRF対策を含める
- エラーは適切なHTTPステータスコードで返す
【制約】
- async/await を使用すること
- エラーハンドリングは try-catch で囲むこと
- SQLインジェクション対策を含めること
AIの出力:
// 本番環境で使える、プロダクションレベルのコード
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { Pool } = require('pg');
const router = express.Router();
const pool = new Pool({ /* DB設定 */ });
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
// バリデーション
if (!email || !password) {
return res.status(400).json({ error: 'メールアドレスとパスワードを入力してください' });
}
// ユーザー取得(SQLインジェクション対策済み)
const result = await pool.query(
'SELECT * FROM users WHERE email = $1',
[email]
);
if (result.rows.length === 0) {
return res.status(401).json({ error: '認証情報が正しくありません' });
}
const user = result.rows[0];
// アカウントロックチェック
if (user.locked_until && new Date() < new Date(user.locked_until)) {
return res.status(423).json({ error: 'アカウントがロックされています' });
}
// パスワード検証
const isValid = await bcrypt.compare(password, user.password_hash);
if (!isValid) {
// ログイン失敗回数を増やす
await pool.query(
'UPDATE users SET failed_attempts = failed_attempts + 1 WHERE id = $1',
[user.id]
);
// 3回失敗でロック
if (user.failed_attempts + 1 >= 3) {
const lockUntil = new Date(Date.now() + 30 * 60 * 1000);
await pool.query(
'UPDATE users SET locked_until = $1 WHERE id = $2',
[lockUntil, user.id]
);
return res.status(423).json({ error: 'ログイン失敗が3回を超えました。30分後に再試行してください' });
}
return res.status(401).json({ error: '認証情報が正しくありません' });
}
// ログイン成功 - 失敗回数リセット
await pool.query(
'UPDATE users SET failed_attempts = 0, locked_until = NULL WHERE id = $1',
[user.id]
);
// JWTトークン生成
const token = jwt.sign(
{ userId: user.id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '24h' }
);
res.json({
token,
user: { id: user.id, email: user.email, name: user.name }
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ error: 'サーバーエラーが発生しました' });
}
});
module.exports = router;
結果の差は歴然です。指示の質が、出力の質を100%決定します。
プロンプトの「ゴルディロックス原則」:粗すぎず、細かすぎず
プロンプトには、**最適な粒度(細かさのレベル)**があります。
🔴 粗すぎる(Too Coarse)
指示:
Netflixのようなサイトを作って
結果:
- 機能しないプレースホルダーだらけ
- AIが「Netflix」の範囲を勝手に解釈(幻覚)
- 使えないコード
🔴 細かすぎる(Too Fine)
指示:
2つの数値を受け取って足し算する関数を書いて。引数名はnumber1とnumber2で。戻り値の型はnumberで。関数名はaddNumbersで。
結果:
- AIに頼む意味がない(自分で書いた方が速い)
- トークンとお金の無駄
🟢 最適(Just Right)
指示:
ReactとTailwindを使って、再利用可能なビデオプレーヤーコンポーネントを作成してください。
【機能】
- ソースURLをpropsで受け取る
- 再生/一時停止ボタン
- 音量調整スライダー
- 再生時間表示
- バッファリング状態の表示
【デザイン】
- モダンでミニマルな見た目
- モバイル対応(レスポンシブ)
結果:
- 実用的なコンポーネント
- 必要な機能が全て含まれる
- そのまま使える品質
原則: プロンプトは「仕事の原子単位」で切り分ける。1回の指示で、1つの完結した機能を作らせる。
【超重要】プロンプトの4層構造を理解する
プロ開発者のプロンプトは、**4つのレイヤー(層)**で構成されています。
レイヤー1:役割の割り当て(ペルソナ)
AIに「誰として振る舞うべきか」を教えます。
例:
あなたは10年以上の経験を持つシニアReact開発者です。パフォーマンス最適化とアクセシビリティに精通しています。
効果: AIのトレーニングデータの中で、「React」「パフォーマンス」「アクセシビリティ」に関連する部分を重点的に参照するようになります。
レイヤー2:目的(The "What")
何を作るのかを明確に述べます。
例:
ユーザープロフィール編集フォームを作成してください。
レイヤー3:制約条件(The "How")
ここが最も重要。どのように作るかを指定します。
技術スタック:
- フレームワーク: Next.js 14 (App Router)
- バリデーション: Zod
- フォーム管理: React Hook Form
- UI: shadcn/ui コンポーネント
スタイル・規約:
- TypeScript strict モード
- Airbnb JavaScriptスタイルガイドに従う
- 関数は必ず型注釈を付ける
パフォーマンス:
- 初期レンダリングは100ms以内
- 画像は Next/Image で最適化
- 不要な再レンダリングを防ぐ
セキュリティ:
- XSS対策を含める
- CSRF トークンを実装
- 入力値は必ずサニタイズ
レイヤー4:参照資料(グラウンディング)
特定のファイルやドキュメントを参照させます。
Cursorの場合:
@auth_controller.ts のエラーハンドリングパターンを参考にして、
@types/user.ts のUserインターフェースを使用してください。
Claude Codeの場合:
CLAUDE.md に記載されているプロジェクト規約に従ってください。既存の API エンドポイント(src/api/)の設計パターンを踏襲してください。
実践テクニック1:「思考の連鎖」でミスを激減させる
複雑なタスクの場合、いきなりコードを書かせてはいけません。
❌ 悪い例
指示:
決済処理の実装をして
AIの動き:
[すぐにコードを書き始める]
→ エッジケースを見落とす
→ セキュリティホールが残る
✅ 良い例
指示:
決済処理を実装する前に、以下を行ってください:
1. 実装計画の概要を説明する
2. 必要なファイルの変更をリストアップする
3. 潜在的なエッジケースを特定する
4. セキュリティ上の考慮点を列挙する
計画が確認できたら、コードを書いてください。
AIの動き:
[Plan]
決済処理の実装には以下のステップが必要です:
1. ファイル変更
- src/api/payment.ts を作成
- src/types/payment.ts にインターフェース追加
- src/services/stripe.ts を作成
2. エッジケース
- ネットワークエラー時の処理
- 決済途中でユーザーが離脱
- 重複決済の防止
- 金額が0円または負の値の場合
3. セキュリティ考慮点
- APIキーは環境変数で管理
- 決済金額はサーバー側で再計算(クライアント送信値を信用しない)
- idempotency key の実装
- ログに機密情報を残さない
この計画でよろしいですか?
あなた: 「OKです。実装してください」
結果: エッジケースとセキュリティを考慮した、堅牢なコードが生成される。
Claude Codeでは think コマンドを使用:
claude think "決済処理の実装計画を立てて"
実践テクニック2:スクリーンショット駆動開発
UIを作るとき、テキストで説明するのは非効率です。画像を使いましょう。
❌ テキストだけで説明(非効率)
指示:
ヘッダーを作って。左側にロゴ、右側にナビゲーションメニュー。背景は白で、文字は黒。ロゴは高さ40pxで、メニューは横並び。メニュー項目は「Home」「About」「Contact」。ホバー時に下線を表示。
結果: イメージと違うものが出来上がる可能性が高い。
✅ スクリーンショットを使用(超効率的)
指示:
[Figmaデザインのスクリーンショットを貼り付け]
この画像の通りにヘッダーを実装してください。
- Tailwind CSS を使用
- パディングとタイポグラフィを正確に一致させる
- モバイル(768px未満)ではハンバーガーメニューに変更
結果: デザイン通りのUIが1回で完成。
さらに強力:「バイブチェック」ループ
UIに問題がある場合:
- 壊れたUIのスクリーンショットを撮る
- チャットに貼り付けて「このレイアウトの問題を修正して」と指示
- 修正されたコードを確認
テキストで「divが左に10pxずれすぎている」と説明するより、10倍速いです。
実践テクニック3:コンテキスト・レイヤリング
AIに「全体像」を理解させることが重要です。
❌ コンテキストなしの指示
指示:
ユーザー一覧ページを作って
AIの思考:
「ユーザー」って何のユーザー?どんなデータ構造?既存のコードとの関係は?デザインシステムはある?
結果: 推測で作るため、既存コードと統合できない。
✅ コンテキストを含む指示
指示:
ユーザー一覧ページを作成してください。
【コンテキスト】
@types/user.ts に定義されたUserインターフェースを使用。
@components/Table.tsx の既存テーブルコンポーネントを再利用。
@api/users.ts から getUserList() でデータ取得。
【機能要件】
- ページネーション(1ページ20件)
- 名前とメールアドレスで検索
- ロール(Admin/User)でフィルタリング
- 「編集」「削除」ボタン
【デザイン】既存の管理画面デザインシステムに従う。
結果: 既存コードと完璧に統合された、一貫性のあるページが完成。
プロのテクニック:「コンテキストマップ」の作成
大規模プロジェクトでは、一時的なMarkdownファイルを作ります。
feature_context.md の例:
# 決済機能のコンテキスト
## 関連ファイル
- src/types/payment.ts - 決済関連の型定義
- src/services/stripe.ts - Stripe連携
- src/api/orders.ts - 注文API
## 使用するインターフェース
```typescript
interface Payment {
id: string;
amount: number;
currency: string;
status: 'pending' | 'completed' | 'failed';
}
```
## 既存のエラーハンドリングパターンすべてのAPI呼び出しは以下の形式:
```typescript
try {
const result = await apiCall();
return { success: true, data: result };
} catch (error) {
logger.error(error);
return { success: false, error: error.message };
}
```
使い方:
@feature_context.md を参照して、決済確認ページを作成してください。
これにより、プロジェクト全体を読み込ませることなく、必要な情報だけをピンポイントで提供できます。
プロンプト・テンプレート集(コピペOK)
テンプレート1:新規コンポーネント作成
あなたは経験豊富な[フレームワーク名]開発者です。
【タスク】
[コンポーネント名]を作成してください。
【技術スタック】
- フレームワーク: [例: React 18]
- スタイリング: [例: Tailwind CSS]
- 状態管理: [例: Zustand]
【機能要件】
1. [機能1の説明]
2. [機能2の説明]
3. [機能3の説明]
【制約条件】
- TypeScript strict モード
- Props の型定義は必須
- コメントは日本語で記述
- アクセシビリティ(ARIA属性)を考慮
【参照】
@existing-component.tsx のスタイルパターンを踏襲してください。
テンプレート2:バグ修正
以下のエラーが発生しています:
【エラーログ】
[エラーメッセージをペースト]
【コンテキスト】
@problematic-file.ts を分析して、問題の原因を特定してください。
【要求】
1. エラーの原因を説明する
2. 修正案を提示する
3. 修正後のコード全体を提供する
4. 同様のバグが他の箇所にないか確認する
エラーハンドリングを追加し、将来同じエラーが起きないようにしてください。
テンプレート3:リファクタリング
@target-file.ts をリファクタリングしてください。
【目的】コードの保守性とパフォーマンスを向上させる。
【制約】
- 既存の機能・動作は一切変更しない
- テストが通ることを確認
- 複雑度を下げる(if文のネストを減らす)
【実施項目】
1. 重複コードの削除
2. 関数を小さな単位に分割
3. 変数名をより分かりやすく変更
4. 型安全性の向上
変更内容の説明も含めてください。
テンプレート4:セキュリティレビュー
@api/ フォルダ内のすべてのファイルをセキュリティの観点でレビューしてください。
【チェック項目】
- SQLインジェクション対策
- XSS対策
- CSRF対策
- 認証・認可の適切な実装
- 機密情報のログ出力
- レート制限の実装
問題が見つかった場合:
1. ファイル名と行番号を指摘
2. 脆弱性の説明
3. 修正案の提示
問題がない場合も、その旨を報告してください。
よくある失敗パターンと対策
失敗1:曖昧な指示
❌ 悪い例:
エラーを直して
✅ 良い例:
以下のエラーを修正してください:
[エラーログをペースト]
@error-file.ts の該当箇所を特定し、修正案を提示してから実装してください。
失敗2:コンテキスト不足
❌ 悪い例:
データベースに保存して
✅ 良い例:
フォームデータを PostgreSQL に保存してください。
【テーブル】
users テーブル(@schema.sql 参照)
【使用するライブラリ】
pg (node-postgres)
【エラーハンドリング】一意制約違反は 409 Conflict を返すその他のDBエラーは 500 Internal Server Error
失敗3:一度に詰め込みすぎ
❌ 悪い例:
ユーザー登録、ログイン、プロフィール編集、パスワードリセット、メール認証を実装して
✅ 良い例:
【ステップ1】まずユーザー登録機能を実装してください。(詳細な要件)
完成したら、次のステップに進みます。
プロンプトの品質チェックリスト
指示を出す前に、このリストを確認しましょう:
- 役割(ペルソナ)を指定したか?
- 何を作るか明確に述べたか?
- 技術スタックを指定したか?
- 制約条件(スタイル、パフォーマンス、セキュリティ)を含めたか?
- 参照すべきファイルを@で指定したか?
- 複雑なタスクの場合、計画フェーズを含めたか?
- UIの場合、スクリーンショットを添付したか?
- 期待する出力形式を明示したか?
まとめ:プロンプトは「コードの設計図」
バイブコーディングにおいて、プロンプトはソースコードそのものです。
良いプロンプトの条件:
- 明確 - 曖昧さがない
- 具体的 - 技術スタックと制約を含む
- 構造化 - 4層レイヤーで整理
- 適切な粒度 - 粗すぎず細かすぎず
この記事で紹介したテクニックを実践すれば、あなたのAIは別次元の賢さを発揮します。
プロンプトの書き方を磨くことは、未来のプログラミングスキルそのものなのです。
📚 次に読むべき記事:
🔗 参考Web記事:
- Anthropic - Prompt Engineering Guide
- OpenAI - Best practices for prompt engineering
- [Cursor Documentation - Using @-mentions](https://docs.cursor.com/chat/@ mentions)
- Google AI - Prompting Guide
- Microsoft - Prompt engineering techniques