Lewati ke konten utama

OpenAI Realtime API: Panduan dengan Contoh

Pelajari cara membangun aplikasi AI real-time dengan Realtime API dari OpenAI. Tutorial ini membahas WebSocket, setup Node.js, pengiriman/penerimaan teks/audio, function calling, dan deployment demo asisten suara React.
Diperbarui 28 Sep 2026  · 15 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

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”.

Membuat secret key baru untuk OpenAI Realtime API

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

Opsi default untuk membuat OpenAI API key

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

Menyalin OpenAI API key

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:

Biaya penggunaan OpenAI Realtime API

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:

Struktur direktori awal

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.delta berisi respons yang dipecah menjadi potongan-potongan pada field delta. Ini penting saat kita ingin memberikan pengalaman real-time karena memungkinkan kita melakukan streaming respons potongan demi potongan seketika. 
  • Event response.text.done menandai akhir respons tekstual dan berisi jawaban lengkap pada field text.
  • Event response.done menandai 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-lpcm16 merekam suara dari mikrofon sehingga kita dapat mengirim prompt suara.
  • speaker digunakan 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:

  1. Perbarui konten createConversationEvent untuk menggunakan tipe “input_audio” alih-alih “input_text dan ganti field text dengan           audio: base64AudioData.
  2. Tambahkan “audio” ke modality respons dalam createResponseEvent.

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:

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 type menyatakan bahwa kita mendefinisikan sebuah fungsi.
  • Field name digunakan untuk mengidentifikasi fungsi. Inilah yang digunakan LLM untuk memberi tahu fungsi mana yang ingin dipanggil.
  • Field description digunakan untuk mengidentifikasi kapan LLM harus menggunakan fungsi ini.
  • Field parameters digunakan untuk menentukan argumen fungsi. Dalam hal ini, dua angka bernama a dan b.

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:

  1. Mendapatkan informasi fungsi dan memanggil fungsi tersebut.
  2. Mengirim hasil pemanggilan fungsi.
  3. 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:

  1. Frontend React yang merupakan antarmuka web aplikasi.
  2. Relay server yang digunakan sebagai perantara antara frontend dan OpenAI API. 

Interaksi antara API, relay server, dan frontend

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.

Antarmuka konsol Realtime

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.

Menyambungkan ke API

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

Merekam pesan suara

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.

Berpindah ke mode voice activity detection

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.

Tampilan fungsi lokasi dan memori

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: 

  1. Nama event.
  2. 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.event di sini digunakan untuk menyimpan log semua event.
  • Event error di sini hanya mencatat error ke konsol untuk tujuan debugging.
  • Event conversation.interrupted di sini digunakan untuk membatalkan permintaan ketika percakapan terputus.
  • Terakhir, event conversation.updated di 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:


François Aubry's photo
Author
François Aubry
LinkedIn
Insinyur full-stack & pendiri di CheapGPT. Mengajar selalu menjadi passion saya. Sejak masa awal sebagai mahasiswa, saya aktif mencari peluang untuk membimbing dan membantu mahasiswa lain. Passion ini mendorong saya menempuh studi PhD, di mana saya juga menjadi asisten pengajar untuk mendukung kegiatan akademik saya. Selama tahun-tahun itu, saya menemukan kepuasan besar dalam suasana kelas tradisional, membangun koneksi dan memfasilitasi proses belajar. Namun, dengan hadirnya platform pembelajaran daring, saya melihat potensi transformatif pendidikan digital. Bahkan, saya terlibat aktif dalam pengembangan salah satu platform tersebut di universitas kami. Saya sangat berkomitmen untuk mengintegrasikan prinsip-prinsip pengajaran tradisional dengan metodologi digital yang inovatif. Tujuan saya adalah menciptakan kursus yang tidak hanya menarik dan informatif, tetapi juga mudah diakses oleh para pembelajar di era digital ini.
Topik
Kecerdasan Buatan
OpenAI
Large Language Models

Pelajari cara mengembangkan aplikasi AI!

Kursus

Mengembangkan Aplikasi LLM dengan LangChain

3 jam
52K
Temukan cara membangun aplikasi bertenaga AI menggunakan LLM, prompt, chain, dan agent di LangChain.
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

Lihat SelengkapnyaLihat Selengkapnya