Chatbot UI legacyでGPT-4oを使う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/84ad3f74-cf7d-50f4-2205-e9335826f5e4.png)
作成日：2024年8月30日(土)
更新日：2024年9月29日(日)

## １．はじめに
会社でChatbot UI legacyをコストなどを考慮しながらパイロット運用してきましたが、このシステムで利用しているAzure OpenAIのgpt-35-turbo-16kモデル(0613)が10月1日でEOL（サービス終了）することが発表(**1)されました。Chatbot UI legacyの運用を本番稼働させ、Chatbot UI Version2.0.0をパイロット運用するためにChatbot UI legacyをGPT-4o/GPT-4o miniに対応させる必要があります。*
<font color="red">***Chatbot UI legacyはLMM(Large Multimodal Model)に対応しているわけではありませんので、GPT-4oやGPT-4o miniを安価なLLM(Large Language Model)として利用する取り組みです。***</font>

(*1) 「[What's new in Azure OpenAI Service](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/whats-new)」の「[Retirement date updates](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/whats-new#retirement-date-updates)」  
![Retirement date updates.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/9ac3cbba-fa70-c15d-3295-7d12f0127ee6.png)

## ２．エンドポイントの調査

Azure OpenAIは2023年の5月15日にエンドポイントの仕様を変えたことがあるので、念のため、エンドポイントの仕様を調査します。
調査はAzure AI Studioのチャットプレイグラウンドで「コードの表示」で確認します。

エンドポイントの仕様

エンドポイントの仕様は以下の通りでyour_resource_nameとdeployment_id(Azure AI StudioでLLMをデプロイ時に名付けた名前)を指定します。

| `https://{your_resource_name}.openai.azure.com/openai/deployments/{deployment_id}/chat/completions?api-version=2024-02-01` |
| --- |

実際にチャットプレイグラウンドのコードの表示で確認したところ以下のように上記のルールに則っていることが分かりました。

`https://potofo-eus.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-15-preview`

`https://potofo-eus.openai.azure.com/openai/deployments/gpt-4o-mini/chat/completions?api-version=2024-02-15-preview`

## ３．Chatbot UI legacyでのサポート方法

2024年8月30日(土)時点ではChatbot UI legacyの開発は作者のMckay Wrigley氏によって凍結されてしまっています。
そこで過去のpull requestsを「is:pr gpt-3.5-turbo 」などのキーワードで検索して「[Add gpt-3.5-turbo-16k model #847](https://github.com/mckaywrigley/chatbot-ui/commit/5e5612375caf358c5dcb2e8e0242fc376fa0a4d6)」の変更点を参考にGPT-4o/GPT-4o miniを追加します。

Add gpt-3.5-turbo-16k model #847の修正内容　types/openai.tsファイル

```diff
@@ -9,13 +9,14 @@ export interface OpenAIModel {

export enum OpenAIModelID {
  GPT_3_5 = 'gpt-3.5-turbo',
  GPT_3_5_16K = 'gpt-3.5-turbo-16k',
  GPT_3_5_AZ = 'gpt-35-turbo',
  GPT_4 = 'gpt-4',
  GPT_4_32K = 'gpt-4-32k',
}

// in case the `DEFAULT_MODEL` environment variable is not set or set to an unsupported model
export const fallbackModelID = OpenAIModelID.GPT_3_5;
export const fallbackModelID = OpenAIModelID.GPT_3_5_16K;

export const OpenAIModels: Record<OpenAIModelID, OpenAIModel> = {
  [OpenAIModelID.GPT_3_5]: {
@@ -42,4 +43,10 @@ export const OpenAIModels: Record<OpenAIModelID, OpenAIModel> = {
    maxLength: 96000,
    tokenLimit: 32000,
  },
  [OpenAIModelID.GPT_3_5_16K]: {
    id: OpenAIModelID.GPT_3_5_16K,
    name: 'GPT-3.5-16K',
    maxLength: 96000,
    tokenLimit: 32000,
  }
};
```

変更のポイント

- OpenAIModelID列挙型にでLLMのデプロイ名を追加
- 環境変数DEFAULT_MODEL未設定時のfallbackModelをOpenAIModelIDに含まれるものにする
- OpenAIModelsにモデルのデプロイ名、表示用の名前、最大長、トークンの最大を設定する

## ４．GPT-4o/GPT-4o miniの設定

Add gpt-3.5-turbo-16k model #847の修正内容を参考に実際に修正してみたコードがこちら
(この変更では動きません）

types/openai.ts

``` JavaScript
import { OPENAI_API_TYPE } from '../utils/app/const';

export interface OpenAIModel {
  id: string;
  name: string;
  maxLength: number; // maximum length of a message
  tokenLimit: number;
}

export enum OpenAIModelID {
  GPT_4O_AZ = 'gpt-4o',
  GPT_4O_MINI_AZ = 'gpt-4o-mini',
}

// in case the `DEFAULT_MODEL` environment variable is not set or set to an unsupported model
export const fallbackModelID = OpenAIModelID.GPT_4O_AZ;

export const OpenAIModels: Record<OpenAIModelID, OpenAIModel> = {
  [OpenAIModelID.GPT_4O_MINI_AZ]: {
    id: OpenAIModelID.GPT_4O_MINI_AZ,
    name: 'GPT-4o mini',
    maxLength: 512000,
    tokenLimit: 128000,
  },
  [OpenAIModelID.GPT_4O_AZ]: {
    id: OpenAIModelID.GPT_4O_AZ,
    name: 'GPT-4o',
    maxLength: 512000,
    tokenLimit: 128000,
  },
};

```

.env.local

``` Shell
# Chatbot UI
OPENAI_API_TYPE=azure
OPENAI_API_HOST=https://potofo-eus.openai.azure.com/
AZURE_DEPLOYMENT_ID=gpt-4o-mini
DEFAULT_MODEL=gpt-4o-mini
OPENAI_API_VERSION=2024-02-01
#NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT=You are ChatGPT, a large language model trained by OpenAI. Follow the user's instructions carefully. Respond using markdown.
NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT=You are a chatbot system called Chatbot UI lagacy, launched on April 20, 2023 by Mckay Wrigley. Using OpenAI's large-scale language model, you will carefully answer various questions based on pre-training knowledge up to the cutoff date. Please use Markdown format for your answers and make good use of code blocks Mermaid and tables to respond to user questions in an easy-to-understand manner.
OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Google
GOOGLE_API_KEY=YOUR_API_KEY
GOOGLE_CSE_ID=YOUR_ENGINE_ID

```

ところがモデルスイッチャーが正しく動作しません。

![Doesnotwork_modelswitcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/ef812357-7c41-7d80-b2e8-d684d4a1efe8.png)

pull requestsに「Fix model switcher for Azure #508」というのがありますが、このあたりの修正は必要ないと書かれていたり、私の英語力では理解できませんでした。

試しにカットオフデートを聞いてみると2023年10月と回答が返ってきますので、少なくてもgpt-35-turbo-16kではなくなっているはずです。  

![unknown_cutoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/d20275fe-73b3-ce4f-f134-9dfb45a0050a.png)

少し調べたところ、pages/api/models.tsで${OPENAI_API_HOST}/v1/modelsでAzure OpenAIからOPENAI_API_VERSION(現在の設定：2024-02-01)でサポートされる
モデルと一致しないことが判明しました。

pages/api/models.ts

``` JavaScript
    const models: OpenAIModel[] = json.data
      .map((model: any) => {
        const model_name = (apiVer < 202305) ? model.model : model.id;
        for (const [key, value] of Object.entries(OpenAIModelID)) {
          console.error('model enum :' + value + ':' + model_name);
          if (value === model_name) {
            //console.error('match');
            console.error('model check:' + value + ':' + model_name);
            return {
              id: model.id,
              name: OpenAIModels[value].name,
            };
          }
        }
      })
      .filter(Boolean);

```

このコードでvalue === model_nameに「gpt-4o」がマッチングしていないためリストから削られたもようです。

```
model enum :gpt-4o:dall-e-3-3.0
...
model enum :gpt-4o:gpt-4o-2024-05-13
model enum :gpt-4o-mini:gpt-4o-2024-05-13
model enum :gpt-4o:gpt-4o-2024-08-06
model enum :gpt-4o-mini:gpt-4o-2024-08-06
model enum :gpt-4o:gpt-4o-mini-2024-07-18
model enum :gpt-4o-mini:gpt-4o-mini-2024-07-18
...
model enum :gpt-4o-mini:gpt-4o-mini
model check:gpt-4o-mini:gpt-4o-mini
...
model enum :gpt-4o:text-embedding-ada-002
model enum :gpt-4o-mini:text-embedding-ada-002
```

console.errorで表示してみるとどうやら、
gpt-4o-2024-05-13
または
gpt-4o-2024-08-06
とする必要がありそうです。

gpt-4o miniについても

gpt-4o-mini

と

**gpt-4o-mini-2024-07-18**

があるようです。

**※gpt-4oのモデルバージョンは2024-08-06をデプロイしないと入力トークン数が4096に制限されます。**  
**※gpt-4oのモデルのデプロイの種類は「Standard」にしないと「米国東部」であっても「グローバルリージョン」がデプロイされます。**  
**※AzureポータルのAzure OpenAI Studioでデプロイするときにコンテンツフィルターを「DefaultV2」から「規定」に変更しておかないと日本の総理大臣や大谷翔平選手のことなどを答えなくなってしまうので、留意した方がいいです。**  
![gpt-4o_deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/4bc30ef6-c77f-3442-0536-76a0e9608a06.png)
![gpt-4o-mini_deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/fbf61f2c-730c-448f-affc-8f2ca4e71f6d.png)

修正後のtypes/openai.tsはこちらです。

types/openai.ts

``` JavaScript
import { OPENAI_API_TYPE } from '../utils/app/const';

export interface OpenAIModel {
  id: string;
  name: string;
  maxLength: number; // maximum length of a message
  tokenLimit: number;
}

export enum OpenAIModelID {
  GPT_4O_AZ = 'gpt-4o-2024-05-13',
  GPT_4O_MINI_AZ = 'gpt-4o-mini-2024-07-18',
}

// in case the `DEFAULT_MODEL` environment variable is not set or set to an unsupported model
export const fallbackModelID = OpenAIModelID.GPT_4O_MINI_AZ;

export const OpenAIModels: Record<OpenAIModelID, OpenAIModel> = {
  [OpenAIModelID.GPT_4O_MINI_AZ]: {
    id: OpenAIModelID.GPT_4O_MINI_AZ,
    name: 'GPT-4o mini',
    maxLength: 512000,
    tokenLimit: 128000,
  },
  [OpenAIModelID.GPT_4O_AZ]: {
    id: OpenAIModelID.GPT_4O_AZ,
    name: 'GPT-4o',
    maxLength: 512000,
    tokenLimit: 128000,
  },
};

```

今度はきちんと認識されました。

![modelswitcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/f6617a0f-d496-da37-cbe0-d3b1ba5808f3.png)

## ５．動作確認

長文入力など試してみましたがGPT-4oとGPT-4o miniを区別することは困難でしたので、AzureポータルのCost Managementのリソース単位の価格で調べてみました。

### 5.1. GPT-4oでカットオフデートを確認
![GPT-4o_cutoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/9eac9e68-bc15-c4d1-f2eb-16a8ae4e875d.png)

5.2.GPT-4o miniでカットデートを確認
![GPT-4o_mini_cutoff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/b1e88b57-0bc0-d112-70a2-42e4f72721be.png)

### 5.3.Cost Management

この結果 East USリージョンでGPT-4oとGPT-4o miniの利用が確認できましたので、正しく設定できていると思われます。
![Azure_Portal_Cost_Management.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/f2115318-0c9e-baf1-20c4-fbb2fea99919.png)

## ６．作成したコードのリポジトリ
今回のコード修正をGitHubのブランチとして作成しています。
「[Chatbot UI legacyの問題](https://qiita.com/potofo/items/24b630f2e9b5a0a28de9)」記事でも書いたようにMckay Wrigley氏が作成したLegacyブランチには多少問題があるため、2023年4月4日～2023年4月20日まで差分が含まれるKentaroAOKI氏の[feature-supports-azure-openai-api-2023-05-15-or-later](https://github.com/KentaroAOKI/chatbot-ui/)フォークに「[Chatbot UI legacyをPCで動かす](https://qiita.com/potofo/items/ab5a1f7b1a6ee09fe369)」記事で取り込んだバグ対策を含めた、私の[fixed](https://github.com/potofo/chatbot-ui/)フォークをブランチして「[Support_GPT-4o_and_GPT-4o_mini](https://github.com/potofo/chatbot-ui/tree/Support_GPT-4o_and_GPT-4o_mini)」を作成して対応しています。  
gpt-35-turbo-16kのEOL後マージしようと思います。
自分で書いて混乱するので、図にしておきます。

留意事項
・Azure東日本リージョンではGPT-4oのみが利用可能です。
　GPT-4oはAzureの東日本リージョンではグローバルリージョンからのデプロイとなります。
　ややこしいのですがサーバは東日本リージョンですが、LLMの推論モデルはグローバルなリージョンのどこかが使用されるということらしいです。
・GPT-4o/GPT-4o miniのテストは米国東部(East US)リージョンで実施しています。
　GPT-4o miniは米国東部(East US)リージョンでもグローバルリージョンでした。


``` mermaid
gitGraph:
    commit id:"138950c5:Update README.md"
    branch feature-supports-azure-openai-api-2023-5-15-or-later
    checkout feature-supports-azure-openai-api-2023-5-15-or-later
    commit id:"e66b9bc9:feature-supports-azure-openai-api-2023-05-15-or-later"
    branch fixed
    checkout fixed
    commit id:"868e20e9:Added Azure current models"
    commit id:"36f0110d:Use custom max_tokens #316"
    commit id:"23486362:Bug fix for [DONE] is not valid JSON"
    branch Support_GPT-4o_and_GPT-4o_mini
    checkout Support_GPT-4o_and_GPT-4o_mini
    commit id:"ee5ed627:Supported GPT-4o/GPT-4o mini LLM"
```

https://github.com/potofo/chatbot-ui/tree/Support_GPT-4o_and_GPT-4o_mini