プロンプトエンジニアリングとは

プロンプトエンジニアリングは、LLM(大規模言語モデル)から望む出力を得るためのプロンプト(指示文)を設計する技術です。

モデルのパラメータを変更せずに、インプットの工夫だけでLLMの能力を最大化できます。2023年以降、AI開発の現場で最も重要なスキルの一つとなっています。

技術1: ゼロショット・プロンプティング

最もシンプルな手法です。具体的な例を与えず、タスクだけを記述します。

以下のPythonコードのバグを見つけて修正してください:

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # 非常に遅い

現代のLLM(GPT-4, Claude 3.5など)はゼロショットで多くのタスクを解決できますが、複雑なタスクには不十分なことがあります。

技術2: Few-shotプロンプティング

入力と望ましい出力のペアを数例示すことで、LLMに「パターン」を教えます。

以下のフォーマットで技術用語を日本語で説明してください。

用語: API
説明: アプリケーション同士が通信するための「接続口」。レストランで例えると、
      ウェイターがお客(アプリ)とキッチン(サービス)を仲介する役割。

用語: コンテナ
説明: アプリとその実行環境をまとめてパッケージ化したもの。「引越し用の
      コンテナボックス」に荷物(アプリ)と必要な道具(依存関係)を
      一緒に入れるイメージ。

用語: マイクロサービス
説明:

Few-shotの例は多様性(異なるパターンをカバー)と品質(望む出力の典型例)が重要です。

技術3: Chain-of-Thought(CoT)プロンプティング

複雑な推論が必要なタスクには、思考過程を段階的に示すよう指示します。

問題を解く前に、思考過程を段階的に示してください。

問題: あるAPIが1秒に100リクエストを処理できます。
      1日に1,000万リクエストが来る場合、何台のサーバーが必要ですか?
      各サーバーは同等の性能で、可用性のために20%の余裕を持たせてください。

思考過程:
1. 1日のリクエスト数を1秒あたりに換算...

研究によると、CoTプロンプティングは数学的推論や複雑なロジックで精度を大幅に向上させます。

技術4: ロールプロンプティング

LLMに特定の役割(ペルソナ)を与えることで、その専門領域に特化した回答を引き出します。

あなたはGoogle SREチームの10年ベテランです。
以下のインシデントレポートをレビューし、
改善点を3つ指摘してください:

[インシデントレポートの内容]

効果的なロール設定のポイント:

  • 具体的な専門性を明示する
  • 経験年数や所属を含める
  • 期待する視点・スタイルを示す

技術5: 構造化出力の指定

JSON、Markdown、特定フォーマットで出力を要求することで、プログラムからの利用が簡単になります。

import openai
import json

response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{
        "role": "user",
        "content": """
以下のコードをレビューし、結果をJSON形式で返してください。

コード: {code}

JSON形式:
{{
  "score": 評価(1〜10),
  "issues": [
    {{"severity": "critical|major|minor", "description": "問題の説明", "line": 行番号}}
  ],
  "suggestions": ["改善提案1", "改善提案2"],
  "summary": "総合コメント"
}}
"""
    }],
    response_format={"type": "json_object"}
)

result = json.loads(response.choices[0].message.content)

技術6: 制約とガードレールの設定

出力の品質と安全性を保つため、明示的な制約を設けます。

以下のルールに従ってコードレビューを行ってください:

必須ルール:
- セキュリティの問題(SQLインジェクション、XSSなど)は必ず指摘すること
- 指摘は具体的な行番号と修正例を含めること
- 推測による指摘は行わないこと

禁止事項:
- 「問題ありません」という評価は行わない(必ず改善点を見つけること)
- コード全体の書き直しを提案しない
- フレームワークの選択を批判しない

技術7: メタプロンプティング

LLM自身にプロンプトを生成・改善させます。

以下のタスクを達成するための最適なプロンプトを作成してください。

タスク: GitHubのコードレビューコメントを日本語で生成する
対象ユーザー: 中級Pythonエンジニア
トーン: 建設的・教育的
制約: 1コメントあたり100字以内

あなたが考える最良のプロンプトを出力してください。

技術8: ReActパターン

Reasoning(推論)Acting(行動) を繰り返すパターンです。エージェント開発の基礎となります。

以下のタスクを解決してください。各ステップで「思考→行動→観察」を繰り返してください。

タスク: 現在の東京の天気を調べて、今日の服装を提案してください。

思考: まず天気情報を取得する必要がある
行動: get_weather(location="Tokyo")
観察: {"temperature": 15, "condition": "cloudy", "humidity": 70}

思考: 15度で曇りなら...
行動: [次のアクション]

技術9: コンテキスト圧縮

長いコンテキストを効率的に使うための技術です。

def compress_context(long_document: str, query: str, llm) -> str:
    """関連する情報だけを抽出してコンテキストを圧縮する"""
    compression_prompt = f"""
以下のドキュメントから、クエリに関連する情報だけを抽出してください。
不要な情報は省略し、重要な情報は原文を保持してください。

クエリ: {query}

ドキュメント:
{long_document}

関連情報のみを抽出:
"""
    return llm.complete(compression_prompt)

技術10: 自己一貫性(Self-Consistency)

同じプロンプトを複数回実行し、多数決で最終的な答えを決定します。

import asyncio
from collections import Counter

async def self_consistent_answer(prompt: str, llm, n: int = 5) -> str:
    """複数回実行して最も一貫した答えを選択する"""
    tasks = [llm.acomplete(prompt) for _ in range(n)]
    answers = await asyncio.gather(*tasks)
    
    # 多数決
    answer_counts = Counter(answers)
    return answer_counts.most_common(1)[0][0]

複雑な推論問題で精度を向上させる効果がありますが、コストが増加するためトレードオフに注意が必要です。

まとめ:プロンプトエンジニアリングの原則

  1. 明確さ: 曖昧な指示を避け、具体的に記述する
  2. コンテキスト: 必要な背景情報を提供する
  3. 制約: 出力の形式・スコープ・ルールを明示する
  4. 例示: 期待する出力のパターンを示す
  5. 反復改善: プロンプトをバージョン管理し、継続的に改善する

次の記事では、これらの技術を組み合わせたAIエージェントの設計パターンを解説します。