Kursus
OpenAI Realtime API yang baru diperkenalkan memungkinkan kita mengintegrasikan pengalaman multimodal yang cepat dan berlatensi rendah ke dalam aplikasi kita. Dengan API ini, kita dapat menciptakan interaksi suara-ke-suara yang mulus antara pengguna dan large language models (LLM).
API ini menghilangkan kebutuhan menggunakan banyak model untuk menghadirkan pengalaman berbasis suara karena menawarkan solusi lengkap dalam satu API terintegrasi. Selain menurunkan latensi, API ini juga mempertahankan nuansa emosi dan alur percakapan yang natural.
Dalam artikel ini, kita akan mempelajari cara menggunakan OpenAI Realtime API untuk membangun asisten AI yang dikendalikan suara. Kita akan membuat koneksi WebSocket yang persisten menggunakan Node.js dan bagaimana ini dapat dimanfaatkan di terminal untuk berkomunikasi dengan API. Selain itu, saya akan memandu Anda men-deploy aplikasi React yang memanfaatkan kapabilitas API ini.
Buat API Key untuk OpenAI Realtime API
Untuk menggunakan OpenAI Realtime API, pertama-tama kita harus membuat API key. Untuk itu, buka halaman API key. Perlu dicatat bahwa Anda harus memiliki akun. Di bagian atas halaman, klik tombol “Create new secret key”.

Jendela pop-up akan terbuka. Kita dapat menggunakan opsi default dan klik “Create secret key”.

Saat key dibuat, kita diberi kesempatan untuk menyalinnya. Pastikan untuk menyalinnya sebelum menutup jendela, karena ini satu-satunya waktu key akan ditampilkan.

Jika key hilang, kita selalu dapat menghapusnya dan membuat yang baru.
Untuk menyimpan key, kami menyarankan membuat file bernama .env dan menyimpan key di sana dengan format berikut:
OPENAI_API_KEY=<paste_they_key_here>
Kita akan menggunakan file ini sepanjang artikel untuk terhubung ke API.
Pertimbangan Biaya untuk Realtime API
Sebelum melanjutkan, perhatikan bahwa Realtime API tidak gratis, dan kita perlu menambahkan kredit ke akun untuk menggunakannya. Kita dapat menambahkan kredit di halaman penagihan yang ada di profil kita.
Sebagai gambaran biaya, berikut ringkasan berapa banyak yang saya keluarkan untuk bereksperimen dengan API saat mengerjakan artikel ini:

Saya menghabiskan sekitar lima dolar secara total. Ini bukan jumlah besar, tetapi jauh lebih mahal dibandingkan API OpenAI lainnya. Harap perhatikan hal ini saat Anda mengikuti artikel ini.
Sebagian besar biaya (batang pertama) berasal dari saya mencoba aplikasi konsol React yang kita bahas di akhir artikel ini. Sisanya, sekitar setengah dolar, adalah biaya penggunaan API melalui WebSocket. Karena itu, Anda bisa mengikuti artikel ini dengan biaya kurang dari satu dolar.
Untuk detail lebih lanjut tentang harga API, lihat bagian “Realtime API” di halaman harga mereka.
Menggunakan Realtime API dengan WebSocket
Berbeda dengan komponen lain dari OpenAI API, Realtime API menggunakan WebSocket. WebSocket adalah protokol komunikasi yang membangun kanal komunikasi dua arah antara klien dan server. Berbeda dengan model request–response konvensional yang digunakan HTTP, WebSocket mendukung interaksi berkelanjutan secara real-time. Hal ini membuat WebSocket sangat cocok untuk aplikasi real-time, seperti voice chat.
Artikel ini akan membahas cara kerja WebSocket dan menyertakan beberapa contoh berinteraksi dengan Realtime API.
Kita akan menggunakan Node.js, jadi pastikan sudah terpasang di komputer Anda. Jika belum, Anda dapat mengunduh dan memasang Node.js dari situs resminya.
Inisialisasi skrip
Agar mudah mengikuti, kami menyarankan membuat folder dengan file .env yang telah dibuat di atas. Di dalam folder tersebut, jalankan perintah berikut untuk menginisialisasi skrip:
npm init -y && touch index.js
Setelah perintah selesai, file-file ini seharusnya ada di dalam folder:

Menginstal dependensi
Mulailah dengan memasang dua paket:
ws: Paket WebSocket, paket utama untuk berinteraksi dengan API.dotenv: Paket utilitas untuk memuat API key dari file.env.
Pasang dengan menjalankan perintah:
npm install ws dotenv
Menyambungkan ke Realtime API
Untuk memulai koneksi dengan Realtime API, kita membuat objek WebSocket baru dengan menyertakan URL API dan header yang berisi informasi yang diperlukan untuk terhubung:
// Import the web socket library
const WebSocket = require("ws");
// Load the .env file into memory so the code has access to the key
const dotenv = require("dotenv");
dotenv.config();
function main() {
// Connect to the API
const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01";
const ws = new WebSocket(url, {
headers: {
"Authorization": "Bearer " + process.env.OPENAI_API_KEY,
"OpenAI-Beta": "realtime=v1",
},
});
}
main();
Menetapkan aksi saat koneksi dibuka
Kode di atas membuat koneksi web socket ke API tetapi belum melakukan apa pun dengannya.
WebSocket memungkinkan kita menetapkan aksi yang dieksekusi saat peristiwa tertentu terjadi. Kita dapat menggunakan event open untuk menentukan kode yang ingin dijalankan setelah koneksi terbangun.
Sintaks umum untuk menambahkan event listener adalah sebagai berikut:
ws.on(<event>, <function>);
Ganti <event> dengan string nama event dan <function> dengan fungsi yang dijalankan saat event terjadi.
Berikut cara menampilkan teks ketika koneksi siap:
// Add inside the main() function of index.js after creating ws
async function handleOpen() {
console.log("Connection is opened");
}
ws.on("open", handleOpen);
Untuk menjalankan kode ini, gunakan perintah:
node index.js
Jika API key sudah diatur dengan benar, kita akan melihat pesan “Connection is open” di terminal. Skrip akan tetap berjalan karena koneksi masih terbuka sehingga kita harus menghentikannya secara manual.
Menetapkan aksi saat pesan diterima
Event lain yang bisa kita tanggapi saat menggunakan WebSocket adalah event message. Ini dipicu setiap kali pesan diterima dari server. Mari tambahkan fungsi yang menampilkan setiap pesan yang diterima:
// Add inside the main() function of index.js
async function handleMessage(messageStr) {
const message = JSON.parse(messageStr);
console.log(message);
}
ws.on("message", handleMessage);
Menjalankan skrip sekarang juga akan menampilkan event session.created yang dikirim API saat sesi diinisialisasi.
Event WebSocket lainnya
Di atas, kita telah mempelajari cara menambahkan event listener untuk event open dan message. WebSocket mendukung dua event tambahan yang tidak kita gunakan di contoh kita.
Event close dapat digunakan untuk menambahkan callback ketika socket ditutup:
async function handleClose() {
console.log(“Socket closed”);
}
ws.on(“close”, handleClose);
Event error digunakan untuk menambahkan callback ketika terjadi error:
async function handleError(error) {
console.log(“Error”, error);
}
ws.on(“error”, handleError);
Berkomunikasi dengan Realtime API
Bekerja dengan WebSocket mengharuskan kita untuk memrogram secara event-driven. Pesan dikirim bolak-balik pada kanal komunikasi, dan kita tidak dapat mengontrol kapan pesan-pesan tersebut dikirim atau diterima.
Kode yang memulai komunikasi harus ditambahkan di dalam handleOpen(). O Jika tidak, akan terjadi error karena kode tersebut mungkin dieksekusi sebelum kanal komunikasi web socket dibuat.
Hal yang sama berlaku untuk kode yang menangani pesan. Seluruh logika harus dimasukkan ke dalam fungsi handleMessage().
Pada contoh-contoh berikut, kita akan menggunakan kode berikut sebagai titik awal. Sebagian besar perubahan melibatkan pembaruan handleOpen() dan handleMessage().
// Import the web socket library
const WebSocket = require("ws");
// Load the .env file into memory so the code has access to the key
const dotenv = require("dotenv");
dotenv.config();
function main() {
// Connect to the API
const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01";
const ws = new WebSocket(url, {
headers: {
"Authorization": "Bearer " + process.env.OPENAI_API_KEY,
"OpenAI-Beta": "realtime=v1",
},
});
async function handleOpen() {
console.log("Connection is opened");
}
ws.on("open", handleOpen);
async function handleMessage(messageStr) {
const message = JSON.parse(messageStr);
console.log(message);
}
ws.on("message", handleMessage);
}
main();
Menggunakan Realtime API untuk mengirim dan menerima teks
Komunikasi dengan Realtime API dilakukan menggunakan event. Dokumentasi real-time OpenAI API mencantumkan event yang didukung. Kita menggunakan conversation.item.create untuk memulai percakapan. Event direpresentasikan sebagai objek JSON dengan field yang dijelaskan dalam dokumentasi.
Berikut contoh event conversation.item.create yang mengirim prompt “Explain in one sentence what a web socket is”:
const createConversationEvent = {
type: "conversation.item.create",
item: {
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "Explain in one sentence what a web socket is"
}
]
}
};
Event ini memberi tahu API bahwa kita ingin memulai percakapan tekstual. Hal ini ditentukan di field content, menggunakan tipe “input_text” dan memberikan prompt teks.
Kita menggunakan metode ws.send() untuk mengirim pesan. Paket web socket mengharapkan argumen berupa string sehingga kita perlu mengonversi event JSON menjadi string menggunakan fungsi JSON.stringify(). Jika digabungkan, berikut cara mengirim event di atas:
ws.send(JSON.stringify(createConversationEvent));
Ini akan memulai percakapan, tetapi tidak akan otomatis memicu API untuk mengirim respons. Untuk memicunya, kita mengirim event response.create. Contohnya:
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text"],
instructions: "Please assist the user.",
}
}
ws.send(JSON.stringify(createResponseEvent));
Event ini menggunakan parameter respons modalities untuk meminta respons teks. Instruksi adalah bagian terpenting yang menjelaskan apa yang kita inginkan dari model, dalam hal ini prompt generik untuk membantu pengguna.
Kita mengirim dua event ini di fungsi handleOpen() sehingga percakapan dimulai segera setelah koneksi terbangun. Berikut implementasi lengkap fungsi handleOpen() pada contoh ini:
async function handleOpen() {
// Define what happens when the connection is opened
// Create and send an event to initiate a conversation
const createConversationEvent = {
type: "conversation.item.create",
item: {
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "Explain in one sentence what a web socket is"
}
]
}
};
// Create and send an event to initiate a response
ws.send(JSON.stringify(createConversationEvent));
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text"],
instructions: "Please assist the user.",
}
}
ws.send(JSON.stringify(createResponseEvent));
}
Terkait pesan yang masuk, ada tiga jenis event yang patut diperhatikan untuk contoh ini: event response.text.delta, response.text.done, dan response.done:
- Event
response.text.deltaberisi respons yang dipecah menjadi potongan-potongan pada fielddelta. Ini penting saat kita ingin memberikan pengalaman real-time karena memungkinkan kita melakukan streaming respons potongan demi potongan seketika. - Event
response.text.donemenandai akhir respons tekstual dan berisi jawaban lengkap pada fieldtext. - Event
response.donemenandai akhir dari respons.
Kita dapat menentukan bagaimana skrip merespons event-event ini menggunakan pernyataan switch di fungsi handleMessage():
async function handleMessage(messageStr) {
const message = JSON.parse(messageStr);
// Define what happens when a message is received
switch(message.type) {
case "response.text.delta":
// We got a new text chunk, print it
process.stdout.write(message.delta);
break;
case "response.text.done":
// The text is complete, print a new line
process.stdout.write("\n");
break;
case "response.done":
// Response complete, close the socket
ws.close();
break;
}
}
Dalam contoh ini, kita menggunakan event response.text.delta untuk mencetak potongan respons ke konsol saat diterima. Ketika respons selesai, event response.text.done dipicu, dan kita mencetak baris baru untuk menandai bahwa output telah selesai. Terakhir, kita menutup web socket saat menerima event response.done.
Untuk menjalankan contoh ini, tempelkan fungsi-fungsi tersebut ke dalam kode templat di atas dan jalankan dengan perintah:
node index.js
Ini akan menghasilkan respons di terminal untuk prompt "Explain in one sentence what a web socket is", mirip seperti saat kita menggunakan ChatGPT.
Kode lengkap untuk contoh teks tersedia di sini.
Menggunakan Realtime API untuk mengirim dan menerima audio
Contoh sebelumnya menunjukkan cara menangani data teks. Namun, minat utama pada Realtime API adalah membuat asisten suara yang merespons secara real-time.
Menangani data audio sedikit lebih rumit dibandingkan data teks. Kita akan melewatkan beberapa detail spesifik audio karena dapat mengalihkan fokus dari topik utama artikel ini.
Pertama, pasang dua paket berikut:
npm install node-record-lpcm16 speaker
node-record-lpcm16merekam suara dari mikrofon sehingga kita dapat mengirim prompt suara.speakerdigunakan untuk memutar respons suara AI.
Kita juga perlu memasang SoX (Sound eXchange), utilitas command-line untuk pemrosesan audio yang digunakan library Node untuk berinteraksi dengan mikrofon dan merekam audio. Gunakan brew install sox untuk memasangnya di macOS atau sudo apt install sox di Linux.
Setelah paket-paket ini terpasang, impor dan tambahkan fungsi startRecording() yang merekam prompt audio pengguna. Kami tidak menjelaskan fungsi ini secara rinci agar tidak terlalu jauh dari pokok bahasan.
Tambahkan kode berikut ke file index.js setelah memuat environment:
// Add to index.js before the main() function
// Import the web socket library
const WebSocket = require("ws");
// Load the .env file into memory so the code has access to the key
const dotenv = require("dotenv");
dotenv.config();
const Speaker = require("speaker");
const record = require("node-record-lpcm16");
// Function to start recording audio
function startRecording() {
return new Promise((resolve, reject) => {
console.log("Speak to send a message to the assistant. Press Enter when done.");
// Create a buffer to hold the audio data
const audioData = [];
// Start recording in PCM16 format
const recordingStream = record.record({
sampleRate: 16000, // 16kHz sample rate (standard for speech recognition)
threshold: 0, // Start recording immediately
verbose: false,
recordProgram: "sox", // Specify the program
});
// Capture audio data
recordingStream.stream().on("data", (chunk) => {
audioData.push(chunk); // Store the audio chunks
});
// Handle errors in the recording stream
recordingStream.stream().on("error", (err) => {
console.error("Error in recording stream:", err);
reject(err);
});
// Set up standard input to listen for the Enter key press
process.stdin.resume(); // Start listening to stdin
process.stdin.on("data", () => {
console.log("Recording stopped.");
recordingStream.stop(); // Correctly stop the recording stream
process.stdin.pause(); // Stop listening to stdin
// Convert audio data to a single Buffer
const audioBuffer = Buffer.concat(audioData);
// Convert the Buffer to Base64
const base64Audio = audioBuffer.toString("base64");
resolve(base64Audio); // Resolve the promise with Base64 audio
});
});
};
Fungsi startRecording() merekam audio dari mikrofon dan menunggu tombol “Enter” ditekan.
Selanjutnya, kita memperbarui fungsi main() dengan menginisialisasi Speaker() yang digunakan untuk memutar respons AI:
// Add to the main() function after ws is initialized
const speaker = new Speaker({
channels: 1, // Mono or Stereo
bitDepth: 16, // PCM16 (16-bit audio)
sampleRate: 24000, // Common sample rate (44.1kHz)
});
Dengan itu, kita dapat mengimplementasikan handleOpen() dan handleMessage() untuk memproses audio.
Di fungsi handleOpen(), kita hanya perlu memanggil fungsi startRecording() untuk merekam prompt audio pengguna. Kita juga perlu sedikit memperbarui event:
- Perbarui konten
createConversationEventuntuk menggunakan tipe“input_audio”alih-alih“input_textdan ganti fieldtextdenganaudio: base64AudioData. - Tambahkan
“audio”ke modality respons dalamcreateResponseEvent.
Berikut fungsi handleOpen() yang telah diperbarui:
async function handleOpen() {
// Define what happens when the connection is opened
const base64AudioData = await startRecording();
const createConversationEvent = {
type: "conversation.item.create",
item: {
type: "message",
role: "user",
content: [
{
type: "input_audio",
audio: base64AudioData,
},
],
},
};
ws.send(JSON.stringify(createConversationEvent));
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text", "audio"],
instructions: "Please assist the user.",
},
};
ws.send(JSON.stringify(createResponseEvent));
}
Untuk mengimplementasikan fungsi handleMessage(), kita memodifikasi event “response.audio.delta” untuk memperbarui buffer audio dan memutar delta suara yang baru:
case "response.audio.delta":
// We got a new audio chunk
const base64AudioChunk = message.delta;
const audioBuffer = Buffer.from(base64AudioChunk, "base64");
speaker.write(audioBuffer);
break;
Kita menghapus event “response.text.done” dari pernyataan switch dan memperbarui event “response.done” untuk menghentikan speaker:
case "response.audio.done":
speaker.end();
ws.close();
break;
Implementasi akhir fungsi handleMessage() terlihat seperti ini:
function handleMessage(messageStr) {
const message = JSON.parse(messageStr);
// Define what happens when a message is received
switch (message.type) {
case "response.audio.delta":
// We got a new audio chunk
const base64AudioChunk = message.delta;
const audioBuffer = Buffer.from(base64AudioChunk, "base64");
speaker.write(audioBuffer);
break;
case "response.audio.done":
speaker.end();
ws.close();
break;
}
}
Untuk menjalankan contoh ini, terapkan modifikasi ini pada kode templat dan jalankan dengan perintah:
node index.js
Mikrofon akan mulai merekam. Kita dapat mengucapkan permintaan dan menekan “Enter” untuk mengirimkannya. Kemudian, respons AI akan diputar melalui speaker (pastikan mikrofon tidak dibisukan dan volume speaker cukup).
Kode lengkap untuk contoh audio tersedia di sini.
Function calling
Salah satu fitur menarik dari OpenAI API adalah kemampuan melakukan function call. Kita dapat menambahkan fungsi ke asisten dan jika asisten mendeteksi salah satu fungsi tersebut berguna untuk memberikan jawaban, ia akan mengirim event yang meminta fungsi tertentu dipanggil.
Dokumentasi OpenAI menyediakan diagram berikut yang menjelaskan siklus hidup function call:

Sumber: OpenAI
Dari diagram tersebut, kita melihat bahwa klien harus menyediakan definisi fungsi-fungsi yang dapat dipanggil LLM. Juga, eksekusi fungsi akan terjadi di sisi klien; AI akan mengirim event yang meminta fungsi dan argumennya dipanggil. Kemudian, kita bertanggung jawab mengirimkan kembali hasilnya.
Mari memperkaya asisten kita dengan fungsi yang menjumlahkan dua angka. Kita akan membangun contoh ini dengan memperluas contoh audio di atas.
Untuk menentukan fungsi yang tersedia, kita harus memberikan daftar tools kepada LLM. Setiap tool adalah objek JSON yang menentukan informasi tentang fungsi tersebut. Berikut cara mendefinisikan tool untuk fungsi penjumlahan:
const sumTool = {
type: "function",
name: "calculate_sum",
description: "Use this function when asked to add numbers together, for example when asked 'What's 4 + 6'?.",
parameters: {
type: "object",
properties: {
"a": { "type": "number" },
"b": { "type": "number" }
},
required: ["a", "b"]
}
}
Mari jelaskan struktur objeknya:
- Field
typemenyatakan bahwa kita mendefinisikan sebuah fungsi. - Field
namedigunakan untuk mengidentifikasi fungsi. Inilah yang digunakan LLM untuk memberi tahu fungsi mana yang ingin dipanggil. - Field
descriptiondigunakan untuk mengidentifikasi kapan LLM harus menggunakan fungsi ini. - Field
parametersdigunakan untuk menentukan argumen fungsi. Dalam hal ini, dua angka bernamaadanb.
Langkah berikutnya adalah mendefinisikan fungsi di kode kita. Kita akan menggunakan dictionary dengan key calculate_sum untuk memudahkan pemanggilan fungsi yang sesuai saat menanggapi event function call:
const functions = {
calculate_sum: (args) => args.a + args.b,
}
API akan menyediakan argumen fungsi sebagai dictionary dengan struktur yang sama seperti yang didefinisikan pada parameters di atas. Dalam kasus ini, untuk menjumlahkan, misalnya 3 dan 5, dictionary-nya adalah {“a”: 3, “b”: 5}.
Konstanta sumTool dan functions dapat ditambahkan di bagian atas index.js, setelah impor dan sebelum fungsi main().
Selanjutnya, kita memperbarui event response.create untuk memberi tahu LLM bahwa sumTools tersedia. Ini dilakukan dengan menambahkan field tools dan tool_choice ke response:
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text", "audio"],
instructions: "Please assist the user.",
tools: [sumTool], // New
tool_choice: "auto", // New
},
};
Saat LLM memutuskan ingin memanggil sebuah fungsi, ia akan memancarkan event response.function_call_arguments.done. Kita perlu menanggapinya dengan:
- Mendapatkan informasi fungsi dan memanggil fungsi tersebut.
- Mengirim hasil pemanggilan fungsi.
- Meminta respons.
Kita menangani ini dengan menambahkan case berikut ke pernyataan switch di dalam fungsi hanldeMessage():
case "response.function_call_arguments.done":
console.log(Using function ${message.name} with arguments ${message.arguments});
// 1. Get the function information and call the function
const function_name = message.name;
const function_arguments = JSON.parse(message.arguments);
const result = functions[function_name](function_arguments);
// 2. Send the result of the function call
const functionOutputEvent = {
type: "conversation.item.create",
item: {
type: "function_call_output",
role: "system",
output: ${result},
}
};
ws.send(JSON.stringify(functionOutputEvent));
// 3. Request a response
ws.send(JSON.stringify({type: "response.create"}));
break;
Jika sekarang kita menjalankan skrip dan meminta hasil penjumlahan dua angka, model akan memanggil fungsi tersebut dan memberikan hasilnya.
Fungsi ini relatif sederhana, tetapi karena fungsi dieksekusi oleh klien, fungsinya bisa apa saja. Pada bagian berikutnya, kita akan melihat dua contoh fungsi yang lebih kompleks.
Kode lengkap untuk contoh ini tersedia di sini.
Aplikasi Demo Menggunakan OpenAI Realtime API
Tim OpenAI menyediakan aplikasi demo React untuk memamerkan Realtime API. Di sini kita akan mempelajari cara menyiapkannya dan menelusuri cara kerjanya. Ini adalah titik awal yang bagus untuk membangun aplikasi yang lebih kompleks.
Penyiapan aplikasi
Pengetahuan React tidak diperlukan untuk menjalankannya. Namun, Anda perlu familiar dengan React untuk memodifikasi atau memperluasnya.
Aplikasi mereka di-host di repositori ini. Untuk menyiapkannya, mulai dengan meng-clone menggunakan perintah Git berikut:
git clone org-14957082@github.com:openai/openai-realtime-console.git
Sebagai alternatif, kita juga bisa mengunduhnya secara manual dari antarmuka GitHub.
Untuk memasang aplikasinya, gunakan perintah NPM (node package manager) berikut:
npm install
Setelah pemasangan selesai, buat file bernama .env di folder root proyek dan tempel konten berikut:
OPENAI_API_KEY=<openai_api_key>
REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
Ganti <openai_api_key> dengan OpenAI API key Anda.
Aplikasi kini siap dijalankan. Aplikasi terdiri dari dua bagian:
- Frontend React yang merupakan antarmuka web aplikasi.
- Relay server yang digunakan sebagai perantara antara frontend dan OpenAI API.

Tujuan utama menerapkan relay server antara frontend dan OpenAI API adalah untuk menyimpan API key dengan aman. Berinteraksi dengan API tidak mungkin tanpa key ini.
Namun, jika key disimpan di frontend, key tersebut akan dapat diakses oleh siapa saja. Karena itu, solusinya melibatkan penyiapan server yang menyimpan key dengan aman dan memfasilitasi pertukaran data antara API dan frontend. Dalam skenario khusus ini, kekhawatiran keamanan minimal karena aplikasi hanya akan dijalankan secara lokal.
Untuk menjalankan aplikasi, perlu memulai relay server dan frontend. Untuk memulai relay server, gunakan perintah berikut:
npm run relay
Untuk memulai frontend React gunakan perintah:
npm start
Setelah selesai memuat, sebuah tab akan terbuka di browser dengan aplikasi yang berjalan.

Menggunakan aplikasi
Sebelum mulai menggunakan aplikasi, pastikan komputer tidak dalam mode mute dan izinkan akses mikrofon untuk aplikasi.
Kita mulai dengan mengeklik tombol “connect”. Ini akan mengirim pesan “Hello” ke Realtime API, dan kita akan menerima sapaan.

Setelah koneksi terbangun, tombol baru akan muncul di tengah, memungkinkan kita berbicara dengan asisten AI.

Untuk menggunakannya, tekan dan bicara tanpa melepas tombol. Pesan akan dikirim saat tombol dilepas.
Aplikasi ini juga memiliki mode VAD (voice activity detection) di mana kita tidak perlu menekan tombol apa pun. Dalam mode ini, aplikasi akan mendengarkan terus-menerus sehingga kita dapat melakukan percakapan aktif dengan asisten. Untuk menggunakannya, cukup tekan tombol “vad” dan berbicara.

Fungsi
Seperti yang kita pelajari, Realtime API menawarkan fitur yang memungkinkan AI menjalankan fungsi tertentu. Demo ini menampilkan dua fungsi: satu untuk menanyakan prakiraan cuaca di lokasi tertentu dan satu lagi untuk menambahkan item memori guna mempersonalisasi asisten.
Coba fungsi-fungsi ini dengan mengajukan pertanyaan seperti “What’s the weather like tomorrow in New York?” dan menyatakan preferensi seperti “My favorite color is blue.” Asisten akan memberikan jawaban secara lisan, dan informasinya juga akan ditampilkan di sisi kanan aplikasi.

Ada kalanya saya meminta laporan cuaca, dan respons menunjukkan ketidakmampuan mengaksesnya saat itu. Namun, informasinya tetap konsisten ditampilkan di sisi kanan. Karena ini aplikasi demo, ia tidak dimaksudkan sebagai produk yang sepenuhnya fungsional, melainkan untuk menampilkan kapabilitas API.
Memahami klien
Bagian ini memerlukan pemahaman tingkat tinggi tentang React karena kita membahas beberapa detail implementasi aplikasi.
Kita akan melihat file ConsolePage.tsx. Di sinilah sebagian besar logika aplikasi didefinisikan. Aplikasi demo tidak menggunakan WebSocket mentah seperti pada contoh aplikasi baris perintah Node.js kita. Mereka membuat klien real-time yang membantu berinteraksi dengan API. Inilah yang diimpor di bagian atas file:
import { RealtimeClient } from '@openai/realtime-api-beta';
Integrasi dengan API didefinisikan dalam pemanggilan useEffect() ini. Kode di dalam useEffect() ini dijalankan saat halaman konsol pertama kali dirender. Mirip dengan skrip Node.js kita, bagian ini menjabarkan cara merespons event API. Perbedaan utamanya adalah penggunaan pembungkus klien RealtimeClient.
Mendefinisikan tools
Fungsi RealtimeClient.addTool() digunakan untuk mendefinisikan tools. Fungsi ini menerima dua parameter:
- Objek JSON definisi tool.
- Fungsi yang akan dieksekusi.
Pendekatan ini menyederhanakan integrasi tools karena klien telah siap menangani event dan mengotomatisasi pemanggilan fungsi. Tool memori didefinisikan di sini, sedangkan definisi tool cuaca didefinisikan di sini.
Sebagai contoh, untuk menambahkan sum tool yang sebelumnya didefinisikan, kita dapat melakukan hal berikut:
client.addTool(
{
name: "calculate_sum",
description: "Use this function when asked to add numbers together, for example when asked 'What's 4 + 6'?.",
parameters: {
type: "object",
properties: {
"a": { "type": "number" },
"b": { "type": "number" }
},
required: ["a", "b"]
}
},
(a: number, b: number): number => a + b
);
Perhatikan bahwa aplikasi menggunakan TypeScript, sehingga memerlukan penentuan tipe pada definisi fungsi.
Mendengarkan event
Untuk mendengarkan event, digunakan fungsi RealtimeClient.on(). Fungsi ini menerima dua parameter:
- Nama event.
- Callback yang akan dieksekusi.
Pendekatan ini mirip dengan fungsi WebSocket.on() yang digunakan sebelumnya, namun mengimplementasikan serangkaian event yang berbeda. Halaman GitHub mereka menyediakan daftar event yang didukung.
Dalam contoh khusus ini, event berikut digunakan:
- Event
realtime.eventdi sini digunakan untuk menyimpan log semua event. - Event
errordi sini hanya mencatat error ke konsol untuk tujuan debugging. - Event
conversation.interrupteddi sini digunakan untuk membatalkan permintaan ketika percakapan terputus. - Terakhir, event
conversation.updateddi sini digunakan untuk menambahkan audio baru ke aliran audio ketika potongan baru datang dari API.
Kesimpulan
Dalam tutorial ini, kita mengeksplorasi OpenAI Realtime API dan bagaimana ia menggunakan WebSocket untuk komunikasi real-time. Kita membahas penyiapan lingkungan Node.js untuk berinteraksi dengan API, mengirim dan menerima pesan teks dan audio, serta mengimplementasikan function calling untuk meningkatkan fungsionalitas.
Kita juga menjelajahi aplikasi demo React dari OpenAI, yang menunjukkan cara men-deploy aplikasi asisten suara dasar.
Untuk mempelajari lebih lanjut tentang alat pengembangan OpenAI terbaru, saya merekomendasikan tutorial berikut:

