Azure ボットを構成して、会話のエスカレーションと終了をさせる

この記事では、Customer Service 用オムニチャネルで、Azure ボットが人間のエージェントに会話をルーティングするプログラム方法について説明します。 また、ボットが会話を終了するようにプログラムする方法についても説明します。

重要

  • ボットは、プッシュ型のワーク ストリームに追加された場合のみ、会話を受け取ることができます。
  • ボットエージェントは、コンサルト モードではサポートされていません。

前提条件

  • Customer Service 用オムニチャネルに設定され、統合された Azure ボットが必要です。 詳細: Azure ボットの統合
  • スキル ベースのルーティングが有効化されている必要があります。

人間のエージェントに会話をエスカレートする

顧客サービス用オムニチャネルでは、ボットは現在の会話を人間のエージェントにエスカレートできます。 会話のルーティングは、作業ストリームに対して構成したルーティング規則によって異なります。

会話をボットから人間のエージェントに転送し、そのエージェントがエスカレーション要求を受け入れると、顧客とサポート案件の詳細が 自動的に識別されます。 その会話に関連付けられた Customer Service 用オムニチャネルのコンテキスト変数を使用して、ボットが会話をルーティングします。 ボットは、エスカレーション リクエストとともに、コンテキスト変数と関連する値のリストを Customer Service 用オムニチャネルに送信できます。 また、ボットはスキル ファインダー モデルで新しいスキルを識別し、会話の既存のスキル リストに追加するために使用できるコンテキスト項目を設定できます。 その後、Customer Service 用オムニチャネルは、指定された値でコンテキスト変数を更新し、ルーティング エンジンを再度実行します。 これにより、エスカレートした会話が正しいキューにルーティングされます。 コンテキスト項目と変数名に関する詳細は ボットによる会話のエスカレートや終了で、顧客とサポート案件を会話にリンクする を参照してください。

エージェントがエスカレーション要求を受け入れると、ボットが顧客と交わした会話のトランスクリプトがエージェントの会話ウィジェットに表示されます。 その後、エージェントは顧客と会話を続行できます。

Note

会話の概要は顧客には表示されません。

会話の終了

Azure ボットは、顧客の質問に答えたと判断した場合や、顧客が反応しなくなった場合に、会話の終了を選択することができます。 ボットは Customer Service 用オムニチャネルに EndConversation リクエストを送信できます。

サンプル コード

このセクションには、会話をエスカレートして終了する Azure ボットの構成に使用できるコード サンプルが含まれています。

  1. コマンド クラスを実装して、会話のエスカレーションと終了に関するタスクをモデル化します。

コードの例は以下の通りです。

using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace EchoBot.OmniChannel
{
    /// <summary>
    /// Command types that bot can send to Omnichannel
    /// </summary>
    [JsonConverter(typeof(StringEnumConverter))]
    public enum CommandType
    {
        [EnumMember(Value = "Escalate")]
        Escalate = 0,
        [EnumMember(Value = "EndConversation")]
        EndConversation = 1,
    }
    /// <summary>
    /// Action
    /// </summary>
    [DataContract]
    public class Command
    {
        /// <summary>
        /// Type of action that bot can send to Omnichannel
        /// </summary>
        [DataMember(Name = "type")]
        public CommandType Type { get; set; }

        /// <summary>
        /// Dictionary of Workstream Context variable and value pairs to be sent to Omnichannel for Customer Service
        /// </summary>
        [DataMember(Name = "context")]
        public Dictionary<string, object> Context { get; set; }
    }
}
  1. コマンド コンテキストを設定する Customer Service 用オムニチャネルのクライアント クラスを実装します。

コードの例は以下の通りです。

using Microsoft.Bot.Schema;
using Newtonsoft.Json;
using System.Collections.Generic;

namespace EchoBot.OmniChannel
{
    /// <summary>
    /// Extension class for middleware implementation management
    /// </summary>
    public static class OmnichannelBotClient
    {
        /// <summary>
        /// Delivery mode of bot's reply activity
        /// </summary>
        private const string DeliveryMode = "deliveryMode";
        /// <summary>
        /// Delivery Mode value bridged
        /// </summary>
        private const string Bridged = "bridged";
        /// <summary>
        /// Custom data tag
        /// </summary>
        private const string Tags = "tags";

        /// <summary>
        /// Adds Omnichannel for Customer Service escalation context to the bot's reply activity.
        /// </summary>
        /// <param name="activity">Bot's reply activity</param>
        /// <param name="contextVars">Omnichannel for Customer Service workstream context variable value pairs</param>
        public static void AddEscalationContext(IActivity activity, Dictionary<string, object> contextVars)
        {
            Command command = new Command
            {
                Type = CommandType.Escalate,
                Context = contextVars
            };

            string serializedString = JsonConvert.SerializeObject(command);
            if (activity.ChannelData != null)
            {
                (activity as IActivity).ChannelData[Tags] = serializedString;
            }
            else
            {
                activity.ChannelData = new Dictionary<string, object>() { { Tags, serializedString } };
            }
        }

        /// <summary>
        /// Adds Omnichannel end conversation context to the bot's reply activity.
        /// </summary>
        /// <param name="activity">Bot's reply activity</param>
        public static void AddEndConversationContext(IActivity activity)
        {
            Command command = new Command
            {
                Type = CommandType.EndConversation,
                Context = new Dictionary<string, object>()
            };

            string serializedString = JsonConvert.SerializeObject(command);
            if (activity.ChannelData != null)
            {
                (activity as IActivity).ChannelData[Tags] = serializedString;
            }
            else
            {
                activity.ChannelData = new Dictionary<string, object>() { { Tags, serializedString } };
            }
        }

        /// <summary>
        /// Sets delivery mode for bot as bridged so that Customer can see bot messages
        /// </summary>
        /// <param name="activity">Bot's reply activity</param>
        public static void BridgeBotMessage(IActivity activity)
        {
            if (activity.ChannelData != null)
            {
                (activity as IActivity).ChannelData[DeliveryMode] = Bridged;
            }
            else
            {
                activity.ChannelData = new Dictionary<string, object>() { { DeliveryMode, Bridged } };
            }
        }
    }
}

  1. ボットの ActivityHandler クラスの適切なクライアント メソッドを呼び出します。

    EscalateEndConversation のコマンドの基準は、必要に応じて変更してください。

    コード ステートメント OmnichannelBotClient.BridgeBotMessage(turnContext.Activity); をご利用のボットに追加して、Customer Service 用オムニチャネルにメッセージを送信します。 このメソッドは、顧客に送信されるすべての Activity メッセージに対して呼び出す必要があります。

コードの例は以下の通りです。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using EchoBot.OmniChannel;
using Microsoft.Bot.Schema;

namespace Microsoft.Bot.Builder.EchoBot
{
    public class EchoBot : ActivityHandler
    {
        /// <summary>
        /// This method is called when the bot receives a message.
        /// </summary>
        /// <param name="turnContext">Turn Context object</param>
        /// <param name="cancellationToken">CancellationToken</param>
        /// <returns></returns>
        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                // Replace with your own message
                IActivity replyActivity = MessageFactory.Text($"Echo: {turnContext.Activity.Text}");

                // Replace with your own condition for bot escalation
                if (turnContext.Activity.Text.Equals("escalate", StringComparison.InvariantCultureIgnoreCase))
                {
                    Dictionary<string, object> contextVars = new Dictionary<string, object>() { { "Bo-tHandoffTopic", "CreditCard" } };
                    OmnichannelBotClient.AddEscalationContext(replyActivity, contextVars);
                }
                // Replace with your own condition for bot end conversation
                else if (turnContext.Activity.Text.Equals("endconversation", StringComparison.InvariantCultureIgnoreCase))
                {
                    OmnichannelBotClient.AddEndConversationContext(replyActivity);
                }
                // Call method BridgeBotMessage for every response that needs to be delivered to the customer.
                else
                {
                    OmnichannelBotClient.BridgeBotMessage(replyActivity);
                }

                await turnContext.SendActivityAsync(replyActivity, cancellationToken);
            }
        }

        /// <summary>
        /// This method is called when there is a participant added to the chat.
        /// </summary>
        /// <param name="membersAdded">Member being added to the chat</param>
        /// <param name="turnContext">TurnContext</param>
        /// <param name="cancellationToken">CancellationToken</param>
        /// <returns></returns>
        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurn-Context<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in membersAdded)
            {
                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    //Set the bridge mode for every message that needs to be delivered to customer
                    OmnichannelBotClient.BridgeBotMessage(turnContext.Activity); 
                    await turnContext.SendActivityAsync(MessageFactory.Text($"Welcome to Echo Bot."), cancellationToken);
                }
            }
        }
    }
}

辞書 contextVars には、エスカレーション要求の一部として更新するすべての顧客サービス用オムニチャネルのコンテキスト変数名と値のペアを含みます。 ここでは、BotHandoffTopic はコンテキスト変数名で、CreditCard はコンテキスト変数値です。 ルール: BotHandoffTopicCreditCar と等しいを含むエージェント キューがある場合、このエスカレーションされたチャットはそのキューにルーティングされます。

コンテキストの変数名は、文字列型です。 コンテキスト変数の値は整数型、または文字列型型で、エスカレーション時には Dictionary<string, object> として渡す必要があります。 コードの例は以下の通りです。

Dictionary<string, Object> keyValues = new Dictionary<string, object>() {
{ "BotHandoffTopic", "CreditCard" },
{ "IDNumber", 101}
}

ボットは、エスカレーションされたチャット リクエストが受け入れられた後に、エージェントにのみ表示されるエスカレーションのサマリーを送信することもできます。 概要を送信するには、エスカレーション活動メッセージで活動テキストを適切に設定します。

参照

Azure ボットの統合
コンテキスト変数の追加
Azure Bot Service
ボットをチャンネルに接続する
独自のカスタム メッセージング チャネルを用意します: Direct Line ボット
Azure ボットと Copilot Studio ボットを構成するためのベスト プラクティス