Azure OpenAI で JSON モードを試したメモ

# 背景
OpenAI の JSON モードが Azure OpenAI でも利用できるので試してみる。
JSON モードは、チャットのレスポンスを JSON 形式で受け取れるようにするものでプログラムなどで扱いやすくなる

# ドキュメント
以下公式ドキュメント
https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/json-mode?tabs=python
- 注意点
    - サポートされているモデルは `gpt-4-1106-preview`
    - 対応しているリージョンは限られる
        - https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/models#gpt-4-and-gpt-4-turbo-preview-model-availability
    - API バージョンには `2023-12-01-preview` を指定

# 手順
1. openai のライブラリをインストール
    - `pip install openai`
    - バージョンは `0.28.1` ではなく `1.x` 以上
1. sample.py など適当なファイルを作成してソースを貼り付ける(上記ドキュメントより)
    ```python
    import os
    from openai import AzureOpenAI
    
    client = AzureOpenAI(
      azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
      api_key=os.getenv("AZURE_OPENAI_KEY"),  
      api_version="2023-12-01-preview"
    )
    
    response = client.chat.completions.create(
      model="gpt-4-1106-preview", # Model = should match the deployment name you chose for your 1106-preview model deployment
      response_format={ "type": "json_object" },
      messages=[
        {"role": "system", "content": "You are a helpful assistant designed to output JSON."},
        {"role": "user", "content": "Who won the world series in 2020?"}
      ]
    )
    print(response.choices[0].message.content)
    ```
1. エンドポイントや API キーを設定する。モデル名もはデプロイした名前に置き換える。
1. プログラムを実行して結果を確認すると、JSON で応答されている
```
{
  "World_Series_Winner_2020": {
    "Team_Name": "Los Angeles Dodgers",
    "Victory_Over": "Tampa Bay Rays",
    "Series_Result": "Dodgers won 4-2"
  }
}
```

## デフォルトのレスポンスフォーマット
response_format を指定せずシステムプロンプトの JSON 指定を外した場合、テキストで応答された
```python
response = client.chat.completions.create(
    model="gpt-4-1106-preview",  # Model = should match the deployment name you chose for your 1106-preview model deployment
    messages=[
        {"role": "user", "content": "Who won the world series in 2020?"},
    ],
)
print(response.choices[0].message.content)
```

```:出力結果
The Los Angeles Dodgers won the World Series in 2020. They defeated the Tampa Bay Rays in six games to capture their first championship since 1988.
```

## デフォルトのレスポンスフォーマットで、JSON で出力するよう指示
```python
response = client.chat.completions.create(
    model="gpt-4-1106-preview",  # Model = should match the deployment name you chose for your 1106-preview model deployment
    messages=[
        {
            "role": "system",
            "content": "You are a helpful assistant designed to output JSON.",
        },
        {"role": "user", "content": "Who won the world series in 2020?"},
    ],
)
print(response.choices[0].message.content)
```
JSON で返されたが、Markdownで出力する形式で加工が難しくなる
```:出力結果
    ```json
    {
      "World_Series_Winner_2020": "Los Angeles Dodgers"
    }
    ```
```

## JSON モードで指定するが、プロンプトで JSON に言及しない
```python
response = client.chat.completions.create(
    model="gpt-4-1106-preview",  # Model = should match the deployment name you chose for your 1106-preview model deployment
    response_format={"type": "json_object"},
    messages=[
        {"role": "user", "content": "Who won the world series in 2020?"},
    ],
)
print(response.choices[0].message.content)
```

エラーとなる。JSON として出力する旨は指定する必要がある
```
openai.BadRequestError: Error code: 400 - {'error': {'message': "'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.", 'type': 'invalid_request_error', 'param': 'messages', 'code': None}}
```

# まとめ
応答結果をプログラムで処理する際には便利そう
日本のリージョンではまだ利用できないので早く対応して欲しい