T-CREATOR

GPT-5 構造化出力チートシート:JSON/表/YAML/コードブロックの安定生成パターン

GPT-5 構造化出力チートシート:JSON/表/YAML/コードブロックの安定生成パターン

AI 開発の現場で、GPT-5 などの大規模言語モデルを活用していると「もっと安定した形式でデータを出力してほしい」と感じることはありませんか。自然言語での回答は柔軟ですが、システム連携やデータ処理には構造化された出力が不可欠です。

本記事では、GPT-5 でJSON、Markdown 表、YAML、コードブロックなどの構造化出力を安定的に生成するための実践的なパターンを解説します。プロンプトエンジニアリングの基礎から、実務で即使えるテンプレートまで、初心者の方にもわかりやすくお届けしますね。

構造化出力パターン早見表

#出力形式適用場面安定性主なメリット注意点
1JSON SchemaAPI 連携・型安全★★★★★厳密な型定義、バリデーション自動化スキーマ定義の学習コスト
2Markdown 表ドキュメント・比較★★★★☆可読性、GitHub 対応複雑な構造には不向き
3YAML設定ファイル・階層データ★★★★☆インデント構造、コメント対応インデント崩れリスク
4TypeScript 型定義フロントエンド連携★★★★★IDE サポート、型推論複雑な型の表現制約
5コードブロック(言語指定)実装例・サンプル★★★★☆シンタックスハイライト実行環境への配慮必要
6CSV 形式データエクスポート★★★☆☆Excel 互換、軽量改行・カンマのエスケープ

背景

構造化出力が求められる理由

近年の AI 開発では、言語モデルを単なる対話エージェントとしてではなく、システムの一部として組み込むケースが急増しています。例えば、カスタマーサポートの自動応答、データ分析レポートの生成、設定ファイルの自動作成など、多岐にわたります。

これらのユースケースでは、AI の出力をそのまま後続処理に渡せる形式であることが重要です。自然言語の文章では、パースエラーやデータ抽出の失敗が頻発してしまうでしょう。

以下の図は、構造化出力を用いたシステム連携の基本フローを示しています。

mermaidflowchart LR
  user["開発者"] -->|プロンプト| gpt["GPT-5 API"]
  gpt -->|構造化データ| parser["パーサー<br/>(JSON/YAML/CSV)"]
  parser -->|オブジェクト| app["アプリケーション"]
  app -->|保存・処理| db[("データベース")]
  app -->|表示| ui["UI/ダッシュボード"]

この図のように、GPT-5 からの出力をそのままパーサーに渡せる形式にすることで、エラーハンドリングやデータ変換のコストを大幅に削減できます。

GPT-5 の構造化出力機能の進化

GPT-4 までは、構造化出力を得るためにプロンプト内で「JSON で返してください」と指示しても、不完全な形式や余計な説明文が混入することがありました。しかし GPT-5 では、JSON ModeStructured Outputs APIといった機能が強化され、スキーマに基づいた厳密な出力が可能になっています。

これにより、フロントエンドとバックエンドの間で API レスポンスの型を統一したり、複数の AI エージェントが共通のデータ形式でやり取りしたりすることが、より確実になりました。

課題

構造化出力における代表的な問題

AI に構造化出力を依頼する際、以下のような課題に直面することがあります。

  1. フォーマットの不安定性: プロンプトの書き方次第で、JSON 構文エラーや YAML のインデント崩れが発生
  2. 余計な説明文の混入: 「以下が JSON です」といった前置きや、コードブロック外のコメントが入る
  3. キー名の揺れ: 同じデータでも user_nameuserName のように表記が統一されない
  4. ネストの深さ制御: 複雑な階層構造を指示しても、浅い構造に簡略化されてしまう
  5. エスケープ処理の不備: 文字列内の改行やダブルクォートが正しくエスケープされない

以下の図は、プロンプト設計が不十分な場合に起こる問題の流れを示しています。

mermaidflowchart TD
  prompt["曖昧なプロンプト"] -->|指示不足| gpt["GPT-5"]
  gpt -->|不完全なJSON| parser["JSONパーサー"]
  parser -->|構文エラー| error1["SyntaxError"]
  gpt -->|余計な説明文| extractor["正規表現抽出"]
  extractor -->|抽出失敗| error2["データ欠損"]
  gpt -->|キー名の揺れ| validator["バリデーター"]
  validator -->|検証失敗| error3["型エラー"]

こうした問題を回避するには、プロンプト設計の段階で出力形式を明確に定義し、GPT-5 の機能を適切に活用することが重要です。

エラーコード例:よくある失敗パターン

構造化出力の失敗時には、以下のようなエラーが頻出します。

エラーコード: SyntaxError: Unexpected token } in JSON at position 42

json{
  "name": "太郎",
  "age": 30,
  "hobbies": ["読書", "旅行"] // 末尾のカンマが原因
}

発生条件: JSON の配列やオブジェクトの末尾に不要なカンマがある、またはクォートの閉じ忘れ

解決方法:

  1. プロンプトで「JSON の末尾カンマを含めない」と明示
  2. JSON Schema を使った Structured Outputs API を利用
  3. 出力後にバリデーションライブラリ(ajvzodなど)で検証

解決策

基本戦略:プロンプトと API 機能の組み合わせ

構造化出力を安定させるには、プロンプトエンジニアリングAPI の機能活用の両輪が必要です。以下の 3 つの戦略を組み合わせることで、高い安定性を実現できます。

  1. 明示的なフォーマット指示: プロンプト内で出力形式のテンプレートを示す
  2. JSON Schema / TypeScript 型定義の提供: API パラメータで厳密なスキーマを指定
  3. Few-shot プロンプティング: 正しい出力例を 2〜3 個示し、パターンを学習させる

以下の図は、これらの戦略を組み合わせた安定出力の仕組みです。

mermaidflowchart TD
  dev["開発者"] -->|1. スキーマ定義| schema["JSON Schema<br/>or TypeScript型"]
  dev -->|2. テンプレート| prompt["プロンプト<br/>(Few-shot含む)"]
  schema --> api["GPT-5 API<br/>(Structured Outputs)"]
  prompt --> api
  api -->|厳密な型チェック| output["構造化データ"]
  output -->|バリデーション成功| app["アプリケーション"]

この図のように、スキーマとプロンプトの両方を最適化することで、パースエラーやデータ不整合を事前に防止できます。

JSON 出力の安定化パターン

JSON 出力を安定させるには、OpenAI API の response_format: { type: "json_object" } を利用するのが最も確実です。さらに、Structured Outputs API を使えば、JSON Schema に基づいた厳密な型検証が行われます。

プロンプト設計のポイント

  • 出力形式を冒頭で明示: 「以下の形式で JSON を出力してください」と指示
  • キー名を固定: 「必ず user_id, user_name, created_at のキーを含む」と列挙
  • 余計な説明文を禁止: 「JSON のみを出力し、説明文は含めないでください」と明記
  • Few-shot 例を示す: 正しい JSON 例を 1〜2 個提示

プロンプト例

以下は、ユーザー情報を JSON 形式で出力させる基本的なプロンプトです。

typescriptconst prompt = `
以下のユーザー情報をJSON形式で出力してください。
**出力ルール**:
- キー名は user_id, user_name, email, age を使用
- 余計な説明文は含めない
- JSONのみを出力

**入力**:
名前: 山田太郎
メール: taro@example.com
年齢: 28歳
ID: 12345

**期待する出力形式**:
{
  "user_id": "12345",
  "user_name": "山田太郎",
  "email": "taro@example.com",
  "age": 28
}
`;

このプロンプトでは、期待する出力形式を明示することで、GPT-5 に正確な JSON 構造を学習させています。

API 呼び出し例(TypeScript)

次に、OpenAI API を使った実装例を示します。

typescriptimport OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});
typescript// JSON出力を強制するための設定
const response = await client.chat.completions.create({
  model: 'gpt-5-turbo',
  messages: [
    {
      role: 'system',
      content:
        'あなたは構造化データを生成するアシスタントです。',
    },
    {
      role: 'user',
      content: prompt,
    },
  ],
  response_format: { type: 'json_object' }, // JSON出力を強制
  temperature: 0.3, // 安定性重視で低めに設定
});
typescript// レスポンスの取得とパース
const jsonText = response.choices[0].message.content;
const userData = JSON.parse(jsonText);

console.log(userData);
// 出力: { user_id: "12345", user_name: "山田太郎", email: "taro@example.com", age: 28 }

ポイント:

  • response_format: { type: "json_object" } を指定することで、GPT-5 が必ず JSON 形式で返答
  • temperature を低く設定し、出力の揺れを抑制
  • パース前にバリデーションを挟むとさらに安全

Markdown 表の安定生成パターン

Markdown 形式の表は、ドキュメント作成や GitHub Issue での情報整理に便利です。GPT-5 は表の生成が得意ですが、列の揃えやエスケープ処理で問題が起きることがあります。

プロンプト設計のポイント

  • 列数と列名を明示: 「以下の 3 列で表を作成: 名前、年齢、部署」
  • 行数の指定: 「5 行分のサンプルデータを含む」
  • フォーマット例を提示: テンプレート表を示す

プロンプト例

text以下のデータをMarkdown形式の表で出力してください。

**列構成**: 名前、年齢、部署、入社年
**行数**: 5行分のサンプルデータ

**出力形式**:
| # | 名前 | 年齢 | 部署 | 入社年 |
|---|------|------|------|--------|
| 1 | 山田太郎 | 28 | 開発部 | 2020 |

このように、表のテンプレートを示すことで、GPT-5 が形式を正確に再現できます。

生成例

GPT-5 が生成する表は以下のようになります。

#名前年齢部署入社年
1山田太郎28開発部2020
2佐藤花子32営業部2018
3鈴木一郎25人事部2022
4田中美咲30企画部2019
5高橋健太27総務部2021

注意点:

  • セル内に改行やパイプ(|)が含まれる場合は、エスケープ処理を明示
  • 複雑なネスト構造は表形式に不向きなため、JSON 形式を検討

YAML 出力の安定化パターン

YAML は設定ファイルや階層的なデータ表現に適しています。しかし、インデントの揺れやコロンの位置ミスが起きやすいため、プロンプトで細かく指示する必要があります。

プロンプト設計のポイント

  • インデント幅を指定: 「2 スペースでインデント」
  • コメントの有無を明示: 「各キーに説明コメントを付ける」
  • 階層構造を事前に定義: ネストレベルを示す

プロンプト例

text以下の設定をYAML形式で出力してください。

**要件**:
- インデントは2スペース
- 各キーに説明コメントを付ける
- 階層: database > connection > host, port, user, password

**出力形式**:
# データベース設定
database:
  # 接続情報
  connection:
    host: localhost
    port: 5432
    user: admin
    password: secret

生成例

GPT-5 が生成する YAML は以下のようになります。

yaml# アプリケーション設定
app:
  # サーバー設定
  server:
    host: 0.0.0.0
    port: 3000
    timeout: 30
  # データベース設定
  database:
    connection:
      host: localhost
      port: 5432
      user: app_user
      password: secure_password
    pool:
      min: 2
      max: 10

注意点:

  • YAML 1.2 の仕様に準拠しているか確認(タブ文字は使用不可)
  • yamllint などのバリデーションツールで検証を推奨

TypeScript 型定義の生成パターン

フロントエンド開発では、API レスポンスに対応する TypeScript 型定義を自動生成したいケースが多いです。GPT-5 を使えば、JSON Schema から型定義を生成したり、既存の API ドキュメントから型を起こしたりできます。

プロンプト例

text以下のJSON Schemaに対応するTypeScript型定義を生成してください。

**JSON Schema**:
{
  "type": "object",
  "properties": {
    "user_id": { "type": "string" },
    "user_name": { "type": "string" },
    "age": { "type": "number" },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["user_id", "user_name", "age"]
}

**出力形式**: TypeScriptのinterface定義のみ

生成例

typescript// ユーザー情報の型定義
interface User {
  user_id: string;
  user_name: string;
  age: number;
  email?: string; // オプショナル(requiredに含まれていない)
}

ポイント:

  • required の有無でオプショナル(?)を適切に判定
  • format: "email" などの情報は型定義では表現できないため、バリデーションライブラリと併用

コードブロックの言語指定パターン

技術ドキュメントやチュートリアルを生成する際、シンタックスハイライト付きのコードブロックが必要です。GPT-5 に言語指定を徹底させるには、プロンプトで明示的に指示します。

プロンプト例

textReactのカスタムフックを作成するサンプルコードを出力してください。

**要件**:
- 言語: TypeScript
- コードブロックは ```typescript で囲む
- 説明文は含めない

生成例

typescriptimport { useState, useEffect } from 'react';

// カスタムフック: ローカルストレージと同期するstate
function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}

export default useLocalStorage;

注意点:

  • コードブロックの開始と終了を正確に(バッククォート 4 つで囲む場合も明示)
  • 長いコードは機能ごとに分割し、各ブロックに説明を添える

具体例

実例 1:API レスポンスの JSON Schema 定義

ここでは、ブログ記事の API レスポンスを JSON Schema で定義し、GPT-5 に生成させる実例を紹介します。

JSON Schema の定義

まず、期待するデータ構造を JSON Schema で記述します。

json{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "articles": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string" },
          "author": { "type": "string" },
          "published_at": {
            "type": "string",
            "format": "date-time"
          },
          "tags": {
            "type": "array",
            "items": { "type": "string" }
          }
        },
        "required": [
          "id",
          "title",
          "author",
          "published_at"
        ]
      }
    }
  },
  "required": ["articles"]
}

プロンプト例

text上記のJSON Schemaに従って、ブログ記事3件分のサンプルデータをJSON形式で出力してください。

**条件**:
- published_at は ISO 8601 形式
- tags は2〜3個のタグを含む
- 余計な説明文は不要

生成される JSON

json{
  "articles": [
    {
      "id": "article-001",
      "title": "GPT-5で始める構造化出力入門",
      "author": "山田太郎",
      "published_at": "2025-11-20T10:30:00Z",
      "tags": ["AI", "GPT-5", "プログラミング"]
    },
    {
      "id": "article-002",
      "title": "TypeScriptで型安全なAPIクライアントを作る",
      "author": "佐藤花子",
      "published_at": "2025-11-22T14:00:00Z",
      "tags": ["TypeScript", "API", "開発効率化"]
    },
    {
      "id": "article-003",
      "title": "YAMLで管理する設定ファイルのベストプラクティス",
      "author": "鈴木一郎",
      "published_at": "2025-11-25T09:15:00Z",
      "tags": ["YAML", "設定管理", "DevOps"]
    }
  ]
}

ポイント:

  • スキーマで定義した required フィールドが必ず含まれる
  • format: "date-time" の指定により、ISO 8601 形式で日時が生成される
  • 実際のアプリケーションでは、zodajv でバリデーションを実施

実例 2:Markdown 表での比較表生成

複数のツールやライブラリを比較する表を生成する例です。

プロンプト例

text以下の観点で、React、Vue、Svelteを比較するMarkdown表を作成してください。

**比較項目**:
1. 学習曲線
2. パフォーマンス
3. エコシステム
4. TypeScriptサポート
5. ビルドサイズ

**出力形式**:
| # | フレームワーク | 学習曲線 | パフォーマンス | エコシステム | TypeScriptサポート | ビルドサイズ |
|---|----------------|----------|----------------|--------------|---------------------|--------------|

生成される表

#フレームワーク学習曲線パフォーマンスエコシステムTypeScript サポートビルドサイズ
1React★★★★★ネイティブ対応
2Vue★★★★☆公式サポート
3Svelte非常に高★★★☆☆標準対応非常に小

図で理解できる要点:

  • Svelte はビルドサイズが最小でパフォーマンスが高い
  • React はエコシステムが最も充実
  • Vue は学習曲線が緩やかで初心者向き

実例 3:Docker Compose 設定の YAML 生成

開発環境の Docker Compose 設定を自動生成する例です。

プロンプト例

text以下の要件でdocker-compose.ymlを生成してください。

**サービス構成**:
- Webサーバー: Nginx (ポート80)
- アプリケーション: Node.js 20 (ポート3000)
- データベース: PostgreSQL 15 (ポート5432)
- キャッシュ: Redis 7 (ポート6379)

**要件**:
- インデントは2スペース
- 各サービスにコメントを付ける
- volumesでデータを永続化

生成される YAML

yamlversion: '3.8'

services:
  # Webサーバー(リバースプロキシ)
  nginx:
    image: nginx:latest
    ports:
      - '80:80'
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app

  # Node.jsアプリケーション
  app:
    image: node:20-alpine
    working_dir: /app
    ports:
      - '3000:3000'
    volumes:
      - ./src:/app
    environment:
      NODE_ENV: development
      DATABASE_URL: postgres://user:pass@db:5432/mydb
      REDIS_URL: redis://cache:6379
    depends_on:
      - db
      - cache

  # PostgreSQLデータベース
  db:
    image: postgres:15-alpine
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data

  # Redisキャッシュ
  cache:
    image: redis:7-alpine
    ports:
      - '6379:6379'
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

ポイント:

  • depends_on で起動順序を制御
  • volumes で開発中のコード変更を即座に反映
  • 環境変数で接続情報を管理

実例 4:TypeScript 型定義の自動生成

既存の API ドキュメントから型定義を起こす例です。

プロンプト例

text以下のREST APIエンドポイントのレスポンスに対応するTypeScript型定義を生成してください。

**エンドポイント**: GET /api/users/:id

**レスポンス例**:
{
  "user": {
    "id": "user-123",
    "profile": {
      "name": "山田太郎",
      "avatar_url": "https://example.com/avatar.jpg",
      "bio": "ソフトウェアエンジニア"
    },
    "stats": {
      "followers": 120,
      "following": 80,
      "posts": 45
    },
    "created_at": "2023-01-15T00:00:00Z"
  }
}

**要件**: interfaceで定義し、ネストした型も分離

生成される型定義

typescript// ユーザープロフィール情報
interface UserProfile {
  name: string;
  avatar_url: string;
  bio: string;
}
typescript// ユーザー統計情報
interface UserStats {
  followers: number;
  following: number;
  posts: number;
}
typescript// ユーザー詳細情報
interface User {
  id: string;
  profile: UserProfile;
  stats: UserStats;
  created_at: string; // ISO 8601形式の日時文字列
}
typescript// APIレスポンス全体の型
interface GetUserResponse {
  user: User;
}

ポイント:

  • ネストした構造を適切に分離し、再利用性を高める
  • created_atDate 型ではなく string 型(JSON 経由のため)
  • 必要に応じて typeenum も活用

実例 5:CSV 形式でのデータエクスポート

データ分析用に CSV 形式で出力する例です。

プロンプト例

text以下のユーザーアクセスログをCSV形式で出力してください。

**データ項目**: タイムスタンプ、ユーザーID、ページURL、滞在時間(秒)
**行数**: 10行分のサンプルデータ
**日時形式**: YYYY-MM-DD HH:MM:SS

**注意**:
- カンマを含むURLは ""(ダブルクォート)で囲む
- ヘッダー行を含める

生成される CSV

csvtimestamp,user_id,page_url,duration_seconds
2025-11-26 10:15:30,user-001,https://example.com/home,45
2025-11-26 10:18:12,user-002,https://example.com/products,120
2025-11-26 10:20:05,user-001,https://example.com/about,30
2025-11-26 10:22:40,user-003,"https://example.com/search?q=typescript,tutorial",60
2025-11-26 10:25:18,user-002,https://example.com/pricing,90
2025-11-26 10:28:33,user-004,https://example.com/contact,25
2025-11-26 10:30:50,user-001,https://example.com/blog,150
2025-11-26 10:35:12,user-005,https://example.com/docs,200
2025-11-26 10:40:28,user-003,https://example.com/support,75
2025-11-26 10:45:00,user-002,https://example.com/dashboard,180

ポイント:

  • カンマを含む URL はダブルクォートでエスケープ
  • ヘッダー行があることで Excel や BigQuery での取り込みが容易
  • 改行を含むフィールドは \n にエスケープ

以下の図は、構造化出力の各形式をどのユースケースで使い分けるかを示しています。

mermaidflowchart TD
  start["データ出力の目的"] --> api["API連携・型安全"]
  start --> doc["ドキュメント・可読性"]
  start --> config["設定ファイル"]
  start --> export["データエクスポート"]

  api --> json["JSON<br/>(JSON Schema)"]
  api --> ts["TypeScript型定義"]

  doc --> md_table["Markdown表"]
  doc --> code_block["コードブロック"]

  config --> yaml["YAML"]
  config --> env["環境変数ファイル"]

  export --> csv["CSV"]
  export --> json_lines["JSON Lines"]

この図を参考に、目的に応じた最適な出力形式を選択してください。

まとめ

本記事では、GPT-5 を使った構造化出力の安定生成パターンを詳しく解説しました。JSON、Markdown 表、YAML、TypeScript 型定義、コードブロック、CSV など、各形式ごとに実践的なプロンプト設計と実装例を紹介しています。

重要なポイントを振り返りましょう。

まず、プロンプト設計が最も重要です。出力形式のテンプレートを明示し、キー名や構造を具体的に指示することで、GPT-5 の出力が大幅に安定します。Few-shot プロンプティングで正しい例を示すことも効果的ですね。

次に、OpenAI API の機能を活用しましょう。response_format: { type: "json_object" } や Structured Outputs API を使えば、スキーマに基づいた厳密な型検証が可能になります。これにより、パースエラーや型エラーを事前に防げるでしょう。

また、バリデーションの実施も忘れずに。生成されたデータは必ず zodajvyamllint などのツールで検証し、品質を担保してください。

さらに、エラーハンドリングの整備も重要です。構文エラーやキー名の揺れに備えて、フォールバック処理やリトライロジックを実装しておくと、本番環境でのトラブルを減らせます。

最後に、用途に応じた形式選択です。API 連携なら JSON Schema、ドキュメント作成なら Markdown 表、設定ファイルなら YAML と、適材適所で使い分けることが大切ですね。

これらのパターンを活用すれば、AI を活用したシステム開発がより効率的かつ安全になるでしょう。ぜひ実務で試してみてください。

関連リンク