直線 API 作為客戶端應用程式與 Copilot Studio 內建的對話代理互動的通訊介面。 直線 API 促進客戶端應用程式與代理程式之間透過 WebSocket 串流或 HTTP 請求傳遞訊息。 在效能測試方面,Direct Line 讓負載測試工具能模擬實際使用者行為、產生負載並衡量回應時間。
使用 WebSockets 與直線通話
使用 Copilot Studio 建立的對話代理會部署到網頁應用程式中,無論是作為 嵌入式 iframe ,或透過 自訂畫布。 這兩種部署方式都使用 WebSocket 與 Direct Line 通訊。 如果你的對話代理是部署到使用上述方法的應用程式,效能測試腳本應該利用 WebSocket 通訊產生類似真實使用者行為的負載,並以高度信心衡量效能。
使用直線與 WebSocket 通訊的用戶端應用程式應遵循以程:
- 要發起對話,客戶端應用程式必須先取得一個對話代幣。 如果您的代理設定了 直線秘密,請透過呼叫 直線區域端點取得令牌。 不使用秘密的代理可以從 標記端取得代幣。
- 用戶端應用程式使用該令牌 開始對話 ,並接收對話 ID 與 WebSocket 串流網址。
- 使用者訊息透過發送 帶有對話 ID 的 HTTP POST 請求來發送。
- 來自對話代理的訊息會 透過 WebSocket 串流接收。
使用 HTTP GET 與直線通話
如果你的負載測試工具無法使用 WebSocket 通訊,或是你的客戶端應用程式不使用 WebSocket 通訊,你可以透過 發送 HTTP GET 來接收活動。 如下圖所示,對話啟動流程並未改變。
衡量反應時間
要評估負載如何影響使用者體驗,請確保效能測試腳本追蹤並報告以下步驟的回應時間:
| Step | 對使用者體驗的影響 |
|---|---|
| 生成令牌 | 開啟新對話所需的時間 |
| 開始對話 | 開啟新對話所需的時間 |
| 傳送活動 | 發送新用戶訊息所需的時間(不含客服的回覆) |
| 接收活動/獲取活動 | 客服人員回應所需的時間 |
對於負載測試工具來說,追蹤產生令牌、開始對話和發送活動的回應時間非常直接,因為這些步驟使用標準的 HTTP 請求。 然而,測量代理回覆用戶訊息所需的時間較為複雜,原因如下:
透過直線線路的發送與接收活動遵循非同步模式。 當使用者訊息是透過發送活動請求發送時,回應並非代理的訊息。 它只是確認用戶訊息已 成功發布。
根據其設計,對話代理可能會回應使用者訊息,發送任意數量的訊息。 因此,在大多數情況下,你應該以用戶訊息到最後一則客服訊息之間的時間來衡量。 以下範例中,單一使用者訊息會觸發三個代理訊息,中間會有 API 呼叫。 每則訊息約需兩秒鐘回覆;然而,從使用者的角度來看,代理人員回應使用者請求需要六秒鐘。
辨識代理人的最後回應
要衡量客服完成回應所需的時間,你的效能測試腳本需要:
- 識別使用者訊息後的最後一個代理訊息
- 計算兩者之間的時間差
Copilot Studio 使用的底層協定沒有「最後回應」的概念,因為代理和使用者都可以隨時發送訊息。 因此,你的效能測試腳本必須假設,如果代理在指定時間內沒有發送訊息,就不會再發送訊息,直到下一次使用者訊息發出。 這個邏輯的實作方式會依據你的腳本與 Direct Line 的溝通方式而有所不同。
使用 WebSockets
透過 WebSockets 與 Direct Line 通訊時,假設當無法從 WebSocket 讀取更多框架時,代理程式不再發送訊息。 你可能會在嘗試讀取下一幀時看到逾時,但具體行為取決於你的實作方式。 若參考實作使用WebSockets,請考慮 使用 HTTP GET。
使用 HTTP GET
使用 HTTP GET 取代 WebSockets 的效能測試腳本,應該會輪詢 Activities 端點,取得完整的使用者與代理訊息集合。 投票時,務必預留足夠時間讓經紀人回應。 舉例來說,如果你的代理需要呼叫後端 API 來回應使用者查詢,而 API 回應最多要花 5 秒,那麼你的腳本應該在 5 秒內輪詢 Activities 端點。
以下簡化有效載荷代表活動端點回傳的回應:
[
{
"type": "message",
"id": "98SryQaHr2rGthOGpChPK2-us|0000012",
"timestamp": "2025-01-07T09:12:22.0329242Z",
"from": {
"id": "a688eb7d-092a-42a8-8ef5-73123b9c2aaa",
"name": ""
},
"conversation": {
"id": "98SryQaHr2rGthOGpChPK2-us"
},
"text": "I also want to set up a new account",
},
{
"type": "message",
"id": "98SryQaHr2rGthOGpChPK2-us|0000017",
"timestamp": "2025-01-07T09:12:24.5478686Z",
"from": {
"id": "4b56bfa5-5574-5bb3-7aa3-99b8798b9d90",
"name": "Load Testing",
"role": "bot"
},
"conversation": {
"id": "98SryQaHr2rGthOGpChPK2-us"
},
"text": "Sure, please bear with me as I set up your new account",
"replyToId": "98SryQaHr2rGthOGpChPK2-us|0000012",
},
{
"type": "message",
"id": "98SryQaHr2rGthOGpChPK2-us|0000018",
"timestamp": "2025-01-07T09:12:33.1960413Z",
"from": {
"id": "4b56bfa5-5574-5bb3-7aa3-99b8798b9d90",
"name": "Load Testing",
"role": "bot"
},
"conversation": {
"id": "98SryQaHr2rGthOGpChPK2-us"
},
"text": "Almost done! Thank you for your patience",
"replyToId": "98SryQaHr2rGthOGpChPK2-us|0000012",
},
{
"type": "message",
"id": "98SryQaHr2rGthOGpChPK2-us|0000019",
"timestamp": "2025-01-07T09:12:41.9166159Z",
"from": {
"id": "4b56bfa5-5574-5bb3-7aa3-99b8798b9d90",
"name": "Load Testing",
"role": "bot"
},
"conversation": {
"id": "98SryQaHr2rGthOGpChPK2-us"
},
"text": "All done! Your new account is now active.",
"inputHint": "acceptingInput",
"replyToId": "98SryQaHr2rGthOGpChPK2-us|0000012"
}
]
在解析有效載荷並計算反應時間時,請考慮以下指引:
- 代理的訊息具有
role: bot屬性,而使用者的訊息則沒有role屬性。 - 回應使用者訊息的代理訊息具有屬性 ,而該屬性
replyToId具有使用者訊息屬性id的值。 - 你可以計算代理回覆時間,視為使用者訊息與最後回覆該代理訊息的時間差。