Power Platform から Azure OpenAIの新機能「Add your data」を利用する


# はじめに

独自ナレッジをノーコードでChatGPTに連携できる Azure Open AI の「Add your data」がパブリックプレビューになりました。

https://zenn.dev/microsoft/articles/azure-openai-add-your-data

https://zenn.dev/microsoft/articles/azure-openai-add-your-data-api

こちらの機能自体は、上記記事等を参照いただければと思いますが、例えば、以下のように、Power Platform のライセンスガイドの日本語版と英語版を Azure Blob Storage に格納し、Azure Cognitive Search でインデックスを作成し、追加するだけで、独自データからチャットで回答を得ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f71b5339-984f-04f4-c792-2c4852d92c65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ed6471d5-26df-b039-ffcd-13260e5eda05.png)

こちらを API で利用する方法についても、上記記事で紹介いただいているのですが、今回は、こちらの API を Power Platform から利用する方法を紹介します。

# 完成イメージ

これまで、いくつかの記事で、Power Platform と Azure OpenAI を連携する方法について紹介してきました。

https://qiita.com/Takashi_Masumori/items/8a07fb6d1869967ce1f9

https://qiita.com/Takashi_Masumori/items/fcf71ea63a04f2ddbc18

今回は、上記記事などで紹介してきたアプリをベースに少し変更を加えました。以下、完成形のイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/dada51e8-33ef-9591-42d4-41ec914165f7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a80da98d-6705-4eca-8bd1-4dd07f73f5cc.png)

# Power Automate 側処理

全体処理イメージは以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/23c3cbb8-f8f7-92b5-c817-2c1c1f3146e8.png)

コアとなる部分を見ていきます。

まず、HTTP リクエスト部分です。API リクエスト時のヘッダー部分が異なります。こちらは、上記記事やプライグラウンドでチャットした際の HTTP トレースから確認可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/3d75729d-bbe6-274e-0256-d4106124f26d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/30ee4cc1-2bbe-7a4b-af95-e761412d6f84.png)

リクエストボディは以下のような感じで、`"dataSources"`部分がこれまでと異なります。

```
{
  "dataSources": [
    {
      "type": "AzureCognitiveSearch",
      "parameters": {
        "endpoint": "https://*****.search.windows.net",
        "key": "*****",
        "indexName": "azureblob-index"
      }
    }
  ],
  "messages": @{json(triggerBody()['text'])}
}
```

問題なく API からレスポンスが返ってきましたら、応答を解析しますが、こちらのレスポンスは通常の API とちょっと異なるので、その点を加味して変更する必要があります。以下、レスポンスの例です。citations の部分は長文のため割愛しています。

```
{
  "id": "72bf13f5-6046-4993-9c9d-66006b9f93b4",
  "model": "gpt-35-turbo",
  "created": 1688252256,
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "messages": [
        {
          "index": 0,
          "role": "tool",
          "content": "{\"citations\": [{\"content\": ""]\"}",
          "end_turn": false
        },
        {
          "index": 1,
          "role": "assistant",
          "content": "Power Apps のライセンスについてですね。Dynamics 365 や Microsoft/Office 365 の一部のプランには、Power Apps の機能が含まれています [doc1]。詳細については、「Dynamics 365 ライセンスに含まれる Power Apps の使用権限」、「Microsoft/Office 365 ライセンスに含まれる Power Apps の使用権限」のセクションを確認してください [doc1]。",
          "end_turn": true
        }
      ]
    }
  ]
}
```

citations の箇所について、オブジェクトになっているため、別途 JSON の解析をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/94212f90-2516-0004-d168-5d2b495a26ce.png)

```
body('JSON_の解析')?['choices'][0]['messages'][0]['content']
```

結果は以下のようになります。

```
{
  "citations": [
    {
      "content": "また、Dynamics 365 および Microsoft/Office 365 \nの一部のライセンスには、Power Apps の限定的な機能が含まれています。.詳細については、このガイドの「Dynamics 365 ライセンスに\n含まれる Power Apps の使用権」「Microsoft/Office 365 ライセンスに含まれる Power Apps の使用権」のセクションを確認してくださ\nい。.以下の表に、ライセンス体系の概要を示します。",
      "id": null,
      "title": null,
      "filepath": null,
      "url": null,
      "metadata": {
        "chunking": "orignal document size=47535. Scores=6.656927 and None.Org Highlight count=3040.Filtering to chunk no. 10/Highlights=32 of size=186"
      },
      "chunk_id": "10"
    },
    {
      "content": "....................................23 \n付録 B: Power Platform の機能を含む Dynamics 365、Microsoft/Office 365、Windows のライセンス ...........25 \n付録 C: 変更履歴 ......................................................................................................................................................................26 \n \n \n Power Platform ライセンス ガイド | 2023 年 5 月 ページ | 1 \nこのガイドの使用について \nこのガイドは、Microsoft Power Apps、Power Automate、Power Virtual Agents、Power Pages、Power \nPlatform キャパシティ アドオンのライセンスについて理解を深めることを目的としています。.マイクロソフトは予告なくいつでもこのガイドの見直しや更新を行う権利を留保しています。.このガイドはライセンス要件について理解を深めることを目的としており、以下の章で構成されています。",
      "id": null,
      "title": null,
      "filepath": null,
      "url": null,
      "metadata": {
        "chunking": "orignal document size=47535. Scores=6.656927 and None.Org Highlight count=3040.Filtering to chunk no. 5/Highlights=43 of size=317"
      },
      "chunk_id": "5"
    },
    {
      "content": "• 無人ボットがアクセスするサービスやアプリケーションを利用するには、別途ライセンスの取得が必要です。.たとえば、ボットが \nWindows や Office にアクセスしている場合、Power Automate 無人 RPA アドオンに加えて、Microsoft 365 無人ライセン\nスも購入する必要があります。.Power Apps ライセンスに含まれる Power Automate の使用権 \nPower Apps ライセンス (「Power Apps per app プラン」「Power Apps per user プラン」「Power Apps 従量課金プラン」) には \nPower Automate の使用権が含まれており、Power Apps アプリケーションに関連付けられたワークフローを自動化するために使用でき\nます。.Power Apps 内での Power Automate の使用は、Power Apps アプリケーションのコンテキスト内に制限されています。.つまり、トリガー\nとアクションの両方において、Power Apps アプリケーションに含まれるフローは以下に接続できます。",
      "id": null,
      "title": null,
      "filepath": null,
      "url": null,
      "metadata": {
        "chunking": "orignal document size=47535. Scores=6.656927 and None.Org Highlight count=3040.Filtering to chunk no. 30/Highlights=54 of size=413"
      },
      "chunk_id": "30"
    },
    {
      "content": "ms/platformlimits\n Power Platform ライセンス ガイド | 2023 年 5 月 ページ | 17 \nPower Platform の Dataverse のキャパシティ \n \nDataverse の既定および付加されるサブスクリプション キャパシティ \nPower Apps、Power Automate、Power Virtual Agents、Power Pages のそれぞれの既定のサブスクリプション キャ\nパシティは、同じテナントおよびインフラストラクチャで使用し、1 つのテナント全体で計上されます。.Power Apps、Power \nAutomate、Power Virtual Agents、または Power Pages のライセンスを購入したテナントには、既定のキャパシティが\n提供されます。.さらに、Power Apps per user、Power Apps per app、Power Automate per user、Power \nAutomate per flow プラン、Power Pages の各ライセンスに対して、追加のキャパシティがテナントに付加されていきま\nす。.Dataverse for Teams のキャパシティとサービスの上限については、こちらの公開ドキュメントを参照してください。",
      "id": null,
      "title": null,
      "filepath": null,
      "url": null,
      "metadata": {
        "chunking": "orignal document size=47535. Scores=6.656927 and None.Org Highlight count=3040.Filtering to chunk no. 55/Highlights=50 of size=386"
      },
      "chunk_id": "55"
    },
    {
      "content": "これを超えるサービス クレジットが必要な場合は AI Builder キャパシティ アドオンをご利用ください。.詳細については、http://aka.ms/platformlimits を参照してください。.Power Automate \nサービスの概要 \nPower Automate を使用すると、企業はワークフローやビジネス プロセスを自動化し、業務効率を向上でき\nます。.詳細については、https://powerautomate.microsoft.com/ja-jp/を参照してください。.ライセンスの概要 \nPower Automate の汎用的な機能はスタンドアロンで提供されます。.また、Power Apps、Dynamics 365、Microsoft/Office 365、\nWindows のライセンスには、Power Automate の限定的な機能が含まれています。.詳細については、このガイドの「Power Apps ライセ\nンスに含まれる Power Automate の使用権」「Dynamics 365 ライセンスに含まれる Power Automate の使用権」\n「Microsoft/Office 365 ライセンスに含まれる Power Automate の使用権」「Windows ライセンスに含まれる Power Automate の\n使用権」の各セクションを確認してください。.以下の表に、ライセンス体系の概要を示します。",
      "id": null,
      "title": null,
      "filepath": null,
      "url": null,
      "metadata": {
        "chunking": "orignal document size=47535. Scores=6.656927 and None.Org Highlight count=3040.Filtering to chunk no. 20/Highlights=60 of size=502"
      },
      "chunk_id": "20"
    }
  ],
  "intent": "[\"Power Apps のライセンスについて教えて\"]"
}
```

配列のため、以下のような感じで文字列を追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/d7ef2d43-0623-be76-a8b0-debe658a0f98.png)

応答は以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/df0bf024-ff24-f546-7a51-9b415d170ec9.png)

content、role 部分は以下のような感じになります。

```
body('JSON_の解析')?['choices'][0]['messages'][1]['content']

body('JSON_の解析')?['choices'][0]['messages'][1]['role']
```

# Power Apps 側

まず、こちらの API を利用する際、以下のチェックをオンにするようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ccc89afb-5586-04da-983d-70e745af5fe8.png)

:::note
分かりやすくするために表示させていたますが、最終的に非表示にして、暗黙的にチェックをいれるようにする、もしくは、チェックボックス自体なくしても問題ないです。

その際は、以下のチェックを外しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/76cb01ef-cef5-f701-ef5b-4f354b31b0a0.png)
:::

送信ボタンを押した際の処理は以下のような感じです。

```
UpdateContext({locLoading: true});
Collect(
    colChat,
    {
        role: "user",
        content: txtChatMessage.Text
    }
);
ClearCollect(
    colManufacturedChat,
    colChat
);
If(
    gblTotalTokens > 3500,
    ClearCollect(
        colManufacturedChat,
        LastN(
            colChat,
            3
        )
    )
);
If(
    chkIsAskBasedOnInternalData,
    Set(
        gblChatGPTResponse,
        'ChatGTPAzureOpenAI(Addyourdata)'.Run(JSON(colChat));
    );
    ,
    Set(
        gblChatGPTResponse,
        ChatGTPAzureOpenAI.Run(JSON(colManufacturedChat));
    );
    
);
If(
    gblChatGPTResponse.result = "0",
    Collect(
        colChat,
        {
            role: gblChatGPTResponse.role,
            content: gblChatGPTResponse.content
        }
    );
    Set(
        gblTotalTokens,
        Value(gblChatGPTResponse.totaltokens)
    );
    Set(
        gblShowlblChat,
        true
    );
    
Select(
        galChat,
        CountRows(galChat.AllItems)
    );
    ,
    Set(
        gblShowErrorMessage,
        true
    );
    
);
Reset(txtChatMessage);
UpdateContext({locLoading: false});

```

:::note warn
こちらの API を利用す際は、現状、total_tokens が返されていないため、total_tokens を元にデータ送信量を制御することが出来ない点について注意が必要です。通常の API を呼ぶ場合は、以下のような応答となるため、total_tokens を元にデータ送信量を制御することが可能です。


```
{
  "id": "chatcmpl-7XdoqOIIXkC5SG8prarAU7Msv7puK",
  "object": "chat.completion",
  "created": 1688252244,
  "model": "gpt-35-turbo",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "富士山(3776m)です。"
      }
    }
  ],
  "usage": {
    "completion_tokens": 12,
    "prompt_tokens": 18,
    "total_tokens": 30
  }
}
```

total_tokens を元にデータ送信量を制御する例

```
If(
    gblTotalTokens > 3500,
    ClearCollect(
        colManufacturedChat,
        LastN(
            colChat,
            3
        )
    )
);
```
:::

受け取ったデータの表示はこれまでと大きく変わらないです。citations がある場合は、リンクをクリックすると表示させるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/73129dc8-880d-2b46-b939-7339c31d8810.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b25358eb-e4b3-e3e4-dfce-2667f53a848b.png)

リンクのアイコンの`[Visible]`は以下のようにしています。

```
If(ThisItem.role="assistant" And chkIsAskBasedOnInternalData　And !IsBlank(gblChatGPTResponse.citations),true,false)
```

こちらで、Power Platform から「Add your data」の API を利用することができました。

# まとめ

今回は、Power Platform から Azure OpenAIの新機能「Add your data」を利用する方法について紹介しました。まだプレビュー段階で、回答の精度についても課題はあると思いますが、こちらが利用できるようになると、ChatGPT ＋必要に応じて独自データを元にチャットベースで回答を得る機能を簡単に実装することが出来ます。

また、フロントエンドを Power Platform にする場合、こちらで紹介しているように、テンプレートを利用したり、細かな制御を実装したりするなど、カスタマイズが簡単に出来るため、一つの選択肢になるかと思います。

やや API の利用の仕方に癖があるため、こちらの記事が少しでも参考になれば幸いです。