Azure Open AIサービスを試してみた

Azure Open AIサービスに触れる機会があったため、復習を兼ねて記事を投稿いたします。

もともと「凄い人が使うサービス」という印象が強く「難しそう！」と思っていたのですが、冬休みの間に試してみました。

### Azure Open AIサービスとは
Azure上で、OpenAI社が開発したGPT-4等の生成AIのモデルをAPI経由で使用できるサービスです。

### まずは写経
ようさんのブログとYoutubeを写経させていただきました🙇‍♂️

https://yo-yon.hatenablog.com/entry/powerautoamte20231217

https://www.youtube.com/playlist?list=PLh5EaM_vXDs1yNx24K9loyUvIXVKmD7Ys

ブログには「リソース作成編」「モデルのデプロイ編」まで記事にしてくださっていたので、私でも設定することができました。
難しいことを大変分かりやすくお教えいただき、ありがとうございます🙇‍♂️
写経させていただき恐縮なのですが、私なりに試して学んだことを記載いたします。

### URI、APIキー、パラメータ
Azure Open AIサービスはPower AutomateのHTTPコネクタから操作するのですが、その際に**URI**、**APIキー**、**パラメータ**の3つの情報が必要となります。

#### Azure Open AIサービスで確認
下記ページのメニューの共有リソースのデプロイをクリックすると、エンドポイントの**ターゲットURI**、**キー**が表示されますので、メモ帳などに控えます。（URI、APIキーになります）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/cdf80c5c-5199-3b06-34cd-654ae55f4089.png)
※リソース作成、モデルのデプロイは割愛しております。

下記ページのプレイグラウド＞チャットをクリックし、コードの表示をクリックすると「サンプル コード」のフォームが表示されますので、「json」を選択するとパラメータが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/865ccce5-4ad0-3819-1342-4c815ecfca2e.png)


パラメータは下記のリファレンスを確認することで理解できると思っています。

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/reference

ただ、難しいので自分なりに調べてみました。

|パラメータ|内容|
|---|---|
|messages|AIとの対話を表現する部分。主にAIの役割と指示を書く|
|temperature|以下参照|
|top_p|以下参照|
|max_tokens|生成されるテキストの文字数|

temperatureは語彙どうしの頻度の差。
下記の図の場合、A、B、C、D、E間の頻度の差になる。
temperatureの値を低く設定すると、語彙どうしの頻度の差が大きくなる。
temperatureの値を高く設定すると、語彙どうしの頻度の差が小さくなる。
要は低く設定すると、頻度の高い語彙が選択され、語彙の一貫性が高まる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/c3a7d752-5f39-0594-99ad-0649ccc02c56.png)

top_pは、語彙を選択する際の範囲。
下記の図の場合、上位のA、Bは使用して、C、D、Eは使用しない。
top_pの値を低く設定すると、選択語彙の範囲が狭まる。
top_pの値を高く設定すると、選択語彙の範囲が広がる。
要は低く設定すると、候補の語彙の範囲が狭まり、語彙の一貫性が高まる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/069bd3fb-8506-664b-93e7-93ed2b46c451.png)

#### Power Automate側で設定
Azure Open AIサービスで**URI**、**APIキー**、**パラメータ**を確認できたとして、Power Automate側でフローを作成しました。

まず **「手動でフローをトリガーします」アクション** を指定します。
依頼文を書けるように、Inputの入力を設けており、**パラメータ**の **Messages**の一部として指定する予定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/5e50631a-e6cf-3568-0d55-a8aafba1a097.png)

続いて **「変数を初期化する」アクション** で**APIキー**を設定します。
値にはAzure Open AIサービスで確認したキーを指定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/4cd9491e-4079-6a52-9f87-f4126a59e38b.png)

続いて**パラメータ**の**Messages**にAIとの対話を表現する部分のプロンプトを書く必要がありますので **「変数を初期化する」アクション**で「#役割」「#タスク」「#入力」の内容を書きます。
- 「#役割」は変数「Prompt1」に「#タスク」「#入力」は「Prompt2」にそれぞれ指定
- 「#入力」にはトリガーの入力値を指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/0a605882-0eff-f12f-a84b-8137845ccd99.png)
プロンプトは以下の要素で構成するとAIの性能を引き出せるとのことです。

- **記号を使用して構造化し、AIが読みやすい文章にする**
#：見出し　-：箇条書き　など
- **役割を与えて、AIにより良い出力をしてもらう**
質問・指示の背景や文脈を理解してもらえるため、意図した回答の出力に繋がる
- **具体的に書く**
具体的であればあるほど、良い出力を得られる傾向がある

以下の本から引用。大変勉強になりました。

https://www.amazon.co.jp/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEChatGPT%E6%B4%BB%E7%94%A8%E3%82%AC%E3%82%A4%E3%83%89-%E5%B2%A9%E6%89%8B%E3%83%86%E3%83%8A%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3/dp/4297142953

続いて **「HTTP」アクション**でAzure Open AIサービスにHTTP要求の設定をします。
**URI**、**APIキー**、**パラメータ**を全て設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/5b031879-bc36-0927-d51e-77f730f4d92f.png)
設定値は以下のとおりです。
|パラメータ|内容|
|---|---|
|方法|POST（データの送信）|
|URI|Azure Open AIサービスで確認したターゲットURI ※**URI** |
|ヘッダー（Content-Type）|application/json|
|ヘッダー（API-Key）|「変数を初期化する」アクションの出力「API-Key」※**APIキー**|
|本文|Azure Open AIサービスで確認したパラメータにrole": "user","content"を追加 ※**パラメータ**|

ここまでを保存して起動してみると、Azure Open AIサービスの出力内容は**①HTTPアクション出力**の**②"body"配下**の**③"Choices"1番目** 配下の**④"message"** 配下の **⑤"content"** にJSON形式で設定されていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/9798ff64-e311-437d-32c6-6e6f454ded73.png)

JSON形式のデータから特定の内容を取得するには以下の式を **「作成」アクション** に設定する必要があります。

```
outputs('HTTP')?['body']?['choices']?[0]?['message']?['content']
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/4cc5e746-8bf0-0b67-d207-eef827b3502d.png)

保存して再度起動してみると「作成」アクションの結果はここもシンプルではありながらJSON形式で出力されており、メールの「件名」「本文」を取り出してそれぞれを設定する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/e28189f1-a940-23af-134b-a8b7f81fd3e7.png)

メールの件名、本文をJSON形式から取得するには、**「JSONの解析」アクション**を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/f876756b-f98f-d0c7-2c75-b88b6665d55c.png)

|パラメータ|内容|
|---|---|
|コンテンツ|「作成」アクションの出力|
|スキーマ|以下手順を実施|

**①「サンプルから生成」ボタンをクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/cfdbd9bc-f7e7-9b32-71ec-64ca97ddcb4f.png)

**②実行結果の「作成」アクション出力をコピー**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/9acdcd0e-7249-63fc-1a92-2af1931a46f4.png)

**③コピーした内容を貼付けして完了ボタン**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/b82e2582-37bb-c8f0-4ecd-7b80a8189cd0.png)

これにより、「件名」「本文」の内容を「動的なコンテンツ」として追加できるようになります。

最後に **「メールの送信（V2)」アクション** に「件名」「本文」を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/ff0ec504-d8e4-7ac7-bcbb-01f4814ecebf.png)

|パラメータ|内容|
|---|---|
|件名|「JSONの解析」アクションの件名|
|本文|以下の式を設定|
```
replace(body('JSON_の解析')?['本文'],decodeUriComponent('%0A'),'<br>')
```

「メールの送信（V2)」アクションの本文は**HTML形式**でコードを指定する必要がありますが、Azure Open AIサービスで出力された「本文」の改行コードは 「**\n**」 となっています。
この、「**\n**」 をHTML形式の改行タグ **&lt;br&gt;** に変換する必要があります。

では、以下のように書けばよいのではないかと思ったのですが、Power Automateの式ではエスケープシーケンスが効かず、「**\n**」が認識されません。そのため、「**\n**」の文字をURLエンコードされた「**%0A**」をわざわざdecodeUriComponent関数でデコードする式で記載する必要があります。
```
replace(body('JSON_の解析')?['本文'],'\n','<br>')
```
※「\n」をURLエンコードすると「%0A」
※「%0A」をURLデコードすると「\n」
※URLを半角英数字・記号に変換する事を「URLエンコード」
※URLを日本語に戻す事を「URLデコード」

メールはこのような形で送信されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532455/3058e545-7c5c-78d2-1ab0-e4a0b70cae6e.png)

### 最後に
私はJSONも今一扱えてないし、Power Automateといえば直感的な操作でできるという理由だけで使えていましたが、ようさんのブログ、Youtubeのお陰でAzure Open AIサービスについて試すことができ、これまでの「気ままに勉強会」で教わったMiyakeさんのJSON攻略法のお陰で、Outputs関数や「JSONの解析」アクションを使用できるようになりました。
本当にありがとうございます🙇‍♂️

今後はもっとAzure Open AIサービスを活用したり、JSONをもっと活用して「もう怖くない!」と思えるようにしたいと思います。