はじめに

プロンプトは単なるチャット欄に入力する質問ではありません。LLMに対して「何を」「どのように」「どの形式で」応答するかを伝える唯一の指示源です。コンパイラが決定論的なルールに従って動作する従来のコードとは異なり、LLMはプロンプトを確率的に解釈します。つまり、出力の質は意図の伝え方次第で大きく変わります。

明瞭さと具体性

曖昧なプロンプトは曖昧な結果を生みます。「Webアプリについて何か書いて」のような指示はモデルに自由度を与えすぎ、汎用的で焦点のぼやけた出力が得られます。具体的なプロンプトはモデルを制約し、曖昧さを減らします。

python
prompt_vague = "Tell me about web apps"
prompt_specific = "List the top 3 security risks of a Node.js REST API that uses JWT authentication, each with a one-sentence mitigation."

2つ目のプロンプトが機能するのは、ドメイン(Node.js REST API)を定義し、トピックを絞り(JWTのセキュリティリスク)、数を指定し(トップ3)、構造を要求しているからです(それぞれ1文の緩和策)。曖昧さを排除することで、モデルの推測余地も排除できます。

構造と役割の割り当て

LLMは、役割を割り当て、タスクを定義し、制約を設定する構造化されたプロンプトによく応答します。一般的なパターンは次の通りです:Role — Task — Context — Constraints — Output Format。これらのレイヤーを順に積み重ねると、一文でだらだら書くより予測可能な出力が得られます。

javascript
const structuredPrompt = `
Role: You are a senior backend engineer reviewing code.
Task: Review the following Express.js route handler for bugs.
Context: This endpoint handles payment webhooks from Stripe.
Constraints: Focus only on error handling and idempotency. Do not suggest new dependencies.
Output Format: Return a numbered list of issues, each with a code fix.
`;

役割設定はモデルに特定の視点を priming します。制約は不要なアドバイスを排除します。出力形式は応答を整形し、プログラムで解析可能にします ── これはAIの出力が次のステップに流れるエージェントワークフローで重要です。

Role-Task-Context-Constraints-Formatのプロンプト構造をLLMへのリニアパイプラインとして示すフローチャート

LLMがコードを処理するのと異なる方法で指示を解釈する仕組み

従来のコードは厳密な構文ルールに基づき上から下へ実行されます。LLMはプロンプト全体を自然言語の塊として読み、最も確率の高い続きを予測します。つまり、語順が重要であり、プロンプト内の例が出力スタイルに大きく影響し、長いプロンプトの最後にある重要な指示はattention driftにより「失われる」可能性があります。

python
# Bad: key instruction buried in the middle of noise
prompt_bad = "You can be creative. Try different tones. Oh and by the way, respond only in valid JSON."
# Good: key instruction placed last where attention is strongest
prompt_good = "You can be creative. Try different tones. Respond only in valid JSON."

人間には微妙な差に見えますが、モデルにとっては大きな差です。これがプロンプトエンジニアリングがスキルである理由です ── モデルの入力の各部分への重み付けを予測する方法を学びます。

実践例:カジュアルからプロダクションレディへ

Reactフォームライブラリ向けのフォームバリデーションルールを生成するAIエージェントを作っていると想像してください。

typescript
const casualPrompt = "Write validation for a login form.";
const productionPrompt = `
Task: Generate Yup validation schemas for a React login form.
Fields: email (required, valid format), password (required, min 8 chars, must contain 1 number).
Output: Return a single JavaScript code block exporting the schema object. No explanations.
`;

カジュアルなプロンプトは散文、サンプルHTML、未完成のスキーマを返すかもしれません。プロダクション向けプロンプトは、ビルドプロセスに直接パイプできる単一のパース可能なコードブロックを正確に返します。

よくある間違い

初心者のプロンプトには繰り返し現れる3つの間違いがあります。1つ目、一つのプロンプトに複数の無関係なタスクを混在させる ── 分離しないとモデルは一方を優先し他方を無視します。2つ目、出力形式を省略する ── 指定がないとモデルが形式を選ぶため、結果を解析できない可能性があります。3つ目、長いセッションでモデルが以前の会話コンテキストを完璧に覚えていると仮定する ── 重要な制約は新しいプロンプトごとに再記述してください。

まとめ

効果的なプロンプトは明瞭で、具体的で、構造化されています。役割を割り当て、タスクを明示し、コンテキストを提供し、制約を適用し、出力形式を定義します。LLMが決定論的に実行するのではなく確率的に言語を解釈する仕組みを理解することが、従来のプログラミングからの重要なマインドシフトです。次のレッスンでは、これらの基礎を複数ステップのエージェントワークフローの構築に応用します。

レッスンのチェックポイント

1. 「Webアプリについて教えて」のような曖昧なプロンプトを書くことの主なリスクは何ですか?

2. Role-Task-Context-Constraints-Format構造における「Constraints」セクションの目的は何ですか?

3. 長いプロンプトの最後に重要な指示を置くことで信頼性が向上するのはなぜですか?

4. コードとLLMが指示を処理する主な違いは何ですか?

5. ログインフォームバリデーションの例において、「Return a single JavaScript code block exporting the schema object. No explanations.」と指定することが重要な理由は?

6. レッスンで触れられた初心者の3つのよくある間違いに該当しないのはどれですか?

7. モデルの出力が散文とコードが混在し、プログラムで解析しにくい場合の推奨される修正方法は?