Skip to content

Streaming

Tokens gateway দিয়ে chat completions আর messages-এ Server-Sent Events streaming কীভাবে কাজ করে: event format, usage chunk, timeout আর disconnect সামলানো।

সর্বশেষ আপডেট 11 অক্টোবর 2026

Markdown-এ দেখুন
এই পাতায়

chat completions, messages, responses বা legacy completions-এ "stream": true দিলে gateway upstream provider-এর Server-Sent Events (SSE) আসার সাথে সাথেই আপনার কাছে পাঠিয়ে দেয়। gateway content buffer করে না, বদলায়ও না। billing-এর জন্য শুধু stream থেকে token count পড়ে নেয়, বাকি bytes যেমন আছে তেমনই পাঠায়।

Chat completions-এর SSE format#

প্রতিটা event হলো একটা data: লাইন, যার ভেতরে একটা JSON chunk থাকে। দুটো event-এর মাঝে একটা ফাঁকা লাইন থাকে। stream শেষ হয় data: [DONE] দিয়ে।

text
data: {"id":"chatcmpl-a1b2","object":"chat.completion.chunk","created":1790000000,"model":"deepseek/deepseek-v4.1-flash","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-a1b2","object":"chat.completion.chunk","created":1790000000,"model":"deepseek/deepseek-v4.1-flash","choices":[{"index":0,"delta":{"content":"Retry"},"finish_reason":null}]}

data: {"id":"chatcmpl-a1b2","object":"chat.completion.chunk","created":1790000000,"model":"deepseek/deepseek-v4.1-flash","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-a1b2","object":"chat.completion.chunk","created":1790000000,"model":"deepseek/deepseek-v4.1-flash","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":42,"total_tokens":60}}

data: [DONE]

Reasoning model-এ delta.reasoning_content-ও আসতে পারে। tool call আসে delta.tool_calls-এর ছোট ছোট অংশ হিসেবে (tool calling দেখুন)।

include_usage দিয়ে streaming-এর সময় token usage পাওয়া#

"choices": [] আর usage object-ওয়ালা chunk-টা আপনি না চাইলে আসে না। চাইতে হয় এভাবে:

json
{
  "stream": true,
  "stream_options": { "include_usage": true }
}

এটা না দিলে usage chunk আসবে না, OpenAI-ও ঠিক এভাবেই কাজ করে। তবে billing এই flag-এর ওপর নির্ভর করে না, gateway সব সময়ই stream মেপে রাখে। flag শুধু ঠিক করে, সংখ্যাগুলো আপনি দেখতে পাবেন কি না।

এটা দিলে আপনার loop-এ ফাঁকা choices array-র জন্য check রাখুন। যে code কোনো শর্ত ছাড়াই chunk.choices[0] পড়ে, সেটা শেষ chunk-এ crash করবে।

Anthropic messages-এর SSE format#

/v1/messages নামওয়ালা event stream করে: message_start, content_block_start, content_block_delta, content_block_stop, message_delta আর message_stop। input token-এর usage থাকে message_start-এ, output-এর usage message_delta-তে, তাই আলাদা কোনো flag দিতে হয় না। পুরো sequence messages পেজে আছে। Responses API-র নিজস্ব event-এর নাম আছে, সেগুলো responses পেজে পাবেন।

Python আর Node.js-এ stream করা#

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
    timeout=600,  # seconds; long reasoning answers can take minutes
)

stream = client.chat.completions.create(
    model="deepseek/deepseek-v4.1-flash",
    messages=[{"role": "user", "content": "Explain exponential backoff with jitter."}],
    stream=True,
    stream_options={"include_usage": True},
)

finished = False
for chunk in stream:
    if chunk.choices:
        choice = chunk.choices[0]
        if choice.delta.content:
            print(choice.delta.content, end="", flush=True)
        if choice.finish_reason:
            finished = True
    if chunk.usage:
        print("\n", chunk.usage)

if not finished:
    print("\n[stream ended without a finish_reason: treat the answer as incomplete]")

সরাসরি HTTP-তে দেখতে চাইলে curl -N দিন। এতে output buffer হয় না, তাই event আসার সাথে সাথে চোখের সামনে দেখতে পাবেন:

bash
curl -N https://tokens.bd/v1/chat/completions \
  -H "Authorization: Bearer $TOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek/deepseek-v4.1-flash","stream":true,"messages":[{"role":"user","content":"Count to five."}]}'

Stream শুরুর আগে ও চলার সময়ের error#

প্রথম byte আসার আগে যে error হয়, যেমন ভুল key, ব্যালান্স নেই, rate limit, বা upstream request ফিরিয়ে দিয়েছে, সেগুলো SSE event হিসেবে আসে না। আসে সাধারণ JSON error হিসেবে, সঠিক HTTP status সহ। তাই event parse করা শুরুর আগে status code দেখে নিন। সব code-এর তালিকা errors পেজে আছে।

stream একবার শুরু হয়ে গেলে status আগেই 200 হয়ে গেছে। মাঝপথে upstream fail করলে [DONE] ছাড়াই connection বন্ধ হয়ে যায় (messages-এ message_stop ছাড়া)। যে stream finish_reason বা stop event ছাড়া শেষ হয়েছে, সেটাকে অসম্পূর্ণ ধরে নিন।

x-tokens-request-id response header আসে header-এর সাথেই, কোনো content আসার আগে। প্রতিটা request-এর শুরুতেই এটা log করে রাখুন। stream পরে মাঝপথে মরে গেলেও id আপনার হাতে থাকবে।

লম্বা request-এর timeout#

লম্বা request নিয়ে চিন্তা নেই। upstream সাড়া দেওয়া শুরু করার জন্য gateway 600 সেকেন্ড পর্যন্ত অপেক্ষা করে। যেসব reasoning model প্রথম token দেওয়ার আগে কয়েক মিনিট ভাবে, তাদের জন্য এটা যথেষ্ট। stream চালু হওয়ার পর দুটো chunk-এর মাঝে অপেক্ষা করে 300 সেকেন্ড পর্যন্ত। upstream সময়মতো শুরু না করলে আপনি পান 504 upstream_timeout। কোনো model-এর পেছনে backup provider থাকলে প্রথম token ছাড়া প্রায় 30 সেকেন্ড পার হলে gateway backup-এ চলে যায়। তাই পুরো অপেক্ষা তখনই লাগে, যখন শেষ provider-টাই ধীর। এই বদলটা আপনি টেরও পান না।

আপনার client-এর timeout-ও অন্তত এতটাই বড় রাখতে হবে। উপরের উদাহরণের মতো নিজে ঠিক করে দিন। library-র default ধরে বসে থাকবেন না, আর আপনার app-এর সামনে এমন কোনো proxy থাকলে সতর্ক থাকুন যেটা 30 বা 60 সেকেন্ড idle থাকলেই connection কেটে দেয়।

Client disconnect সামলানো#

stream-এর মাঝখানে আপনার client disconnect বা abort করলে gateway upstream request বাতিল করে দেয়। ততক্ষণ পর্যন্ত যা তৈরি হয়েছে তার জন্য বিল হয়: input আর এর মধ্যে stream হয়ে যাওয়া output। এর পরে আর কিছু কাটা হয় না।

ভাঙা stream retry করার আগে মনে রাখবেন, retry-তে পুরো prompt আবার পাঠানো হয় আর আবার বিল হয়। agent-এর লম্বা prompt হলে খরচটা জমে যায়। কোনো content আসার আগেই retryable error-এ fail হওয়া stream retry করুন। মাঝপথে ভাঙা stream-এর ক্ষেত্রে আগে ভেবে দেখুন আংশিক output কাজে লাগবে কি না। error code অনুযায়ী retry-র নিয়ম errors পেজে আছে।

প্রতিটা খোলা stream শেষ না হওয়া পর্যন্ত আপনার অ্যাকাউন্টের concurrency limit-এর একটা slot দখল করে রাখে। যে stream ফেলে রেখেছেন কিন্তু বন্ধ করেননি, সেটাও slot ধরে রাখে। তাই নিজে close বা abort করুন। বিস্তারিত rate limits পেজে।

এই পাতাটা কি কাজে লেগেছে?

এখনো আটকে আছেন? Support ticket খুলুন

আপনার agent set up করতে সাহায্য লাগবে?

Connection tester দিয়ে সংযোগ পরীক্ষা করে নিন, অথবা একটা API key তৈরি করুন।