
قطع پاسخ AI در Next.js همیشه از مدل نیست. مرورگر، Route Handler، مسیر API مدل و پروکسی میان آنها هرکدام میتوانند جریان را متوقف یا تا پایان بافر کنند. برای رفع مشکل، ابتدا مشخص کنید پاسخ از ابتدا جریانی نبوده، در میانه قطع شده یا کامل رسیده اما رابط کاربری درست نمایش نداده است.
در این راهنما یک مسیر تشخیص مرحلهای و نمونه Route Handler متصل به API هوش مصنوعی پاستا داریم. نمونه برای تست سروربهسرور با curl طراحی شده است. پس از تأیید انتقال داده، میتوانید احراز هویت کاربران و رابط گفتوگوی محصول را با قرارداد روشن روی همان مسیر بسازید. برای بررسی محیط استقرار، هاست Next.js پاستا مقصد مرتبط این آموزش است.
نشانه مشکل را قبل از تغییر تنظیمات ثبت کنید
یک بار اجرای مشخص را با زمان شروع، زمان رسیدن اولین داده و زمان پایان ثبت کنید. شناسه درخواست را اگر سرویس میدهد نگه دارید. آیا مرورگر خطای شبکه نشان میدهد؟ آیا پاسخ HTTP از ابتدا ناموفق است؟ یا پس از چند قطعه، اتصال تمام میشود؟ این تفاوتها تعیین میکنند بررسی را از اعتبارنامه، محدودیت اجرا یا نمایش سمت کاربر شروع کنید.
| نشانه | علتهایی که باید بررسی شوند | اولین بررسی کمهزینه |
|---|---|---|
| تمام متن یکجا میآید | خواندن کامل بدنه یا بافر مسیر | مقایسه دریافت قطعهها با curl |
| پاسخ از ابتدا خطاست | اعتبارنامه، مدل، بدنه یا ظرفیت | وضعیت و خطای پیش از شروع جریان |
| جریان بعد از مدتی قطع میشود | timeout، لغو یا خطای بالادستی | زمان قطع و وضعیت همان درخواست |
| شبکه کامل است ولی متن ناقص دیده میشود | parser یا مدیریت state رابط | بررسی رویدادهای دریافتی مستقل از رندر |
برای بازتولید، ورودی ثابت و کوتاه انتخاب کنید. هر بار مدل، پرامپت، سقف خروجی و مسیر را همزمان تغییر ندهید. ابتدا خطای واضح را روی یک سناریو پیدا کنید و سپس پاسخ طولانیتر و لغو کاربر را آزمایش کنید. ثبت بدنه کامل گفتوگو در لاگ برای این کار ضروری نیست؛ زمانها و وضعیتها معمولاً اطلاعات تشخیصی بهتری میدهند.
SSE، قطعه شبکه و توکن مدل یک چیز نیستند
در SSE، پیامها قالب متنی مشخص دارند و مرز یک پیام با مرز قطعه خواندهشده از شبکه لزوماً برابر نیست. ممکن است یک JSON بین دو قطعه شکسته شود یا چند پیام در یک قطعه برسد. راهنمای SSE در MDN قرارداد رویدادها را توضیح میدهد. parser نباید روی هر chunk بهتنهایی JSON.parse اجرا کند.
مدل نیز الزاماً هر توکن را در یک رویداد مستقل نمیفرستد. یک قطعه میتواند شامل متن، اطلاعات مصرف یا نشانه پایان باشد. در قراردادهای رایج Chat Completions، نشانهای مانند [DONE] مربوط به همان سرویس است و جزئی از استاندارد عمومی SSE نیست. پایان اتصال TCP را بهتنهایی موفقیت کامل پاسخ اعلام نکنید؛ قرارداد پایان سرویس را بررسی کنید.
لایه مدل را از لایه برنامه جدا بررسی کنید
از همان محیط سرور، یک درخواست محدود با stream: true به API مدل بفرستید. کلید را از متغیر محیطی بخوانید و خروجی را با curl بدون بافر مشاهده کنید. اگر این مسیر هم قطع میشود، هنوز رابط React را مقصر ندانید. ابتدا مدل، شکل درخواست، محدودیت خروجی و وضعیت سرویس را بررسی کنید.
برای پاستا، شناسه مدل را از کاتالوگ زنده بردارید و درخواست مطابق مستندات API بسازید. داشتن یک مدل در فهرست، پشتیبانی تمام گزینههای اختیاری یا ابزارها را ثابت نمیکند. تست پایه را با متن ساده شروع کنید و بعد قابلیتهایی مانند ابزار یا خروجی ساختاریافته را مستقل اضافه کنید.
Route Handler نباید پیش از ارسال، کل پاسخ را بخواند
اگر در سرور ابتدا await response.text() یا await response.json() اجرا کنید، بدنه کامل پیش از ادامه مصرف میشود. برای انتقال جریانی، از بدنه قابل خواندن پاسخ استفاده کنید. قرارداد Request و Response در مستندات Route Handler توضیح داده شده است. درخواست ناموفق بالادستی را پیش از بازگرداندن جریان موفق بررسی کنید.
نمونه Route Handler پاستا ورودی را محدود میکند، مقصد ثابت دارد، کلید مدل را سمت سرور نگه میدارد و لغو درخواست را به مسیر بالادستی منتقل میکند. فایل متنی دانلودشده را در یک پروژه App Router سازگار، با نام app/api/chat-demo/route.ts ذخیره کنید. این فایل یک مسیر آموزشی سروربهسرور است، نه endpoint عمومی آماده برای همه کاربران.