استریم کردن Claude در مرورگر با مدیریت فشار معکوس (Backpressure) واقعی

استریم کردن توکن‌های LLM به‌گونه‌ای که ۸۰٪ مسیر را درست طی کنید، آسان است. اما ۲۰٪ باقی‌مانده همان جایی است که اکثر توسعه‌دهندگان شکست می‌خورند. تنظیمات ساده (Naive) روی سیستم محلی شما کار می‌کنند، اما در اتصالات کند یا با مدل‌های سریع از کار می‌افتند.

اگر استریمینگ در سطح تولید (production-grade) می‌خواهید، باید دو مشکل خاص را مدیریت کنید.

۱. مشکل بافر Nginx بسیاری از توسعه‌دهندگان هدر X-Accel-Buffering را فراموش می‌کنند. بدون تنظیم این هدر روی no ، Nginx استریم شما را بافر می‌کند. کاربر شما تا زمانی که کل پاسخ تمام نشود، هیچ‌چیز نمی‌بیند. این کار هدف اصلی استریمینگ را از بین می‌برد.

۲. مشکل استریم رها شده (Abandoned Stream) این گران‌ترین اشتباه ممکن است. اگر کاربر در حین تولید پاسخ توسط مدل، تب را ببندد یا اتصال خود را از دست بدهد، سرور همچنان به کار خود ادامه می‌دهد. حلقه (loop) شما همچنان توکن‌ها را از Claude دریافت می‌کند. شما بابت خروجی‌ای هزینه پرداخت می‌کنید که هیچ‌کس آن را نمی‌بیند.

راه حل: لغو عملیات سرتاسری (End-to-End Aborts) شما باید سیگنال درخواست را به استریم Claude متصل کنید. وقتی کلاینت قطع می‌شود، سرور باید بلافاصله تولید پاسخ را متوقف کند.

در مسیر (route) Next.js خود، سیگنال درخواست را به Anthropic SDK پاس دهید:

  • در فراخوانی SDK خود از { signal: request.signal } استفاده کنید.
  • یک شنونده رویداد (event listener) برای سیگنال لغو (abort signal) اضافه کنید.
  • هنگام وقوع لغو، llm.abort() و controller.close() را فراخوانی کنید.

این کار تولید پاسخ را متوقف کرده و از افزایش هزینه‌های شما جلوگیری می‌کند.

در سمت فرانت‌اند (Frontend) مرورگر تکه‌ها (chunks) را در مرزهای تصادفی دریافت می‌کند. شما باید این تکه‌ها را بافر کرده و آن‌ها را بر اساس جداکننده SSE تقسیم کنید.

  • از یک AbortController در فراخوانی fetch خود استفاده کنید.
  • آن کنترلر را به کامپوننت React خود برگردانید.
  • در تابع پاکسازی (cleanup function) کامپوننت، controller.abort() را فراخوانی کنید.

این کار تضمین می‌کند که سیگنال لغو از رابط کاربری (UI) مستقیماً تا سرور شما منتقل شود.

یک نکته نهایی برای عملکرد (performance): مدل‌های سریع، توکن‌ها را سریع‌تر از آنچه DOM بتواند بازترسیم (repaint) کند، منتشر می‌کنند. به‌روزرسانی وضعیت (state) React برای تک‌تک توکن‌ها باعث کندی رابط کاربری شما می‌شود. توکن‌ها را بافر کرده و در دسته‌های مشخص (batches) به‌روزرسانی کنید. این کار باعث روان ماندن رابط کاربری شما می‌شود.

از ساخت استریم‌هایی که فقط برای دمو هستند دست بردارید. با غیرفعال کردن بافرینگ پروکسی و انتشار سیگنال‌های لغو (abort)، در هزینه‌ها صرفه‌جویی کنید و اپلیکیشن‌های قدرتمندی بسازید.

Source: https://dev.to/pavelespitia/streaming-claude-to-the-browser-with-backpressure-that-actually-works-4oaf

Optional learning community: https://t.me/GyaanSetuAi