はじめに
大規模言語モデルはデフォルトでは柔軟です—あらゆるフォーマット、長さ、スタイルで回答できます。Webアプリ内での実プロダクション利用では、その柔軟性が問題になります。予測可能でパース可能な出力が必要です。このレッスンでは、LLMの出力を制御する4つのコアなテクニックを扱います:システムプロンプトによる永続的な振る舞いの設定、few-shot例による実例を通じた出力パターンの学習、構造を保証するフォーマット強制、そしてモデルが想定外の挙動をしたときのためのエッジケース対応です。
システムプロンプトとユーザープロンプト
システムプロンプトは、ユーザーメッセージより高い優先度を持つ独立したメッセージとして送信されます。会話全体を通じてモデルの役割、制約、トーンを定義します。ユーザープロンプトは実際のタスクや質問です。システムプロンプトは安定したルールに集中させ、ユーザープロンプトは変動するタスクに集中させてください。
`temperature: 0` に注意してください—構造化された出力が必要な場合は、ランダム性をゼロに固定してください。temperatureを上げると、強いシステムプロンプトを使っていてもフォーマットのブレが生じます。
Few-Shot Examples
Few-shotプロンプティングとは、希望する入力から出力へのマッピングを説明する代わりに、その正確な例を2〜4個示すことです。モデルはパターンマッチングによって学習します。例はユーザープロンプト内に置くか、ユーザー/アシスタントの交互メッセージペアとして配置します。
3番目のユーザーメッセージにはアシスタントの返信がありません—モデルがそれを埋めます。2つ一貫した例を見たため、ほぼ常に同じJSONの形状に従います。
フォーマット強制の戦略
モデルが頑固でフォーマット指示を無視する場合は、以下の対策を順に重ねてください。第一に、「『Here is your JSON:』と書かないこと」のような明示的な否定例でシステムプロンプトを強化します。第二に、構造化出力モード(JSONモードまたはtool/function calling)をサポートするモデルに切り替えます。APIが有効なJSONを保証するためです。第三に、コードに後処理ステップを追加し、スキーマで出力をバリデートし、失敗時にリトライします。
Zodスキーマは契約として機能します—LLMが文字列の代わりに数値を返したり、3つではなく4つの色を返した場合、parseがエラーを投げ、フォールバックが発動します。プロダクションコードでは生のLLM出力を決して信用しないでください。
エッジケースの対応
頻繁に発生する3つのエッジケースがあります。第一に、モデルがデータの代わりに謝罪を返し拒否する場合—拒否フレーズを検知し、より明確なプロンプトでリトライすることで対応します。第二に、モデルがスキーマに存在しないフィールドを幻覚(ハルシネート)する場合—JSON.parseだけでなく、スキーマでバリデートすることで対応します。第三に、トークン上限に達して出力が途切れる場合—明示的にmax_tokensを設定し、長いリクエストを分割するか、簡潔に答えるようモデルに依頼することで対応します。
まとめ
LLMの出力を制御するのは1つのトリックではなく、防御の積み重ねです。明確なシステムプロンプトから始め、フォーマットが曖昧な場合はfew-shot例を追加し、スキーマとバリデーションで構造を強制し、拒否・ハルシネーション・途切れには常にフォールバックを用意してください。次のレッスンでは、モデルが自由形式のテキスト生成ではなくツールを選択できるようにするfunction callingを扱います。
レッスンのチェックポイント
学んだ内容を復習し、回答へのフィードバックを受けましょう。