デバッグのガイドラインDebugging guidelines

適用対象: SDK v4APPLIES TO: SDK v4

ボットは様々なパーツが連携する複雑なアプリです。Bots are complex apps, with a lot of different parts working together. そのため、他の複雑なアプリの場合と同様、興味深いバグが発生したり、期待どおりにボットが動作しなかったりすることがあります。Like any other complex app, this can lead to some interesting bugs or cause your bot to behave differently than expected.

ボットのデバッグは、場合によっては難しい作業になります。Debugging, your bot can sometimes be a difficult task. 開発者それぞれが独自のやり方でそのタスクを実行しています。以下のガイドラインでは、大部分のボットに適用できる推奨事項を紹介します。Every developer has their own preferred way to accomplish that task; guidelines we present below are suggestions for you to use that apply to a large majority of bots.

お使いのボットが意図したとおりに動作するように見えるのを確認したら、次はそれをチャネルに接続します。After verifying your bot appears to work how you'd like it to, the next step is connecting it to a channel. これを行うには、ご自身のボットをステージング サーバーに展開し、そのボットの接続先となる独自のダイレクト ライン クライアントを作成します。To do this, you can deploy your bot to a staging server and create your own direct line client for your bot to connect to.

独自のクライアントを作成すると、チャネルの内部動作を定義できるほか、ご自身のボットが特定のアクティビティの交換に対してどのように応答するかを具体的にテストできます。Creating your own client allows you to define the inner workings of the channel, as well as specifically test how your bot responds to certain activity exchanges. そのクライアントに接続されたら、テストを実行してボットの状態を設定し、お使いの機能を確認します。Once connected to your client, run your tests to set up your bot state and verify your features. お使いのボットで音声などの機能が使用されている場合は、これらのチャネルを使用して、その機能を確認する手段を提供できます。If your bot utilizes a feature like speech, using these channels can offer a way to verify that functionality.

ここで Azure portal からエミュレーターと Web チャットの両方を使用すると、さまざまなチャネルと対話しているときの、ご利用のボットの動作に関するより詳細な分析情報が得られます。Use of both the Emulator and Web Chat via Azure portal here can provide further insight into how your bot performs while interacting with different channels.

お使いのボットのデバッグは、他のマルチスレッド アプリと同様に動作し、ブレークポイントを設定する機能が用意されています。また、イミディエイト ウィンドウなどの機能を使用することもできます。Debugging your bot works similarly to other multi-threaded apps, with the ability to set breakpoints or use features like the immediate window.

ボットはイベント ドリブン方式のプログラミング パラダイムに従っています。このパラダイムに詳しくない場合、これを合理的に説明するのは困難です。Bots follow an event driven programming paradigm, which can be hard to rationalize if you're not familiar with it. お使いのボットがステートレスかつマルチ スレッドであり、非同期/待機の呼び出しを処理するという考え方は、予期しないバグにつながることあります。The idea of your bot being stateless, multi-threaded, and dealing with async/await calls can result in unexpected bugs. こうしたボットのデバッグは他のマルチスレッド アプリと同様に動作しますが、ここでは役に立つ提案、ツール、およびリソースをいくつか紹介します。While debugging your bot works similarly to other multi-threaded apps, we'll cover some suggestions, tools, and resources to help.

エミュレーターを使用した bot アクティビティについてUnderstanding bot activities with the Emulator

お使いのボットでは、通常の "メッセージ" アクティビティだけでなく、さまざまな種類の アクティビティが処理されます。Your bot deals with different types of activities besides the normal message activity. エミュレーターを使用すると、これらのアクティビティがどのようなものか、いつ発生するか、どのような情報が含まれているかがわかります。Using the Emulator will show you what those activities are, when they happen, and what information they contain. これらのアクティビティを理解すると、ボットのコードを効率的に書いたり、ボットが送受信しているアクティビティが期待どおりのものかを確認したりするうえで役立ちます。Understanding those activities will help you code your bot efficiently and allows you to verify the activities your bot is sending and receiving are what you expect.

ユーザーとの対話のトランスクリプトの保存と取得Saving and retrieving user interactions with transcripts

Azure BLOB のトランスクリプト ストレージは、ユーザーとボットの間の対話が含まれるトランスクリプトを格納して保存できる、特殊化されたリソースを提供します。Azure blob transcript storage provides a specialized resource where you can both store and retrieve transcripts containing interactions between your users and your bot.

さらに、ユーザー入力の対話が格納された後は、Azure の "ストレージ エクスプローラー" を使用して、BLOB のトランスクリプト ストア内に格納されたトランスクリプトに含まれるデータを手動で確認できます。Additionally, once user input interactions have been stored, you can use Azure's "storage explorer" to manually view data contained in transcripts stored within your blob transcript store. 次の例では、"mynewtestblobstorage" の設定から "ストレージ エクスプローラー" を開きます。The following example opens "storage explorer" from settings for "mynewtestblobstorage." 保存されたユーザー入力を開くには、 [BLOB コンテナー] > [ChannelId] > [TranscriptId] > [ConversationId] の順に選択します。To open a saved user input select: Blob Container > ChannelId > TranscriptId > ConversationId


これにより、JSON 形式で格納された会話のユーザー入力が開きます。This opens the stored user conversation input in JSON format. ユーザー入力はキーとなる "text" と共に保持されます。User input is preserved together with the key "text:."

ミドルウェアのしくみHow middleware works

特に実行の継続やショートサーキットに関して言えば、初めて使うミドルウェアは直感的とは言えないでしょう。Middleware may not be intuitive when first attempting to use it, particularly regarding the continuation, or short-circuiting, of execution. ミドルウェアは、ボット ロジックに実行が渡されるタイミングをディクテーションする next() デリゲートへの呼び出しを使用して、ターンの立ち上がりまたは立ち下がりで実行できます。Middleware can execute on the leading or trailing edge of a turn, with a call to the next() delegate dictating when execution is passed to the bot logic.

複数のミドルウェアを使用している場合は、お使いのパイプラインの方向付けに従って、デリゲートによって別のミドルウェアに実行が渡されることがあります。If you are using multiple pieces of middleware the delegate may pass execution to a different piece of middleware if that is how your pipeline is oriented. 詳細については、ボットのミドルウェア パイプラインに関する記事をご覧ください。この考え方を、さらに明確に理解するうえで役立ちます。Details on the bot middleware pipeline can help make that idea clearer.

next() デリゲートが呼び出されない場合、それはショート サーキット ルーティングと呼ばれます。If the next() delegate is not called, that's referred to as short circuit routing. ミドルウェアが現在のアクティビティを満たしている場合、そして実行を渡す必要ないと判断した場合に、これが発生します。This happens when the middleware satisfies the current activity and determines it's not necessary to pass execution on.

ミドルウェアでショートサーキットが発生するタイミングと理由を理解すると、どのミドルウェアをパイプラインの先頭にするかを指定するときに役立ちます。Understanding when, and why, middleware short-circuits helps indicate which piece of middleware should come first in your pipeline. また、予期される結果を理解することは、SDK または他の開発者によって提供される組み込みのミドルウェアには特に重要です。Additionally, understanding what to expect is particularly important for built-in middleware provided by the SDK or other developers. 組み込みのミドルウェアを使用する前に、まず独自のミドルウェアを作成して少し実験してみると役立つ場合もあります。Some find it helpful to try creating your own middleware first to experiment a bit before diving into the built-in middleware.

状態の理解Understanding state

特に複雑なタスクの場合、状態を追跡することが、お使いのボットにとっては重要です。Keeping track of state is an important part of your bot, particularly for complex tasks. 一般的に、ベスト プラクティスは、アクティビティをできるだけ迅速に処理し、状態が永続化されるようにその処理を完了させることです。In general, best practice is to process activities as quickly as possible and let the processing complete so that state gets persisted. 複数のアクティビティがほぼ同時にご使用のボットに送信されるため、非同期アーキテクチャが原因で、非常に紛らわしいバグが発生することがあります。Activities can be sent to your bot at nearly the same time, and that can introduce very confusing bugs because of the asynchronous architecture.

重要なのは、自分が意図したとおりに状態が永続化されているかどうかを確認することです。Most importantly, make sure that state is persisting in a way that matches your expectations. 永続化の状態が存在する場所によっては、Cosmos DB および Azure Table Storage 用のストレージ エミュレーターが、運用環境のストレージを使用する前にその状態を確認するうえで役立つ場合があります。Depending on where your persisted state lives, storage emulators for Cosmos DB and Azure Table storage can help you verify that state before using production storage.


Cosmos DB ストレージ クラスは非推奨となりました。The Cosmos DB storage class has been deprecated. CosmosDbStorage で作成されたコンテナーにはパーティションキーが設定されておらず、_ / partitionkey の既定のパーティションキーが指定されました。Containers originally created with CosmosDbStorage had no partition key set, and were given the default partition key of _/partitionKey.

Cosmos DB ストレージ で作成されたコンテナーは、 Cosmos DB パーティション分割 されたストレージで使用できます。Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. 詳細については、Azure Cosmos DB でのパーティション分割に関するページを参照してください。Read Partitioning in Azure Cosmos DB for more information.

また、従来の Cosmos DB ストレージとは異なり、Cosmos DB パーティション分割されたストレージは、Cosmos DB アカウント内にデータベースを自動的に作成しません。Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. 新しいデータベースは手動で作成する必要がありますが、コンテナーを手動で作成する必要はありません。これは、 CosmosDbPartitionedStorage によってコンテナーが作成されるためです。You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

アクティビティ ハンドラーを使用する方法How to use activity handlers

アクティビティ ハンドラーにより、別の複雑さが生じることがあります。具体的には、各アクティビティが独立したスレッドで実行されます (お使いの言語によっては Web worker で実行されます)。Activity handlers can introduce another layer of complexity, particularly since each activity runs on an independent thread (or web workers, depending on your language). ご利用のハンドラーが行っている処理によっては、現在の状態が、期待どおりのものではないという問題が発生することがあります。Depending on what your handlers are doing, this can cause issues where the current state is not what you expect.

組み込みの状態はターンの最後に書き込まれますが、そのターンによって生成されたアクティビティはすべて、ターン パイプラインとは無関係に実行されています。Built-in state gets written at the end of a turn, however any activities generated by that turn are executing independently of the turn pipeline. 多くの場合、この影響を受けることはありませんが、アクティビティ ハンドラーによって状態が変更された場合は、その変更を含めるために状態を書き込む必要があります。Often this doesn't impact us, but if an activity handler changes state we need the state written to contain that change. この場合、ターン パイプラインは、アクティビティ上で処理が完了するのを待つことができます。これにより、完了前に、そのターンについて適切な状態が確実に記録されます。In that case, the turn pipeline can wait on the activity to finish processing before completing to make sure it records the correct state for that turn.

send activity メソッドとそのハンドラーにより、独自の問題が発生します。The send activity method, and its handlers, pose a unique problem. on send activities ハンドラー内から send activity を単に呼び出すと、スレッドの無限フォークが発生します。Simply calling send activity from within the on send activities handler causes an infinite forking of threads. この問題を回避する方法はいくつかあります。たとえば、メッセージを送信情報に追加します。また、コンソールやファイルなどの別の場所に書き出してボットのクラッシュを回避します。There are ways you can work around that problem, such as by appending additional messages to the outgoing information or writing out to another location like the console or a file to avoid crashing your bot.

次のステップNext steps

その他のリソースAdditional resources