Транскрипция в реальном времени
Непрерывно отправляйте аудио через Realtime WebSocket и получайте новые фрагменты и окончательный текст транскрипции.
Транскрипция в реальном времени принимает непрерывное аудио через постоянное соединение WebSocket и возвращает новые фрагменты текста и окончательные результаты для каждого аудиоэлемента. Она подходит для субтитров в реальном времени, записей встреч, транскрипции звонков и голосового ввода. Для однократной загрузки полной записи используйте интерфейс транскрипции аудио.
gpt-live-transcribe подходит для транскрипции фрагментами с низкой задержкой; gpt-transcribe — для высокоточной транскрипции после отправки полного речевого сегмента и может вернуть обнаруженный язык в окончательном событии. Модель в подключении и в сеансе должна совпадать.
wss://api.agtcloud.cn/v1/realtime?model=MODEL_IDАутентификация и подключение
Серверное приложение должно использовать Bearer-ключ API при рукопожатии WebSocket:
| Параметр | Значение |
|---|---|
| Адрес подключения | wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID |
| Authorization | Bearer your-api-key |
| OpenAI-Safety-Identifier | Необязательный обезличенный идентификатор конечного пользователя |
WebSocket API обычного браузера не позволяет задавать Header Authorization, поэтому не добавляйте долгосрочный ключ API во frontend HTML, JavaScript или клиентский пакет. Для браузерных продуктов соединение должен устанавливать доверенный backend либо должен применяться контролируемый механизм краткосрочных учётных данных.
Требования к входному аудио
Входное аудио в этом документе — PCM16 little-endian, 24 kHz, моно, без заголовков WAV или других контейнеров. Поле audio в input_audio_buffer.append содержит строку Base64 с необёрнутыми байтами PCM.
При отправке в реальном времени рекомендуются небольшие аудиофрагменты стабильного размера; одно событие не должно превышать 15 MiB. Ошибки формата аудио, частоты дискретизации или обработки контейнера приводят к ошибке транскрипции.
Конфигурация сеанса
В session.update поле session.type всегда равно transcription. Настройки транскрипции находятся в session.audio.input.transcription:
| Поле | Описание |
|---|---|
model | Модель транскрипции, совпадающая с моделью в URL подключения |
prompt | Подсказка о бизнес-сценарии, условиях речи и контексте |
keywords | Подсказки об именах собственных, сокращениях и названиях продуктов; принудительный вывод не гарантируется |
languages | Список ожидаемых языков, например zh-cn, en |
delay | Настройка задержки модели реального времени, например low |
noise_reduction.type=near_field подходит для гарнитуры, far_field — для переговорной комнаты или микрофона ноутбука. Значение null отключает шумоподавление.
Ручная отправка и серверный VAD
turn_detection: null: Клиент вызываетinput_audio_buffer.commitпосле отправки аудио; подходит для явного управления сегментацией в приложении.- Серверный VAD: настройте порог, аудиопрефикс и длительность тишины; сервер автоматически обнаруживает начало и окончание речи.
В ручном режиме не отправляйте пустой буфер. При включённом VAD можно обновлять интерфейс записи по speech_started и speech_stopped, но окончательную транскрипцию определяет событие completed.
Примеры подключения
Следующие примеры предполагают, что audio.pcm уже преобразован в необёрнутое аудио PCM16, 24 kHz, моно. В реальном приложении следует непрерывно отправлять небольшие аудиоблоки, а не читать полную запись за один раз.
import fs from 'node:fs';
import WebSocket from 'ws';
const ws = new WebSocket('wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID', {
headers: {
Authorization: 'Bearer your-api-key',
},
});
ws.on('open', async () => {
ws.send(JSON.stringify({
"type": "session.update",
"session": {
"type": "transcription",
"audio": {
"input": {
"format": { "type": "audio/pcm", "rate": 24000 },
"noise_reduction": { "type": "near_field" },
"transcription": {
"model": "MODEL_ID",
"prompt": "Разговор службы поддержки на китайском языке",
"keywords": ["AGTCloud", "Шлюз API"],
"languages": ["zh-cn", "en"]
},
"turn_detection": null
}
}
}
}));
const audio = fs.createReadStream('audio.pcm', { highWaterMark: 4800 });
for await (const chunk of audio) {
ws.send(JSON.stringify({
type: 'input_audio_buffer.append',
audio: chunk.toString('base64'),
}));
await new Promise((resolve) => setTimeout(resolve, 100));
}
ws.send(JSON.stringify({ type: 'input_audio_buffer.commit' }));
});
ws.on('message', (message) => {
const event = JSON.parse(message.toString());
if (event.type.endsWith('.delta')) process.stdout.write(event.delta);
if (event.type.endsWith('.completed')) console.log('\n', event.transcript);
});Справочник событий
Клиент управляет вводом через события сеанса и аудиобуфера; сервер связывает новые фрагменты, окончательный текст и ошибки по Item ID. Аудиоэлементы могут завершаться в разном порядке, поэтому объединяйте текст по item_id.
session.update
Настраивает сеанс транскрипции в реальном времени, входное аудио и способ сегментации.
| Поле | Тип | Обязательно | Описание | Пример |
|---|---|---|---|---|
event_id | string | Нет | ID события, созданный клиентом. | evt_session_001 |
type | string | Да | Всегда session.update. | session.update |
session.type | string | Да | Всегда transcription. | transcription |
session.audio.input.format.type | string | Да | На этой странице используется PCM16 little-endian. | audio/pcm |
session.audio.input.format.rate | integer | Да | Частота дискретизации входного PCM. | 24000 |
session.audio.input.noise_reduction.type | string | Нет | Шумоподавление ближнего или дальнего поля. | near_field |
session.audio.input.transcription.model | string | Да | Модель транскрипции, совпадающая с моделью в URL подключения. | MODEL_ID |
session.audio.input.transcription.prompt | string | Нет | Подсказка о сценарии и контексте транскрипции. | Разговор службы поддержки на китайском языке |
session.audio.input.transcription.keywords | string[] | Нет | Подсказки об именах собственных, сокращениях или названиях продуктов. | ["AGTCloud", "Шлюз API"] |
session.audio.input.transcription.languages | string[] | Нет | Список ожидаемых языков. | ["zh-cn", "en"] |
session.audio.input.transcription.delay | string | Нет | Настройка задержки модели реального времени. | low |
session.audio.input.turn_detection | object or null | Да | null означает ручную отправку; объект включает серверный VAD. | null |
{
"event_id": "evt_session_001",
"type": "session.update",
"session": {
"type": "transcription",
"audio": {
"input": {
"format": {
"type": "audio/pcm",
"rate": 24000
},
"noise_reduction": {
"type": "near_field"
},
"transcription": {
"model": "MODEL_ID",
"prompt": "Разговор службы поддержки на китайском языке",
"keywords": [
"AGTCloud",
"Шлюз API"
],
"languages": [
"zh-cn",
"en"
],
"delay": "low"
},
"turn_detection": null
}
}
}
}Обработка ошибок и восстановление
| Тип | Частые причины | Действия |
|---|---|---|
| Неудачное рукопожатие | Неверный адрес WSS, ключ API или Header запроса | Исправьте параметры и подключитесь заново |
| Ошибка параметров | Неверная структура сеанса, значение поля или несовпадающие модели | Прочитайте error.event_id и исправьте соответствующее клиентское событие |
| Ошибка аудио | Формат, частота дискретизации, Base64 или заголовок файла не соответствуют требованиям | Преобразуйте аудио заново и очистите буфер |
| Ошибка транскрипции | Аудио неразборчиво или обработка текущего аудиоэлемента завершилась ошибкой | Запишите Item ID ошибки и повторите только соответствующий речевой сегмент |
| Соединение прервано | Сбой сети или недействительный сеанс | Остановите отправку аудио, ограничьте число переподключений и создайте сеанс заново |
Новые фрагменты текста могут быть исправлены последующими результатами. Не сохраняйте их в неизменяемую запись при получении delta; только transcript события completed следует считать окончательным текстом текущего аудиоэлемента.