Azure OpenAI On Your DataとHULFT Squareを繋いでみた

# 初めに
こんにちは。すぎもんです:grinning:
以前、「[Azure OpenAI On Your Dataを使ってみた](https://qiita.com/sugimon/private/dcae8e1935f161e072e6)」という記事を書きました。
Azure OpenAI On Your DataとHULFT Squareの連携は、企業が所有する社内システムにある非公開データをChatGPTのような高度な言語モデルと組み合わせることで企業のデータ活用とAI導入を革新的に進化させる可能性を秘めています。この組み合わせにより、社内データをRAGとして蓄積させAIに必要な情報だけを抽出させ社内の他のSaaSや異なるサービス、システムと連携させることが可能になります。

そこで今回は、Azure OpenAI On Your DataとHULFT Squareの連携方法をご紹介し実際に動かしてみるところまで詳しく解説します。この連携により、企業のデジタルトランスフォーメーション（DX）をさらに加速させ、データドリブンな意思決定を支援する強力なツールとなることが期待できます。


# 今回やること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/daf62f9d-0816-784e-06ac-8be57d48d3a6.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/8ac2551f-c5f1-06a2-63da-e6cea21574e6.png)

# 実施するのに必要な設定
1．コネクション
2．RESTコネクター
3．入力側マッパー
4．出力ファイル
5．出力側マッパー
6．実行してみる

:::note info
[前回の記事参照](https://qiita.com/sugimon/private/dcae8e1935f161e072e6)
前回下記のサンプルコードをご紹介しました。
今回はこの内容をHULFT Squareに設定していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/10dccf82-22e3-15a7-6cbf-69c1cbd45adf.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/f813f332-2ebc-f48a-387e-6809da0613be.png)

:::



# 1．コネクション
HULFT Squareのコネクションを設定します。

名前：`REST接続（Azure OpenAI Service On Your Data）`
URL：`<➀YOUR_RESOURCE_NAME>`

:::note warn
[前回の記事参照](https://qiita.com/sugimon/private/dcae8e1935f161e072e6)
`<➀YOUR_RESOURCE_NAME>`は前回設定したものを使います。
補足：https://<「1．Azure OpenAI」に設定したサービス名：GPT >.openai.azure.com
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/65adc3b7-ab96-66d4-2500-a3979e462c2a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/6799031f-b173-8908-21f0-6420ee47413b.png)


# 2．RESTコネクター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/96a97fd0-ee14-d806-d7af-42659fb162c9.png)


**Azure OpenAI On Your DataにAPIをコールするための設定をしていきます。**


HULFT Squareのデザイナー画面で「ツールパレット > ネットワーク > REST > `POST`」をドラッグ&ドロップでキャンバスに配置していきます。
「必須設定」
パス：`/openai/deployments/<➁YOUR_DEPLOYMENT_NAME>/extensions/chat/completions`
クリエパラメーター
名前：`api-version`
値　：`2023-06-01-preview`

:::note warn
[前回の記事参照](https://qiita.com/sugimon/private/dcae8e1935f161e072e6)
<➁YOUR_DEPLOYMENT_NAME>は前回設定したものを使います。
補足：「1．Azure OpenAI」に設定したデプロイ名：gpt-35
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/bbcc3b74-f7a9-82da-a601-aa8189bda778.png)

「リクエスト設定」
データ形式：`Json`

「レスポンス設定」
データ形式：`Json`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/a5303c9d-a4fb-2d2f-1454-4f02d0bc4962.png)

「ヘッダー設定」
リクエストヘッダー
|名前 |値  |
|---|---|
|`Content-Type`  |`application/json`  |
|`api-key`  |`<➂YOUR_API_KEY>`  |
|`chatgpt_url`  |`<➃YOUR_RESOURCE_URL>`  |
|`chatgpt_key`  |`<➄YOUR_API_KEY>`  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/b83374b6-ec5e-ef71-6adb-0b52d295d1c3.png)

:::note warn
[前回の記事参照](https://qiita.com/sugimon/private/dcae8e1935f161e072e6)
`<➂YOUR_API_KEY>`
補足：「6. コマンドで実行してみる」チャットプレイグラウンドで出した”AzureSearchリソースキー”

`<➃YOUR_RESOURCE_URL>`
補足：「1．Azure OpenAI」「➁デプロイ」でデプロイしたGPT-35の”ターゲットURL”

`<➄YOUR_API_KEY>`
補足：「1．Azure OpenAI」「➁デプロイ」でデプロイしたGPT-35の”キー”
:::


# 3．入力側マッパー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/c90f4cac-1b17-1d3f-a5e4-dc4f339da575.png)


**次に、リクエストをコールするための設定をしていきます**


リクエストをする為のmapperを設定していきます。
下記JsonをHULFT Squareのスキーマに設定します。

```ruby:Json
{
  "extensions": [],
  "dataSources": [
    {
      "type": "AzureCognitiveSearch",
      "parameters": {
          "endpoint": "'<➅YOUR_AZURE_COGNITIVE_SEARCH_ENDPOINT>'",
          "key": "'<➆YOUR_AZURE_COGNITIVE_SEARCH_KEY>'",
          "indexName": "'<➇YOUR_AZURE_COGNITIVE_SEARCH_INDEX_NAME>'"
      }
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": "What are Yamada Shoji's sales?"
    }
  ],
  "temperature": 0.7,
  "top_p": 0.95,
  "max_tokens": 800,
  "stop": null,
  "stream": false
}
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/94f1221d-f6e9-e967-c42f-d3d24e3fc093.png)

マッパーからスキーマを読み取ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/d2adb424-940f-5a8a-2978-2274a0fd4c5f.png)



HULFT SquareのマッパーでJsonの構造に合わせて、画像のようにアイコンと出力先の項目をつかってつないでいきます。
※マッパーの仕様により今回は「array」や「object」も指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/d1c5d4fd-c31c-34f2-533e-964cf6f7b522.png)

**”単一文字列”ロジック**
|出力先 |アイコン設定値  |
|---|---|
|"extensions"  |`[]`  |
|type |`array`　*mapperの仕様 |
|type |`object`　*mapperの仕様 |
|"type" |`AzureCognitiveSearch` |
|type |`object`　*mapperの仕様 |
|"endpoint"| `<➅YOUR_AZURE_COGNITIVE_SEARCH_ENDPOINT>`|
|"key"| `<➆YOUR_AZURE_COGNITIVE_SEARCH_KEY>`|
|"indexName"| `<➇YOUR_AZURE_COGNITIVE_SEARCH_INDEX_NAME>`|
|type |`array`　*mapperの仕様 |
|type |`object`　*mapperの仕様 |
|"role"  |`user`  |
|"content" |AIに質問するプロンプト |

**”数値定数”ロジック**
|出力先 |アイコン設定値  |
|---|---|
|"temperature"  |`0.7`  |
|"top_p" |`0.95`  |
|"max_tokens" |`800`  |

**その他のロジック**
|出力先 |アイコン設定値   |
|---|---|
|"stop" |`null` (null値ロジック)|
|"stream"  |`false` (真偽値定数ロジック) |


:::note info
**"content"に入れるプロンプト**
今回は下記プロンプトを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/c395686f-e52b-e8b7-b9f1-0bd7071bf658.png)

:::

# 4．出力ファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/c955464d-be8e-2c87-bca6-d60f030dc713.png)


**Azure OpenAI On Your Dataが返してきた結果を書き込むファイルを設定します。**
今回はCSVファイルに書き込んでいきます。
HULFT Squareのデザイナー画面で「ツールパレット > ファイル > CSV > CSVファイル書き込み」をドラッグ&ドロップでキャンバスに配置していきます。

今回は下記のように設定しました。
ファイルパス：`/Personal/Demo.csv`
列一覧
列名：`Answer`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/016fae63-eb95-7889-7aee-0d00c8a28e62.png)



# 5．出力側マッパー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/10cfbd4e-f6ef-f065-02ed-cbf9129b9688.png)


**Azure OpenAI On Your Dataの「出力結果(レスポンス)」を「書き込みにファイル」と繋げる設定をします。**


:::note warn
レスポンスJson の構造
「"index": 0」は欲しい値ではないので「"index": 1」の値だけ取得できるようにマッパーで設定する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/7271c35a-8bd0-ea62-82a3-a24c7e6dac78.png)
:::

HULFT Squareのスキーマには下記のように設定します。
```ruby:Json
{
  "id": "id",
  "model": "gpt-35-turbo-16k",
  "created": 1723700923,
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "messages": [
        {
          "index": 1,
          "role": "assistant",
          "content": "Answer",
          "end_turn": true
        }
      ]
    }
  ],
  "usage": {
    "prompt_tokens": 3599,
    "completion_tokens": 51,
    "total_tokens": 3650
  }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/94f1221d-f6e9-e967-c42f-d3d24e3fc093.png)

「3．入力側マッパー」と同様に”リソースからスキーマを読み込む”で「入力元」のリソースを設定します。
HULFT Squareのマッパーで「入力元」と「出力先」の項目を、画像のようにつないでいきます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/c2dc7bb2-b692-cc2e-0a48-4972925099e8.png)

使用したアイコンは下記になります。
|アイコン名 |アイコン設定値  |
|---|---|
|`条件による抽出`  |なし  |
|`単一文字列定数`  |`1`  |
|`同じ`  |なし  |


# 6．実行してみる
**早速実行してみたいと思います。**
➀**Blobストレージ**内に格納している読み取るデータの確認
今回は、**Blobストレージ**にあらかじめこちらのデータを格納して読み込ませておきました。

:::note info
**社内データ**(営業会議議事録)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/d326eeb9-5c7a-8e04-6c30-dba22cb85531.png)
:::

**➁実行**
デバック実行を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/1f97e93b-8b64-6d4d-56aa-dcd68e19062f.png)

正常に完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/26212fe9-9d97-9f51-542f-4441ea3b3426.png)

**➂確認**
結果を確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/d63ffaa5-a138-eb62-77a4-0225f966bd0e.png)

会議の関係者と、会議の決定事項を要約出来ているのが確認出来ます。

# 最後に
いかがでしたでしょうか、生成AIに安心して社内データ入れられるだけではなく、そのAIの出力結果も他のシステムに安心して受け渡せることで業務使用でのハードルが下がるのではないでしょうか。

また、生成AIの開発が進む中で柔軟に連携出来るシステムがあることで活用の幅も広がるかと思います。
HULFT SquareはAzureとの連携実績もあり下記のAPIと組み合わせることも可能です。
➀　[HULFT Square Blobストレージコネクター](
https://www.hulft.com/help/ja-jp/HULFTSquare/Content/Designer/Connector/cloud_azure_blob.htm)
➁　[Azure AI Searchインデクサー実行API](
https://learn.microsoft.com/ja-jp/rest/api/searchservice/run-indexer)
上記2つを利用することで、
「ファイルアップロード　→　インデクサー実行(ファイル読み取り) → Azure AI Search(検索）」という流れを一元化することも出来ます。

このブログでは、今後も様々なTopics記事や接続検証等、皆さんの参考になるような記事を投稿していきたいと思います！
それでは、また！:raised_hand: