a2 Tech blog

試したこと・調べたこと・感じたことを発信するITエンジニアの日記です。仕事とは直接関係ないけど興味あることを模索していきます。

Microsoft Bot Serviceで作成したFAQボットをデバッグする

f:id:ninna2:20170815210633p:plain:w360

夏休みの宿題として、Microsoft Bot ServiceQnA Makerを使ってFAQボットを前回作成してみました。30分でノンプログラミングでできるので、興味がある人は是非試してみるとよいかなと思います。

ninna2.hatenablog.com

そんでもって、お盆休みなのでかなり手を抜いた感があったので、今回は少し技術的なことやっていこうと思います。少しだけですけどね。

技術的なことは書くと、読む人少ないんですよね。

当たり前ですけど、興味ある人限られてますしね。でも、読んでもらえなくても書くんです。1人でも読む人がいる限り。

というわけで、FAQボットをデバッグできるようにしていきましょう。 最近、わかったのですが、見切り発車で記事書いていく方が、自分として面白い。

それはたぶん先が読めないから、うまくいくかわからないからですね。 今回も見切り発車です。Bot Serviceはどうやってデバッグしていくのか、一緒に探索していきましょう。

参考資料

何もないところからチャレンジというわけではないのでもちろん参考記事はあります。あと一応、Bot Frameworkではデバッグできる環境を作った経験はあります。なので、まったく知識がないわけではないです。Bot Serviceは初めてですけどね。

docs.microsoft.com

これ通りやればうまくいけばいいんですけど、どこではまるか、ドキドキです。 30分ですんなり終わるのか、1日かかるのかわかりません。

見切り発車スタート。

まずは、ソースコードの登録…

手順通り進めていきましょう。

まずは、"Set up continuous integration"です。 いきなりCIの設定?って思いましたが、気にせず進めましょう。

作成したBot Serviceのソースコードをダウンロードして、リポジトリに突っ込んでおきます。 私はVSTS(Visual Studio Team Services)派なので、VSTSに新しくプロジェクトを作成して、リポジトリを作ります。この辺りは詳しく説明しなくても察してもらえると思うので、説明は端折ります。私の過去記事でも、ググるなりして調べればサクッとできます。

さて、リポジトリができたら、"Download your source code"します。

Azure Portalから作成したBot Serviceを開き、"SETTINGS"から"Continuous integration"を見ます。ソースコードのダウンロードリンクがあるので、自分のソースコードをダウンロードしましょう。

f:id:ninna2:20170820170035p:plain

もちろんViausl Studioでデバッグしますので、Visual Studio 2017がインストール済みの前提です。まず、先ほど作成したリポジトリをCloneしておきます。そのうえで、ダウンロードしたソースコードをCloneした先に突っ込み初回Commit&Pushしておきます。

VSTSで作成した.gitignoreファイルだけは、活かしたかったのでダウンロードした.gitignoreの内容を、コピーして手動で追加しました。別にダウンロードした.gitignoreを使っても問題ないとは思いますが、VSの設定が入っている.gitignoreを使った方がなんとなくうれしい気がします。このあたりは、ダウンロードソースコードは気が利いていないですね。

出来上がると、こんな感じになるはずですね。

f:id:ninna2:20170820171512p:plain:w300

どんどん設定していこう…

ソースコードをダウンロードしてVSTSリポジトリに突っ込めて、Visual Studioから見れるようになったので、次に進めていきます。

Noteに重要なことが書かれています。

Visual Studio 2017 RC changes how Visual Studio handles dependencies. While Visual Studio 2015 uses project.json to handle dependencies, Visual Studio 2017 uses a .csproj model when loading in Visual Studio. If you are using Visual Studio 2017, download this .csproj file to the /messages folder in your repository before you run the dotnet restore command.

何やらVisual Studio 2017では、何かが必要らしい。うーん、"dotnet restore"を実行する前に.csprojファイルを/messageに配置するのか。では配置してみようではないか。

https://aka.ms/bf-debug-project

ダウンロードして、/messageに配置して、それから"dotnet restore"を実行。これがなんの意味があるのか正直わからないけれどやれと言われたことはやるしかない。今度ちゃんと調べてみよう。今は時間がないので、調査は後日。

C:\>cd Source\Repos\a2-sample-bot\messages

C:\Source\Repos\a2-sample-bot\messages>dotnet restore
  Restoring packages for C:\Source\Repos\a2-sample-bot\messages\messages.csproj...
  Generating MSBuild file C:\Source\Repos\a2-sample-bot\messages\obj\messages.csproj.nuget.g.props.
  Generating MSBuild file C:\Source\Repos\a2-sample-bot\messages\obj\messages.csproj.nuget.g.targets.
  Restore completed in 428.39 ms for C:\Source\Repos\a2-sample-bot\messages\messages.csproj.

C:\Source\Repos\a2-sample-bot\messages>

こんな感じに出力されましたね。これでOKなのか… エラーは出ていないようなので先に進みましょう。

ところで"messages.csproj"ってBot.slnに登録してないけどいいのかなって思ったので、一応、Visual StudioからBot.slnに追加しておきました。VSから見れる方が良いものね。

f:id:ninna2:20170820173311p:plain:w300

いろいろダウンロードしなさいって書いてあるやつを、今まで無視して進めてきましたが、そろそろ必要そうなのでダウンロードしてインストールしておきます。

この3つです。いろいろ必要なんですね。インストールは難しくないのでサクサクっと終わらせましょう。

Debug…

いよいよ、Debug実行です。手順では、"debughost.cmd"を実行となっているのでコマンドプロンプトから実行していきます。

実行…

C:\Source\Repos\a2-sample-bot>debughost.cmd
App Settings:
Connection Strings:

                  %%%%%%
                 %%%%%%
            @   %%%%%%    @
          @@   %%%%%%      @@
       @@@    %%%%%%%%%%%    @@@
     @@      %%%%%%%%%%        @@
       @@         %%%%       @@
         @@      %%%       @@
           @@    %%      @@
                %%
                %

No "id" property defined in host.json.
Updating host.json with a new "id"
Listening on http://localhost:3978/
Hit CTRL-C to exit...
Reading host configuration file 'C:\Source\Repos\a2-sample-bot\host.json'
C:\Source\Repos\a2-sample-bot\messages\BasicQnAMakerDialog.csx(4,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

C:\Source\Repos\a2-sample-bot\messages\BasicQnAMakerDialog.csx(5,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

C:\Source\Repos\a2-sample-bot\messages\BasicQnAMakerDialog.csx(6,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

run.csx(9,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

run.csx(10,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

run.csx(11,17): error CS0234: The type or namespace name 'Bot' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)

C:\Source\Repos\a2-sample-bot\messages\BasicQnAMakerDialog.csx(10,36): error CS0246: The type or namespace name 'QnAMakerDialog' could not be found (are you missing a using directive or an assembly reference?)

・・・省略・・・

Generating 1 job function(s)
Starting Host (HostId=af7a8491fa9947238edc726ba0da8995, Version=1.0.10826.0, ProcessId=12108, Debug=False, Attempt=0)
Executing HTTP request: {
  "requestId": "061e818c-f422-4ef3-a64d-ef480cf2d32f",
  "method": "GET",
  "uri": "/"
}
Found the following functions:
Host.Functions.messages

Job host started
Executed HTTP request: {
  "requestId": "061e818c-f422-4ef3-a64d-ef480cf2d32f",
  "method": "GET",
  "uri": "/",
  "authorizationLevel": "Anonymous"
}
Response details: {
  "requestId": "061e818c-f422-4ef3-a64d-ef480cf2d32f",
  "status": "OK"
}
Http Function messages: http://localhost:3978/api/messages
Debugger listening on [::]:5858

なんかいろいろエラーが出ました。手順通りやってもうまくいかないパターンか…道のりは長くなりそうな気配がしてきました。

さて、原因はなんでしょうかね。エラーメッセージを見ると、何かモジュールが足りないか、認識できていない感じに受け取れます。モジュールの定義ってどこに書いてあるのかなーって…たぶん、"project.json"か"project.lock.json"。とりあえずググってみると、こんな記事見つけたので、その通りやってみよう。

teratail.com

ふむふむ、"Microsoft.Bot.Connector"が足りないのか。同じように"project.json"に追加してみます。

{
  "frameworks": {
    "net46": {
      "dependencies": {
        "Microsoft.Bot.Builder.Azure": "3.2.1",
        "Microsoft.Bot.Builder.CognitiveServices": "1.0.3",
        "Microsoft.Bot.Connector": "1.1.0"
      }
    }
  }
}

再実行。うまくいくかな。

実行…

C:\Source\Repos\a2-sample-bot>debughost.cmd
App Settings:
Connection Strings:

                  %%%%%%
                 %%%%%%
            @   %%%%%%    @
          @@   %%%%%%      @@
       @@@    %%%%%%%%%%%    @@@
     @@      %%%%%%%%%%        @@
       @@         %%%%       @@
         @@      %%%       @@
           @@    %%      @@
                %%
                %

Reading host configuration file 'C:\Source\Repos\a2-sample-bot\host.json'
Listening on http://localhost:3978/
Hit CTRL-C to exit...
Package references have been updated.
Restoring packages.
Starting NuGet restore
Restoring packages for C:\Source\Repos\a2-sample-bot\messages\project.json...
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.cognitiveservices/index.json
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.azure/index.json
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.azure/index.json 1031ms
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.cognitiveservices/index.json 1031ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.cognitiveservices/1.0.3/microsoft.bot.builder.cognitiveservices.1.0.3.nupkg
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.azure/3.2.1/microsoft.bot.builder.azure.3.2.1.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.cognitiveservices/1.0.3/microsoft.bot.builder.cognitiveservices.1.0.3.nupkg 786ms
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.azure/3.2.1/microsoft.bot.builder.azure.3.2.1.nupkg 785ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder/index.json
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.history/index.json
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder/index.json 750ms
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.history/index.json 742ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.history/3.0.3/microsoft.bot.builder.history.3.0.3.nupkg
  GET https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder/3.5.5/microsoft.bot.builder.3.5.5.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder.history/3.0.3/microsoft.bot.builder.history.3.0.3.nupkg 683ms
  OK https://api.nuget.org/v3-flatcontainer/microsoft.bot.builder/3.5.5/microsoft.bot.builder.3.5.5.nupkg 683ms
Installing Microsoft.Bot.Builder 3.5.5.
Installing Microsoft.Bot.Builder.History 3.0.3.
Installing Microsoft.Bot.Builder.CognitiveServices 1.0.3.
Installing Microsoft.Bot.Builder.Azure 3.2.1.
Version conflict detected for Microsoft.Rest.ClientRuntime.
 messages (>= 1.0.0) -> Microsoft.Bot.Builder.CognitiveServices (>= 1.0.3) -> Microsoft.Bot.Builder (>= 3.5.5) -> Microsoft.Rest.ClientRuntime (>= 2.3.2)
 messages (>= 1.0.0) -> Microsoft.Bot.Connector (>= 1.1.0) -> Microsoft.Rest.ClientRuntime (>= 1.8.2 && < 2.0.0).
Committing restore...
Writing lock file to disk. Path: C:\Source\Repos\a2-sample-bot\messages\project.lock.json
C:\Source\Repos\a2-sample-bot\messages\project.json
Restore failed in 5281ms.

Errors in C:\Source\Repos\a2-sample-bot\messages\project.json
    Version conflict detected for Microsoft.Rest.ClientRuntime.
     messages (>= 1.0.0) -> Microsoft.Bot.Builder.CognitiveServices (>= 1.0.3) -> Microsoft.Bot.Builder (>= 3.5.5) -> Microsoft.Rest.ClientRuntime (>= 2.3.2)
     messages (>= 1.0.0) -> Microsoft.Bot.Connector (>= 1.1.0) -> Microsoft.Rest.ClientRuntime (>= 1.8.2 && < 2.0.0).

NuGet Config files used:
    C:\AppData\Roaming\NuGet\NuGet.Config

Feeds used:
    https://api.nuget.org/v3/index.json

Installed:
    4 package(s) to C:\Source\Repos\a2-sample-bot\messages\project.json


Packages restored.
Generating 1 job function(s)
Starting Host (HostId=af7a8491fa9947238edc726ba0da8995, Version=1.0.10826.0, ProcessId=11640, Debug=False, Attempt=0)
Executing HTTP request: {
  "requestId": "48f7e08b-4d2a-4100-8b34-5bd6d95c6cc3",
  "method": "GET",
  "uri": "/"
}
Executed HTTP request: {
  "requestId": "48f7e08b-4d2a-4100-8b34-5bd6d95c6cc3",
  "method": "GET",
  "uri": "/",
  "authorizationLevel": "Anonymous"
}
Response details: {
  "requestId": "48f7e08b-4d2a-4100-8b34-5bd6d95c6cc3",
  "status": "OK"
}
Http Function messages: http://localhost:3978/api/messages
Found the following functions:
Host.Functions.messages

Job host started
Debugger listening on [::]:5858

赤いエラーはなくなった!!

途中、若干エラーっぽいもの出てますがどうなんでしょう。とりあえず進めてみてダメだったら見直すことにしましょう。

これで、動いているみたいなので、Bot Framework Emulatorからアクセスしてみましょう。

Bot Framework EmulatorからアクセスするURLは"http://localhost:3978/api/messages"を指定します。APPIDやPasswordは不要で、そのまま"CONNECT"します。

f:id:ninna2:20170820183227p:plain

おぉつながりました。

ちゃんと最初の"Welcome User!“と言ってくれてます。すばらしい。

では話しかけてみましょう。

f:id:ninna2:20170820183423p:plain

はい、エラーです。

mscorlib: Exception while executing function: Functions.messages. Microsoft.Bot.Builder.CognitiveServices.QnAMaker: 値を Null にすることはできません。
パラメーター名:subscriptionKey.

うーん、QnA Makerにつながってないのか…そりゃそうですよね。さてどうやってつなぐのか。そもそもどうやってつながっていたのかがわかればよいのかな。たぶん、こいつをローカルにも設定すればよいのかな。

f:id:ninna2:20170820184222p:plain

どうやって、ローカルのソースコードからこの情報を読み取らせればよいのかですね。Azure Appsなので、環境変数でできるのではと直感で思いましたが、それはちょっと嫌なので設定ファイルを作りましょう。

“appsettings.json"というファイルを作ってみて、そこにキー情報を記載してSaveします。これで読み込んでくれるはずよね。

f:id:ninna2:20170820192741p:plain

もう一度、実行しなおして、話しかけてみます。

f:id:ninna2:20170820185154p:plain

おぉうまくいった。ということは、これでデバッグできるはず。

Visual Studioで実行(F5)してみます。デバッグモードの起動をしてブレイクポイントを張ります。そして話しかけると…

f:id:ninna2:20170820185834p:plain

キターーーー。

できたので一安心。一時はできないのではないかと焦りました。

これでデバッグできるようになったので、ボットの開発ができますね。 いやぁ紆余曲折意外と時間がかかってしまいました。同じことで皆さんがはまらないように参考にしてもらえればと思います。

最後に1つだけ課題が…Bot Serviceのソースコードって、インテリセンス聞かないの?Azure Fuctionsだからかな。そもそも参照設定とかないからか?このあたりまだまだ理解していないので、本格的に開発するためにはもう少し真面目に調査が必要なのかもしれません。