Bot Builder v4 でボット開発 : スキルを開発する - その 2 ソリューションのスクリプト詳細

[前回](https://qiita.com/drafts/02781c3fca2962cab473)は Visual Studio のテンプレートを使って、スキルおよびアシスタントボットを作成しました。今回はスキルテンプレートで作成された各種スクリプトを見ていきます。

スクリプトは以下の 6 種類です。

- deploy.ps1 : Azure リソースの展開
- delpoy_cognitive_models.ps1 : LUIS アプリの展開
- luis_functions.ps1 : LUIS 展開用の関数
- publish.ps1 : ボットアプリの発行
- qna_functions.ps1 : QnA メーカー展開用の関数
- update_cognitive_models.ps1 : LUIS アプリの更新

# 展開スクリプト

ソリューション作成後初めに実行するスクリプトで、Azure リソースを作成します。

## パラメーターとツールチェック
まず始めの 100 行程度は入力パラメーターや各種ツールの事前チェックが行われています。

## アプリケーション登録
次に以下コマンドで Azure AD にマルチテナント用アプリケーションを登録します。

```powershell
# Create app registration
$app = (az ad app create `
	--display-name $name `
	--password `"$($appPassword)`" `
	--available-to-other-tenants `
	--reply-urls 'https://token.botframework.com/.auth/web/redirect' `
    --output json)
```
作成されたアプリケーションは Azure AD の画面から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/bddc2d60-b488-9c3d-48a8-6adcb3282e66.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/0baab476-0a51-6606-9f5e-5da5f98c023f.png)

## リソースグループ作成とリソース作成

リソースグループを以下コマンドで作成。

```powershell
az group create --name $resourceGroup --location $location
``` 
完了後、Resources/template.json を使ってリソースを作成しています。ここで事前にプランを無償プランに変更しておくことも可能です。

```powershell
$validation = az group deployment validate `
		--resource-group $resourcegroup `
		--template-file "$(Join-Path $PSScriptRoot '..' 'Resources' 'template.json')" `
		--parameters name=$name microsoftAppId=$appId microsoftAppPassword="`"$($appPassword)`"" luisAuthoringLocation=$armLuisAuthoringRegion useLuisAuthoring=$createLuisAuthoring `
        --output json
```
## アプリケーション情報の更新

リソースが作成できたら、まずは Azure AD に登録したアプリのホームページ情報を更新します。

```powershell
# Update AD app with homepage
az ad app update --id $appId --homepage "https://$($outputs.botWebAppName.value).azurewebsites.net"
```
この情報は Azure AD の Branding で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/33a3c456-1c89-76a3-1de4-62dc469e8ca8.png)

そのあとで appsettings.json の中身を更新します。

```powershell
$settings | ConvertTo-Json -depth 100 | Out-File -Encoding utf8 $(Join-Path $projDir appsettings.json)
```

## LUIS アプリの作成

構成を書き終えたら deploy_cognitive_models.ps1 を起動して LUIS アプリを作成します。

```powershell
Invoke-Expression "& '$(Join-Path $PSScriptRoot 'deploy_cognitive_models.ps1')' -name $($name) -resourceGroup $($resourceGroup) -outFolder '$($projDir)' -languages '$($languages)' -luisAuthoringRegion '$($luisAuthoringRegion)' -luisAuthoringKey '$($luisAuthoringKey)' -luisAccountName '$($outputs.luis.value.accountName)' -luisAccountRegion '$($outputs.luis.value.region)' -luisSubscriptionKey '$($outputs.luis.value.key)' -qnaSubscriptionKey '$($qnaSubscriptionKey)' -qnaEndpoint '$($qnaEndpoint)'"
```
deploy_cognitive_models.ps1 は初めの読込みで luis_functions.ps1 と qna_functions.ps1 を読み込みます。

```powershell
. $PSScriptRoot\luis_functions.ps1
. $PSScriptRoot\qna_functions.ps1
```
その後 140 行くらいは各種チェックを行い、その後で指定した言語について Resources/LU フォルダに .lu ファイルがあるか確認します。

```powershell
$luisFiles = Get-ChildItem "$(Join-Path $PSScriptRoot .. 'Resources' 'LU' $langCode)" | Where {$_.extension -eq ".lu"}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/a769b12f-7ca1-9df0-bd74-48921ed78a84.png)

.lu ファイルを使って LUIS をデプロイします。

```powershell
# Deploy LUIS model
$luisApp = DeployLUIS `
	-name $name `
	-lu_file $lu `
	-region $luisAuthoringRegion `
	-authoringKey $luisAuthoringKey `
	-language $language `
    -gov $gov `
	-log $logFile
```

DeployLUIS 関数はluis_functions.ps1 にあり、まず bf (BotFramework CLI) を使って .lu ファイルを LUIS にアップロードできる形式へ変換します。

```powershell
bf luis:convert `
    --name $appName `
    --in $lu_file `
    --culture $language `
    --out $outFile `
```

そして luis CLI で LUIS アプリを作成、

```powershell
luis import application `
    --appName $appName `
    --authoringKey $authoringKey `
    --subscriptionKey $authoringKey `
    --region $region `
    --in $outFile `
    --cloud $cloud
```

モデルのトレーニングを実施、

```powershell
luis train version `
    --appId $luisApp.id `
    --region $region `
    --authoringKey $authoringKey `
    --versionId $luisApp.activeVersion `
    --cloud $cloud
```
最後に公開します。

```powershell
luis publish version `
    --appId $luisApp.id `
    --region $region `
    --authoringKey $authoringKey `
    --versionId $luisApp.activeVersion `
    --cloud $cloud 
```
この流れは LUIS アプリを更新する際も利用するので、理解しておく価値はあります。

### .lu ファイルと LUIS アプリ

.lu ファイルは言語ごとに Resources/LU フォルダに配置されており、Intent、Utterance、Entity を完結に記述できます。フォーマットの詳細は [.lu File Format](https://github.com/Microsoft/botbuilder-tools/blob/master/packages/Ludown/docs/lu-file-format.md) を参照してください。

スキルテンプレートでは以下の .lu ファイルが提供されます。またそれぞれに対応した LUIS アプリが作成されます。

- General.lu: キャンセル、確認、ヘルプなど一般的なインテント
- <YourSkill>.lu: スキルに関するインテント。既定で Sample と None が提供

```shell
# Sample
- sample dialog
- demo dialog
- Test dialog
- Run dialog
- run sample dialog

# None
- hi
- hello
- logout
- goodbye
```

[LUIS ポータル](https://www.luis.ai) に行くとプロビジョンした LUIS アプリが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/981214fd-738b-f666-054e-1cce18534b80.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1fa273ca-22c4-b6e4-2010-886929605b39.png)


## コグニティブ構成ファイル

LUIS アプリの作成から公開が完了したら、作成したアプリの情報を cognitivemodels.json に書き出します。言語やモデル毎の情報が書き出され、実際のボットアプリでも利用されます。

## ボットの公開

全ての作業が終われば、deploy.ps1 に戻ってきて、その時点のボットをコンパイルして Azure に発行します。

```powershell
Invoke-Expression "& '$(Join-Path $PSScriptRoot 'publish.ps1')' -name $($outputs.botWebAppName.value) -resourceGroup $($resourceGroup) -projFolder '$($projDir)'"
```

# ボット公開スクリプト

前回の記事でも使いましたが、ソースを変更した後、publish.ps1 単体でプロジェクトを公開できます。
deploy.ps1 の最後と同じ形式です。

```powershell
.\Deployment\Scripts\publish.ps1 -name kenakamumyassistant-qbp5igb -resourceGroup  kenakamumyassistant
```

# LUIS モデルの更新

LUIS モデルの更新は LUIS ポータルか、.lu ファイルを更新し、update_cognitive_models.ps1 を実行することで更新が行えます。このスクリプトはローカルの .lu ファイルからリモートの LUIS アプリを更新することも、その逆も可能です。

オプションを指定しない場合はローカルからクラウド、--RemoteToLocal オプションを指定するとクラウドからローカルへの更新となります。

```powershell
.\Deployment\Scripts\update_cognitive_models.ps1 
```

いずれにしても .lu ファイルを最新にすることでソース管理に組み込めるため重要です。

## .lu ファイルから更新

1\. Deployment\Resources\LU\en-us\HelloSkill.lu ファイルの Sample インテントに例文を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/22b90757-68c2-bdbd-b5c3-a0f99a353c30.png)

2\. スクリプトを実行。

```powershell
.\Deployment\Scripts\update_cognitive_models.ps1
```
3\. スクリプトの実行結果を確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1a9259f5-bbf0-239c-75d6-c088225c475f.png)

4\. LUIS アプリも更新されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ac1e017c-6e81-3404-e852-d12b290b0e4d.png)

5\. 以前のバージョンは backup として保存される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/14c36a81-2bd8-8985-8443-2d4b5f0bbad8.png)

6\. 公開されているアプリも Versions から確認可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/463811f9-92c9-7b58-4f3a-285f98cf37f1.png)

7\. Services/<Skill名>Luis.cs も更新。インテントなどが増えた場合はファイルの中身が変わる。

## LUIS アプリから更新

1\. LUIS アプリ上で新しい例文を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/d95ab892-76f7-3f8e-26e1-517776ae017e.png)

2\. -RemoteToLocal スイッチを指定してスクリプトを実行。

```powershell
.\Deployment\Scripts\update_cognitive_models.ps1 -RemoteToLocal
```

3\. スクリプトの実行結果を確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ad58f726-d831-ed46-03d9-870f1c61e9de.png)

4\. .lu ファイルを確認。新しい例文だけでなく、その他の情報も更新されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ca764d48-5616-6dd0-bf2e-1b3b5410dd7d.png)


# まとめ

今回はテンプレートで作成されるスクリプトを見ていきました。これらのスクリプトはアシスタントボットでも共通のため、一度しっかり目を通しておくと良いでしょう。次回は生成されたコードを見ていきます。

[次の記事へ](https://qiita.com/kenakamu/items/0d6a85da25390a425054)
[目次に戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883)