رفتن به محتوا

پشتیبانی از Stream (SSE)

دریافت پاسخ به صورت جریانی با Server-Sent Events

مستندات

Stream چیست؟

تصور کنید از هوش مصنوعی یک داستان بلند درخواست کنید. بدون stream، باید منتظر بمانید تا کل داستان نوشته شود و بعد یکجا ببینید. اما با stream، هوش مصنوعی هر کلمه را که می‌نویسد، فوراً برای شما می‌فرستد - دقیقاً مثل وقتی که با ChatGPT صحبت می‌کنید و می‌بینید که کلمات یکی یکی ظاهر می‌شوند! این باعث می‌شود تجربه کاربری بهتری داشته باشید.

برای استفاده از حالت stream (جریانی)، پارامتر stream را بر روی true تنظیم کنید. پاسخ با فرمت Server-Sent Events (SSE) برگردانده می‌شود:

درخواست کامل

کوتاه‌ترین چیزی که کار می‌کند. تب cURL را در ترمینال اجرا کنید تا خطوط را یکی‌یکی ببینید؛ بقیهٔ تب‌ها همان درخواست‌اند و هرکدام خواندنِ جریان را به شیوهٔ همان زبان نشان می‌دهند:

curl --no-buffer https://api-ai.hibanacloud.ir/v1/chat/completions \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "gpt-5-nano",    "messages": [{"role": "user", "content": "یک داستان خیلی کوتاه در سه جمله بگو."}],    "stream": true,    "max_completion_tokens": 4096  }'

ساختار کامل درخواست:

POST https://api-ai.hibanacloud.ir/v1/chat/completions Headers:  Content-Type: application/json  Authorization: Bearer YOUR_API_TOKEN Body (JSON):{  "model": "gpt-5-nano",  "messages": [    { "role": "user", "content": "یک داستان کوتاه بگو" }  ],  "stream": true,  "max_tokens": 4096}

به‌جز stream، هیچ پارامتر دیگری فرق نمی‌کند؛ همان پارامترهای Chat Completions اینجا هم معتبرند.

پاسخ (SSE)

data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":"روزی"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" روزگاری"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" پرنده‌ای"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" کوچک"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" در"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" جنگل"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" زندگی"},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":" می‌کرد."},"finish_reason":null}]} data: {"id":"chatcmpl-stream123","object":"chat.completion.chunk","created":1704067200,"model":"gpt-5-nano","choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}],"usage":{"prompt_tokens":15,"completion_tokens":45,"total_tokens":60,"cost_rial":120}} data: [DONE]
  • هر خط با پیشوند data: شروع می‌شود.
  • آخرین پیام data: [DONE] نشان‌دهنده پایان stream است.
  • اطلاعات usage فقط در آخرین chunk (با finish_reason: "stop") ارسال می‌شود.

فیلدهای هر chunk

متن هر خط پس از data: یک شیء JSON است با همان شکل پاسخ عادی، با یک تفاوت: به‌جای message فیلد delta دارد که فقط تکهٔ تازه را نگه می‌دارد. کاری که کد شما می‌کند این است که delta.contentها را پشت سر هم بچسباند.

فیلدهای chunk
فیلدتوضیح
objectهمیشه chat.completion.chunk، یعنی این یک تکه است، نه پاسخ کامل.
choices[0].delta.contentتکهٔ تازهٔ متن. آن را به چیزی که تا حالا جمع کرده‌اید اضافه کنید. در برخی chunkها وجود ندارد یا خالی است؛ همیشه بررسی کنید.
choices[0].finish_reasonتا آخرین chunk برابر null است. مقدار stop یعنی مدل تمام کرده است.
usageفقط در chunk پایانی می‌آید و شامل توکن‌های مصرفی و cost_rial است.
data: [DONE]یک خط متنی ساده، نه JSON. پایان stream را اعلام می‌کند؛ آن را parse نکنید.

اگر از SDK رسمی OpenAI استفاده می‌کنید، همهٔ این‌ها را خودِ کتابخانه parse می‌کند و شما فقط روی chunkها حلقه می‌زنید، نمونه‌های پایین همین را نشان می‌دهند. برای گرفتن usage در انتهای stream به Stream با شامل‌کردن Usage نگاه کنید.

قطع‌شدن و تلاش مجدد

اگر stream وسط کار قطع می‌شود، معمولاً مقصر timeout کوتاه یا buffering در proxy است؛ هر دو با راه‌حل در حل مشکلات آمده‌اند. برای تلاش مجدد بدون کسر هزینهٔ دوباره، محدودیت نرخ درخواست را ببینید.