WebSockets के साथ Realtime API का उपयोग
OpenAI API के अन्य घटकों के विपरीत, Realtime API WebSockets का उपयोग करता है। WebSockets एक संचार प्रोटोकॉल है जो क्लाइंट और सर्वर के बीच द्विदिश संचार चैनल स्थापित करता है। HTTP द्वारा उपयोग किए जाने वाले पारंपरिक रिक्वेस्ट-रिस्पॉन्स मॉडल के विपरीत, WebSockets निरंतर, रियल-टाइम इंटरेक्शन का समर्थन करते हैं। यह WebSockets को वॉइस चैट जैसे रियल-टाइम एप्लिकेशन के लिए विशेष रूप से उपयुक्त बनाता है।
यह लेख बताएगा कि WebSockets कैसे काम करते हैं और Realtime API के साथ इंटरेक्ट करने के कई उदाहरण शामिल करेगा।
हम Node.js का उपयोग करने जा रहे हैं, इसलिए सुनिश्चित करें कि यह हमारे कंप्यूटर पर इंस्टॉल है। यदि नहीं, तो हम Node.js को इसके आधिकारिक वेबसाइट से डाउनलोड और इंस्टॉल कर सकते हैं।
स्क्रिप्ट आरंभ करना
साथ चलने के लिए, हम ऊपर बनाई गई .env फ़ाइल के साथ एक फ़ोल्डर बनाने की सलाह देते हैं। उस फ़ोल्डर के अंदर, स्क्रिप्ट आरंभ करने के लिए निम्न कमांड चलाएँ:
npm init -y && touch index.js
इस कमांड के पूरा होने के बाद, इन फ़ाइलों को फ़ोल्डर के अंदर होना चाहिए:

डिपेंडेंसी इंस्टॉल करना
दो पैकेज इंस्टॉल करके शुरू करें:
ws: यह WebSocket पैकेज है, API के साथ इंटरेक्ट करने के लिए मुख्य पैकेज।dotenv: एक यूटिलिटी पैकेज जो.envफ़ाइल से API कुंजी लोड करता है।
इन्हें निम्न कमांड चलाकर इंस्टॉल करें:
npm install ws dotenv
Realtime API से कनेक्ट करना
Realtime API से कनेक्शन शुरू करने के लिए, हम API URL पास करते हुए और कनेक्ट होने के लिए आवश्यक जानकारी वाले हेडर्स के साथ एक नया WebSocket ऑब्जेक्ट बनाते हैं:
// 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();
कनेक्शन खुलने पर एक कार्रवाई सेट करना
ऊपर का कोड API के लिए वेब सॉकेट कनेक्शन बनाता है लेकिन अभी उसके साथ कुछ नहीं करता।
WebSockets हमें कुछ घटनाएँ होने पर निष्पादित की जाने वाली कार्रवाइयाँ सेट करने की अनुमति देता है। हम open इवेंट का उपयोग यह निर्दिष्ट करने के लिए कर सकते हैं कि कनेक्शन स्थापित होने पर कौन-सा कोड चलाना है।
इवेंट लिस्नर जोड़ने का सामान्य सिंटैक्स इस प्रकार है:
ws.on(<event>, <function>);
यहाँ <event> को इवेंट के नाम वाले स्ट्रिंग से और <function> को उस फंक्शन से बदलें जिसे इवेंट होने पर निष्पादित होना है।
यहाँ बताया गया है कि कनेक्शन तैयार होने पर हम टेक्स्ट कैसे दिखा सकते हैं:
// Add inside the main() function of index.js after creating ws
async function handleOpen() {
console.log("Connection is opened");
}
ws.on("open", handleOpen);
इस कोड को चलाने के लिए, हम यह कमांड उपयोग करते हैं:
node index.js
यदि API कुंजी सही से सेट है, तो हमें टर्मिनल में “Connection is open” संदेश दिखाई देगा। स्क्रिप्ट चलती रहेगी क्योंकि कनेक्शन अभी भी खुला है, इसलिए हमें इसे मैन्युअली रोकना होगा।
संदेश प्राप्त होने पर कार्रवाई सेट करना
WebSockets का उपयोग करते समय हम जिस अन्य इवेंट पर प्रतिक्रिया दे सकते हैं वह message इवेंट है। यह हर बार ट्रिगर होता है जब सर्वर से कोई संदेश प्राप्त होता है। आइए प्रत्येक प्राप्त संदेश को प्रदर्शित करने वाला एक फंक्शन जोड़ें:
// Add inside the main() function of index.js
async function handleMessage(messageStr) {
const message = JSON.parse(messageStr);
console.log(message);
}
ws.on("message", handleMessage);
अब स्क्रिप्ट चलाने पर session.created इवेंट भी दिखना चाहिए, जो सत्र के प्रारंभ होने पर API द्वारा भेजा जाता है।
अन्य WebSocket इवेंट
ऊपर, हमने open और message इवेंट्स पर इवेंट लिस्नर जोड़ना सीखा। WebSockets दो अतिरिक्त इवेंट्स का समर्थन करता है जिन्हें हम अपने उदाहरणों में उपयोग नहीं करेंगे।
close इवेंट का उपयोग सॉकेट बंद होने पर कॉलबैक जोड़ने के लिए किया जा सकता है:
async function handleClose() {
console.log(“Socket closed”);
}
ws.on(“close”, handleClose);
error इवेंट का उपयोग तब किया जाता है जब कोई त्रुटि होती है तो कॉलबैक जोड़ने के लिए:
async function handleError(error) {
console.log(“Error”, error);
}
ws.on(“error”, handleError);
Realtime API के साथ संवाद करना
WebSockets के साथ काम करने के लिए हमें इवेंट-ड्रिवन तरीके से प्रोग्राम करना पड़ता है। संदेश संचार चैनल पर आगे-पीछे भेजे जाते हैं, और हम नियंत्रित नहीं कर सकते कि ये संदेश कब भेजे या प्राप्त किए जाएंगे।
संचार शुरू करने वाला कोड handleOpen() के अंदर जोड़ा जाना चाहिए। O अन्यथा, एक त्रुटि हो सकती है क्योंकि वह कोड वेब सॉकेट संचार चैनल बनने से पहले निष्पादित हो सकता है।
संदेशों को हैंडल करने वाले कोड के लिए भी यही सच है। पूरी लॉजिक handleMessage() फंक्शन में जानी चाहिए।
आने वाले उदाहरणों में, हम निम्न कोड को शुरुआती बिंदु के रूप में उपयोग करेंगे। अधिकांश परिवर्तन handleOpen() और 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();
Realtime API का उपयोग करके टेक्स्ट भेजना और प्राप्त करना
Realtime API के साथ संचार इवेंट्स का उपयोग करके होता है। OpenAI की रियल-टाइम डॉक्यूमेंटेशन API समर्थित इवेंट्स की सूची देता है। हम conversation.item.create इवेंट का उपयोग बातचीत शुरू करने के लिए करते हैं। इवेंट्स JSON ऑब्जेक्ट के रूप में प्रस्तुत किए जाते हैं जिनके फ़ील्ड डॉक्यूमेंटेशन में वर्णित हैं।
यहाँ एक conversation.item.create इवेंट का उदाहरण है जो संकेत भेजता है: ”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"
}
]
}
};
यह इवेंट API को बताता है कि हम एक टेक्स्टुअल बातचीत शुरू करना चाहते हैं। यह content फ़ील्ड में निर्दिष्ट है, जहाँ ”input_text” टाइप का उपयोग करते हुए टेक्स्ट प्रॉम्प्ट प्रदान किया गया है।
संदेश भेजने के लिए हम ws.send() मेथड का उपयोग करते हैं। वेब सॉकेट पैकेज तर्क के रूप में एक स्ट्रिंग की अपेक्षा करता है, इसलिए हमें अपने JSON इवेंट को JSON.stringify() फंक्शन का उपयोग करके स्ट्रिंग में परिवर्तित करना होगा। इन्हें एक साथ रखते हुए, ऊपर का इवेंट भेजने का तरीका इस प्रकार है:
ws.send(JSON.stringify(createConversationEvent));
यह बातचीत शुरू करेगा, लेकिन यह स्वचालित रूप से हमें API से प्रतिक्रिया भेजने के लिए ट्रिगर नहीं करेगा। प्रतिक्रिया ट्रिगर करने के लिए, हम response.create इवेंट भेजते हैं। उदाहरण:
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text"],
instructions: "Please assist the user.",
}
}
ws.send(JSON.stringify(createResponseEvent));
यह इवेंट modalities रिस्पॉन्स पैरामीटर का उपयोग करके टेक्स्टुअल प्रतिक्रिया का अनुरोध करता है। निर्देश सबसे महत्वपूर्ण भाग हैं, जो बताते हैं कि हम मॉडल से क्या करवाना चाहते हैं—इस मामले में, उपयोगकर्ता की सहायता करने के लिए सामान्य प्रॉम्प्ट।
हम इन दोनों इवेंट्स को handleOpen() फंक्शन में भेजते हैं ताकि कनेक्शन स्थापित होते ही बातचीत शुरू हो जाए। इस उदाहरण से handleOpen() फंक्शन का पूर्ण इम्प्लीमेंटेशन यहाँ है:
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));
}
इनकमिंग संदेशों के संदर्भ में, इस उदाहरण के लिए ध्यान देने योग्य तीन प्रकार के इवेंट हैं: response.text.delta, response.text.done, और response.done इवेंट्स:
-
response.text.deltaइवेंट्स में प्रतिक्रिया कोdeltaफ़ील्ड में टुकड़ों में तोड़कर भेजा जाता है। जब हम रियल-टाइम अनुभव प्रदान करना चाहते हैं तो ये महत्वपूर्ण होते हैं क्योंकि ये हमें प्रतिक्रिया को टुकड़ा-दर-टुकड़ा स्ट्रीम करने की अनुमति देते हैं। -
response.text.doneइवेंट टेक्स्टुअल प्रतिक्रिया के अंत को चिह्नित करता है औरtextफ़ील्ड में पूर्ण उत्तर रखता है। -
response.doneइवेंट प्रतिक्रिया के अंत को चिह्नित करता है।
हम यह निर्दिष्ट कर सकते हैं कि हमारी स्क्रिप्ट इन इवेंट्स पर कैसे प्रतिक्रिया दे, इसके लिए handleMessage() फंक्शन में switch स्टेटमेंट का उपयोग करें:
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;
}
}
इस उदाहरण में, हम response.text.delta इवेंट का उपयोग जैसे-जैसे प्रतिक्रियाएँ मिलती हैं, उनके टुकड़े कंसोल में प्रिंट करने के लिए करते हैं। जब प्रतिक्रिया पूरी हो जाती है, तो response.text.done इवेंट ट्रिगर होता है, और हम एक नई लाइन प्रिंट करते हैं ताकि आउटपुट का समापन दिखे। अंत में, response.done इवेंट प्राप्त होने पर हम वेब सॉकेट को बंद कर देते हैं।
इस उदाहरण को चलाने के लिए, इन फंक्शन्स को ऊपर दिए टेम्पलेट कोड में पेस्ट करें और निम्न कमांड से चलाएँ:
node index.js
यह टर्मिनल में प्रॉम्प्ट "Explain in one sentence what a web socket is" का उत्तर जेनरेट करेगा, ठीक वैसे ही जैसे हम ChatGPT का उपयोग करते समय होता है।
टेक्स्ट उदाहरण का पूरा कोड यहाँ उपलब्ध है।
Realtime API का उपयोग करके ऑडियो भेजना और प्राप्त करना
पिछले उदाहरण ने दिखाया कि हम टेक्स्ट डेटा को कैसे हैंडल करते हैं। हालाँकि, Realtime API में वास्तविक दिलचस्पी एक ऐसे वॉइस असिस्टेंट बनाने में है जो रियल-टाइम में जवाब देता है।
ऑडियो डेटा को हैंडल करना टेक्स्टुअल डेटा की तुलना में थोड़ा अधिक जटिल है। हम ऑडियो कैसे काम करता है, उससे संबंधित कुछ विवरणों को छोड़ देंगे क्योंकि वे हमें इस लेख के मुख्य विषय से भटका देंगे।
पहले, हम दो पैकेज इंस्टॉल करते हैं:
npm install node-record-lpcm16 speaker
node-record-lpcm16माइक्रोफ़ोन से ध्वनि रिकॉर्ड करता है ताकि हम वॉइस प्रॉम्प्ट भेज सकें।speakerAI की वॉइस प्रतिक्रिया चलाने के लिए उपयोग होता है।
हमें SoX (Sound eXchange) भी इंस्टॉल करनी होगी, जो एक कमांड-लाइन यूटिलिटी है जिसे नोड लाइब्रेरी माइक्रोफ़ोन से इंटरफ़ेस करने और ऑडियो रिकॉर्ड करने के लिए उपयोग करेगी। macOS पर इंस्टॉल करने के लिए brew install sox या Linux पर sudo apt install sox का उपयोग करें।
इन पैकेजों के इंस्टॉल हो जाने के बाद, हम इन्हें इम्पोर्ट करते हैं और एक startRecording() फंक्शन जोड़ते हैं जो उपयोगकर्ता के ऑडियो प्रॉम्प्ट को रिकॉर्ड करता है। हम इस फंक्शन का विस्तार से वर्णन नहीं करेंगे क्योंकि यह हमें मुख्य विषय से काफी हद तक भटका देगा।
पर्यावरण लोड करने के बाद निम्न कोड index.js फ़ाइल में जोड़ें:
// 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
});
});
};
startRecording() फंक्शन माइक्रोफ़ोन से ऑडियो रिकॉर्ड करता है और “Enter” दबाए जाने का इंतज़ार करता है।
इसके बाद, हम Speaker() को इनिशियलाइज़ करके main() फंक्शन को अपडेट करते हैं, जो 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)
});
यह हो जाने के बाद, हम handleOpen() और handleMessage() को ऑडियो प्रोसेस करने के लिए इम्प्लीमेंट कर सकते हैं।
handleOpen() फंक्शन में, हमें केवल उपयोगकर्ता के ऑडियो प्रॉम्प्ट को रिकॉर्ड करने के लिए startRecording() को कॉल करना है। हमें इवेंट्स को थोड़ा अपडेट करने की भी आवश्यकता है:
-
createConversationEventकी सामग्री को”input_textकी जगह”input_audio”टाइप उपयोग करने के लिए अपडेट करें औरtextफ़ील्ड कोaudio: base64AudioDataसे बदलें। -
createResponseEventमें रिस्पॉन्स मॉडैलिटी में”audio”जोड़ें।
यहाँ अपडेट किया गया handleOpen() फंक्शन है:
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));
}
handleMessage() फंक्शन को इम्प्लीमेंट करने के लिए, हम ”response.audio.delta” इवेंट को संशोधित करते हैं ताकि ऑडियो बफ़र अपडेट हो और नया साउंड डेल्टा चलाया जा सके:
case "response.audio.delta":
// We got a new audio chunk
const base64AudioChunk = message.delta;
const audioBuffer = Buffer.from(base64AudioChunk, "base64");
speaker.write(audioBuffer);
break;
हम ”response.text.done” इवेंट को स्विच स्टेटमेंट से हटा देते हैं और ”response.done” इवेंट को स्पीकर रोकने के लिए अपडेट करते हैं:
case "response.audio.done":
speaker.end();
ws.close();
break;
handleMessage() फंक्शन का अंतिम इम्प्लीमेंशन इस प्रकार दिखता है:
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;
}
}
इस उदाहरण को चलाने के लिए, इन संशोधनों को टेम्पलेट कोड पर लागू करें और निम्न कमांड से चलाएँ:
node index.js
माइक्रोफ़ोन रिकॉर्डिंग शुरू कर देगा। हम अपना अनुरोध बोल सकते हैं और उसे भेजने के लिए “Enter” दबा सकते हैं। फिर AI की प्रतिक्रिया स्पीकर पर चलेगी (सुनिश्चित करें कि माइक्रोफ़ोन म्यूट न हो और स्पीकर की वॉल्यूम हो)।
ऑडियो उदाहरण का पूरा कोड यहाँ उपलब्ध है।
फंक्शन कॉलिंग
OpenAI API की एक बढ़िया विशेषता है फंक्शन कॉल करने की क्षमता। हम असिस्टेंट में फंक्शन जोड़ सकते हैं और यदि उसे लगता है कि किसी फंक्शन का उपयोग उत्तर देने में सहायक होगा, तो वह एक इवेंट भेजेगा जिसमें किसी विशेष फंक्शन को कॉल करने का अनुरोध होगा।
OpenAI डॉक्यूमेंटेशन फंक्शन कॉल के जीवन-चक्र को समझाने वाला निम्न आरेख प्रदान करता है:

स्रोत: OpenAI
आरेख से हम देखते हैं कि क्लाइंट को उन फंक्शन्स की परिभाषाएँ प्रदान करनी होती हैं जिन्हें LLM कॉल कर सकता है। साथ ही, फंक्शन का निष्पादन क्लाइंट साइड पर होगा; AI फंक्शन को कॉल करने और उसके आर्गुमेंट भेजने का अनुरोध करने वाला इवेंट भेजेगा। फिर, परिणाम वापस भेजना हमारी ज़िम्मेदारी है।
आइए अपने असिस्टेंट को एक ऐसे फंक्शन से सक्षम करें जो दो संख्याओं को जोड़ता है। हम यह उदाहरण ऊपर दिए ऑडियो उदाहरण का विस्तार करके बनाएँगे।
उपलब्ध फंक्शन्स को निर्दिष्ट करने के लिए, हमें LLM को टूल्स की एक सूची प्रदान करनी होगी। प्रत्येक टूल एक JSON ऑब्जेक्ट होता है जो फंक्शन के बारे में जानकारी निर्दिष्ट करता है। यहाँ सम फंक्शन के लिए एक टूल को कैसे परिभाषित किया जा सकता है:
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"]
}
}
आइए ऑब्जेक्ट संरचना समझें:
-
typeनिर्दिष्ट करता है कि हम एक फंक्शन परिभाषित कर रहे हैं। -
nameफंक्शन की पहचान के लिए उपयोग होता है। LLM इसी से हमें बताता है कि वह कौन-सा फंक्शन कॉल करना चाहता है। -
descriptionका उपयोग यह पहचानने के लिए होता है कि LLM को यह फंक्शन कब उपयोग करना चाहिए। -
parametersफंक्शन के आर्गुमेंट्स को निर्दिष्ट करते हैं। इस मामले में,aऔरbनामक दो संख्याएँ।
अगला चरण हमारे कोड में फंक्शन परिभाषित करना है। हम calculate_sum की कुंजी के साथ एक डिक्शनरी का उपयोग करेंगे ताकि जब हम फंक्शन कॉल इवेंट का जवाब दें तो उचित फंक्शन को कॉल करना आसान हो जाए:
const functions = {
calculate_sum: (args) => args.a + args.b,
}
API फंक्शन आर्गुमेंट्स को उसी संरचना वाले डिक्शनरी के रूप में प्रदान करेगा जैसा कि ऊपर parameters में परिभाषित है। इस मामले में, मान लें 3 और 5 जोड़ने के लिए, डिक्शनरी {“a”: 3, “b”: 5} होगी।
sumTool और functions कॉन्स्टेंट्स को index.js के शीर्ष पर, इम्पोर्ट्स के बाद और main() फंक्शन से पहले जोड़ा जा सकता है।
अगला, हम response.create इवेंट को अपडेट करते हैं ताकि LLM को पता चले कि sumTools उपलब्ध है। यह response में tools और tool_choice फ़ील्ड जोड़कर किया जाता है:
const createResponseEvent = {
type: "response.create",
response: {
modalities: ["text", "audio"],
instructions: "Please assist the user.",
tools: [sumTool], // New
tool_choice: "auto", // New
},
};
जब LLM निर्णय लेता है कि वह कोई फंक्शन कॉल करना चाहता है, तो वह response.function_call_arguments.done इवेंट एमिट करेगा। हमें इसका उत्तर इस प्रकार देना है:
- फंक्शन की जानकारी लेना और फंक्शन को कॉल करना।
- फंक्शन कॉल का परिणाम भेजना।
- प्रतिक्रिया का अनुरोध करना।
हम इसे hanldeMessage() फंक्शन के अंदर switch स्टेटमेंट में निम्न केस जोड़कर हैंडल करते हैं:
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;
यदि हम अब स्क्रिप्ट चलाएँ और दो संख्याओं के योग का परिणाम माँगें, तो मॉडल को फंक्शन कॉल करना चाहिए और परिणाम प्रदान करना चाहिए।
यह फंक्शन अपेक्षाकृत सरल है, लेकिन क्योंकि फंक्शन क्लाइंट द्वारा निष्पादित होता है, यह कुछ भी हो सकता है। अगले सेक्शन में, हम अधिक जटिल फंक्शन्स के दो उदाहरण देखेंगे।
इस उदाहरण का पूरा कोड यहाँ उपलब्ध है।
OpenAI Realtime API का उपयोग करने वाला डेमो ऐप
OpenAI टीम Realtime API को प्रदर्शित करने के लिए एक डेमो React ऐप प्रदान करती है। यहाँ हम इसे सेटअप करना और यह कैसे काम करता है, इसका पता लगाएंगे। यह एक अधिक जटिल ऐप बनाने के लिए बेहतरीन शुरुआती बिंदु है।
ऐप सेटअप
इसे चलाने के लिए React का ज्ञान आवश्यक नहीं है। हालाँकि, इसे संशोधित या विस्तारित करने के लिए आपको React से परिचित होना होगा।
उनका ऐप इस रिपॉज़िटरी में होस्ट किया गया है। इसे सेट करने के लिए, निम्न क्लोनिंग Git कमांड का उपयोग करते हुए शुरू करें:
git clone [email protected]:openai/openai-realtime-console.git
वैकल्पिक रूप से, हम इसे GitHub इंटरफ़ेस से मैन्युअली भी डाउनलोड कर सकते हैं।
ऐप इंस्टॉल करने के लिए, हम निम्न NPM (node package manage) कमांड का उपयोग करते हैं:
npm install
इंस्टॉलेशन पूरा हो जाने पर, प्रोजेक्ट के रूट फ़ोल्डर में .env नामक एक फ़ाइल बनाएँ और निम्न सामग्री पेस्ट करें:
OPENAI_API_KEY=<openai_api_key>
REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
<openai_api_key> को OpenAI API कुंजी से बदलें।
एप्लिकेशन अब चलने के लिए तैयार होना चाहिए। यह दो भागों से बना है:
- एक React फ्रंटएंड जो एप्लिकेशन का वेब यूज़र इंटरफ़ेस है।
- एक रिले सर्वर जो फ्रंटएंड और OpenAI API के बीच मध्यस्थ के रूप में उपयोग होता है।

फ्रंटएंड और OpenAI API के बीच रिले सर्वर लागू करने का प्राथमिक उद्देश्य API कुंजी को सुरक्षित रूप से संग्रहीत करना है। इस कुंजी के बिना API के साथ इंटरेक्ट करना असंभव है।
हालाँकि, यदि कुंजी फ्रंटएंड पर संग्रहीत की जाती, तो यह किसी भी उपयोगकर्ता के लिए सुलभ होती। इसलिए, समाधान में एक ऐसा सर्वर सेटअप करना शामिल है जो कुंजी को सुरक्षित रूप से संग्रहीत करता है और API और फ्रंटएंड के बीच डेटा विनिमय की सुविधा देता है। इस विशेष परिदृश्य में, सुरक्षा चिंताएँ न्यूनतम हैं क्योंकि एप्लिकेशन केवल लोकली चलाया जाएगा।
एप्लिकेशन लॉन्च करने के लिए, रिले सर्वर और फ्रंटएंड दोनों को प्रारंभ करना आवश्यक है। रिले सर्वर शुरू करने के लिए निम्न कमांड का उपयोग करें:
npm run relay
React फ्रंटएंड शुरू करने के लिए यह कमांड उपयोग करें:
npm start
लोडिंग पूरा होने के बाद, ब्राउज़र में एक टैब खुलेगा जिसमें एप्लिकेशन चल रहा होगा।

ऐप का उपयोग
ऐप का उपयोग शुरू करने से पहले, सुनिश्चित करें कि कंप्यूटर म्यूट न हो और एप्लिकेशन को माइक्रोफ़ोन एक्सेस की अनुमति दें।
हम “connect” बटन पर क्लिक करके शुरू करते हैं। यह Realtime API को “Hello” संदेश भेजेगा, और हमें एक अभिवादन प्राप्त होगा।

कनेक्शन स्थापित होने पर, केंद्र में एक नया बटन दिखाई देगा, जो हमें AI असिस्टेंट से बात करने की अनुमति देगा।

इसे उपयोग करने के लिए, बटन को दबाएँ और छोड़े बिना बात करें। बटन छोड़ने पर संदेश भेज दिया जाता है।
एप्लिकेशन में VAD (वॉइस एक्टिविटी डिटेक्शन) मोड भी है जिसमें हमें कोई बटन दबाने की आवश्यकता नहीं होती। इस मोड में, एप्लिकेशन लगातार सुनता है जिससे हम असिस्टेंट के साथ सक्रिय बातचीत कर सकते हैं। इसका उपयोग करने के लिए, बस “vad” बटन दबाएँ और बोलें।

फंक्शन्स
जैसा कि हमने सीखा, Realtime API एक ऐसी सुविधा प्रदान करता है जो AI को विशिष्ट फंक्शन्स करने में सक्षम बनाती है। यह डेमो दो फंक्शन्स दिखाता है: किसी स्थान में मौसम पूर्वानुमान पूछने के लिए एक और असिस्टेंट को वैयक्तिकृत करने के लिए मेमोरी आइटम जोड़ने के लिए दूसरा।
इन फंक्शन्स का अनुभव “What’s the weather like tomorrow in New York?” जैसे प्रश्न पूछकर और “My favorite color is blue.” जैसी प्राथमिकताएँ बताकर करें। असिस्टेंट इन प्रश्नों के मौखिक उत्तर देगा, और जानकारी एप्लिकेशन के दाहिने भाग में भी प्रदर्शित होगी।

कभी-कभी मैंने मौसम रिपोर्ट का अनुरोध किया, और प्रतिक्रिया में उस समय उसे एक्सेस न कर पाने की सूचना मिली। हालाँकि, जानकारी हमेशा दाहिने तरफ प्रदर्शित होती रही। चूँकि यह एक डेमो ऐप है, इसका उद्देश्य पूरी तरह कार्यात्मक उत्पाद होना नहीं है, बल्कि API की क्षमताओं को प्रदर्शित करना है।
क्लाइंट को समझना
इस सेक्शन को फॉलो करने के लिए React की उच्च-स्तरीय समझ आवश्यक है क्योंकि हम एप्लिकेशन के कुछ इम्प्लीमेंटेशन विवरण कवर करेंगे।
हम ConsolePage.tsx फ़ाइल देखेंगे। यहीं अधिकांश एप्लिकेशन लॉजिक परिभाषित है। डेमो ऐप हमारे Node.js कमांड लाइन ऐप उदाहरणों की तरह कच्चे WebSockets का उपयोग नहीं करता। उन्होंने एक रियल-टाइम क्लाइंट बनाया है जो API के साथ इंटरेक्ट करने में मदद करता है। यही फ़ाइल के शीर्ष पर इम्पोर्ट किया गया है:
import { RealtimeClient } from '@openai/realtime-api-beta';
API के साथ इंटीग्रेशन इस useEffect() कॉल में परिभाषित है। इस useEffect() के भीतर का कोड कंसोल पेज के प्रारंभिक रेंडर पर निष्पादित होता है। हमारे Node.js स्क्रिप्ट के समान, यह बताता है कि API इवेंट्स पर कैसे प्रतिक्रिया देनी है। मुख्य अंतर इसका RealtimeClient क्लाइंट रैपर का उपयोग है।
टूल्स परिभाषित करना
RealtimeClient.addTool() फंक्शन का उपयोग टूल्स को परिभाषित करने के लिए किया जाता है। यह दो पैरामीटर्स लेता है:
- टूल डेफिनिशन JSON ऑब्जेक्ट।
- निष्पादित होने वाला फंक्शन।
यह तरीका टूल्स के इंटीग्रेशन को सरल बनाता है क्योंकि क्लाइंट पहले से ही इवेंट्स को हैंडल करने और फंक्शन इन्वोकेशन को ऑटोमेट करने से लैस है। मेमोरी टूल यहाँ परिभाषित है, जबकि वेदर टूल की परिभाषा यहाँ है।
उदाहरण के लिए, पहले परिभाषित सम टूल जोड़ने के लिए, हम निम्न कर सकते हैं:
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
);
ध्यान दें कि एप्लिकेशन TypeScript का उपयोग करता है, इसलिए फंक्शन डेफिनिशन में टाइप्स निर्दिष्ट करना आवश्यक है।
इवेंट्स सुनना
किसी इवेंट को सुनने के लिए, RealtimeClient.on() फंक्शन का उपयोग किया जाता है। यह दो पैरामीटर्स स्वीकार करता है:
- इवेंट का नाम।
- निष्पादित होने वाला कॉलबैक फंक्शन।
यह तरीका पहले उपयोग किए गए WebSocket.on() फंक्शन के समान है, बस यह अलग सेट के इवेंट्स इम्प्लीमेंट करता है। उनका GitHub पेज समर्थित इवेंट्स की सूची प्रदान करता है।
इस विशेष उदाहरण में निम्न इवेंट्स का उपयोग होता है:
realtime.eventइवेंट यहाँ सभी इवेंट्स का लॉग रखने के लिए उपयोग होता है।errorइवेंट यहाँ केवल डिबगिंग उद्देश्यों के लिए त्रुटियों को कंसोल में लॉग करता है।conversation.interruptedइवेंट यहाँ बातचीत बाधित होने पर अनुरोधों को रद्द करने के लिए उपयोग होता है।- अंत में,
conversation.updatedइवेंट यहाँ तब ऑडियो स्ट्रीम में नया ऑडियो जोड़ने के लिए उपयोग होता है जब API से नए चंक्स आते हैं।
निष्कर्ष
इस ट्यूटोरियल में, हमने OpenAI Realtime API और रियल-टाइम संचार के लिए इसके WebSockets उपयोग का अन्वेषण किया। हमने API के साथ इंटरेक्ट करने के लिए Node.js वातावरण की सेटअप, टेक्स्ट और ऑडियो संदेश भेजना-प्राप्त करना, और उन्नत कार्यक्षमता के लिए फंक्शन कॉलिंग को इम्प्लीमेंट करना कवर किया।
हमने OpenAI के डेमो React ऐप का भी अन्वेषण किया, जो एक बुनियादी वॉइस असिस्टेंट एप्लिकेशन को डिप्लॉय करना प्रदर्शित करता है।
OpenAI के नवीनतम डेवलपमेंट टूल्स के बारे में और जानने के लिए, मैं ये ट्यूटोरियल्स सुझाता हूँ:

नए पेश किए गए OpenAI Realtime API हमें अपने एप्लिकेशन में तेज, कम-विलंबता, मल्टीमोडल अनुभवों को एकीकृत करने में सक्षम बनाता है। इस API के साथ, हम उपयोगकर्ताओं और लार्ज लैंग्वेज मॉडल्स (LLMs) के बीच सहज स्पीच-टू-स्पीच इंटरेक्शन बना सकते हैं।
यह API वॉइस-ड्रिवन अनुभवों के लिए कई मॉडलों की आवश्यकता को समाप्त कर देता है क्योंकि यह एकीकृत API में सम्पूर्ण समाधान प्रदान करता है। यह न केवल विलंबता को कम करने का लक्ष्य रखता है, बल्कि बातचीत के भावनात्मक सूक्ष्मताओं और प्राकृतिक प्रवाह को भी बनाए रखता है।
इस लेख में, हम OpenAI Realtime API का उपयोग करके वॉइस-नियंत्रित AI असिस्टेंट बनाना सीखेंगे। हम Node.js का उपयोग करके स्थायी WebSocket कनेक्शन बनाएंगे और देखेंगे कि टर्मिनल के भीतर API से संवाद करने के लिए इसका उपयोग कैसे किया जा सकता है। इसके अतिरिक्त, मैं आपको इस API की क्षमताओं का उपयोग करने वाले एक React ऐप को डिप्लॉय करने का मार्गदर्शन दूंगा।
OpenAI Realtime API के लिए API कुंजी जनरेट करें
OpenAI Realtime API का उपयोग करने के लिए, हमें पहले एक API कुंजी जनरेट करनी होगी। ऐसा करने के लिए, API कुंजी पेज पर जाएँ। ध्यान दें कि इसके लिए एक खाता होना आवश्यक है। पेज के शीर्ष पर “Create new secret key” बटन पर क्लिक करें।
एक पॉप-अप विंडो खुलेगी। हम डिफ़ॉल्ट विकल्पों का उपयोग कर सकते हैं और “Create secret key” पर क्लिक कर सकते हैं।
कुंजी बनने पर, हमें उसे कॉपी करने का अवसर मिलेगा। विंडो बंद करने से पहले इसे अवश्य कॉपी कर लें, क्योंकि यही एकमात्र समय है जब यह दिखाई देगी।
यदि कुंजी खो जाती है, तो हम हमेशा उसे हटा सकते हैं और नई बना सकते हैं।
कुंजी को स्टोर करने के लिए, हम सलाह देते हैं कि
.envनामक एक फ़ाइल बनाएँ और उसमें कुंजी को निम्न प्रारूप में सहेजें:हम इस लेख में API से कनेक्ट होने के लिए इसी फ़ाइल का उपयोग करेंगे।
Realtime API के लिए लागत संबंधी विचार
आगे बढ़ने से पहले ध्यान दें कि Realtime API निःशुल्क नहीं है, और इसका उपयोग करने के लिए हमें अपने खाते में क्रेडिट जोड़ने होंगे। हम अपने प्रोफ़ाइल में स्थित बिलिंग पेज पर क्रेडिट जोड़ सकते हैं।
लागत का अंदाज़ा देने के लिए, यहाँ बताया गया है कि इस लेख पर काम करते समय API के साथ प्रयोग करने में मुझे कितना खर्च आया:
मैंने कुल मिलाकर लगभग पाँच डॉलर खर्च किए। यह बहुत बड़ी राशि नहीं है, लेकिन OpenAI के अन्य APIs की तुलना में यह काफी महंगा है। इस लेख पर काम करते समय इसे ध्यान में रखें।
लागत का अधिकांश भाग (पहली बार) उस React कंसोल ऐप से संबंधित है जिसके साथ हमने इस लेख के अंत में खेला। शेष, लगभग आधा डॉलर, WebSockets का उपयोग करते हुए API के उपयोग पर लगा। इसलिए, इस लेख के साथ कम से कम एक डॉलर से भी कम में आगे बढ़ना संभव है।
API की प्राइसिंग के बारे में अधिक विवरण के लिए, उनके प्राइसिंग पेज में “Realtime API” सेक्शन देखें।