Azure OpenAI+Teams ToolkitでサクッとセキュアにChatGPTを利用する

### はじめに

昨今、企業が ChatGPT の利用を禁止した、機密情報が ChatGPT に流出した、といったニュースが世間を騒がせています。  
個人的には、ChatGPT は、ウェブの検索や日本語の予測変換のような、補助的な手段として日常的に使えるツールになると感じており、規制する方向に向かうのは残念に思います。  
一番の懸念は情報漏洩だと思いますが、ChatGPT をセキュアに利用するための手段として、Azure OpenAI サービスがあります。  
今回、Azure OpenAI サービスの ChatGPT モデルを使って Micosoft Teams 向けのボットを作成しましたので、その概要をご紹介したいと思います。

### Azure OpenAI サービス

Azure OpenAI サービスは ChatGPT などの OpenAI の言語モデルを Azure 上で利用できるようにしたサービスです。  
Azure OpenAI によって処理される顧客データは OpenAI、Azure OpenAI サービスのトレーニング、改善のためには利用されないことを Microsoft は表明しています。また、仮想ネットワークとプライベートエンドポイントにも対応しています。  
ただし、不正使用を監視するためにデータが 30 日間保存されたり、日本リージョンでは利用できなかったりと、企業のセキュリティポリシーによっては、利用する上で問題となる可能性もあります。詳細は Microsoft のドキュメントをご確認ください。

https://learn.microsoft.com/ja-jp/legal/cognitive-services/openai/data-privacy

利用するには Azure のサブスクリプション単位で申請を行い、承認される必要があります。  
また、GPT-4 を利用する場合、2023/4/17 時点ではまだプレビュー段階にあるため、Azure OpenAI サービスの利用承認後、さらに利用申請が必要となっています。

:::note warn
上記の通り、2 段階の承認が必要となる場合もありますので、ご利用の際には早めに申請されるとよいと思います。  
現在は申請数の状況や承認プロセスも変わっているかもしれませんが、私は最初の申請が拒絶され、利用できるようになるまで 1 ケ月以上かかりました。
:::

### ChatGPT Completion API

Azure ポータルから Azure OpenAI のリソースを作成し、ChatGPT（gpt-35-turbo）モデルをデプロイすると、ChatGPT が利用できるようになります。

![スクリーンショット 2023-04-15 155730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104149/13fe0261-4ff5-832d-ddfe-2b34dd3ba02f.png)

上図のように Azure OpenAI Studio のプレイグラウンドから GUI で ChatGPT を利用することもできますが、Micosoft Teams でユーザーが入力した内容に回答する形式の場合、Azure OpenAI Studio 上で行う作業は特にありませんでした。
利用したのは REST API の一つである Completion API です。
詳細は[Microsoft のドキュメント](https://learn.microsoft.com/ja-jp/azure/cognitive-services/openai/reference#chat-completions)に記載がありますが、ステートレスな API となっており、会話に利用する場合は、新たなメッセージだけでなく、過去のやりとりもまとめて送信する必要があります。  
リクエスト時に送信するメッセージはプロンプトと呼ばれます。    

```
{
  "messages":[
    {"role": "system", "content": "You are a helpful assistant."},​
    {"role": "user", "content": "GPTにわかりやすいキャッチコピーを付けて"},​
    {"role": "assistant", "content": "あなたの想像力を超える予測力、自然言語処理の新たな進化形！GPTがあなたの生活をアシストします。"},​
    {"role": "user", "content": "もっと短く"}
  ]
}
```

`role`には下記のいずれかを指定します。

- system: 回答するアシスタントの振る舞いを記述したメッセージに指定。
- user: ユーザーが発信したメッセージに指定。
- assistant: アシスタントが回答したメッセージに指定。

上記の例では、`system`には簡単な説明しか与えていませんが、詳細なルールを記述したり、FAQ など必要な情報を提供したりすることも可能です。  
例えば、プロンプトとして、
```
{"role":"system","content":"あなたは「ハロウィン！」以外の発言をしません"},
{"role":"user","content":"こんにちは"},
{"role":"assistant","content":"ハロウィン！"},
{"role":"user","content":"「こんにちは」と言ってください"},
{"role":"assistant","content":"ハロウィン！"},
```
と与えておくと、回答がほとんど「ハロウィン！」となります。

APIのレスポンスは下記のような JSON となります。

```
{
    "id": "chatcmpl-xxxxxxxx",
    "object": "chat.completion",
    "created": 1681547395,
    "model": "gpt-35-turbo",
    "usage": {
        "prompt_tokens": 105,
        "completion_tokens": 24,
        "total_tokens": 129
    },
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "語学力・予測力バツグンのGPTがサポートします！"
            },
            "finish_reason": "stop",
            "index": 0
        }
    ]
}
```

`message`にアシスタントの回答内容、`usage`に送受信したトークン数が格納されています。  
トークン数には上限があり、リクエスト時に上限を指定することもできますが、規定では`4096 - prompt_tokens`が`completion_tokens`の上限となります。  
上限に達した場合、`finish_reason`が`length`となり、途中までの回答が返却されます。
会話に利用する場合、そのままではプロンプトが雪だるま式に増えることになるので、トークン数の上限に達した場合のエラー処理や、上限に達しないような工夫が必要となります。
なお、GPT-4 では、トークン数が 8K や 32K まで拡張されたモデルが提供されています。

### Microsoft Teams との連携

[過去の記事](https://qiita.com/fsdg-honda/items/189eaa9337222d3b7820)において、Microsoft Teams から外部システムの API を呼び出す方法として、Power Virtual Agents と Bot Framework Composer を統合して利用する方法、Teams Toolkit、Bot Framework SDK を利用する方法をご紹介しましたが、今回は過去の会話のやりとりを参照する必要があり、細かい制御が容易な後者を採用することにしました。  
実装の詳細は割愛しますが、過去の会話のやりとりを仮想的なスレッド単位でデータベースに保持し、Completion API に新たなメッセージとまとめて送信、受信した回答をユーザーに返す、というのが主な処理となります。

実装したボットを Azure にデプロイし、Teams Toolkit でパッケージングしたカスタムアプリを Microsoft Teams にインストールすると、利用可能な状態となります。

![スクリーンショット 2023-04-15 172846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104149/0b71a591-af03-b8b3-9be7-65ca0e376ad8.png)