Як використовувати OpenAI Realtime API для створення голосових агентів та перекладу в реальному часі

Дізнайтесь як створювати голосових агентів і перекладати мову в реальному часі за допомогою OpenAI Realtime API

OpenAI Realtime API дозволяє будувати додатки, де голос користувача миттєво обробляється та отримує голосову відповідь — без затримок, характерних для класичного підходу STT → LLM → TTS. Цей туторіал покаже, як підключитись до API, налаштувати голосового агента та реалізувати переклад мовлення в реальному часі. На проходження знадобиться приблизно 60–90 хвилин, а для старту потрібні базові знання JavaScript та активний акаунт OpenAI з балансом від $5.

🛠️ Що знадобиться

  • OpenAI акаунт з API-ключем — основний сервіс; Realtime API є платним, тариф ~$0.06/хв аудіо вводу та $0.24/хв виводу (станом на 2026 рік)
  • Node.js 20+ або Python 3.11+ — для запуску серверної частини; рекомендую Node.js через нативну підтримку WebSocket
  • ws пакет (npm) або websockets (pip) — бібліотека для роботи з WebSocket-з’єднанням до Realtime API
  • SoX або ffmpeg — безкоштовні інструменти для захоплення та перетворення аудіо з мікрофона у формат PCM16
  • Visual Studio Code — редактор коду; безкоштовний, зручний для налагодження WebSocket-трафіку

📋 Покрокова інструкція

Крок 1: Отримання API-ключа та перевірка доступу до Realtime API

Зайди на platform.openai.com → натисни у лівому меню API Keys → клікни зелену кнопку Create new secret key → дай ключу назву “realtime-agent” → натисни Create secret key та одразу скопіюй значення (воно показується лише один раз). Потім перейди до Settings → Billing та переконайся, що баланс є — без поповненого рахунку Realtime API повертатиме помилку 429. Збережи ключ у файл .env у кореневій папці проєкту: OPENAI_API_KEY=sk-proj-....

Крок 2: Ініціалізація проєкту та встановлення залежностей

Відкрий термінал, створи папку проєкту та встанови пакети. Виконай по черзі: mkdir realtime-agent && cd realtime-agent, потім npm init -y, потім npm install ws dotenv node-record-lpcm16. Пакет node-record-lpcm16 захоплює аудіо з мікрофона одразу у форматі PCM16 з частотою 24000 Гц — саме такий формат очікує Realtime API. Якщо на Windows SoX не знайдено, встанови його через winget install SoX.SoX і перезапусти термінал.

Крок 3: Підключення до Realtime API через WebSocket та конфігурація сесії

Створи файл agent.js і вставте наступний код підключення та налаштування сесії:

require('dotenv').config();
const WebSocket = require('ws');

const ws = new WebSocket(
  'wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview',
  {
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'OpenAI-Beta': 'realtime=v1'
    }
  }
);

ws.on('open', () => {
  // Налаштування сесії: голосовий агент-перекладач
  ws.send(JSON.stringify({
    type: 'session.update',
    session: {
      modalities: ['audio', 'text'],
      instructions: `Ти — синхронний перекладач. 
        Якщо користувач говорить українською — перекладай англійською. 
        Якщо англійською — перекладай українською. 
        Відповідай ТІЛЬКИ перекладом, без пояснень.`,
      voice: 'alloy',
      input_audio_format: 'pcm16',
      output_audio_format: 'pcm16',
      input_audio_transcription: { model: 'whisper-1' },
      turn_detection: {
        type: 'server_vad',
        threshold: 0.5,
        silence_duration_ms: 800
      }
    }
  }));
  console.log('✅ З\'єднання встановлено, сесію налаштовано');
});

Параметр server_vad (Voice Activity Detection) — ключовий: сервер сам визначає, коли ти закінчив говорити, і не потрібно вручну надсилати сигнал кінця мовлення. Встанови silence_duration_ms: 800 — це 0.8 секунди тиші перед тим, як API почне генерувати відповідь.

Крок 4: Потокова передача аудіо з мікрофона та відтворення відповіді

Додай до agent.js код для захоплення мікрофона та обробки відповіді. Після блоку ws.on('open', ...) додай:

const record = require('node-record-lpcm16');
const { Writable } = require('stream');

// Захоплення аудіо з мікрофона і надсилання до API
const mic = record.record({ sampleRateHertz: 24000, channels: 1 });
mic.stream().on('data', (chunk) => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({
      type: 'input_audio_buffer.append',
      audio: chunk.toString('base64')
    }));
  }
});

// Обробка подій від API
ws.on('message', (data) => {
  const event = JSON.parse(data);

  if (event.type === 'conversation.item.input_audio_transcription.completed') {
    console.log('🎤 Ти сказав:', event.transcript);
  }

  if (event.type === 'response.audio.delta') {
    // Аудіо відповідь — Base64 PCM16, записуємо у буфер
    const audioChunk = Buffer.from(event.delta, 'base64');
    process.stdout.write(audioChunk); // Перенаправляємо до динаміків через pipe
  }

  if (event.type === 'response.audio_transcript.delta') {
    process.stdout.write(event.delta); // Друкуємо переклад у термінал
  }

  if (event.type === 'error') {
    console.error('❌ Помилка API:', event.error.message);
  }
});

Щоб відтворювати аудіо через динаміки, запускай скрипт з pipe до ffplay: node agent.js | ffplay -f s16le -ar 24000 -ac 1 -nodisp -. Команда ffplay із параметром -f s16le -ar 24000 розуміє сирий PCM16-потік і відтворює його без затримок.

Крок 5: Запуск агента та тестування перекладу в реальному часі

У терміналі виконай команду запуску: node agent.js | ffplay -f s16le -ar 24000 -ac 1 -nodisp -i pipe:0 2>/dev/null. Дочекайся повідомлення ✅ З’єднання встановлено, після чого говори в мікрофон — спочатку українською, потім англійською. У терміналі з’являтиметься транскрипт того, що ти сказав, а через динаміки лунатиме переклад голосом. Затримка між кінцем фрази та початком перекладу має становити 300–600 мс — це нормально для Realtime API. Якщо хочеш змінити голос агента, заміни 'alloy' на 'shimmer', 'echo', 'fable' або 'onyx' у параметрі voice в конфігурації сесії.

⚠️ Типові помилки та як їх уникнути

  • Помилка “insufficient_quota” або 429 — поповни баланс на platform.openai.com → Billing → Add payment method; Realtime API не працює на безкоштовному tier
  • Аудіо надходить із неправильною частотою дискретизації — переконайся, що SoX записує саме 24000 Гц (параметр sampleRateHertz: 24000); якщо надіслати 16000 Гц, API сприйматиме звук спотвореним і Whisper видаватиме нісенітницю
  • WebSocket закривається через 30 секунд тиші — надсилай ping кожні 20 секунд: setInterval(() => ws.ping(), 20000), інакше з’єднання обривається і доводиться переналаштовувати сесію
  • VAD спрацьовує на фонові шуми — підніми поріг до threshold: 0.7 або використовуй навушники з мікрофоном, щоб уникнути акустичного відлуння

💡 Поради для кращого результату

1. Точні інструкції в system prompt різко покращують якість. Замість “перекладай” напиши “Ти — синхронний перекладач ООН. Зберігай стиль мовлення та паузи оригіналу. Не додавай нічого від себе.” — різниця у якості перекладу буде відчутна одразу.

2. Логуй усі події WebSocket у файл під час розробки — додай fs.appendFileSync('log.jsonl', data + '\n') в обробник ws.on('message'). Так ти бачитимеш повну картину того, які події API надсилає і в якому порядку, що дуже допомагає при налагодженні.

3. Для продакшн-середовища ніколи не передавай API-ключ на фронтенд — замість цього підними проміжний Node.js-сервер, який сам з’єднується з Realtime API, а браузер підключається до твого сервера через звичайний WebSocket без ключа.

4. Використовуй conversation.item.create для ін’єкції контексту — перед початком сесії можна надіслати повідомлення з фоновою інформацією (наприклад, словник специфічних термінів), і агент враховуватиме їх під час перекладу без зайвих пояснень.

❓ Часті запитання (FAQ)

1. Чи підтримує Realtime API українську мову?
Так, модель Whisper-1, яка використовується для транскрипції вводу, підтримує українську. GPT-4o також добре розуміє та генерує українську. Однак голосовий синтез (TTS) поки що звучить природніше англійською — для критичних застосунків це варто врахувати.

2. Скільки коштує 1 година роботи агента?
За тарифами 2026 року: ~$3.60 за аудіо вводу (60 хв × $0.06) та ~$14.40 за аудіо виводу (60 хв × $0.24). Разом приблизно $18/год — але реальні сесії рідко тривають годину безперервно, тому середня сесія перекладу на 10 хвилин обходиться близько $3.

3. Чи можна використовувати Realtime API у браузері без сервера?
Технічно — так, API підтримує WebRTC-з’єднання напряму з браузера. OpenAI надає ephemeral-токени для цього через endpoint POST /v1/realtime/sessions. Але для отримання цього токена все одно потрібен бекенд, щоб не засвічувати основний API-ключ.

4. Як обмежити теми розмови, щоб агент не відповідав не по темі?
У параметрі instructions додай явну заборону: “Якщо питання не стосується перекладу — відповідай: ‘Я спеціалізуюся лише на перекладі.’ та більше нічого не пояснюй.” Realtime API поважає такі обмеження так само, як і звичайний Chat Completions API.

5. Чи можна зберігати аудіо розмови для подальшого аналізу?
Так — просто записуй усі чанки з подій response.audio.delta у масив та об’єднай їх після закінчення відповіді (подія response.audio.done). Збережи результат як WAV-файл за допомогою пакету wav: npm install wav. Транскрипти автоматично доступні через подію response.audio_transcript.done.

🏁 Підсумок

Ти навчився підключатися до OpenAI Realtime API через WebSocket, налаштовувати голосову сесію з VAD, потоково передавати аудіо з мікрофона та отримувати переклад голосом у реальному часі з затримкою менше секунди. Результат — повноцінний голосовий агент-перекладач, який реагує на живе мовлення без кнопок і ручного управління.

Почни прямо зараз із кроку 1 — отримай API-ключ і запусти мінімальний WebSocket-скрипт із кроку 3, навіть без мікрофона, просто щоб побачити живі події від API у терміналі. Це займе 10 хвилин і одразу дасть розуміння того, як працює протокол — після цього решта кроків стане очевидною.

РОЗСИЛКА

📬 Щотижневий AI-дайджест

Найкращі статті про ШІ та автоматизацію — без спаму, лише суть

Без спаму · Відписатись будь-коли

Telegram