Консоль OpenAI Realtime предназначена для использования в качестве инспектора и интерактивного справочника по API для OpenAI Realtime API. Он поставляется в комплекте с двумя служебными библиотеками: openai/openai-realtime-api-beta, которая действует как эталонный клиент (для браузера и Node.js), и /src/lib/wavtools
, которая позволяет просто управлять звуком в браузере.
Это проект React, созданный с помощью create-react-app
, который поставляется через Webpack. Установите его, распаковав содержимое этого пакета и используя;
$ npm i
Запустите свой сервер с:
$ npm start
Он должен быть доступен через localhost:3000
.
Для консоли требуется ключ API OpenAI ( ключ пользователя или ключ проекта ), который имеет доступ к API Realtime. При запуске вам будет предложено ввести его. Он будет сохранен через localStorage
и может быть изменен в любой момент из пользовательского интерфейса.
Чтобы начать сеанс, вам необходимо подключиться . Для этого потребуется доступ к микрофону. Затем вы можете выбирать между ручным режимом разговора (Push-to-talk) и vad (обнаружение голосовой активности) и переключаться между ними в любое время.
Включены две функции;
get_weather
: запросите информацию о погоде в любом месте, и модель сделает все возможное, чтобы определить это местоположение, отобразить его на карте и получить информацию о погоде для этого места. Обратите внимание, что у него нет доступа к местоположению, а координаты «угадываются» на основе обучающих данных модели, поэтому точность может быть не идеальной.set_memory
: вы можете попросить модель запомнить информацию, и она сохранит ее в JSON-объекте слева.Вы можете свободно прервать модель в любой момент в режиме «нажми и говори» или в режиме VAD.
Если вы хотите создать более надежную реализацию и поиграть с эталонным клиентом, используя свой собственный сервер, мы включили сервер ретрансляции Node.js.
$ npm run relay
Он запустится автоматически на localhost:8081
.
Вам нужно будет создать файл .env
со следующей конфигурацией:
OPENAI_API_KEY=YOUR_API_KEY
REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
Вам нужно будет перезапустить приложение React и сервер ретрансляции для .env.
изменения вступят в силу. URL-адрес локального сервера загружается через ConsolePage.tsx
. Чтобы в любой момент прекратить использование сервера ретрансляции, просто удалите переменную среды или установите для нее пустую строку.
/**
* Running a local relay server will allow you to hide your API key
* and run custom logic on the server
*
* Set the local relay server address to:
* REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
*
* This will also require you to set OPENAI_API_KEY= in a `.env` file
* You can run it with `npm run relay`, in parallel with `npm start`
*/
const LOCAL_RELAY_SERVER_URL : string =
process . env . REACT_APP_LOCAL_RELAY_SERVER_URL || '' ;
Этот сервер представляет собой всего лишь простой ретранслятор сообщений , но его можно расширить до:
instructions
), непосредственно на сервере.Вам придется реализовать эти функции самостоятельно.
Последняя версия справочного клиента и документация доступны на GitHub по адресу openai/openai-realtime-api-beta.
Вы можете использовать этот клиент самостоятельно в любом проекте React (интерфейс) или Node.js. Полную документацию можно найти в репозитории GitHub, но вы можете использовать это руководство в качестве основы для начала работы.
import { RealtimeClient } from '/src/lib/realtime-api-beta/index.js' ;
const client = new RealtimeClient ( { apiKey : process . env . OPENAI_API_KEY } ) ;
// Can set parameters ahead of connecting
client . updateSession ( { instructions : 'You are a great, upbeat friend.' } ) ;
client . updateSession ( { voice : 'alloy' } ) ;
client . updateSession ( { turn_detection : 'server_vad' } ) ;
client . updateSession ( { input_audio_transcription : { model : 'whisper-1' } } ) ;
// Set up event handling
client . on ( 'conversation.updated' , ( { item , delta } ) => {
const items = client . conversation . getItems ( ) ; // can use this to render all items
/* includes all changes to conversations, delta may be populated */
} ) ;
// Connect to Realtime API
await client . connect ( ) ;
// Send an item and triggers a generation
client . sendUserMessageContent ( [ { type : 'text' , text : `How are you?` } ] ) ;
Чтобы отправить потоковое аудио, используйте метод .appendInputAudio()
. Если вы находитесь в режиме turn_detection: 'disabled'
, вам нужно использовать .generate()
чтобы сообщить модели о необходимости ответа.
// Send user audio, must be Int16Array or ArrayBuffer
// Default audio format is pcm16 with sample rate of 24,000 Hz
// This populates 1s of noise in 0.1s chunks
for ( let i = 0 ; i < 10 ; i ++ ) {
const data = new Int16Array ( 2400 ) ;
for ( let n = 0 ; n < 2400 ; n ++ ) {
const value = Math . floor ( ( Math . random ( ) * 2 - 1 ) * 0x8000 ) ;
data [ n ] = value ;
}
client . appendInputAudio ( data ) ;
}
// Pending audio is committed and model is asked to generate
client . createResponse ( ) ;
Работать с инструментами легко. Просто вызовите .addTool()
и установите обратный вызов в качестве второго параметра. Обратный вызов будет выполнен с параметрами инструмента, а результат будет автоматически отправлен обратно в модель.
// We can add tools as well, with callbacks specified
client . addTool (
{
name : 'get_weather' ,
description :
'Retrieves the weather for a given lat, lng coordinate pair. Specify a label for the location.' ,
parameters : {
type : 'object' ,
properties : {
lat : {
type : 'number' ,
description : 'Latitude' ,
} ,
lng : {
type : 'number' ,
description : 'Longitude' ,
} ,
location : {
type : 'string' ,
description : 'Name of the location' ,
} ,
} ,
required : [ 'lat' , 'lng' , 'location' ] ,
} ,
} ,
async ( { lat , lng , location } ) => {
const result = await fetch (
`https://api.open-meteo.com/v1/forecast?latitude= ${ lat } &longitude= ${ lng } ¤t=temperature_2m,wind_speed_10m`
) ;
const json = await result . json ( ) ;
return json ;
}
) ;
Возможно, вам захочется вручную прервать модель, особенно в режиме turn_detection: 'disabled'
. Для этого мы можем использовать:
// id is the id of the item currently being generated
// sampleCount is the number of audio samples that have been heard by the listener
client . cancelResponse ( id , sampleCount ) ;
Этот метод приведет к немедленному прекращению генерации модели, а также к усечению воспроизводимого элемента путем удаления всего звука после sampleCount
и очистки текстового ответа. Используя этот метод, вы можете прервать работу модели и не дать ей «запомнить» все сгенерированное ею, что опережает состояние пользователя.
В RealtimeClient
существует пять основных клиентских событий для потока управления приложением. Обратите внимание, что это всего лишь обзор использования клиента. Полная спецификация событий API реального времени значительно больше. Если вам нужно больше контроля, посетите репозиторий GitHub: openai/openai-realtime-api-beta.
// errors like connection failures
client . on ( 'error' , ( event ) => {
// do thing
} ) ;
// in VAD mode, the user starts speaking
// we can use this to stop audio playback of a previous response if necessary
client . on ( 'conversation.interrupted' , ( ) => {
/* do something */
} ) ;
// includes all changes to conversations
// delta may be populated
client . on ( 'conversation.updated' , ( { item , delta } ) => {
// get all items, e.g. if you need to update a chat window
const items = client . conversation . getItems ( ) ;
switch ( item . type ) {
case 'message' :
// system, user, or assistant message (item.role)
break ;
case 'function_call' :
// always a function call from the model
break ;
case 'function_call_output' :
// always a response from the user / application
break ;
}
if ( delta ) {
// Only one of the following will be populated for any given event
// delta.audio = Int16Array, audio added
// delta.transcript = string, transcript added
// delta.arguments = string, function arguments added
}
} ) ;
// only triggered after item added to conversation
client . on ( 'conversation.item.appended' , ( { item } ) => {
/* item status can be 'in_progress' or 'completed' */
} ) ;
// only triggered after item completed in conversation
// will always be triggered after conversation.item.appended
client . on ( 'conversation.item.completed' , ( { item } ) => {
/* item status will always be 'completed' */
} ) ;
Wavtools обеспечивает простое управление аудиопотоками PCM16 в браузере, как записью, так и воспроизведением.
import { WavRecorder } from '/src/lib/wavtools/index.js' ;
const wavRecorder = new WavRecorder ( { sampleRate : 24000 } ) ;
wavRecorder . getStatus ( ) ; // "ended"
// request permissions, connect microphone
await wavRecorder . begin ( ) ;
wavRecorder . getStatus ( ) ; // "paused"
// Start recording
// This callback will be triggered in chunks of 8192 samples by default
// { mono, raw } are Int16Array (PCM16) mono & full channel data
await wavRecorder . record ( ( data ) => {
const { mono , raw } = data ;
} ) ;
wavRecorder . getStatus ( ) ; // "recording"
// Stop recording
await wavRecorder . pause ( ) ;
wavRecorder . getStatus ( ) ; // "paused"
// outputs "audio/wav" audio file
const audio = await wavRecorder . save ( ) ;
// clears current audio buffer and starts recording
await wavRecorder . clear ( ) ;
await wavRecorder . record ( ) ;
// get data for visualization
const frequencyData = wavRecorder . getFrequencies ( ) ;
// Stop recording, disconnects microphone, output file
await wavRecorder . pause ( ) ;
const finalAudio = await wavRecorder . end ( ) ;
// Listen for device change; e.g. if somebody disconnects a microphone
// deviceList is array of MediaDeviceInfo[] + `default` property
wavRecorder . listenForDeviceChange ( ( deviceList ) => { } ) ;
import { WavStreamPlayer } from '/src/lib/wavtools/index.js' ;
const wavStreamPlayer = new WavStreamPlayer ( { sampleRate : 24000 } ) ;
// Connect to audio output
await wavStreamPlayer . connect ( ) ;
// Create 1s of empty PCM16 audio
const audio = new Int16Array ( 24000 ) ;
// Queue 3s of audio, will start playing immediately
wavStreamPlayer . add16BitPCM ( audio , 'my-track' ) ;
wavStreamPlayer . add16BitPCM ( audio , 'my-track' ) ;
wavStreamPlayer . add16BitPCM ( audio , 'my-track' ) ;
// get data for visualization
const frequencyData = wavStreamPlayer . getFrequencies ( ) ;
// Interrupt the audio (halt playback) at any time
// To restart, need to call .add16BitPCM() again
const trackOffset = await wavStreamPlayer . interrupt ( ) ;
trackOffset . trackId ; // "my-track"
trackOffset . offset ; // sample number
trackOffset . currentTime ; // time in track
Спасибо, что ознакомились с консолью Realtime. Мы надеемся, что вам понравится API Realtime. Особая благодарность всей команде Realtime API за то, что это стало возможным. Пожалуйста, не стесняйтесь обращаться к нам, задавать вопросы или оставлять отзывы, создавая проблему в репозитории. Вы также можете связаться с нами и сообщить нам, что вы думаете напрямую!