このページの目次
プロンプトエンジニアリングと構造化出力
サンプリングパラメータが削除された後、「創造性/決定論の調整」ノブは2つに置き換わった: prompt(意図を明確にする)と effort(十分な計算リソースを確保する)。そして、出力をプログラムが消費可能にするのは、「JSONを返してください」というお願いではなく、スキーマ制約である。
概要
トークンとサンプリング で触れた分岐点: Claude のマネージド API は Opus 4.7 から temperature/top_p/top_k を削除し、これらを送信すると即座に 400 エラーとなる。旧時代の「温度を調整して創造性を制御し、温度0で決定論を求める」という手触りは失われた。Anthropic は制御権を、より高レベルで制御可能な2つのノブへと移行させた:
- プロンプティング——決定論を望めば指示を固定し、発散を望めばプロンプト内で明示的に多様性を要求する;
- effort——どの程度深く推論するか、どのくらいのトークンを消費するかを制御する (推論と思考 参照)。
この章では、この2つのノブをどのように活用するか(前半: プロンプトエンジニアリング)、そして出力をダウンストリームのプログラムに渡す際に、構造化出力を用いて「自由テキスト」を「確実に解析可能な JSON」に制約する方法(後半)について解説する。これら2つはよく組み合わせて用いられる: プロンプトで振る舞いを定め、スキーマで形状を定める。
前半: プロンプトエンジニアリング
モデルが一度に見ているのは、連結された1つのテキストである
コンテキストエンジニアリング でレンダリング順序 tools → system → messages について述べた。プロンプトエンジニアリングとは、このテキストに何を、どのように記述するかを決定することである:
- system: 安定したロール、ルール、出力規約——これを凍結し、タイムスタンプを挿入しない(キャッシュの維持のため)。
- user: 本ラウンドの具体的なタスク + 必要な動的コンテキスト(検索スニペット、状態)。
- few-shot 例: 数個の入力→出力の例は、長い抽象的なルールの羅列よりも、フォーマットやスタイルを「教える」のに効果的である。system と user の間に配置する。
手を動かせば実感できる4つの原則
- 「〜しなければならない」と積み重ねるのではなく、「いつ/境界」を明確にする。 最近の Opus (4.7/4.8) は指示遵守が非常に強く、旧時代に使われていたモデルを「威圧するための」
CRITICAL: YOU MUSTは過剰にトリガーされる。CRITICAL: 検索ツールを使わなければならないを、答えが会話に含まれていない情報に依存している場合は、まず検索してから回答するのように緩和する。 - 重要な指示は注意力の強い位置に配置する。 重要な制約は、先頭の system または末尾の user に配置し、XMLタグや区切り文字で囲む(
<rules>...</rules>)。中段に埋め込まない(真ん中で失われる現象を防ぐため)。 - 正例は負例より優れている。 「このように書く: …」は「こうしないで」よりも安定している。簡潔さを求めるなら、1つの簡潔な例を与える方が、「冗長にするな」という10のルールを列挙するよりも効果的である。
- 意図を与え、指示だけでなく。 「誰のために、何に使うものなのか」を説明すれば、モデルは合理的な詳細を自ら補完できる——特に長期的なタスクで顕著である。
移行レシピ: temperature → prompt + effort
旧コードのサンプリングパラメータを、意図に応じて変換する:
| 旧書き方 (意図) | 新書き方 |
|---|---|
temperature=0 (決定論を求める) | effort:"low" + 指示を固定し、出力フォーマットを指定 |
temperature=高 (発散を求める) | プロンプト内で「N個の異なる方向を提示せよ」と明示; フロントエンドで、モデルに「まず4つの異なる方向を提示してから実装する」ようなシナリオを設計 |
temperature で出力長を制御 | プロンプト内で長さ/詳しさの要件を直接記述(モデルはタスクの複雑さに応じて自己調整するため、必要であれば固定する) |
古い誤解への注意:
temperature=0は旧モデルでも決してバイト単位の完全な再現を保証しない(浮動小数点の累積順序、バッチ処理、MoE ルーティングの揺らぎによるもの。詳細は トークンとサンプリング 参照)。「決定論」はエンジニアリング上の目標(プロンプトの固定 + 低 effort + 微小なドリフトの許容)であり、あるパラメータが保証するものではない。
後半: 構造化出力
モデルの出力をプログラムに渡す(データベースへの保存、ダウンストリームAPIの呼び出し、アサーションの実行)場合、「JSONを返してください」というお願いは信頼できない——モデルは前言語を追加したり、フィールドを漏らしたり、フォーマットがぶれたりする可能性がある。構造化出力は、スキーマを用いてAPIレベルで出力を制約し、確実に有効な形状に保つ。2つのレイヤーがある:
1. JSON出力: 応答全体を制約
messages.create で output_config.format を渡す(注意: 従来のトップレベルの output_format パラメータは廃止された):
=
# 最初の text block が有効な JSON となる
SDK は client.messages.parse() + Pydantic/Zod も提供しており、手動解析なしで検証済みのオブジェクトを直接取得できる。
2. 厳格なツール呼び出し: ツール引数を制約
モデルがツールを呼び出す際、引数もスキーマに従って厳密に検証されるようにする——ツール定義に strict: true を追加する(tool_choice ではなく、ツール自体に設定)。スキーマには additionalProperties: false と required を含める必要がある:
=
これにより、tool_use.input がスキーマに厳密に適合することが保証される——分類タスクにおいて、enum付きのツールや構造化出力を用いることは、モデルに「ラベルを出力せよ」と言ってから解析するよりも、はるかに安定している。
スキーマの能力の限界(知っておかないと、静かにハマる)
構造化出力はサポート: 基本型、enum/const/anyOf/$ref、文字列フォーマット(date-time/email/uri/uuid…)、additionalProperties: false(各オブジェクトで指定が必要)。サポートしない: 再帰スキーマ、数値制約(minimum/maximum)、文字列長(minLength/maxLength)、複雑な配列制約。Python/TS SDK はサポートされない制約を自動的に除去し、クライアント側での検証に委ねる。
実務上の2点:最初の新しいスキーマには一度限りのコンパイルオーバーヘッドがあり、その後24時間はキャッシュがヒットする。構造化出力と引用(citations)は排他(両方を有効にすると400エラー。RAG 参照)。
構造化出力 × 評価: 検証をプログラム可能にする
これが構造化出力で最も過小評価されている価値である。評価と観測 で述べたように、「コードで判定できるなら、モデルに任せるな」。構造化出力により、多くの検証が「LLM-as-judge」から「コードアサーション」へと格下げされる——スキーマに適合しているか、enum値が有効か、必須フィールドが揃っているか——すべて assert で行え、確実で、ゼロコスト、バイアスがない。まずスキーマで出力をアサート可能な形状に固定し、その上で LLM 裁判官を使うかどうかを検討する。
ベストプラクティス
- サンプリングパラメータはすべて削除し、意図を prompt + effort に変換する。
temperature=0→effort:"low"+ 指示の固定; 発散を求めたい場合→プロンプトで「N個の方向を提示」を明示。 - 指示は「いつ/境界」を記述し、「〜しなければならない」を積み重ねない。 新 Opus は指示遵守が強く、過激な表現は過剰にトリガーされる; 重要な制約は強い位置に配置し、XMLで囲む。
- few-shot 正例 > 抽象的なルールの羅列。 例を与えてフォーマットやスタイルを教え、簡潔さを求めるなら簡潔な例を与える。
- 出力をプログラムに渡す場合はスキーマを使用する。
output_config.formatで応答全体を制約、strict:trueでツール引数を制約; 「JSONを返してください」に頼らない。 - 各オブジェクトで
additionalProperties:falseとrequiredを記述する。 さもないと、厳格モードは機能しない。 - スキーマを用いて検証をコードアサーションに格下げする。
assertできるものは裁判官に頼らない; 構造化出力は評価のプログラム可能性の前提条件である。 - スキーマの限界と排他条件を覚える。 再帰/数値/長さの制約はサポートされない; 引用とは排他なので、どちらか一方を選ぶ。
トレードオフと失敗パターン
- 新モデルでも
temperature/top_p/top_kを送信する: 400 → 削除し、prompt + effort に移行。 - 旧式の
CRITICAL: YOU MUST攻撃: ツール/スキルが過剰にトリガーされる → 「いつ使うか」の条件文に緩和。 - 「JSONを返してください」に頼る: 偶発的な前言語/フィールド漏れ/フォーマットのぶれ →
output_config.formatで強く制約。 strictをtool_choiceに設定する: 機能しない → ツール定義に配置し、additionalProperties:falseを設定。- スキーマに
minLength/minimumを記述する: 静かに除去され、制約が機能しない → このような範囲検証はクライアントコードで行う。 - 構造化出力と同時に citations を有効にする: 400 → どちらか一方を選ぶ; 出典を追いたい場合はプレーンテキスト + 引用を、解析可能にしたい場合はスキーマを使用。
- 思考を無効化すると冗長になる:
thinking:disabled下で推論が本文に漏れ出る → adaptive を残すか、「最終回答のみを出力せよ」を追加(推論と思考 参照)。
参考
- Anthropic 公式ドキュメント: 構造化出力 (
output_config.format/strict)、移行ガイド (サンプリングパラメータの削除、プロンプトの最適化)、ツール使用 (platform.claude.com、実装前に公式情報を確認) - 関連: トークンとサンプリング、推論と思考、コンテキストエンジニアリング、評価と観測
キーワード: プロンプトエンジニアリング、system prompt、few-shot、XMLタグ、指示の配置、temperature の移行、effort、構造化出力、structured outputs、output_config.format、json_schema、厳格なツール使用、additionalProperties、required、messages.parse、Pydantic、Zod、enum、スキーマコンパイルキャッシュ、citations の排他、プログラム可能な検証、決定論