---
title: プロンプトエンジニアリングと構造化出力
url: https://doc.liz6.com/ja/ai/03-applications-and-production/02-prompt-engineering-and-structured-output
locale: ja
area: ai
tags:
- ai
- applications-and-production
date: 2026-06-30
modified: 2026-07-19
description: 'サンプリングパラメータが削除された後、「創造性/決定論の調整」ノブは2つに置き換わった: prompt(意図を明確にする)と effort(十分な計算リソースを確保する)。そして、出力をプログラムが消費可能にするのは、「JSONを返してください」というお願いではなく、スキーマ制約である。'
---

# プロンプトエンジニアリングと構造化出力

> サンプリングパラメータが削除された後、「創造性/決定論の調整」ノブは2つに置き換わった: prompt(意図を明確にする)と effort(十分な計算リソースを確保する)。そして、出力をプログラムが消費可能にするのは、「JSONを返してください」というお願いではなく、スキーマ制約である。

## 概要

[トークンとサンプリング](/ai/01-models-and-context/02-tokens-and-sampling.md) で触れた分岐点: Claude のマネージド API は Opus 4.7 から **`temperature`/`top_p`/`top_k` を削除**し、これらを送信すると即座に 400 エラーとなる。旧時代の「温度を調整して創造性を制御し、温度0で決定論を求める」という手触りは失われた。Anthropic は制御権を、より高レベルで制御可能な2つのノブへと移行させた:

- **プロンプティング**——決定論を望めば指示を固定し、発散を望めばプロンプト内で明示的に多様性を要求する;
- **effort**——どの程度深く推論するか、どのくらいのトークンを消費するかを制御する ([推論と思考](/ai/01-models-and-context/04-reasoning-and-thinking.md) 参照)。

この章では、この2つのノブをどのように活用するか（前半: プロンプトエンジニアリング）、そして出力をダウンストリームのプログラムに渡す際に、**構造化出力**を用いて「自由テキスト」を「確実に解析可能な JSON」に制約する方法（後半）について解説する。これら2つはよく組み合わせて用いられる: プロンプトで振る舞いを定め、スキーマで形状を定める。

## 前半: プロンプトエンジニアリング

### モデルが一度に見ているのは、連結された1つのテキストである

[コンテキストエンジニアリング](/ai/01-models-and-context/01-context-engineering.md) でレンダリング順序 `tools → system → messages` について述べた。プロンプトエンジニアリングとは、このテキストに何を、どのように記述するかを決定することである:

- **system**: 安定したロール、ルール、出力規約——これを凍結し、タイムスタンプを挿入しない（[キャッシュ](/ai/01-models-and-context/01-context-engineering.md)の維持のため）。
- **user**: 本ラウンドの具体的なタスク + 必要な動的コンテキスト（検索スニペット、状態）。
- **few-shot 例**: 数個の入力→出力の例は、長い抽象的なルールの羅列よりも、フォーマットやスタイルを「教える」のに効果的である。system と user の間に配置する。

### 手を動かせば実感できる4つの原則

- **「〜しなければならない」と積み重ねるのではなく、「いつ/境界」を明確にする。** 最近の Opus (4.7/4.8) は指示遵守が非常に強く、旧時代に使われていたモデルを「威圧するための」`CRITICAL: YOU MUST` は**過剰にトリガーされる**。`CRITICAL: 検索ツールを使わなければならない` を、`答えが会話に含まれていない情報に依存している場合は、まず検索してから回答する` のように緩和する。
- **重要な指示は注意力の強い位置に配置する。** 重要な制約は、先頭の system または末尾の user に配置し、XMLタグや区切り文字で囲む（`<rules>...</rules>`）。中段に埋め込まない（[真ん中で失われる](/ai/01-models-and-context/01-context-engineering.md)現象を防ぐため）。
- **正例は負例より優れている。** 「このように書く: …」は「こうしないで」よりも安定している。簡潔さを求めるなら、1つの簡潔な例を与える方が、「冗長にするな」という10のルールを列挙するよりも効果的である。
- **意図を与え、指示だけでなく。** 「誰のために、何に使うものなのか」を説明すれば、モデルは合理的な詳細を自ら補完できる——特に長期的なタスクで顕著である。

### 移行レシピ: temperature → prompt + effort

旧コードのサンプリングパラメータを、意図に応じて変換する:

| 旧書き方 (意図) | 新書き方 |
|---|---|
| `temperature=0` (決定論を求める) | `effort:"low"` + 指示を固定し、出力フォーマットを指定 |
| `temperature=高` (発散を求める) | プロンプト内で「N個の異なる方向を提示せよ」と明示; フロントエンドで、モデルに「まず4つの異なる方向を提示してから実装する」ようなシナリオを設計 |
| `temperature` で出力長を制御 | プロンプト内で長さ/詳しさの要件を直接記述（モデルはタスクの複雑さに応じて自己調整するため、必要であれば固定する） |

> 古い誤解への注意: `temperature=0` は旧モデルでも**決して**バイト単位の完全な再現を保証しない（浮動小数点の累積順序、バッチ処理、MoE ルーティングの揺らぎによるもの。詳細は [トークンとサンプリング](/ai/01-models-and-context/02-tokens-and-sampling.md) 参照）。「決定論」はエンジニアリング上の目標（プロンプトの固定 + 低 effort + 微小なドリフトの許容）であり、あるパラメータが保証するものではない。

## 後半: 構造化出力

モデルの出力をプログラムに渡す（データベースへの保存、ダウンストリームAPIの呼び出し、アサーションの実行）場合、「JSONを返してください」というお願いは信頼できない——モデルは前言語を追加したり、フィールドを漏らしたり、フォーマットがぶれたりする可能性がある。**構造化出力**は、スキーマを用いてAPIレベルで出力を**制約**し、確実に有効な形状に保つ。2つのレイヤーがある:

### 1. JSON出力: 応答全体を制約

`messages.create` で `output_config.format` を渡す（注意: 従来のトップレベルの `output_format` パラメータは廃止された）:

```python
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=16000,
    messages=[{"role": "user", "content": "Extract: John (john@co.com), Enterprise plan"}],
    output_config={"format": {
        "type": "json_schema",
        "schema": {
            "type": "object",
            "properties": {
                "name":  {"type": "string"},
                "email": {"type": "string"},
                "plan":  {"type": "string"},
            },
            "required": ["name", "email", "plan"],
            "additionalProperties": False,   # 必須
        },
    }},
)
# 最初の text block が有効な JSON となる
```

SDK は `client.messages.parse()` + Pydantic/Zod も提供しており、手動解析なしで検証済みのオブジェクトを直接取得できる。

### 2. 厳格なツール呼び出し: ツール引数を制約

モデルがツールを呼び出す際、引数もスキーマに従って厳密に検証されるようにする——ツール定義に **`strict: true`** を追加する（`tool_choice` ではなく、ツール自体に設定）。スキーマには `additionalProperties: false` と `required` を含める必要がある:

```python
tools=[{
    "name": "book_flight",
    "strict": True,
    "input_schema": {
        "type": "object",
        "properties": {
            "destination": {"type": "string"},
            "passengers":  {"type": "integer", "enum": [1,2,3,4]},
        },
        "required": ["destination", "passengers"],
        "additionalProperties": False,
    },
}]
```

これにより、`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](/ai/03-applications-and-production/01-rag-and-retrieval-augmented-generation.md) 参照）。

## 構造化出力 × 評価: 検証をプログラム可能にする

これが構造化出力で最も過小評価されている価値である。[評価と観測](/ai/02-Agent/05-evaluation-and-observability.md) で述べたように、「コードで判定できるなら、モデルに任せるな」。構造化出力により、多くの検証が「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 を残すか、「最終回答のみを出力せよ」を追加（[推論と思考](/ai/01-models-and-context/04-reasoning-and-thinking.md) 参照）。

## 参考

- **Anthropic 公式ドキュメント**: 構造化出力 (`output_config.format` / `strict`)、移行ガイド (サンプリングパラメータの削除、プロンプトの最適化)、ツール使用 (platform.claude.com、実装前に公式情報を確認)
- **関連**: [トークンとサンプリング](/ai/01-models-and-context/02-tokens-and-sampling.md)、[推論と思考](/ai/01-models-and-context/04-reasoning-and-thinking.md)、[コンテキストエンジニアリング](/ai/01-models-and-context/01-context-engineering.md)、[評価と観測](/ai/02-Agent/05-evaluation-and-observability.md)

*キーワード: プロンプトエンジニアリング、system prompt、few-shot、XMLタグ、指示の配置、temperature の移行、effort、構造化出力、structured outputs、output_config.format、json_schema、厳格なツール使用、additionalProperties、required、messages.parse、Pydantic、Zod、enum、スキーマコンパイルキャッシュ、citations の排他、プログラム可能な検証、決定論*
