OpenAI Realtime Console dimaksudkan sebagai inspektur dan referensi API interaktif untuk OpenAI Realtime API. Muncul dikemas dengan dua perpustakaan utilitas, openai/openai-realtime-api-beta yang bertindak sebagai Klien Referensi (untuk browser dan Node.js) dan /src/lib/wavtools
yang memungkinkan manajemen audio sederhana di browser.
Ini adalah proyek React yang dibuat menggunakan create-react-app
yang dibundel melalui Webpack. Instal dengan mengekstraksi isi paket ini dan menggunakan;
$ npm i
Mulai server Anda dengan:
$ npm start
Ini harus tersedia melalui localhost:3000
.
Konsol memerlukan kunci API OpenAI ( kunci pengguna atau kunci proyek ) yang memiliki akses ke API Realtime. Anda akan diminta saat startup untuk memasukkannya. Itu akan disimpan melalui localStorage
dan dapat diubah kapan saja dari UI.
Untuk memulai sesi, Anda harus terhubung . Ini memerlukan akses mikrofon. Anda kemudian dapat memilih antara mode percakapan manual (Push-to-talk) dan vad (Deteksi Aktivitas Suara), dan beralih di antara keduanya kapan saja.
Ada dua fungsi yang diaktifkan;
get_weather
: Menanyakan cuaca di mana saja dan model akan melakukan yang terbaik untuk menunjukkan lokasi, menampilkannya di peta, dan mendapatkan cuaca untuk lokasi tersebut. Perhatikan bahwa model ini tidak memiliki akses lokasi, dan koordinat "ditebak" dari data pelatihan model sehingga akurasinya mungkin tidak sempurna.set_memory
: Anda dapat meminta model untuk mengingat informasi untuk Anda, dan model akan menyimpannya dalam gumpalan JSON di sebelah kiri.Anda dapat dengan bebas menginterupsi model kapan saja dalam mode push-to-talk atau VAD.
Jika Anda ingin membangun implementasi yang lebih kuat dan bermain-main dengan klien referensi menggunakan server Anda sendiri, kami telah menyertakan Server Relay Node.js.
$ npm run relay
Ini akan dimulai secara otomatis di localhost:8081
.
Anda perlu membuat file .env
dengan konfigurasi berikut:
OPENAI_API_KEY=YOUR_API_KEY
REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
Anda harus memulai ulang aplikasi React dan server relai untuk .env.
perubahan agar dapat diterapkan. URL server lokal dimuat melalui ConsolePage.tsx
. Untuk berhenti menggunakan server relai kapan saja, cukup hapus variabel lingkungan atau setel ke string kosong.
/**
* 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 || '' ;
Server ini hanyalah penyampaian pesan sederhana , namun dapat diperluas ke:
instructions
) di server secara langsungAnda harus menerapkan sendiri fitur-fitur ini.
Klien referensi dan dokumentasi terbaru tersedia di GitHub di openai/openai-realtime-api-beta.
Anda dapat menggunakan klien ini sendiri di proyek React (front-end) atau Node.js apa pun. Untuk dokumentasi lengkap, lihat repositori GitHub, tetapi Anda dapat menggunakan panduan di sini sebagai panduan untuk memulai.
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?` } ] ) ;
Untuk mengirim audio streaming, gunakan metode .appendInputAudio()
. Jika Anda berada dalam mode turn_detection: 'disabled'
, Anda perlu menggunakan .generate()
untuk memberi tahu model agar merespons.
// 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 ( ) ;
Bekerja dengan alat itu mudah. Panggil saja .addTool()
dan tetapkan panggilan balik sebagai parameter kedua. Callback akan dieksekusi dengan parameter alat, dan hasilnya akan secara otomatis dikirim kembali ke model.
// 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 ;
}
) ;
Anda mungkin ingin menginterupsi model secara manual, terutama dalam mode turn_detection: 'disabled'
. Untuk melakukan ini, kita dapat menggunakan:
// 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 ) ;
Metode ini akan menyebabkan model segera menghentikan pembuatan, namun juga memotong item yang sedang diputar dengan menghapus semua audio setelah sampleCount
dan menghapus respons teks. Dengan menggunakan metode ini Anda dapat menginterupsi model dan mencegahnya "mengingat" apa pun yang dihasilkannya sebelum status pengguna berada.
Ada lima peristiwa klien utama untuk alur kontrol aplikasi di RealtimeClient
. Perhatikan bahwa ini hanya ikhtisar penggunaan klien, spesifikasi acara Realtime API lengkap jauh lebih besar, jika Anda memerlukan kontrol lebih besar, periksa repositori 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 berisi pengelolaan aliran audio PCM16 yang mudah di browser, baik merekam maupun memutar.
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
Terima kasih telah memeriksa Konsol Realtime. Kami harap Anda bersenang-senang dengan Realtime API. Terima kasih khusus kepada seluruh tim Realtime API yang telah mewujudkan hal ini. Silakan menghubungi, mengajukan pertanyaan, atau memberikan masukan dengan membuat masalah di repositori. Anda juga dapat menghubungi kami dan memberi tahu kami pendapat Anda secara langsung!