コードがモデルの答えを読むとき、「だいたい正しい形」はバグです。構造化出力のプロンプティングとは、プログラムが毎回解析できるデータをモデルに返させるための一連の実践です。定義された形式、明示的な制約、そして検証がその中身です。
信頼性の 3 つのレベル
| レベル | 方法 | 保証 |
|---|---|---|
| プロンプトのみ | プロンプトで形式を説明する | なし。通常は正しいが、そうでないこともある |
| JSON モード | API に JSON の応答を要求する | 有効な JSON。ただしスキーマは保証されない |
| スキーマ制約付き出力 | API に JSON Schema を渡す | 出力がスキーマに一致する |
提供元が用意している最も強いレベルを使いましょう。OpenAI、Anthropic、Google のいずれも、応答をスキーマやツールの入力スキーマに制約する手段を提供しています。どのレベルでもプロンプトは重要です。スキーマは出力の形を制御し、プロンプトは内容を制御するからです。
プロンプトに出力の制約を書く
形式、フィールド、型、許可される値を書きます。そのうえで、現れてはいけないものも書きます。
Extract the order details from the email in the tags.
Return a JSON object with exactly these fields:
- "order_id": string, as written in the email
- "items": array of {"name": string, "quantity": integer}
- "total": number, without currency symbol
- "currency": one of "USD", "EUR", "GBP"
If a field is not present in the email, use null.
Return only the JSON object, with no explanation and no code fence.
<email>
{{email}}
</email>
このプロンプトの 4 つのポイントが、ほとんどの失敗を防ぎます。
- 「ちょうどこれらのフィールド」 は、モデルが気を利かせて余計なものを足すのを防ぎます。
currencyの許可される値は、「US dollars」や「$」を防ぎます。- null のルールは、モデルに「見つからない」を正しく表す方法を与え、値の捏造を防ぎます。
- 「JSON のみを返す」 は、
JSON.parseを壊す一言のコメントを取り除きます。
モデルのためにスキーマを設計する
スキーマはプロンプトの一部です。モデルはフィールド名と説明を指示として読みます。
- 中身を表す名前を付ける。
addr2よりshipping_addressのほうが優れています。 - 意味が自明でないフィールドには、単位や形式を含めた説明を加える。例:「ISO 8601 形式の日付、UTC」。
- フィールドの値が決まった集合なら、enum を使う。
- 浅く保つ。 深いネストはミスを増やします。非常に複雑な抽出は連鎖したプロンプトに分けます。
- 答えの前に推論を置く。 説明と判定の両方がほしいなら、フィールドを
"reasoning"、次に"verdict"の順にします。モデルはフィールドを順に書くので、先に書いた推論が判定に反映されます。
JSON 以外
構造化出力は JSON だけではありません。
- 固定の見出しを持つ Markdown は、人が読む回答に向いています。「見出しは次のとおりにする:要約、リスク、次のステップ」。
- XML 風のタグは、正規表現で簡単に取り出せ、中に自由なテキストを入れても問題ありません。
<answer>…</answer>。 - 1 トークンは、あらゆる形式の中で最も信頼できます。分類では、ラベルだけを求めます。
- CSV や表は、小さく規則的なデータには使えますが、自由なテキストが入ると引用符の扱いが不安定になります。
情報を運べる最も単純な形式を選びましょう。
長さと内容の制約
出力の制約には、サイズやスタイルも含まれます。
- At most 3 bullet points, each under 20 words.
- Use only facts from the document. If the document does not say, write "not stated".
- Write in the present tense.
サイズは数値で指定します。「簡潔に」は、パーサーやレイアウトが頼れる制約ではありません。
常に検証する
スキーマ制約付き出力でも、データを使う前に検証しましょう。
- すべての応答をパースしてスキーマを確認する。出力トークンの上限に達すると応答が途中で切れ、JSON が不完全になることがあります。
- スキーマでは表現できない意味を確認する。合計が項目の合計と一致する、日付が未来でない、など。
- 失敗時の経路を決める。 検証エラーをプロンプトに含めて 1 回だけ再試行し、その後は代替手段に切り替えるか、レビュー対象としてフラグを立てます。
- 構造化出力を盲目的に実行しない。 SQL 句、ファイルパス、シェルの引数になるフィールドには、ユーザー入力と同じサニタイズが必要です。プロンプトセキュリティを参照してください。
よくある失敗の型
| 失敗 | 原因 | 対策 |
|---|---|---|
| JSON の前後にテキストがある | 「のみ」の指示がない | 指示を追加するか、JSON モードを使う |
| コードフェンスで囲まれている | モデルの癖 | 「コードフェンスなし」と書くか、コード側で除去する |
| 値が捏造される | 欠損データのルールがない | null または「記載なし」のルールを追加する |
| 余分なフィールド | 自由な書き方 | 「ちょうどこれらのフィールド」と書き、追加プロパティを禁止する |
| 出力が途中で切れる | 出力上限に到達 | 上限を上げるか、タスクを分割する |
| enum の綴りが不統一 | 値を列挙していない | 許可される値を列挙する |
実行前にプロンプトを確認する
コードに入力を渡すプロンプトで最も多い指摘は、出力形式の欠落です。PromptFlowEngine のプロンプトアナライザーは、これに加えて長さの指示の欠落や区切りのない変数も報告します。JSON 抽出テンプレートは、すべてのチェックを通る完全な例です。
アプリケーションコードにどう組み込むかは、開発者のためのプロンプトエンジニアリングを参照してください。