Поток вызовов примерно следующий:
- Аудио вызывающего абонента передается в потоковую передачу на мой сервер через события Twilio media (с метками времени).
- Мои серверные потоки синтезировали аудиоответы обратно в Twilio.
- Я также получаю событие (), который указывает, что вызывающий абонент начал говорить, пока звук все еще воспроизводится (вмешательство).
Код: Выделить всё
input_audio_buffer.speech_started
Я пытаюсь обрезать воспроизводимый в данный момент ответ именно в тот момент, когда вызывающий абонент начинает говорить.
Я правильно распознаю прерывание с помощью события, запускаемого речью, и немедленно отправляю инструкцию обрезания, которая включает в себя:
- Идентификатор воспроизводимого в данный момент ответа.
- Значение audio_end_ms, вычисленное на основе меток времени мультимедиа Twilio.
Другими словами:
- Событие, запускающее речь, срабатывает в нужный момент.
- Команда обрезания отправляется немедленно.
- Но усеченный звук не соответствовать реальной точке прерывания, которую слышит вызывающий абонент
Система: Да, я могу помочь вам разместить заказ. Пожалуйста, скажите мне, чего бы вы хотели.
Клиент: Я хочу бублики и газировку, спасибо.
Система: Это будет 9,05 доллара. Наличными или кредитом?
(В этот момент клиент прерывает.)
(Дополнительный аудио/текст генерируется системой, но никогда не отправляется в Twilio, поскольку аудиопоток очищается — например, «Сейчас вы можете применить скидку в магазине»).
Клиент: Извините, что перебил — у вас тоже есть кофе?
Система: Конечно. Что бы вы хотели заказать?
Проблема в том, что, хотя прерывание происходит после того, как покупатель упоминает товары для заказа, при применении усечения разговор оказывается обрезанным раньше, чем ожидалось, удаляя часть уже сыгранного хода. Это приводит к тому, что состояние разговора становится нестабильным, и теперь это критическая проблема в нашем потоке вызовов.
Это мой фрагмент кода
Код: Выделить всё
# Speech interruption detected
if event_type == "input_audio_buffer.speech_started":
elapsed_ms = current_twilio_timestamp - response_start_timestamp
send({
"type": "conversation.item.truncate",
"item_id": last_response_id,
"content_index": 0,
"audio_end_ms": elapsed_ms
})
Код: Выделить всё
if event == "media":
latest_timestamp_ms = media["timestamp"]
Что я пытаюсь понять
- Какова правильная эталонная временная шкала для audio_end_ms?
Должна ли она быть:- На основе временных меток мультимедиа Twilio?
- На основе времени исходящего аудио отправлено?
- На основе некоторых внутренних часов воспроизведения?
- Ожидается ли, что события, запускаемые речью, немного задерживаются относительно воспроизведения звука?
Если да, то как следует компенсировать усечение? - Существует ли рекомендуемая стратегия упорядочивания или синхронизации при обработке:
- Потоковая передача исходящего звука
- Прием обнаружения входящей речи
- Выдача инструкций обрезания/отмены
- Должна ли инструкция обрезания быть отправлена немедленно при обнаружении речи или должна быть отправлена на исходящий трафик звук сначала сбрасывается/очищается на уровне медиапотока?
Ограничения
- Это живой вызов (без предварительной буферизации полного ответа)
- Усечение должно отражать то, что на самом деле услышал вызывающий абонент, а не то, что было сгенерировано
- Я хочу избежать неправильной регистрации или воспроизведения частичных ответов
Я не разрабатывал эту логику самостоятельно. Я реализовал его на основе запроса на включение, опубликованного Twilio
Twilio AI Interruption, но проблема все еще сохраняется. Похожая проблема обсуждается в ветке сообщества OpenAI, где предполагается, что это может быть известная проблема ограничения или синхронизации, а не ошибка реализации.
realtime-api-interruptions-dont-properly-trim-the-transcript
Подробнее здесь: https://stackoverflow.com/questions/798 ... n-speech-i
Мобильная версия