JAICP

Перебивание бота


Перебивание (англ. barge-in) — возможность телефонного канала, позволяющая абонентам прерывать речь собеседника, не дожидаясь, пока тот закончит говорить.

Использование перебивания в проектах голосовых ботов позволяет им воспринимать запросы клиентов в реальном времени и оперативно на них реагировать. Это делает разговор более живым и стимулирует вовлеченность клиента в диалог.


Параметры перебивания

Для того чтобы включить перебивание, вызовите в нужном стейте метод $dialer.bargeInResponse с нужными настройками перебивания.

Если произойдет перебивание, ответ бота будет прерван, а запрос клиента будет обработан в контексте данного стейта. Рассмотрим пример:

state: Offer
    a: Новое предложение только для вас!
    a: Только сегодня и только у нас на все тарифы линейки «Живи» скидка 20%!
    a: Хотите воспользоваться нашим предложением?
    script:
        $dialer.bargeInResponse({
            bargeIn: "phrase", // Режим перебивания, в котором бот договорит фразу, прежде чем прерваться
            bargeInTrigger: "final", // Перебивание произойдет после окончательного результата распознавания
            noInterruptTime: 1000 // В течение 1 секунды после начала ответа бота нельзя перебить
        });

    state: What || noContext = true
        q: * что [что] *
        script:
            log($dialer.isBargeInInterrupted()); // => true
        a: Сегодня для вас персональная скидка — скидка 20% на все тарифы линейки «Живи»!
        a: Желаете попробовать?

Если клиент не дослушает и перебьет бота вопросом «Что?», бот прервется и отреагирует на вопрос.

Метод $dialer.isBargeInInterrupted позволяет определить, был ли прерван ответ бота.


Контекстное перебивание

При зачитывании длинных последовательностей фраз вы можете настроить перебивание так, чтобы контекст перебивания отличался в зависимости от того, на какой фразе клиент перебил бота.

Для настройки контекстного перебивания используются параметры тегов реакций a или audio, которые передаются через разделитель || после тела тегов. Рассмотрим синтаксис на следующем примере.

state: Offer
    a: Новое предложение только для вас! || bargeInTransition = /Offer/NotDone, bargeInLabel = firstReply
    a: Только сегодня и только у нас || bargeInTransition = /Offer/NotDone, bargeInLabel = secondReply
    a: на все тарифы линейки «Живи» скидка 20%! || ignoreBargeIn = true
    a: Хотите воспользоваться нашим предложением? || bargeInTransition = /Offer/Done, bargeInLabel = thirdReply
    script:
        $dialer.bargeInResponse({
            bargeIn: "forced",
            bargeInTrigger: "interim",
            noInterruptTime: 0
        });
    go: /Offer/Done

    state: NotDone

        state: No
            intent: /Нет
            a: Постойте, вы ведь еще не знаете, о чем речь! Это уникальное предложение!
            go!: /Offer

        state: CatchAll
            event: noMatch
            event: speechNotRecognized
            a: Прошу прощения, я вас не поняла. Позвольте мне продолжить.
            script:
                log($dialer.getBargeInTransition()); // => "/Offer/NotDone"
            go!: /Offer

    state: Done

        state: No
            intent: /Нет
            a: Я поняла вас. Спасибо, что уделили мне время. Всего доброго!
            script:
                $dialer.hangUp();

        state: CatchAll || noContext = true
            event: noMatch
            event: speechNotRecognized
            script:
                if ($dialer.isBargeInInterrupted()) {
                    log($dialer.getBargeInLabel()); // => "thirdReply"
                }
            a: Не совсем поняла. Вы согласны воспользоваться предложением?

bargeInTransition

Параметр bargeInTransition задает путь до стейта, в который будет перенаправлен бот при перебивании. Путь задается в том же формате, что и после тега реакции go.

Например, если клиент откажется от предложения во время произнесения первой или второй фразы, когда бот не успел полностью озвучить условия предложения, будет совершен переход в стейт /Offer/NotDone. После этого бот обработает преждевременный отказ в стейте /Offer/NotDone/No и вернется к предложению.

Если же перебивание отказом произойдет на последней фразе, запрос будет обработан в контексте стейта /Offer/Done. В данном случае бот прервется, чтобы попрощаться с клиентом и завершить звонок.

Путь к стейту для обработки перебивания, установленный для ответа, можно получить из сценария при помощи метода $dialer.getBargeInTransition.


bargeInLabel

Параметр bargeInLabel задает метку перебивания с какой-либо необходимой справочной информацией — например, о номере фразы, на которой произошло перебивание.

Метод $dialer.getBargeInLabel позволяет получить в стейте для обработки перебивания значение установленной метки.


ignoreBargeIn

Если для фразы указан параметр ignoreBargeIn со значением true, то перебивание на такой фразе не сработает, даже если для стейта перебивание включено.

Используйте игнорирование перебивания для фраз с важной информацией, которую клиент не должен пропустить, дослушав до одной из таких фраз.


Перебивание по условию

Способы обработки перебивания, рассмотренные выше, имеют следующий недостаток: при получении любого результата распознавания речи от ASR-провайдера бот обязан прерваться и обработать фразу клиента.

Такой подход может быть неэффективен, например, в условиях фонового шума либо если клиент при прослушивании активно использует речевые маркеры восприятия речи («ага», «ясно», «понятно»). Они не требуют ответной реакции, однако бот вынужден прерываться, чтобы обработать такие фразы.

Для решения этой проблемы используйте возможность перебивания по условию, которая позволяет определить из сценария, в каких случаях бот должен обработать перебивание, а в каких нет. Рассмотрим пример ниже.

state: Yes
    intent: /Да
    a: Спасибо! Опция будет добавлена в течение дня. Всего доброго, до свидания! || bargeInIf = beforeHangup
    script:
        $dialer.bargeInResponse({
            bargeIn: "forced",
            bargeInTrigger: "final",
            noInterruptTime: 0
        });
        $dialer.hangUp();

    state: BargeInIntent || noContext = true
        event: bargeInIntent
        script:
            var bargeInIntentStatus = $dialer.getBargeInIntentStatus();
            log(bargeInIntentStatus.bargeInIf); // => "beforeHangup"
            var text = bargeInIntentStatus.text;

            if (text.indexOf("оператор") > -1) {
                $dialer.bargeInInterrupt(true);
            }

    state: Switch
        intent: /Оператор
        a: Прошу прощения, если я неправильно вас поняла. Перевожу ваш звонок на оператора.
        script:
            $response.replies = $response.replies || [];
            $response.replies.push({
                type: "switch",
                // ...
            });

bargeInIf

Параметр bargeInIf после тега a или audio включает условное перебивание для фразы. Значением параметра является метка условного перебивания — строка с любой необходимой справочной информацией.


bargeInIntent

Если клиент перебьет бота во время произнесения фразы, для которой задан параметр bargeInIf, в сценарии сработает событие bargeInIntent, которое необходимо обработать в отдельном стейте.

Само по себе возникновение этого события не заставит бота прерваться — бот продолжит ответ и одновременно запустит обработчик события. В результате выполнения обработчика бот должен определить, действительно ли ему нужно прерваться или же проигнорировать попытку его перебить.

Для решения этой задачи в обработчике события bargeInIntent доступны следующие методы:

  • $dialer.getBargeInIntentStatus — метод для получения метки условного перебивания и текста запроса, которым клиент пытался перебить бота.
  • $dialer.bargeInInterrupt — метод для задания поведения бота: должен ли бот прерваться, чтобы обработать запрос, или нет.

Таким образом, в примере выше клиент сможет перебить прощание бота, только упомянув в запросе слово «оператор».

Используйте метод $nlp.matchPatterns для динамического сопоставления текста запроса паттернам, чтобы задать более сложную логику классификации запросов на перебивание бота.


Зависимость от bargeInTrigger

Обратите внимание, что условия срабатывания события bargeInIntent отличаются в зависимости от того, какое значение присвоено полю bargeInTrigger при настройке перебивания.

При использовании значения interim событие срабатывает при каждом промежуточном результате распознавания. Большое число вызовов обработчика события могут существенно увеличить потребляемые ресурсы и замедлить работу бота.

Рекомендуется использовать для перебивания по условию только значение final, при котором событие возникает после получения окончательного результата распознавания.