次の方法で共有


Azure エージェントを構成して会話のエスカレーションと終了を行う

注意

Copilot Studio ボットの名前が Copilot エージェント (エージェントまたは AI エージェント) に変更されました。 人間 エージェント は、顧客サービス担当者 (サービス担当者または担当者) に名前が変更されました。 製品の UI、ドキュメント、トレーニング コンテンツを更新しているときに、古い用語と新しい用語への言及に出くわす可能性があります。

この記事では、Azure で AI エージェント (エージェント) をプログラムして、Dynamics 365 Contact Center の顧客サービス担当者 (サービス担当者または担当者) に会話をルーティングする方法について説明します。 また、エージェントが会話を終了するようにプログラムする方法についても説明します。

重要

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

前提条件

  • Dynamics 365 Contact Center で構成され、統合されたエージェントが Azure に必要です。 詳細については、Azure エージェントの統合 を参照してください
  • スキル ベースのルーティングが有効化されている必要があります。

担当者に会話をエスカレートする

Dynamics 365 Contact Center では、エージェントは現在の会話を担当者にエスカレーションできます。 会話のルーティングは、作業ストリームに対して構成したルーティング規則によって異なります。

担当者がエスカレーションのリクエストを受け入れ、AI担当者から会話が転送されると、顧客とケースの詳細 が自動的に特定されます。 エージェントは、会話に関連付けられたDynamics 365 Contact Centerのコンテキスト変数を使って会話をルーティングします。 エージェントはコンテキスト変数と関連値のリストをエスカレーションリクエストとともにDynamics 365 Contact Centerに送信できます。 エージェントはまた、スキルファインダーモデルが新しいスキルを特定し、既存のスキルリストに会話用に付加できるコンテキストアイテムを設定することもできます。 Dynamics 365 Contact Centerは指定された値でコンテキスト変数を更新し、再度ルーティングエンジンを実行します。 システムはエスカレーションされた会話が正しいキューにルーティングされていることを確認します。 担当者が会話をエスカレーションまたは終了した際の「Link customer and case to conversations」のコンテキスト項目や変数名について詳しく学びましょう。

担当者がエスカレーション要求を受け入れると、エージェントが顧客と交わした会話のチャット記録が担当者の会話ウィジェットに表示されます。 その後、担当者 は顧客との会話を続けることができます。

注意

会話の要約は顧客には見えません。

会話の終了

Azureエージェントは、顧客の質問に回答されたか、顧客が応答しなくなった場合に会話を終了することができます。 担当者はDynamics 365 Contact Centerに EndConversation リクエストを送ることができます。

サンプル コード

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

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

  2. コマンドコンテキストを設定するためのOmnichannelクライアントクラスを実装してください。

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

    /// <summary>
    /// Send end of conversation context to user and agent.
    /// </summary>
    public static async Task EndConversationAsync(ITurnContext turnContext, CancellationToken cancellationToken)
    {
        IActivity customerFacingActivity = Activity.CreateMessageActivity();
        customerFacingActivity.Text = "Thanks for talking with me. Have a good day. Bye.";
        BridgeBotMessage(customerFacingActivity);
    
        IActivity agentFacingActivity = Activity.CreateMessageActivity();
        agentFacingActivity.Text = "Ending the conversation as per customer request.";
        AddContext(CommandType.EndConversation, agentFacingActivity);
    
        List<IActivity> messageActivities = new List<IActivity>
        {
            customerFacingActivity,
            agentFacingActivity
        };
    
        await turnContext.SendActivitiesAsync(messageActivities.ToArray(), cancellationToken);
    }
    
    /// <summary>
    /// Send escalation context to user and agent.
    /// </summary>
    public static async Task EscalateConversationAsync(ITurnContext turnContext, IContextManager contextManager, CancellationToken cancellationToken)
    {
        IActivity customerFacingActivity = Activity.CreateMessageActivity();
        customerFacingActivity.Text = "Perfect I’ll transfer you now";
        BridgeBotMessage(customerFacingActivity);
    
        IActivity agentFacingActivity = Activity.CreateMessageActivity();
        agentFacingActivity.Text = GetEscalationSummary(turnContext, contextManager);
        AddContext(CommandType.Escalate, agentFacingActivity, contextManager.GetContext(turnContext.Activity.Conversation.Id));
    
        List<IActivity> messageActivities = new List<IActivity>
        {
            customerFacingActivity,
            agentFacingActivity
        };
    
        await turnContext.SendActivitiesAsync(messageActivities.ToArray(), cancellationToken);
    }
    
  3. ボットの ActivityHandler クラスの適切なクライアント メソッドを呼び出します。

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

  5. コードステートメントをボットコードに OmnichannelBotClient.BridgeBotMessage(turnContext.Activity); 入れて、Dynamics 365 Contact Centerにメッセージを送信します。 このメソッドは、顧客に送信されるすべての Activity メッセージに対して呼び出す必要があります。

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

    protected async Task OnMessageActivityAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(turnContext);
        var text = turnContext.Activity.Text?.ToLower(CultureInfo.InvariantCulture);
        var responseActivity = Activity.CreateMessageActivity();
        Responses.BuildCustomerFileAttachmentResponse(turnContext, responseActivity);
    
        if (string.IsNullOrEmpty(text))
        {
            if (turnContext.Activity.Value is JsonElement jsonElement)
            {
                var activityResponseValue = turnContext.Activity.Value;
                responseActivity.Text = $"You replied with value: {Environment.NewLine}{activityResponseValue}";
            }
        }
        else if (text.StartsWith("echo:", StringComparison.OrdinalIgnoreCase))
        {
            responseActivity.Text = text.Replace("echo:", "", StringComparison.OrdinalIgnoreCase);
        }
        else if (text.Contains("ac ", StringComparison.OrdinalIgnoreCase))
        {
            Responses.BuildAdaptiveCardResponse(responseActivity, text);
        }
        else
        {
            switch (text)
            {
                case Commands.Agent:
                    await OmnichannelAgentClient.EscalateConversationAsync(turnContext, _contextManager, cancellationToken);
                    return;
                case Commands.AnimationCard:
                case Commands.AudioCard:
                case Commands.FaultySigninCard:
                case Commands.HeroCard:
                case Commands.HeroCardIMBack:
                case Commands.HtmlList:
                case Commands.Markdown:
                case Commands.ReceiptCard:
                case Commands.SigninCard:
                case Commands.ThumbnailCard:
                case Commands.VideoCard:
                    Responses.BuildStructuredCardResponse(responseActivity, text);
                    break;
                case Commands.AttachmentFromC2:
                    responseActivity.Text = $"Attachment type has been identified";
                    break;
                case Commands.Debug:
                    Responses.BuildDebugContextResponseText(_contextManager, turnContext, responseActivity);
                    break;
                case Commands.EndChat:
                    await OmnichannelAgentClient.EndConversationAsync(turnContext, cancellationToken);
                    break;
    
                case Commands.Help:
                    Responses.BuildHelpResponse(responseActivity);
                    break;
                default:
                    Responses.BuildDidNotUnderstandResponse(responseActivity, text);
                    break;
            }
        }
        await OmnichannelAgentClient.BridgeAndSendActivityAsync(turnContext, responseActivity, cancellationToken);
    }
    

    辞書 contextVars には、エスカレーションリクエストの一部として更新したいすべてのコンテキスト変数名の値ペアが含まれています。 ここでは、BotHandoffTopic はコンテキスト変数名で、CreditCard はコンテキスト変数値です。 もし BotHandoffTopicCreditCarと等しいルールの代表キューがあれば、このエスカレートされたチャットはそのキューにルーティングされます。

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

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

担当者は、担当者がエスカレーションチャットのリクエストを受け入れた後にのみエスカレーションの要約を送ることができます。 要約を送信するには、エスカレーションメッセージ内のアクティビティテキストを設定してください。

Azure エージェントの統合
コンテキスト変数の追加
Azure ボット サービス
エージェントをチャネルに接続する
Direct Line を使用して独自のカスタム チャネルを統合する
Azure および Copilot Studio エージェントの設定に関するベストプラクティス