すぐに始めるchatGPT API②カスタムコネクタをつくる

前回の記事ではPower Automate のHTTPアクションを利用して、気軽にChatGPTのAPIを呼び出してみました。
https://qiita.com/Satoshi_Yoshino/items/b4fc4a74265069fdf109

今回はPower Appsで実用的に呼び出す方法を考えてみます。HTTPコネクタはPower Appsでは利用できないようなので、今回はカスタムコネクタを利用してみます。

# ChatGPT API の機能その２

前回は一つの user message に対して一つの応答 assistant message を受け取りました。
例えば以下のように system message を付与して回答内容をチューニングすることができます。

```JSON:要求
{
  "model": "gpt-3.5-turbo",
  "messages": [
    {
      "role": "system",
      "content": "クイズを出題するので、お嬢様言葉で解答してください"
    },
    {
      "role": "user",
      "content": "世界で2番目に高い山は何ですか？"
    }
  ]
}
```

```JSON:応答
{
  "id": "chatcmpl-*******",
  "object": "chat.completion",
  "created": 16800000000,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
    "prompt_tokens": 57,
    "completion_tokens": 15,
    "total_tokens": 72
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "それは、K2（ケーツー）ですわ。"
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}
```

また、ChatGPTをWebで利用した際に、何度か会話をやり取りした後に正しい答えを導いたという経験があると思います。それは、以下のように前後の会話を踏まえて応答をするからです。

```JSON:1回目の要求
{
  "model": "gpt-3.5-turbo",
  "messages": [
    {
      "role": "system",
      "content": "クイズを出題するので、ツンデレ口調で解答してください"
    },
    {
      "role": "user",
      "content": "世界で2番目に高い山は何ですか？"
    }
  ]
}
```
1回目はなぜかいい感じに間違えてくれました。
```JSON:1回目の応答
{
  "id": "chatcmpl-**********",
  "object": "chat.completion",
  "created": 1680000000,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
    "prompt_tokens": 54,
    "completion_tokens": 28,
    "total_tokens": 82
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "バカ！それはもちろん、エベレストに決まっているでしょう！"
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}
```

上記の応答と、間違いを指摘したうえでもう一度要求を出してみます。
```JSON:2回目の要求
{
  "model": "gpt-3.5-turbo",
  "messages": [
    {
      "role": "system",
      "content": "クイズを出題するので、ツンデレ口調で解答してください"
    },
    {
      "role": "user",
      "content": "世界で2番目に高い山は何ですか？"
    },
    {
      "role": "assistant",
      "content": "バカ！それはもちろん、エベレストに決まっているでしょう！"
    },
    {
      "role": "user",
      "content": "ちがうよ、それは1番高い山だよ。2番目を聞いてるんだよ。"
    }
  ]
}
```
以下のようになりました
```JSON:2回目の応答
{
  "id": "chatcmpl-*********",
  "object": "chat.completion",
  "created": 1680000000,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
    "prompt_tokens": 120,
    "completion_tokens": 55,
    "total_tokens": 175
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "えっ？私が間違えたわけないじゃない。まあ、それはもちろん、K2に決まっているでしょう！バッカじゃないの？"
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}

```
今度はちゃんと正しい応答を返してくれました。今までのやり取りを含めた要求を出すPower Appsアプリを作りますが、まずはカスタムコネクタを作成します。

# カスタムコネクタの要求を作成する

カスタムコネクタの作成を行います。

①Power Appsホーム画面から「カスタムコネクタ」を選択し、カスタムコネクタの新規作成→一から作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/f9af5cb5-cb67-5cb8-a04b-1a8ace9b24e8.png)

②名前を付けて続行をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/680ce7ea-afa4-01ce-0fd3-b16324ba35e3.png)

③全般の項目は以下のようになります。スキーマをHTTPSにし、ホストを api.openai.com にすればあとは任意で構いません。右下のセキュリティをクリックし次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/9941d648-a218-0a82-ed69-d586b86a3e26.png)

④認証タイプは「APIキー」です。前回同様APIキーによって認証を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/6931ae28-6143-558b-d0d3-39b71c3d1ab3.png)

⑤APIキーの設定は以下のようにします。ラベルは任意の名前、パラメータ名は「Authorization」、パラメータの場所は「ヘッダ」です。これは、前回のHTTPアクションでヘッダ部分にAPIキーをAuthorizationで入力しましたが、それと同じ意味になります。なお、「ユーザーは接続の作成時にAPIキーを入力する必要があります」と書いてあります通り、まだ、**実際のAPIキー（sk-なんちゃらかんちゃら）は入力しません。**
入力したら、次へをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/7be8b103-9169-78c6-5195-70ac70b009af.png)

⑥いったん保存します。「コネクタの作成」をクリックして保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/af8c18ea-619e-4f94-1e88-c51e3ebefbc6.png)

⑦次に定義を設定します。「定義」のアクションにある「新しいアクション」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/777e7084-66db-84e1-e67a-ca9f0ae7fbdb.png)

⑧要求の部分は以下のようになります。とりあえず、操作IDは実際にPower Appsから呼び出すときの関数名になります。あとは表示される説明と概要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/b1fcb92e-4ae0-3a06-3b41-9a01332ebfe5.png)
※表示についてはこちらを参照ください
https://learn.microsoft.com/ja-jp/connectors/custom-connectors/openapi-extensions#x-ms-visibility

⑨次に「要求」を定義します。どんなリクエストを投げるの？という書式設定ですね。「サンプルからのインポート」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/0967eda1-db24-a704-e242-5cf8ab3a9a10.png)

⑩以下のような画面が出てきますので入力します。内容としてはHTTPアクションのときと一緒です。
動詞：HTTPメソッドのことです。本文にJSONを含めるので「POST」になります。
URL：ChatGPT APIのURLである「https://api.openai.com/v1/chat/completions」を入力します。
ヘッダー： Content-Type application/json を入力します。（Authorizationは不要です）
本文：サンプルデータを読み込ませます。それを参考にスキーマを生成してくれます。上に記載したサンプルを利用しても構いませんし、細かいオプションを設定したければ自分で生成しても大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/d96be9fe-37ae-2303-e021-d6a5657b4bdc.png)
入力すると以下のような画面が表示されます。サンプルから自動的に要求が作成されました。
ですが、少しチューニングする必要があります。まずは Content-Type を編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/5ca6a6d5-d485-5502-32ec-db306e717857.png)
以下のように値を変更します。
規定値：application/jsonを入力します。
必須：はいに変更します。
表示：internal に変更します。
これらの意味ですが、ユーザー（カスタムコネクタを利用する人）に何も意識させずにヘッダにapplication/jsonを設定する、ということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/65fbd065-0fda-20df-32b4-bb29cb22dadf.png)
入力したら「戻る」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/04a3f7ea-f0b0-e256-97a7-25fc43fc342a.png)

同じようにBody（本文）を編集しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/ff603a85-582b-cb87-92b8-704e0d227e91.png)

本文をサンプルから分析した結果は以下の通りのようです。本文はもちろん必須で、必ずユーザーに入力させる必要があるため、必須を「はい」、表示を「important」偽ってします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/0b65384a-ec38-db7c-3e17-9ca685afea3b.png)

Contentを編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/6c5b394e-87ab-4463-1730-2a03682934b3.png)
コンテントはChatGPTに話しかけるメッセージのテキストそのものです。なのでこれは必須で表示もimportantに設定します。入力したら上部の戻るをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/c08a61bc-4986-5ed1-d0ae-9b414aad24b1.png)
同様に、roleとmodelも必須、important に設定します。

ここまで作成したらいったん「コネクタの更新」をクリックしておきましょう。


# テストと応答の作成

ここまでで要求が作成できました。どのような応答が返ってくるか見てみましょう。

①「テスト」を実施します。テストをクリックして「新しい接続」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/125e4891-6d3a-7ec4-bd3a-b6042260d645.png)
ここで**「Bearer APIキー」**を入力して「作成」をクリックします。APIキーは新しく作成しても構いませんし、前回取得したものをそのまま利用しても構いません。（Bearer スペース はここで自分で入力する必要があります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/bb106feb-1a6b-61a6-1564-07315fc12d57.png)
接続の画面に遷移したら、カスタムコネクタをクリックして、作成したコネクタを選択し、「編集」をクリックして元の画面に戻ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/469e1efd-0480-ad21-c47c-04a829bcfda3.png)

接続が設定されていることを確認したら、以下のように入力してテスト操作を実行します。
model gpt-3.5-turbo
role  user
content ＜何か質問を入力＞

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/4d3b719a-aeda-9b79-7859-fe78a1f82fbe.png)

微妙に答えが間違ってますが（笑）とりあえず応答として得られた「ボディ」をメモ帳にコピーしておきます。

念のため要求を見ておくとちゃんとAuthorizationが含まれており、role/contentもmessage の中に含まれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/c139d6fb-23ff-eb82-7bd8-d64e4ebecdc3.png)

②次に、得られた応答をサンプルとして利用して、コネクタの応答を作成します。
「定義」にもどって、応急の「既定の応答を追加する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/b05292b9-5553-55b5-2fab-bf9d921f9f52.png)

ヘッダにContent-type application/json を入力し、本文は先ほどの内容をペーストして入力します。インポートをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/9274b337-9975-511f-3ede-23eb1be35813.png)

default をクリックして内容を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/80a4a1f3-fa11-7287-f7fc-4bd9c39a437f.png)

コネクタの更新をクリックして保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/93fdc5ec-c206-b782-4c20-6c7e0f4b9191.png)

ひとまずこれでカスタムコネクタの作成は完了です。次回はPower Appsからこのコネクタを呼び出してみます。

# まとめ
Power Platformのコネクタのアクションというのは、要するにWeb APIのリクエストを投げて受け取るという処理を実行しています。要求や応答の内容を定義しておけば、市民開発者としてはパラメータを指定して気軽に実行できる、ということです。
chatGPTはまだコネクタが提供されていないので、カスタムコネクタとして自作しました、というのが今回の内容でした。