2024/11/22

つないでみよう:#21)GPT4o Structured Outputs とは?

本日 2024 年 11 月 22 日は ノーツコンソーシアム 大阪地区の研究会の開催日です。この研究会で発表するプレゼンテーションをダイジェスト版でお伝えいたします。


2024 年 10 月 1 日の GPT4o のモデルが更新されるとのアナウンスの中に『Structured Outputs がサポートされる』という情報がありました。早速試してみたので、体験レポートとしてまとめます。


Structured Outputs とは?

案内メールのリンク『Introducing Structured Outputs in the API』はこちらでした。ざっくりまとめると、次の通りです。

  • 出力の構造をスキーマとして定義
  • スキーマ通りの出力で強制する機能


アプリ開発とレスポンス制御の種類

まずは、GPT4o の API 連係アプリの一般的な作成方法です。手順は、問い合わせ内容をリクエストの JSON にセットし、API をコールします。そして、API のレスポンスも JSON 形式で返されるという仕組みでした(細かな手順はこの連載の #1#2 をご確認ください)。このレスポンスの JSON から AI の返答部分を取得して後続の処理で利用すれは、連携アプリが構築できるということですね。

GPT4o にはこのレスポンスを制御する機能があります。

  1. 通常の問い合わせ(制御なし)
  2. JSON Mode を指定
  3. Structured Outputs の利用

Structured Outputs 実践に入る前に、これら機能の必要性について確認しましょう。


1. 通常の問い合わせ

AI にメールを作成させる処理を事例に記載します。

まずは、通常の問い合わせのパターンでは次のようなリクエストとレスポンスになります。

1. 通常)リクエスト
{
  "model": "gpt-4o-2024-08-06",
  "messages": [
    {
      "role": "system",
      "content": ""
    },
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "kintone ユーザにHCL Notesの有効性を説明して、購入を促すメールを作成してください。"
        }
      ]
    }
  ]
}

1. 通常)レスポンス
{
  "id": "chatcmpl-ARVrw9GojS5cAhUHswYkLD8VXY6Tl",
  "object": "chat.completion",
  "created": 1731120724,
  "model": "gpt-4o-2024-08-06",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "件名: HCL Notesで業務効率化 … 省略 … \n[あなたの連絡先詳細]",
        "refusal": null
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 40,
    "completion_tokens": 553,
    "total_tokens": 593,
    "prompt_tokens_details": {
      "cached_tokens": 0,
      "audio_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,
      "audio_tokens": 0,
      "accepted_prediction_tokens": 0,
      "rejected_prediction_tokens": 0
    }
  },
  "system_fingerprint": "fp_45cf54deae"
}

赤字の部分がリクエストに対する AI の返答の本体です。ここを取得して、アプリケーションで利用しることになります。この構造は、後述の JSON Mode や Structured Outputs でも同じとなります。

返答の本体部分だけを抽出すると次のようになります。

件名: HCL Notesで業務効率化を実現しましょう!

[お客様名] 様

平素より大変お世話になっております。[あなたの会社名]の[あなたの名前]です。

この度は、業務効率化を実現するための最適なソリューション、HCL Notesをご紹介させていただきます。HCL Notesは、ビジネスコミュニケーションに革新をもたらす総合的なプラットフォームで、多くの企業様にご活用いただいております。

### HCL Notesの特長

1. **シームレスなコラボレーション**
- メール、カレンダー、インスタントメッセージングが一体化され、チームメンバーとの連携がスムーズに行えます。

2. **高いセキュリティ**
- データの暗号化とアクセス管理により ・・・ 後略

人間が見れば件名と本文がどこか判定できます。ですが、プログラムでの処理を考えると少し厄介です。1 行目は必ず件名なのか? ”件名:” で始まるのか? 毎回そのフォーマットで返答してくれるのか? わからないからです。

この問題を回避するための手段がレスポンス制御です。


2. JSON Mode を指定

この手法からはレスポンスを構造化したテキストデータ(JSON)で取得することを目的とした機能です。リクエスト時に返答は JSON で返してとお願いすることに加え、返答は JSON でと指定する方法で JSON Mode と呼ぶようです。この手法は『#19)GPT4o は OCR? - 返答を JSON で返す方法』で紹介しています。

具体的には下記の通りです。response_format を指定することがポイントでした。

2. JSON Mode)リクエスト
{
  "model": "gpt-4o-2024-08-06",
  "messages": [
    {
      "role": "system",
      "content": ""
    },
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "kintone ユーザにHCL Notesの有効性を説明して、購入を促すメールを作成してください。\r\n返答は、”件名”と”本文” のJSON 形式としてください。"
        }
      ]
    }
  ],
  "response_format": {
    "type": "json_object"
  }

}

これで、結果の content は JSON 形式の文字列になります。その部分を整形すると次のようになります。

{
  "件名": "HCL Notesの導入で業務効率を大幅に向上させましょう!",
  "本文": "お世話になっております。日頃よりkintoneをご利用いただき、誠にありがとうございます。今回は、業務効率のさらなる向上を図るため、HCL Notesをご紹介させていただきます。HCL Notesは、企業のコミュニケーションを変革するととも ・・・ 後略

ここで問題となるのが ”件名” や "本文" のノード名です。この名称はリクエストで指示しているとは言え、その文言で必ず生成される保証はありません。また、JSON のフォーマットについてはどこにも記載されていません。AI の判断にゆだねられているということですね。


3. Structured Outputs の利用

いよいよ本題の Structured Outputs の指定です。

これまで事例にしていたメールの作成を指示するリクエストを Structured Outputs で表現すると次のようになります。response_format の type に json_schema を指定し、以降に出力として返してほしい JSON の構造(スキーマ)を記述します。

3. Structured Outputs)リクエスト
{
  "model": "gpt-4o-2024-08-06",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "kintone ユーザにHCL Notesの有効性を説明して、購入を促すメールを作成してください。"
        }
      ]
    }
  ],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "recommendnotes",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "
subject": {
            "type": "string",
            "description": "メールの件名"
          },
          "
body": {
            "type": "string",
            "description": "メールの本文"
          }
        },
        "required": [
          "subject",
          "body"
        ],
        "additionalProperties": false
      }
    }
  }
}

結果の JSON を整形すると次のようになります。

{
  "subject": "ビジネス効率化への新たな一歩:HCL Notes導入のご提案",
  "body": "拝啓 [顧客名] 様平素よりお世話になっております。私たちは、お客様のビジネスがさらなる成長を遂げるために、現代のデジタルツールを駆使して業務効率とコミュニケーションの質を向上させるソリューションをご提供したいと考えております。本日はその一環として、HCL Notesをご紹介する機会をいただきたくご連絡 ・・・ 後略

スキーマで定義したノード名で JSON が出力されていることがわかります。これで後続のプログラムで、例外処理などを省くことができ連携アプリが容易に構築できるようになりますね。


前回 連載:つないでみよう 次回


0 件のコメント:

コメントを投稿