
REALTIME API BUG – WebSocket перестає отримувати повідомлення під час сесії — AudioWorklet надсилає звук, але серверні події не фігурують
https://ift.tt/gcRVfyw
Маємо періодичну, але відтворювану проблему з OpenAI Realtime API: сесія зависає у випадковий момент під час розмови. Помічник відповідає правильно кілька разів, але раптово перестає реагувати на аудіо користувача.
Оточення
Кроки для відтворення
-
Почати сесію Realtime API
-
Вести нормальний обмін між користувачем та помічником — помічник відповідає коректно кілька разів
-
У випадковий момент спробувати говорити після того, як помічник закінчив відповідь
-
Сесію застигає — більш ймовірно, коли є зовнішній шум (наприклад, клавіатура)
Очікувана поведінка Помічник відстежує мову послідовно і викликає input_audio_buffer.speech_started, потім відповідає.
Фактична поведінка У випадковий момент під час розмови WebSocket повністю мовчить після відповіді помічника. Немає жодних подій з боку сервера — ні speech_started, ні speech_stopped, нічого. AudioWorklet продовжує обробляти та надсилати аудіо фрагменти, але сервер їх ніколи не визнає. Сесія здається живою на стороні клієнта, але фактично зафіксована. Єдина відсутність — повний перезапуск сесії.
Що ми бачимо в журналах Після зафіксування кожен окремий аудіо-фрагмент, який надходить від AudioWorklet, помітний як мовчазний, навіть коли користувач говорить голосно. Це триває безмежно без реакції зі сторони сервера.
[AudioWorklet] Перший аудіо-фрагмент є мовчазним (max: 41)
[AudioWorklet] Перший аудіо-фрагмент є мовчазним (max: 78)
[AudioWorklet] Перший аудіо-фрагмент є мовчазним (max: 96)
... (сотні послідовних записів)
Що ми виключили як причини
-
З’єднання WebSocket не переривається і не викидає помилку
-
Проблема не пов’язана з рівнем гучності — збільшення гучності не відновлює сесію
-
Не завжди пов’язано з перемиканням між додатками, хоча це підвищує ймовірність
-
Помічник коректно відповідає кілька разів перед тим, як стан застигає
Код в продакшні, який може бути релевантний
Ми помітили, що ця проблема з’являється лише в продакшні. У нашого продакшн-білда є три механізми, яких немає в девелопмент-білді:
1. Сторонній клієнтський VAD-ворота — аудіо-фрагменти з RMS-енергією нижче порогу замінюються нулями перед відправкою до OpenAI:
ts
const isSilent = this.lastMicrophoneEnergy < this.clientVADThreshold
const dataToSend = isSilent ? new Int16Array(audioData.length) : audioData
2. Підвищений поріг енергії переривання — у продакшні потрібна значно більша енергія, щоб розглядати мову користувача як переривання під час мовлення помічника:
ts
private readonly INTERRUPTION_ENERGY_THRESHOLD = 0.1
private readonly INTERRUPTION_ENERGY_THRESHOLD = 0.02
3. Застряглий VAD-наглядач — якщо сервер лишається у стані speech_started протягом 30 секунд без переходу, продакшн посилає input_audio_buffer.clear для його скидання:
ts
this.stuckVADTimeout = setTimeout(() => {
this.gatewayClient.sendOpenAIMessage({ type: 'input_audio_buffer.clear' })
}, 30_000)
Наша теорія: зовнішній шум (наприклад, клавіатура) запускає speech_started на сервері, клієнтські ворота VAD починають надсилати нулі, і ця комбінація залишає серверний VAD у невідповідному стані, з якого він ніколи не відновлюється — в результаті застигання сесії.
Питання до спільноти
-
Чи хтось зустрічав випадок, коли WebSocket входить у стан, здається, з’єднаний, але перестає отримувати події сервера?
-
Чи існує відома проблема з зависанням серверного VAD після отримання змішаного набору реального аудіо та тиші (нульових даних)?
-
Чи є рекомендовані підходи для виявлення та відновлення від цього застигання без повного перезапуску сесії?
-
Розглядаємо міграцію з WebSocket на WebRTC для Realtime API. Хтось робив таку міграцію та вважає її більш стабільною для використання у браузері? Чи вирішила вона подібні проблеми з застиганням або тишею в сесії? Які є компроміси або відомі обмеження, про які варто знати перед переходом?
HI-FI News
через OpenAI Developer Community – Останні пости https://ift.tt/Neyc0nh
13 травня 2026 р. 21:26PM
May 13, 2026 at 09:26PM

Залишити відповідь