言語を切り替える
テーマを切り替える

AI コード生成のミスを減らす?この5つの Prompt テクニックで効率50%アップ

金曜日の午後4時半、Cursor が生成したコードを見つめながら、私は呆然としていました。

単にユーザーログインのインターフェースを書いてもらいたかっただけなのに、出てきたのは300行の怪物——パラメータの型は間違いだらけ、データベース接続はコードにハードコーディングされ、3つの異なるエラー処理方式が混在していました。深呼吸して削除し、やり直し。2回目は、変更してほしくない設定ファイルまで原形をとどめないほど書き換えられてしまいました。

その瞬間、ハッとしました。問題は AI にあるのではなく、「何をすべきで、何をすべきでないか」を伝えていない私にあるのだと。

こんな感覚はありませんか? AI プログラミングツールを導入し、期待に胸を膨らませていたのに、いざ使ってみると——生成されるコードは的はずれだったり、一見正しそうでも動かすとエラーになったり。何度も修正を繰り返すうちに、自分で書いた方が早いと気づく。

正直なところ、私も以前はプロンプトエンジニアリングなんて重要ではないと思っていました。AI に話しかけるだけでしょ? 難しいことなんてない、と。しかし、同僚が同じ Cursor を使って、同じ機能を、私が1時間かかったところを10分で終わらせるのを見て考えが変わりました。違いはどこにあったのか? 彼のプロンプトは構造が明確で、コンテキストが完全で、境界がはっきりしていたのです。

この記事では、すぐに効果が出る Cursor Prompt の5つのテクニックを伝授します。高尚な理論ではなく、実戦から導き出された「現場の公式」です。これを読めば、AI に要件を真に理解させ、正確で使えるコードを生成させる方法がわかります。

なぜあなたの Prompt はいつも「失敗」するのか

AI は心を読めない、与えられた情報しか「見えない」

多くの人は AI が賢いので、自分が欲しいものを察してくれると思っています。間違いです。AI がどれほど強力でも、それは「高度なテキスト補完器」に過ぎず、あなたが提供した情報に基づいて推論することしかできません。言わなかったことは「推測」するしかないのです。

例えるなら、友人にコーヒーを買ってきてと頼むようなものです。「コーヒー買ってきて」とだけ言われたら、友人は店で困惑します。アメリカーノ? ラテ? サイズは? 砂糖は? 結局、勘で適当に買うしかありません。AI も同じです。

特に大規模プロジェクトでは、AI の「記憶喪失」問題が顕著になります。コンテキストウィンドウには限りがあり、コードベース全体を「脳」に入れることはできません。ある関数を修正させようとしたとき、AI はその関数が他の20箇所から呼び出されていることを知らず、修正して壊してしまうかもしれません。

よくある3つの Prompt の災難

災難1:曖昧すぎる

❌ “ソート機能を実装して”

これは GPS に「東京に行きたい」と入力するようなものです。東京のどこ? 手段は? いつ? AI はこの指示を受け取ると、自由に振るうしかありません。バブルソートを書くかもしれないし、プロジェクトに存在しないサードパーティライブラリを呼び出すかもしれません。

✅ ” utils/array.ts ファイルに、ユーザーリストを登録日時の降順でソートする関数を追加して。ネイティブの Array.sort() メソッドを使用し、新しい依存関係は導入しないで”

違いがわかりますか? 後者は、どのファイルで、どのデータを操作し、どの方法を使い、どんな制限があるかが明確です。

災難2:コンテキスト不足

❌ “エラー処理を追加して”

AI:どこに追加するの? 何のエラーを処理するの? try-catch? エラーコード? 返却フォーマットは?

医者に「どこか具合が悪い」とだけ言って、「痛い」としか答えないようなものです。これでは診察できません。

✅ ” api/login.ts の handleLogin 関数にエラー処理を追加して:

  • ネットワークリクエストの失敗を捕捉(try-catch 使用)
  • 統一されたエラーフォーマット { success: false, error: string } を返す
  • 既存の api/register.ts のエラー処理方式を参考にする”

災難3:制約条件がない

❌ “このコンポーネントのパフォーマンスを最適化して”

AI はこの指示を受けると、コードを跡形もなく書き換えるかもしれません——新しいライブラリの導入、状態管理の変更、さらにはコンポーネントアーキテクチャの書き直しまで。あなたが欲しかったのは React.memo を追加することだけだったのに、大手術になってしまいました。

✅ ” UserList.tsx コンポーネントのパフォーマンスを最適化して:

  • 使用してよいのは React.memo または useMemo のみ
  • コンポーネントの props インターフェースは 変更しない
  • 新しいサードパーティライブラリは 導入しない

AI の「幻覚」の正体

AI が生成したコードの中に、存在しない関数が呼び出されていたり、プロジェクトにない変数が参照されていたりしたことはありませんか? これが AI の「幻覚(ハルシネーション)」です。

Cursor 公式のベストプラクティス研究によると、明確なコンテキスト情報を提供することで 幻覚問題を70%削減 できます。なぜでしょうか?

AI は情報が不完全なとき、自動的に「脳内補完」します。既存のコードがどうなっているか教えなければ、「一般的なパターン」に基づいて推測します。例えばログイン機能を書かせると、authService.login() というメソッドがあるはずだと決めつけますが、あなたのプロジェクトにはそんなものはないかもしれません。

解決策はシンプルです:関連する既存のコードを AI に明確に見せること

私は今、プロンプトを書く前に必ず自分に3つの問いかけをしています:

  1. AI は私がどのファイルを操作しているか知っているか?
  2. AI は既存のコード構造を知っているか?
  3. AI は何を変更してよくて、何を変更してはいけないか知っているか?

これらに答えられないなら、まだプロンプトを送信するべきではありません。

構造化 Prompt の黄金公式

5W1H フレームワーク:AI に要件を秒で理解させる

ニュース記者が記事を書くときの古典的な公式、5W1H(Who, What, When, Where, Why, How)は、プロンプト作成にも使えます。

  • What(目標):AI に何をしてほしいか?
  • Why(理由):なぜそうするのか?(AI に意図を理解させる)
  • Where(場所):どのファイル/モジュールで操作するか?
  • When(タイミング):どんな状況でトリガーされるか?
  • Who(対象):操作するデータオブジェクトは何か?
  • How(方法):どんな技術スタック/ライブラリを使うか?

難しそうですか? 毎回すべて書く必要はありません。核心は:AI に推測させないことです。

例えば、データ検証機能を追加させたい場合:

❌ 曖昧版:

ユーザー入力検証を追加

✅ 5W1H版:

**What**: ユーザー登録フォームに入力検証を追加
**Where**: src/components/RegisterForm.tsx
**Who**: ユーザー名、メール、パスワードの3フィールドを検証
**How**: 既存の Yup ライブラリを使用(インストール済み)
**When**: ユーザーが送信ボタンをクリックした時にトリガー
**Why**: 無効なデータがバックエンドに送信されるのを防ぐため

AI はこの指示を受け取れば、まず道を外れることはありません。

Cursor 公式推奨の構造化テンプレート

Cursor チームがまとめた、より実用的なテンプレートがあります。私自身数ヶ月使っていますが、本当に便利です:

## Goal(目標)
[何を達成したいか一言で]

## Context(コンテキスト)
[現在のファイル、関連コード、技術スタック]

## Current Behavior(現在の振る舞い)
[今の状態はどうなっているか]

## Desired Behavior(期待する振る舞い)
[どのような結果を望むか]

## Acceptance Criteria(受け入れ基準)
[完了の条件]

## Constraints(制約)
[変更してはいけないもの、守るべきルール]

このテンプレートの素晴らしい点は Constraints(制約) セクションにあります。多くの人はプロンプトで「何をすべきか」だけを言い、「何をしてはいけないか」を言いません。その結果、AI は自由奔放に振る舞いすぎます。

実戦ケース:React ログイン機能

実際のシナリオで比較してみましょう。React プロジェクトにユーザーログイン機能を追加するとします。

❌ 曖昧な Prompt(初心者にありがち)

ユーザーログイン機能を実装して

これを受け取った AI は、200行のコンポーネントを書き、不要なライブラリを大量にインポートし、存在しない API インターフェースまで勝手に「発明」するかもしれません。

✅ 構造化 Prompt(達人のやり方)

## Goal
React プロジェクトにユーザーログイン機能を実装する

## Context
- プロジェクトは React 18 + TypeScript
- 状態管理:Redux Toolkit
- 既存 API サービス:src/services/authService.ts(login メソッドを含む)
- UI ライブラリ:Ant Design 5.x

## Current Behavior
ログインページ(src/pages/Login.tsx)は静的な UI のみで、インタラクションロジックがない

## Desired Behavior
1. ユーザーがユーザー名とパスワードを入力して「ログイン」をクリック
2. authService.login() を呼び出して認証
3. 成功:token を Redux に保存し、 /dashboard へ遷移
4. 失敗:エラーメッセージを表示(Ant Design の message.error 使用)

## Acceptance Criteria
- [ ] フォーム検証:ユーザー名とパスワードは必須
- [ ] ログイン処理中は loading 状態を表示
- [ ] パスワード入力欄は type="password" を使用
- [ ] ESLint と TypeScript のチェックを通過する

## Constraints
- authService.ts ファイルは **変更しない**
- 新しいサードパーティライブラリは **導入しない**
- **必ず** 既存の Redux slice(src/store/authSlice.ts)を使用する

生成結果を比較してみましょう:

最初の Prompt では、AI はこんなコードを出すかもしれません:

// ❌ AI が自由に振る舞った結果
import { useState } from 'react';
import axios from 'axios'; // 新しいライブラリを勝手に入れた
// ...

function Login() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = async () => {
    // 存在しない API を直接呼び出し
    const res = await axios.post('/api/auth/login', { username, password });
    localStorage.setItem('token', res.data.token); // Redux を使っていない
  };

  // ... 以下、不要なコードが150行続く
}

2つ目の Prompt なら、AI は厳密に要求に従います:

// ✅ 構造化 Prompt の結果
import { useState } from 'react';
import { Form, Input, Button, message } from 'antd';
import { useDispatch } from 'react-redux';
import { login } from '@/services/authService';
import { setToken } from '@/store/authSlice';
import { useNavigate } from 'react-router-dom';

export default function Login() {
  const [loading, setLoading] = useState(false);
  const dispatch = useDispatch();
  const navigate = useNavigate();

  const handleSubmit = async (values: { username: string; password: string }) => {
    setLoading(true);
    try {
      const { token } = await login(values.username, values.password);
      dispatch(setToken(token));
      navigate('/dashboard');
    } catch (error) {
      message.error('ログインに失敗しました。ユーザー名とパスワードを確認してください');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Form onFinish={handleSubmit}>
      <Form.Item name="username" rules={[{ required: true, message: 'ユーザー名を入力してください' }]}>
        <Input placeholder="ユーザー名" />
      </Form.Item>
      <Form.Item name="password" rules={[{ required: true, message: 'パスワードを入力してください' }]}>
        <Input.Password placeholder="パスワード" />
      </Form.Item>
      <Button type="primary" htmlType="submit" loading={loading}>
        ログイン
      </Button>
    </Form>
  );
}

違いは歴然です。2つ目のコードは:

  • 指定された Ant Design コンポーネントを使用
  • 既存の authService を呼び出し
  • Redux で token を保存
  • フォーム検証と loading 状態を実装
  • 新しい依存関係はゼロ

これが構造化 Prompt の威力です。

すぐに効果が出る5つの Prompt テクニック

テクニック1:まず計画、次にコーディング(Plan Mode)

これは私が使って一番驚いた機能です。

以前は AI に直接コードを書かせていましたが、よく失敗しました——変更すべきでないファイルを変更したり、重要なコードを削除したり、ロジックが破綻していたり。その後 Cursor の Plan Mode(Shift+Tab で切り替え)を見つけ、ワークフローが一変しました。

Plan Mode のロジックは:AI にまず考えさせ、それから手を動かさせる

具体的なフロー:

  1. 要件を記述
  2. AI がコードベースを分析し、質問を投げる(例:「既存のエラー処理は維持しますか?」)
  3. AI が行動計画(どのファイルを修正し、どんな機能を追加するか)を策定
  4. あなたがその計画を審査・修正する
  5. 確認後、AI がコードを書き始める

なぜこれが有効なのか? それは「後悔するチャンス」をくれるからです。

例えば先週、プロジェクトに国際化機能を追加させようとしました。Plan Mode で AI が計画を出してきました:

計画:
1. i18next と react-i18next をインストール
2. src/i18n/locales/ ディレクトリを作成
3. App.tsx を修正し I18nProvider を追加
4. すべてのコンポーネントのハードコーディングされたテキストを更新(約30ファイル)

第4ステップを見てすぐに止めました。「待って、その30ファイルはまだ触らないで。まずは3ページだけで試したい。」計画を修正させ、それから実行させました。

もし Plan Mode がなかったら、AI は30ファイルを一気に書き換えてしまい、元に戻すのが大変だったでしょう。

実戦価値:AI が勝手にコードを壊すのを防ぎます。特に大規模なリファクタリングや新機能開発に適しています。

テクニック2:具体的なコード例を提供する

AI には特徴があります。「見よう見まね」が得意なのです。いくつか例を見せれば、あなたのスタイルを模倣できます。これは技術的には Few-shot Prompting と呼ばれます。

シーン:AI に API インターフェースを書かせたいが、自分独自のスタイルやエラー処理の癖がある場合。

❌ 例のない Prompt:

ユーザーリスト取得 API を書いて

AI はこう書くかもしれません:

app.get('/users', (req, res) => {
  // 全く違うスタイル
  const users = db.getUsers();
  res.json(users);
});

✅ 例のある Prompt:

ユーザーリスト取得 API を書いて。以下の既存インターフェースのスタイルを参考にして:

**例1**
\`\`\`typescript
export const getProductById = async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const product = await productService.findById(id);

    if (!product) {
      return res.status(404).json({
        success: false,
        error: 'Product not found'
      });
    }

    res.json({ success: true, data: product });
  } catch (error) {
    logger.error('Error fetching product:', error);
    res.status(500).json({
      success: false,
      error: 'Internal server error'
    });
  }
};
\`\`\`

このスタイルに従って getUserList インターフェースを実装して:
- async/await を使用
- 統一されたエラー処理
- 返却フォーマット:{ success, data/error }
- logger でエラー記録

AI は以下のようなコードを生成します:

export const getUserList = async (req: Request, res: Response) => {
  try {
    const users = await userService.findAll();
    res.json({ success: true, data: users });
  } catch (error) {
    logger.error('Error fetching users:', error);
    res.status(500).json({
      success: false,
      error: 'Internal server error'
    });
  }
};

あなたのコードスタイルと完璧に一致します。

小技:プロジェクトのルートに prompts/templates.md というファイルを作り、よく使うコード例を保存しておき、必要な時にコピペして使います。

テクニック3:「何をしないか」を明確にする

このテクニックには何度も助けられました。

AI はデフォルトで「助けよう」と努力します。しかし時にその「助け」は不要なお世話です。バグ修正を頼んだら、ついでに周囲のコードも「最適化」してしまい、新たな問題を引き起こすことがあります。

Cursor チームの研究によると、明確な制約条件は予期せぬ変更を60%削減します。

実戦ケース:

❌ 制約のない Prompt:

UserList コンポーネントのページネーションのバグを直して

AI の行動:

  • コンポーネントの props インターフェースを変更(親コンポーネントでエラー発生)
  • ページネーションロジック全体を書き換え(新たなバグ混入)
  • 新しいサードパーティライブラリを導入(依存関係増加)

✅ 制約のある Prompt:

UserList コンポーネントのページネーションのバグを直して

**制約**
- コンポーネントの props インターフェース(TypeScript 型)は **変更しない**
- 新しいサードパーティライブラリは **導入しない**
- handlePageChange 関数の内部ロジック **のみ** 修正する
- スタイルと UI 構造は **変更しない**

AI はこれらのルールを厳守し、必要な部分だけを修正します。

さらに進んだテクニックとして、AI に前提条件をリストアップさせるのも有効です。

ページネーションのバグを修正して。開始前に以下の前提を確認して:
1. バグの原因は何だと思うか?
2. どのコードを修正するつもりか?
3. 何か依存関係やインターフェースを変更するか?

AI はまずこれらに回答します。その理解が正しいか確認してから手を動かせば、複雑なバグ修正も安心です。

テクニック4:受け入れ基準をアンカーにする

これはアジャイル開発からの借用です。

Prompt の冒頭(末尾ではなく)に受け入れ基準(Acceptance Criteria)を定義すると、AI はそれを目標として推論します。「必ず達成すべきゴール」を設定するようなものです。

比較してみましょう:

❌ 受け入れ基準なし:

DataTable コンポーネントのパフォーマンスをリファクタリングして

AI:どうなれば完了? どんな方法で? 基準は?(推測するしかありません)

✅ 受け入れ基準あり:

DataTable コンポーネントのパフォーマンスをリファクタリングして

**受け入れ基準**(すべて満たすこと):
- [ ] 1000行データ描画時、FPS が 55 を下回らない
- [ ] React.memo と useMemo を使用する
- [ ] コンポーネントの API(props と method)を変更しない
- [ ] 既存の全ユニットテストを通過する
- [ ] ESLint チェックを通過する

**現在の問題**
500行データ描画時に FPS が 20 まで落ち、スクロールがカクつく

AI はこれらの基準を「北極星」として、全ての変更がこの方向に向かうようにします。もしある最適化がテストを壊したり API を変えたりする場合、AI は自動的にその方法を避けます。

メリット:「便利そうに見えて実際は役に立たない」変更を防げます。

テクニック5:Inline Edit と Agent Mode の使い分け

多くの人が知らずにいますが、Cursor には2つの動作モードがあり、使い分けることで効率が倍増します。

Inline Edit (Cmd+K)

  • 適用:単一ファイルの小変更、リファクタリング、バグ修正
  • 特徴:高速、精密、ファイルを跨いで余計なことをしない
  • :関数名変更、パラメータ追加、バグ修正

Agent Mode (Cmd+I または Chat)

  • 適用:複数ファイルの推論、新機能開発、アーキテクチャレベルの変更
  • 特徴:コードベース全体を分析、ファイル跨ぎ操作、計画策定が可能
  • :新機能追加、大規模リファクタリング、技術スタック移行

以前は私も Agent Mode ですべてやっていましたが、効率が悪かったです。後に気づきました:単純タスクは Inline Edit、複雑タスクは Agent Mode

決定木:

複数ファイルの修正が必要?
├─ はい → Agent Mode
└─ いいえ → 複雑なコンテキスト理解が必要?
    ├─ はい → Agent Mode
    └─ いいえ → Inline Edit

例:

シーン1:関数 getUserDatafetchUserData にリネーム
Inline Edit:関数名を選択、Cmd+K、「fetchUserData にリネームして」、完了。

シーン2:ユーザー権限管理機能を追加(Model, Controller, View, Config 複数ファイルに関わる)
Agent Mode:プロジェクト構造を分析し、質問し、計画を立て、複数ファイルに実装。

モード選択ミスの結果:

  • Inline Edit で複雑タスク → 全体像が見えず、関連する変更を見落とす
  • Agent Mode で単純タスク → 牛刀で鶏を割く。待ち時間が長く、過剰な変更をするリスクも

小技:どちらを使うか迷ったら、まず Agent Mode の Plan 機能でいくつのファイルを変更するか見てみましょう。1〜2ファイルなら Inline Edit に切り替えた方が早いです。

上級編:Prompt ツールボックスを作る

再利用可能な Prompt テンプレートを作成

Prompt をしばらく書いていると、多くのタスクが繰り返しであることに気づきます——API エンドポイント追加、コンポーネント追加、ユニットテスト作成、DB マイグレーション……

毎回ゼロから書くより、よく使う Prompt をテンプレート化しましょう。

私はプロジェクトのルートに prompts/ フォルダを作り、タスクタイプごとに分類しています:

prompts/
├── api-endpoint.md       # API エンドポイント追加用
├── react-component.md    # React コンポーネント用
├── unit-test.md          # ユニットテスト用
├── migration.md          # DB マイグレーション用
└── refactor.md           # リファクタリング用

例:API エンドポイントテンプレート(prompts/api-endpoint.md

# 新規 API エンドポイントテンプレート

## Goal
[モジュール名] に [機能説明] の API エンドポイントを追加

## Context
- ルートファイル: src/routes/[モジュール].routes.ts
- コントローラー: src/controllers/[モジュール].controller.ts
- サービス層: src/services/[モジュール].service.ts
- データモデル: src/models/[モジュール].model.ts

## Desired Behavior
**リクエスト**:
- Method: [GET/POST/PUT/DELETE]
- Path: /api/[パス]
- Body/Query: [パラメータ説明]

**レスポンス**:
- 成功: { success: true, data: [...] }
- 失敗: { success: false, error: "..." }

## Acceptance Criteria
- [ ] 既存のエラー処理パターンに従う(他のエンドポイント参考)
- [ ] async/await を使用
- [ ] 入力検証を追加(Joi または Zod 使用)
- [ ] エラーログを記録(logger 使用)
- [ ] TypeScript 型チェックを通過

## Constraints
- **変更禁止**: 既存のルーティング設定構造
- **導入禁止**: 新しいサードパーティライブラリ(必須で理由がある場合を除く)
- **必須使用**: 既存のデータベース接続(新規接続を作成しない)

必要なときにテンプレートをコピーし、空欄を埋めるだけです。

チームコラボレーションの利点:メンバー間でテンプレートを共有すれば、誰が書いてもコードスタイルが統一され、新人もすぐに慣れます。

Agent Skills を活用(2026新機能)

これは2026年のAIプログラミングツールの大きなトレンドです。

簡単に言えば、**Agent Skills は再利用可能な「AI アプリケーション」**です。ベストプラクティスを Skill としてカプセル化し、関数のように呼び出せます。

ブログ記事を書く際、毎回手動で画像を入れるのが面倒でした。そこで Agent Skill を作り、自動化しました:

  1. 記事内容を分析
  2. 画像が必要な章を特定
  3. 画像生成プロンプトを作成
  4. 挿入位置をマーク

今ではこの Skill を実行するだけで、プロセス全体が完了します。

Agent Skills の作り方

Cursor では .cursor/ ディレクトリにカスタム Skill を作成できます:

.cursor/
└── skills/
    ├── code-review.md      # コードレビュー Skill
    ├── test-generator.md   # テスト生成 Skill
    └── api-doc.md          # API ドキュメント生成 Skill

最新動向:2025年12月、Agent Skills はオープン仕様となり、Claude Code, Cursor, VS Code, GitHub Copilot 等の主要ツールでサポートされました。つまり、一度書いた Skill はツールを跨いで使えます。

正直、最初は「過剰エンジニアリング」かと思いましたが、チーム開発プロジェクトで共有 Skills を使ってみて——コード品質と効率が一段階上がりました。

プロジェクト構造を最適化し、AI の理解を助ける

AI は人間と違い、コードベースの理解の仕方が異なります。構造が明確なプロジェクトでは、AI のパフォーマンスが向上します。

実用的なアドバイス

  1. /prompts フォルダ作成
    常用テンプレートやコード例を置き、コピペしやすくします。

  2. .cursor/ ディレクトリにプロジェクトコンテキストを置く
    .cursor/context.md ファイルを作り、以下を記述します:

    • 技術スタック
    • コードスタイル規範
    • よく使うサードパーティライブラリ
    • 特殊な約束事(例:「プライベートメソッドは _ で始める」)

    AI はこのファイルを自動で読み込み、プロジェクトの特性を理解します。

  3. 明確なディレクトリ構造と命名
    AI はファイル名とディレクトリ構造からコードの用途を推測します。utils.ts, helpers.ts, common.ts のような名前だと、AI は混乱します。

    このように具体的にしましょう:

    utils/
    ├── date-formatter.ts
    ├── string-validator.ts
    └── array-helpers.ts

私の経験則:プロジェクト構造が乱雑なほど、AI の幻覚が増える。ディレクトリを整理することは、人間にとって見やすいだけでなく、AI にとっても理解しやすくなります。

避けるべき罠:よくある間違いと解決策

間違い1:情報過多——一度に与えすぎ

AI プログラミングを始めた頃、私はよくやっていました。要件ドキュメント、関連ファイル3つ、参考記事5本を全部 AI に貼り付け、「情報は多いほどいいだろう」と考えていました。

結果は? AI は溺れました。

要点を掴めないか、理解がずれるか、タイムアウトでエラーになるか。一度に10のことを話しかけても、相手が覚えているのはほんの僅か、というのと同じです。

正解:段階的開示

最初から全てを投げつけず、次のようにします:

  1. まず核心的な要件を伝える
  2. AI が質問したら、詳細を提供する
  3. コンテキストを段階的に与える

例:

❌ 情報過多版:

ユーザー認証モジュールをリファクタリングして。
[500行のコード貼り付け]
[要件ドキュメント貼り付け]
[技術記事3本貼り付け]
要求:パフォーマンス向上、セキュリティ強化、コードをエレガントに...

✅ 段階的版:

第1ラウンド:
ユーザー認証モジュールをリファクタリングしたい。目標はセキュリティ向上。
現在 JWT を使用しているが、token のリフレッシュ機構がないのが問題。
何を知りたい?

[AI:現在の token 有効期限は? 保存場所は?]

第2ラウンド:
有効期限は1時間、localStorage に保存。
これが現在の認証ロジック(重要コード):
[核心的な50行のみ貼り付け]

どう改善するつもり?

[AI が案を出し、確認してから実行させる]

メリット:AI は核心的な問題に集中でき、あなたもいつでも理解を修正できます。

間違い2:AI に依存しすぎてコードレビューしない

これは私が一番痛い目を見た罠です。

ある時、AI にデータ処理関数を書かせました。エラーもなく、ユニットテストも通りました。コードも綺麗に見えたのでそのままマージ。しかしリリース後、エッジケースで誤った結果を返し、ユーザーデータが破損しました。

AI が生成したコード、特に「完全に見える」コードほど危険です。

警告:生成速度が速いほど、慎重なレビューが必要です。

私は今、AI がコードを書いた後、自分に3つの質問をします:

  1. エッジケース:空配列、null、undefined、最大値、最小値は処理されているか?
  2. 副作用:このコードは他のモジュールに影響しないか?
  3. パフォーマンス:無限ループ、メモリリーク、不要な再計算はないか?

実用テクニック:AI 自身にコードレビューさせる。

今生成したコードをレビューし、以下の質問に答えて:
1. 入力が空配列の場合どうなるか?
2. このコードにパフォーマンスの問題はあるか?
3. どんな仮定を置いているか? その仮定はあらゆる状況で成り立つか?

AI は再チェックし、自分のミスをよく発見します。

間違い3:一度で完璧な答えを期待する

多くの人は AI を「魔法のボタン」だと思っています——要件を入れれば、完璧なコードが出てくる。現実的ではありません。

AI は「全自動コード生成機」ではなく「協業者」です。最も効率的なのは 反復的な対話 です:

  1. 要件を記述
  2. AI が初期案や質問を出す
  3. 確認、修正、補足する
  4. AI がフィードバックに基づき最適化
  5. 3-4 を満足するまで繰り返す

正しい例

あなた:ユーザーリストの検索機能を実装して

AI:分かりました。検索ボックスを追加してリアルタイムフィルターをかけます。
    どのフィールドで検索しますか? ユーザー名? メール?

あなた:ユーザー名とメール。でもリアルタイムじゃなくて、
    「検索」ボタンを押してからトリガーしたい

AI:了解です。ではフロントエンドだけでフィルターしますか? バックエンドに投げますか?

あなた:フロントエンドで。データ量は少ないから

AI:OK。Array.filter() を使います。
    実装計画をお見せします...

わかりましたか? これは「命令」ではなく 対話 です。

ヒント:Cursor の “Show Work” モード(設定でオン)を使うと、AI の推論ステップが表示され、どう考えているかが見えるので問題発見しやすくなります。

番外編:Prompt “調教” に時間をかけすぎない

最後に直感に反するアドバイスを:完璧な Prompt を追い求めすぎないでください

Prompt を30分かけて練り上げ、結果が手書きより遅かった人を見たことがあります。本末転倒です。

Prompt エンジニアリングの目的は 効率化 です。Prompt の美しさを競うことではありません。自分で書いて10分で終わるなら、20分かけて Prompt を書く必要はありません。

いつ AI を使うべきか?

  • ✅ 反復作業(一括修正、テンプレート生成)
  • ✅ 不慣れな領域(新しい技術スタック、ライブラリ)
  • ✅ 複雑だがパターンのあるタスク(API エンドポイント、CRUD 操作)

いつ使わないべきか?

  • ❌ 目を閉じていても書ける簡単なコード
  • ❌ 深い思考が必要なアルゴリズム設計
  • ❌ 高度にカスタマイズされ、参考パターンのないコード

覚えておいてください:AI はツールであり、目的ではありません。問題を早く解決できるかどうかが全てです。

結論

良い Prompt を書くのは高度な技術ではありません。核心は 目標を明確にし、コンテキストを与え、境界を決める ことです。

この記事の5つの重要テクニックを振り返ります:

  1. Plan Mode でまず計画——「後悔するチャンス」を作る
  2. コード例を提供——AI にあなたのスタイルを真似させる
  3. 制約条件を明確化——AI に何をしてはいけないか教える
  4. 受け入れ基準を設定——AI に明確なゴールを与える
  5. 作業モードを使い分け——単純タスクは Inline Edit、複雑タスクは Agent Mode

これらをマスターすれば、AI は「使えない助手」から、真に効率を上げるプログラミングパートナーに変わります。私自身、これらの方法を使ってから、AI のコード生成精度は少なくとも50%向上し、多くの反復作業が10分で終わるようになりました。

今すぐ Cursor を開き、構造化テンプレートを試してみてください。次の機能開発から、“Goal - Context - Desired Behavior - Constraints” のフォーマットで書いてみましょう。違いをすぐに体感できるはずです。

忘れないでください:AI プログラミングの未来は「AI がプログラマーに取って代わる」のではなく、「AI を使えるプログラマーが使えないプログラマーに取って代わる」のです。そのスキルの差は、あなたが書く最初の高品質な Prompt から始まります。

構造化 Prompt で AI コード品質を向上させる

Cursor Prompt エンジニアリングの完全実戦フロー。曖昧な指示から脱却し、正確な出力を得る方法

⏱️ Estimated time: 30 min

  1. 1

    Step1: AI の仕組みを理解:Prompt の災難を避ける

    AI は提供情報から推論するだけで、心を読めません。よくある3つの災難:

    **曖昧すぎる**:
    ❌ "ソート機能を実装して"
    ✅ "utils/array.ts にユーザーリストを登録日時降順でソートする関数を追加。Native Array.sort() 使用、新依存なし"

    **コンテキスト不足**:
    ❌ "エラー処理を追加して"
    ✅ "api/login.ts の handleLogin にエラー処理追加:リクエスト失敗を捕捉(try-catch)、統一形式 { success: false, error: string } を返す、api/register.ts 参考"

    **制約条件なし**:
    ❌ "このコンポーネントの性能を最適化して"
    ✅ "UserList.tsx 最適化:React.memo か useMemo のみ使用、props 変更不可、新ライブラリ不可"

    要点:明確なコンテキストで幻覚70%減、明確な制約で予期せぬ変更60%減。
  2. 2

    Step2: 構造化 Prompt 黄金公式を使用

    Cursor 公式推奨の6パートテンプレートを採用:

    ## Goal(目標)
    一言で何を達成するか

    ## Context(コンテキスト)
    • 技術スタック(React 18 + TypeScript)
    • 関連パス(src/pages/Login.tsx)
    • 既存サービス(src/services/authService.ts)
    • 使用ライブラリ(Ant Design 5.x)

    ## Current Behavior(現在の振る舞い)
    静的UIのみでロジックなし

    ## Desired Behavior(期待する振る舞い)
    1. 入力後ログインクリック
    2. authService.login() 呼び出し
    3. 成功:Redux に保存、/dashboard 遷移
    4. 失敗:エラー表示

    ## Acceptance Criteria(受け入れ基準)
    • フォーム検証必須
    • loading 状態表示
    • type="password" 使用
    • ESLint/TS チェック通過

    ## Constraints(制約)
    • authService.ts 変更不可
    • 新ライブラリ不可
    • 既存 Redux slice 使用必須

    これで AI は推測せず、規範通りのコードを生成します。
  3. 3

    Step3: 5つの即効実戦テクニック

    **技1:先計画・後コード(Plan Mode)**
    • Shift+Tab で Plan モードへ
    • AI が分析し質問
    • 行動計画策定(変更ファイル一覧)
    • 承認・修正後に実行
    • AI の暴走を防ぐ

    **技2:具体的コード例提供(Few-shot Prompting)**
    • Prompt に既存コード例を貼る
    • AI がスタイルやエラー処理を模倣
    • prompts/templates.md に常用例を保存推奨

    **技3:「何をしないか」明確化**
    • Constraints で禁止事項列挙
    • 予期せぬ変更60%減
    • 上級:AI に前提(バグ原因、変更範囲、依存変更)を先に列挙させる

    **技4:受け入れ基準をアンカーに**
    • 冒頭に基準定義
    • AI の推論の「北極星」に
    • 「無駄な変更」防止

    **技5:Inline Edit と Agent Mode 使い分け**
    • Inline (Cmd+K):単ファイル小変更、高速
    • Agent (Cmd+I):多ファイル推論、新機能、構造変更
    • 決定木:複数ファイル?→YesならAgent、NoならInline
  4. 4

    Step4: 再利用可能な Prompt ツールボックス構築

    **Prompt テンプレートライブラリ**:
    ルートに prompts/ フォルダ作成:
    • api-endpoint.md(APIエンドポイント)
    • react-component.md(Reactコンポーネント)
    • unit-test.md(単体テスト)
    • migration.md(DB移行)
    • refactor.md(リファクタ)

    各テンプレートに Goal, Context, Desired Behavior, Acceptance Criteria, Constraints を用意し、コピペで使用。

    **Agent Skills(2026新機能)**:
    .cursor/skills/ に AI アプリ作成:
    • code-review.md
    • test-generator.md
    • api-doc.md

    **プロジェクト構造最適化**:
    • .cursor/context.md に技術スタック、規範、規約を記録
    • date-formatter.ts のように具体的命名(utils.ts は避ける)
    • 構造が乱雑だと幻覚が増える
  5. 5

    Step5: 三大エラー回避

    **過ち1:情報過多**
    ❌ 500行コード+文書+記事を全部貼り付け
    ✅ 段階的開示:核心要件 → AI質問 → 詳細提供 → 段階的コンテキスト

    **過ち2:AI 依存でレビューなし**
    生成後3つの問い:
    • エッジケース(空配列、null、極値)は?
    • 他モジュールへの副作用は?
    • 無限ループやリークなど性能問題は?

    技:AI 自身にレビューさせる(「空配列ならどうなる?」「性能問題は?」)

    **過ち3:一発完璧回答への期待**
    AI は魔法のボタンではなく協業者。
    1. 要件記述
    2. AI 提案・質問
    3. 確認・修正
    4. AI 最適化
    5. 満足するまで反復

    "Show Work" で推論ステップを確認し問題を早期発見。

FAQ

詳細な Prompt を書いても AI が間違ったコードを生成するのはなぜ?
重要なコンテキストが欠けている可能性があります:

• 操作するファイルパスを明確にしましたか?(AI は場所を知りません)
• 既存のコード例を提供しましたか?(AI はスタイルを知りません)
• 制約条件を説明しましたか?(AI は自由にやりすぎます)

実用策:Prompt で「AI は場所を知っているか?」「構造を知っているか?」「何をしてはいけないか知っているか?」と自問自答し、不足あれば補ってください。

また、Plan Mode を使い、計画を承認してから実行させれば、多くの問題を防げます。
Inline Edit と Agent Mode はどう使い分ける?
決定木:

**複数ファイルの修正が必要?**
• はい → Agent Mode (Cmd+I/Chat)
• いいえ → 複雑なコンテキスト理解が必要?
- はい → Agent Mode
- いいえ → Inline Edit (Cmd+K)

具体シーン:
• Inline Edit:関数名変更、引数追加、単一バグ修正、単一リファクタ
• Agent Mode:新機能(Model/Controller/Viewに関わる)、大規模リファクタ、技術移行

ヒント:迷ったら Agent Mode の Plan で変更ファイル数を確認。1-2ファイルなら Inline Edit が早いです。
AI 生成コードをプロジェクトのスタイルに合わせるには?
3つの方法があります:

**法1:具体的コード例提供(最有効)**
Prompt に既存コード例を貼り付ければ、AI はスタイル、エラー処理、命名を模倣します(Few-shot Prompting)。

**法2:プロジェクトコンテキストファイル**
.cursor/context.md に以下を記録:
• 技術スタック
• コード規範(例:「私有メソッドは _ 開始」)
• 常用ライブラリ
• 特殊規約
AI はこれを自動で読みます。

**法3:再利用可能 Prompt テンプレート**
prompts/ フォルダに API やコンポーネント用テンプレートを作り、コピペ利用。チーム共有すればスタイルも統一されます。
AI コードは動くけどバグがある場合は?
AI の「一見正しそうなコード」は最も危険です。

**必ずレビュー** し、問いかけてください:
1. エッジケース(空、null、極値)は処理済か?
2. 副作用はないか?
3. 性能問題はないか?

**実用技**:AI 自身にレビューさせる
「生成コードをレビューして:1)空配列入力でどうなる? 2)性能問題は? 3)どんな仮定を置いている?」

AI は再確認し、自分のミスを見つけます。"Show Work" で推論を見ればさらに発見しやすくなります。
いつ AI を使うべきで、いつ使わないべき?
使うべき:
• 反復作業(一括修正、テンプレート、重複ロジック)
• 不慣れな領域(新技術、新ライブラリ)
• 複雑だがパターンのあるタスク(API、CRUD、検証)

使わないべき:
• 簡単すぎてすぐ書けるコード(変数名変更、コメント)
• 深い思考が必要なアルゴリズム(コアロジック、複雑最適化)
• 高度なカスタムで参考パターンのないコード

基準:自分で10分で書けるなら、20分かけて Prompt を書くのは無駄。AI は効率化ツールであり、コード生成自体が目的ではありません。
Plan Mode の使い方は?有効なシーンは?
**使い方**:
1. Shift+Tab で Plan モードへ
2. 要件記述
3. AI が分析・質問
4. AI が行動計画作成(変更ファイル一覧)
5. あなたが計画を審査・修正
6. 確認後 AI 実行

**有効シーン**:
• 大規模リファクタ(ファイル間違い防止)
• 新機能開発(全体像確認)
• AI の理解が不安な時
• 複雑タスク(国際化、DB移行など)

価値は「後悔するチャンス」を作ること。不可逆な大変更に最適です。
AI が勝手にライブラリを追加しないようにするには?
Constraints で明確に禁止します:

**禁止**:
"新ライブラリは **導入しない**"
"npm パッケージは **インストールしない**"
"既存依存関係 **のみ** 使用"

**強制使用**:
"既存の Ant Design コンポーネント **のみ** 使用"
"既存 authService **のみ** 使用"

**例示**:
Context に既存ライブラリを提示すれば、AI はそれを優先します。

**Plan Mode**:
計画段階で導入ライブラリが見えるので、そこで阻止できます。

制約が明確なほど、AI は勝手なことをしません。

9 min read · 公開日: 2026年1月29日 · 更新日: 2026年2月4日

コメント

GitHubアカウントでログインしてコメントできます

関連記事