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

Bu sayfada
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 (
openaipaket 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:/ 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:
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):
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.içinde gelir. Bazı parçalar metin taşımaz (ilk parça genellikle yalnızca rolü içerir), bu nedenlechoices[0]. delta. content deltadeğerinin boş olmadığını kontrol edin. process.satır sonu olmadan yazdırır, böylece kelimeler art arda görünür.stdout. write stream_ile son parça, istem ve tamamlama token sayılarını içeren biroptions: { include_ usage: true } usagenesnesi taşır vechoicesdizisi boştur. Kodunchunk.ile isteğe bağlı zincirlemeyi kullanmasının nedeni budur.choices[0]?.
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:
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. 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:
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, kendiabort()işleminizden sonra elde ettiğiniz şeydir. Bu bir hata değildir, bu nedenle hata olarak göstermeyin.APIError, HTTPstatuskodunu 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_ 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 | Giriş $/1M | Çıkış $/1M | İstek başına | 1.000 istek | OpenRouter, 1.000 istek |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000072 | $0.072 | $0.143 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.00011 | $0.11 | $0.22 |
| MiniMax-M2.7 | $0.05 | $0.15 | $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#
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
modeldizesini 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.



