偵錯指導方針Debugging guidelines

適用于: SDK v4APPLIES TO: SDK v4

Bot 是將許多不同組件整合在一起運作的複雜應用程式。Bots are complex apps, with a lot of different parts working together. 和其他複雜的應用程式一樣,這種方式會導致一些有趣的錯誤,或是讓 Bot 產生出乎意料的行為。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. 每個開發人員都有自己慣用的方法來完成該工作。我們提供以下的指導方針給您做為建議,可適用於大部分的 Bot。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.

確認您的 Bot 如預期般運作之後,下一步就是將其連線至通道。After verifying your bot appears to work how you'd like it to, the next step is connecting it to a channel. 若要這樣做,您可以將 Bot 部署到預備伺服器,並建立自己的直接線路用戶端以供 Bot 連線。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.

建立自己的用戶端可讓您定義通道內部的運作方式,並且可特別針對 Bot 回應特定活動交換的方式進行測試。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. 一旦 Bot 連線到您的用戶端後,請執行您的測試以設定 Bot 狀態並驗證功能。Once connected to your client, run your tests to set up your bot state and verify your features. 如果您的 Bot 會利用如語音之類的功能,使用這些通道可提供驗證該功能的方式。If your bot utilizes a feature like speech, using these channels can offer a way to verify that functionality.

透過 Azure 入口網站在此處使用模擬器和網路聊天,可提供 Bot 在使用不同通道互動時的執行方式見解。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.

針對 Bot 進行偵錯的方式,與針對其他多執行緒應用程式進行偵錯的方式相似,都要使用設定中斷點或是如即時運算視窗的功能。Debugging your bot works similarly to other multi-threaded apps, with the ability to set breakpoints or use features like the immediate window.

Bot 遵循事件驅動程式設計架構,如果您還不熟悉,就很難進行說明。Bots follow an event driven programming paradigm, which can be hard to rationalize if you're not familiar with it. 讓您的 Bot 處於無狀態、多執行緒以及處理非同步/等候呼叫的概念,都會造成無法預期的錯誤 (Bug)。The idea of your bot being stateless, multi-threaded, and dealing with async/await calls can result in unexpected bugs. 針對 Bot 偵錯的運作方式與針對其他多執行緒應用程式的方式相似,我們將會提供一些實用的建議、工具和資源來協助您。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

您的 Bot 除了處理一般的 訊息 活動之外,也會處理不同類型的 活動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. 了解那些活動有助於您更有效率地撰寫 Bot 的程式碼,並且可讓您確認 Bot 如預期地傳送和接收活動。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 文字記錄儲存體提供特製化資源,您可以在其中儲存及擷取文字記錄,內含使用者與您的 bot 之間的互動。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 > ConversationIdTo open a saved user input select: Blob Container > ChannelId > TranscriptId > ConversationId

Examine_stored_transcript_text

這會開啟以 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. 當執行傳遞給 Bot 邏輯時,中介軟體可透過呼叫 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. 如需詳細資料,請參閱 Bot 中介軟體管線以澄清概念。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

持續追蹤狀態是 Bot 中很重要的一環,特別是針對複雜的工作更是如此。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. 活動可能近乎同時傳送給您的 Bot,而由於非同步架構的關係,可能造成非常令人困惑的錯誤 (Bug)。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 DBAzure 表格儲存體的儲存體模擬器有助於您在使用生產環境儲存體之前先驗證該狀態。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

活動處理常式可能導入另一層次的複雜度,特別是因為每個活動都在獨立的執行緒 (或是背景工作角色,視您的程式設計語言而定) 上執行。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. 針對該問題,有一些方法可以作為因應措施,例如將額外訊息附加到輸出資訊,或寫出到其他位置 (例如主控台),或是寫出檔案來避免造成 Bot 當機。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