ब्लॉग पर वापस जाएं

API और SDKगाइड

OpenAI SDK के साथ Node.js में चैट प्रतिक्रियाएँ स्ट्रीम करें

Node.js में चैट पूर्णता को टोकन दर टोकन स्ट्रीम करें: for await लूप, मांग पर रोकना, त्रुटि प्रबंधन और OpenAI SDK के साथ टोकन उपयोग।

CheapTokens Team द्वाराप्रकाशित अपडेट किया गया 7 मिनट का पाठ

Node.js स्क्रिप्ट से टोकन दर टोकन स्ट्रीम किया गया उत्तर प्रिंट करता टर्मिनल विंडो
इस पृष्ठ पर
  1. आपको क्या चाहिए
  2. चरण 1. for await के साथ उत्तर स्ट्रीम करें
  3. चरण 2. मांग पर स्ट्रीम रोकें
  4. चरण 3. त्रुटियों को संभालें
  5. चरण 4. उपयोग पढ़ें और लागत का अनुमान लगाएँ
  6. पूरी स्क्रिप्ट
  7. अगले कदम

स्ट्रीमिंग आपके ऐप को पूरे उत्तर की प्रतीक्षा करने के बजाय उत्तर उत्पन्न होते ही दिखाने देती है। इस गाइड में आप एक छोटी Node.js स्क्रिप्ट बनाएंगे जो CheapTokens API से चैट पूर्णता को टोकन दर टोकन स्ट्रीम करती है, मांग पर रोकती है और त्रुटियों को संभालती है। इस विषय का Python संस्करण Python में स्ट्रीमिंग प्रतिक्रियाएँ में है।

आपको क्या चाहिए#

  • Node.js 22 या नया (openai पैकेज README में बताया गया न्यूनतम संस्करण, 22 अक्टूबर 2026 को जाँचा गया)।
  • एक CheapTokens API कुंजी। यदि आपके पास अभी तक नहीं है, तो CheapTokens के साथ अपना पहला API अनुरोध का पालन करें।
  • आधिकारिक SDK: npm install openai।

CheapTokens https://api.cheaptokens.dev/v1 पर OpenAI-संगत API प्रदान करता है, इसलिए आधिकारिक openai पैकेज केवल बेस URL और कुंजी बदलकर काम करता है। कुंजी को कोड में नहीं, पर्यावरण चर में रखें:

bash
export CHEAPTOKENS_API_KEY="your-key"

चरण 1. for await के साथ उत्तर स्ट्रीम करें#

stream.mjs बनाएँ (.mjs एक्सटेंशन आपको import और शीर्ष-स्तरीय await का उपयोग करने देता है):

javascript
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.CHEAPTOKENS_API_KEY,
  baseURL: 'https://api.cheaptokens.dev/v1',
});

const stream = await client.chat.completions.create({
  model: 'deepseek-ai/DeepSeek-V4-Flash-0731', // take the id from the CheapTokens docs
  messages: [{ role: 'user', content: 'Explain streaming in two sentences.' }],
  stream: true,
  stream_options: { include_usage: true },
});

let usage = null;
for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) process.stdout.write(delta);
  if (chunk.usage) usage = chunk.usage;
}

console.log('\n\nusage:', usage);

इसे node stream.mjs से चलाएँ। SDK API से सर्वर-सेंट इवेंट्स पढ़ता है और आपको for await के प्रत्येक पुनरावृत्ति पर एक चंक देता है। तीन विवरण मायने रखते हैं:

  • टेक्स्ट chunk.choices[0].delta.content में आता है। कुछ चंक्स में कोई टेक्स्ट नहीं होता (पहला अक्सर केवल भूमिका रखता है), इसलिए जाँचें कि delta खाली नहीं है।
  • process.stdout.write बिना लाइन ब्रेक के प्रिंट करता है, इसलिए शब्द एक के बाद एक दिखाई देते हैं।
  • stream_options: { include_usage: true } के साथ अंतिम चंक में प्रॉम्प्ट और पूर्णता टोकन गणना के साथ एक usage ऑब्जेक्ट होता है, और इसकी choices सरणी खाली होती है। इसलिए कोड वैकल्पिक चेनिंग के साथ chunk.choices[0]?. का उपयोग करता है।

मॉडल आईडी CheapTokens दस्तावेज़ से आता है: प्रदाता एक ही मॉडल को अलग-अलग नाम देते हैं, इसलिए आईडी वहीं से कॉपी करें।

चरण 2. मांग पर स्ट्रीम रोकें#

उपयोगकर्ता Stop दबाते हैं, टैब बंद करते हैं या चैट बदलते हैं। अनुरोध रद्द करें ताकि आप उन टोकन की प्रतीक्षा न करें जिन्हें कोई नहीं पढ़ेगा। अनुरोध विकल्पों में एक AbortSignal पास करें:

javascript
const controller = new AbortController();

process.on('SIGINT', () => controller.abort()); // Ctrl+C stops the stream

const stream = await client.chat.completions.create(
  {
    model: 'deepseek-ai/DeepSeek-V4-Flash-0731',
    messages: [{ role: 'user', content: 'Write a long story about a lighthouse.' }],
    stream: true,
  },
  { signal: controller.signal },
);

स्ट्रीम ऑब्जेक्ट का अपना stream.controller.abort() भी होता है, और break के साथ for await लूप से बाहर निकलने पर कनेक्शन भी बंद हो जाता है। जो आपके कोड के करीब हो उसका उपयोग करें: सिग्नल जब कैंसल बटन कहीं और हो, break जब निर्णय लूप के अंदर लिया जाए (उदाहरण के लिए, आपको स्टॉप शब्द मिला)।

चरण 3. त्रुटियों को संभालें#

एक स्ट्रीम पहले टोकन से पहले (गलत कुंजी, खाली शेष) या बीच में (नेटवर्क ड्रॉप) विफल हो सकती है। अनुरोध और लूप दोनों को एक try में लपेटें:

javascript
try {
  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta?.content;
    if (delta) process.stdout.write(delta);
  }
} catch (err) {
  if (err instanceof OpenAI.APIUserAbortError) {
    console.log('\n[stopped by user]');
  } else if (err instanceof OpenAI.APIError) {
    console.error(`\nAPI error ${err.status}: ${err.message}`);
  } else {
    throw err;
  }
}
  • APIUserAbortError वह है जो आपको अपने स्वयं के abort() के बाद मिलता है। यह विफलता नहीं है, इसलिए इसे विफलता के रूप में न दिखाएँ।
  • APIError में HTTP status होता है: 401 का अर्थ है गलत या अनुपलब्ध कुंजी, 429 का अर्थ है बहुत अधिक अनुरोध, और टोकन के बारे में संदेश का अर्थ है कि शेष राशि को टॉप-अप की आवश्यकता है। अधिक कारण और समाधान सामान्य कनेक्शन त्रुटियाँ और उन्हें कैसे ठीक करें और "पर्याप्त टोकन नहीं" त्रुटि में हैं।
  • पहले से प्रिंट किया गया टेक्स्ट त्रुटि के बाद भी मान्य रहता है। यदि आप आंशिक उत्तर दिखाना चाहते हैं तो इसे रखें।

चरण 4. उपयोग पढ़ें और लागत का अनुमान लगाएँ#

usage ऑब्जेक्ट में prompt_tokens और completion_tokens होते हैं। प्रति 1M टोकन मॉडल मूल्य के साथ, यह आपको अनुरोध की सटीक लागत देता है। कुछ भी चलाने से पहले मोटे अनुमान के लिए, नीचे दी गई लाइव तालिका का उपयोग करें: यह प्रत्येक 2,000 इनपुट और 800 आउटपुट टोकन के साथ 1,000 अनुरोधों की लागत दिखाती है।

मॉडल प्रति अनुरोध 1,000 अनुरोध OpenRouter, 1,000 अनुरोध
GLM-5.3-Flash $0.000072 $0.072 $0.143
DeepSeek-V4-Flash $0.00011 $0.11 $0.22
MiniMax-M2.7 $0.00022 $0.22 $1.56

प्रति अनुरोध 2,000 इनपुट और 800 आउटपुट टोकन। प्रति 1M टोकन की कीमतें वर्तमान हैं और हमारे टैरिफ के साथ बदलती रहती हैं; OpenRouter कॉलम समान कार्यभार के लिए संदर्भ कीमतें दिखाता है।

स्ट्रीम किए गए चैट उत्तरों के लिए, MiniMax-M2.7 का मूल्य $0.05 प्रति 1M इनपुट और $0.15 प्रति 1M आउटपुट टोकन है, जिसमें 180K संदर्भ और प्रति उत्तर अधिकतम 8,192 आउटपुट टोकन हैं। मूल्य दिन के किसी भी समय प्रति मॉडल निश्चित है, और एक शेष सभी मॉडलों को कवर करता है, इसलिए अपने स्वयं के प्रॉम्प्ट पर उनकी तुलना करने के लिए model स्ट्रिंग बदलना पर्याप्त है।

पूरी स्क्रिप्ट#

javascript
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.CHEAPTOKENS_API_KEY,
  baseURL: 'https://api.cheaptokens.dev/v1',
});

const controller = new AbortController();
process.on('SIGINT', () => controller.abort());

try {
  const stream = await client.chat.completions.create(
    {
      model: 'deepseek-ai/DeepSeek-V4-Flash-0731',
      messages: [{ role: 'user', content: 'Explain streaming in two sentences.' }],
      stream: true,
      stream_options: { include_usage: true },
    },
    { signal: controller.signal },
  );

  let usage = null;
  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta?.content;
    if (delta) process.stdout.write(delta);
    if (chunk.usage) usage = chunk.usage;
  }
  console.log('\n\nusage:', usage);
} catch (err) {
  if (err instanceof OpenAI.APIUserAbortError) {
    console.log('\n[stopped by user]');
  } else if (err instanceof OpenAI.APIError) {
    console.error(`\nAPI error ${err.status}: ${err.message}`);
  } else {
    throw err;
  }
}

अगले कदम#

  • अपने स्वयं के एंडपॉइंट से सर्वर-सेंट इवेंट्स के साथ चंक्स को ब्राउज़र में भेजें, ताकि कुंजी कभी सर्वर न छोड़े।
  • केवल model स्ट्रिंग बदलकर अन्य मॉडल आज़माएँ: MiniMax-M2.7 उसी शेष और उसी बेस URL पर उपलब्ध है।
  • कुंजी प्राप्त करें और स्क्रिप्ट चलाएँ: CheapTokens API कुंजी बनाएँ और शेष राशि टॉप अप करें।

प्रत्येक मॉडल के एंडपॉइंट, मॉडल आईडी और सीमाएँ CheapTokens दस्तावेज़ में हैं।