Bloga dön

API ve SDKKılavuz

OpenAI SDK ile Node.js'te sohbet yanıtlarını akıtın

Node.js'te bir sohbet tamamlamasını token token akıtın: for await döngüsü, istek üzerine durdurma, hata işleme ve OpenAI SDK ile token kullanımı.

Yazan: CheapTokens TeamYayınlanma tarihi: Güncellenme tarihi: 4 dk okuma

Bir Node.js betiğinden token token akıtılan bir yanıtı yazdıran terminal penceresi
Bu sayfada
  1. İhtiyacınız olanlar
  2. Adım 1. Yanıtı for await ile akıtın
  3. Adım 2. Akışı istek üzerine durdurun
  4. Adım 3. Hataları işleyin
  5. Adım 4. Kullanımı okuyun ve maliyeti tahmin edin
  6. Tam betik
  7. Sonraki adımlar

Streaming, uygulamanızın tüm yanıtı beklemesi yerine yanıtı oluşturuldukça göstermesini sağlar. Bu rehberde, CheapTokens API'sinden bir sohbet tamamlamasını token token akıtan, istek üzerine durduran ve hataları işleyen küçük bir Node.js betiği oluşturacaksınız. Bu konunun Python sürümü Python'da akış yanıtları sayfasındadır.

İhtiyacınız olanlar#

  • Node.js 22 veya daha yenisi (openai paket README dosyasında belirtilen minimum sürüm, 22 Ekim 2026'da kontrol edildi).
  • Bir CheapTokens API anahtarı. Henüz yoksa CheapTokens ile ilk API isteğiniz sayfasını izleyin.
  • Resmi SDK: npm install openai.

CheapTokens, https://api.cheaptokens.dev/v1 adresinde OpenAI uyumlu bir API sunar, bu nedenle resmi openai paketi yalnızca temel URL ve anahtarı değiştirerek çalışır. Anahtarı kodda değil, bir ortam değişkeninde tutun:

bash
export CHEAPTOKENS_API_KEY="your-key"

Adım 1. Yanıtı for await ile akıtın#

stream.mjs dosyasını oluşturun (.mjs uzantısı import ve üst düzey await kullanmanıza olanak tanır):

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 ile çalıştırın. SDK, API'den Server-Sent Events okur ve for await döngüsünün her yinelemesinde size bir parça verir. Üç ayrıntı önemlidir:

  • Metin chunk.choices[0].delta.content içinde gelir. Bazı parçalar metin taşımaz (ilk parça genellikle yalnızca rolü içerir), bu nedenle delta değerinin boş olmadığını kontrol edin.
  • process.stdout.write satır sonu olmadan yazdırır, böylece kelimeler art arda görünür.
  • stream_options: { include_usage: true } ile son parça, istem ve tamamlama token sayılarını içeren bir usage nesnesi taşır ve choices dizisi boştur. Kodun chunk.choices[0]?. ile isteğe bağlı zincirlemeyi kullanmasının nedeni budur.

Model kimliği CheapTokens belgelerinden gelir: sağlayıcılar aynı modeli farklı adlandırır, bu nedenle kimliği oradan kopyalayın.

Adım 2. Akışı istek üzerine durdurun#

Kullanıcılar Durdur'a basar, bir sekmeyi kapatır veya sohbet değiştirir. Kimsenin okumayacağı tokenları beklememek için isteği iptal edin. İstek seçeneklerinde bir AbortSignal geçirin:

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 },
);

Akış nesnesinin kendi stream.controller.abort() yöntemi de vardır ve for await döngüsünden break ile çıkmak da bağlantıyı kapatır. Kodunuza hangisi daha yakınsa onu kullanın: iptal düğmesi başka bir yerdeyse bir sinyal, karar döngü içinde veriliyorsa (örneğin bir durdurma kelimesi bulduysanız) break.

Adım 3. Hataları işleyin#

Bir akış ilk tokendan önce (yanlış anahtar, boş bakiye) veya ortasında (ağ kopması) başarısız olabilir. Hem isteği hem de döngüyü tek bir try içine alın:

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, kendi abort() işleminizden sonra elde ettiğiniz şeydir. Bu bir hata değildir, bu nedenle hata olarak göstermeyin.
  • APIError, HTTP status kodunu taşır: 401 yanlış veya eksik anahtar anlamına gelir, 429 çok fazla istek anlamına gelir ve tokenlarla ilgili bir mesaj bakiyenin yüklenmesi gerektiği anlamına gelir. Daha fazla neden ve çözüm Yaygın bağlantı hataları ve nasıl düzeltileceği ve "Yeterli token yok" hatası sayfalarındadır.
  • Zaten yazdırılmış metin bir hatadan sonra geçerliliğini korur. Kısmi yanıtı göstermek istiyorsanız onu saklayın.

Adım 4. Kullanımı okuyun ve maliyeti tahmin edin#

usage nesnesi prompt_tokens ve completion_tokens değerlerini tutar. 1M token başına model fiyatıyla birlikte size bir isteğin tam maliyetini verir. Herhangi bir şey çalıştırmadan önce kaba bir tahmin için aşağıdaki canlı tabloyu kullanın: her biri 2.000 giriş ve 800 çıkış tokenı olan 1.000 isteğin maliyetini gösterir.

Model İstek başına 1.000 istek OpenRouter, 1.000 istek
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

İstek başına 2.000 giriş ve 800 çıkış token'ı. 1M token başına fiyatlar günceldir ve tarifelerimizle birlikte değişir; OpenRouter sütunu aynı iş yükü için referans fiyatları gösterir.

Akışlı sohbet yanıtları için MiniMax-M2.7, 1M giriş tokenı başına $0.05 ve 1M çıkış tokenı başına $0.15 olarak fiyatlandırılır; 180K bağlam ve yanıt başına en fazla 8.192 çıkış tokenı sunar. Fiyat, günün her saatinde model başına sabittir ve tek bir bakiye tüm modelleri kapsar, bu nedenle bunları kendi istemlerinizde karşılaştırmak için model dizesini değiştirmek yeterlidir.

Tam betik#

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;
  }
}

Sonraki adımlar#

  • Parçaları kendi uç noktanızdan Server-Sent Events ile bir tarayıcıya gönderin, böylece anahtar sunucudan hiç ayrılmaz.
  • Yalnızca model dizesini değiştirerek diğer modelleri deneyin: MiniMax-M2.7 aynı bakiye ve aynı temel URL üzerinde kullanılabilir.
  • Bir anahtar alın ve betiği çalıştırın: bir CheapTokens API anahtarı oluşturun ve bakiyeyi yükleyin.

Her model için uç noktalar, model kimlikleri ve sınırlar CheapTokens belgelerinde bulunur.