چرا از تکیه بر یک ارائهدهنده واحد هوش مصنوعی دست کشیدم
من یک چتبات بلادرنگ (real-time) برای یک انجمن گفتگو ساختم. فکر میکردم استفاده از یک API کافی باشد. اما اشتباه میکردم.
بعد از سه هفته، در ساعات اوج مصرف با خطای 5xx مواجه شدم. چتبات من از کار افتاد. کاربران کلافه شدند. متوجه شدم که نمیتوانم برای اپلیکیشنهای عملیاتی (production) تنها به یک ارائهدهنده اعتماد کنم.
من از GPT-4 استفاده میکردم. تا زمانی که خوب کار میکرد، اما بعد از آن دیگر نه. با محدودیت نرخ درخواست (rate limits)، تایماوت (timeout) و قطعیهای کامل مواجه شدم. پرداخت هزینه برای سطوح بالاتر، بیشتر شبیه درمان یک علامت بود تا حل خودِ مشکل.
ارائهدهندگان دیگر را هم امتحان کردم، اما همه آنها فرمتها و روشهای احراز هویت (auth) متفاوتی داشتند. کدم به مجموعهای آشفته از دستورات switch-case تبدیل شد. من به سیستمی نیاز داشتم تا:
- تفاوتهای ارائهدهندگان را پنهان کند.
- در صورت بروز خطا، به یک ارائهدهنده پشتیبان سوئیچ کند.
- پاسخها را کش (cache) کند.
- از وابستگی به یک فروشنده (vendor lock-in) جلوگیری کند.
من از کتابخانههای شخص ثالث دوری کردم چون خیلی پیچیده بودند و به راحتی از کار میافتادند. در عوض، یک روتر (router) ساده ساختم.
ابتدا، یک رابط (interface) مشترک برای همه ارائهدهندگان تعریف کردم. هر ارائهدهنده یک متد generate و یک بررسی سلامت (health check) را پیادهسازی میکند.
سپس، یک کلاس روتر ساختم. این کلاس ارائهدهندگان را با ترتیب مشخصی امتحان میکند. از مکانیزم backoff نمایی و یک کش ساده استفاده میکند. اگر اولین ارائهدهنده شکست بخورد، سیستم منتظر میماند و سراغ بعدی میرود.
این سیستم در طول سه قطعی مختلف، آخر هفتههای من را نجات داد. این سیستم باعث میشود اپلیکیشن من حتی زمانی که یک ارائهدهنده بزرگ از کار میافتد، همچنان فعال بماند.
اگر قصد ساخت چنین سیستمی را دارید، این نکات را در نظر بگیرید:
- در محیط عملیاتی (production) به جای یک دیکشنری محلی، از Redis برای کش کردن استفاده کنید.
- بررسیهای سلامت (Health checks) موفقیت را تضمین نمیکنند. یک ارائهدهنده ممکن است از بررسی سلامت عبور کند اما در یک درخواست واقعی با شکست مواجه شود.
- هدرهای
Retry-Afterرا برای مدیریت صحیح محدودیتهای نرخ درخواست (rate limits) تجزیه (parse) کنید. - برای ردیابی هزینهها، لاگگیری برای میزان استفاده از توکنها را اضافه کنید.
- از
asyncioبرای عملکرد بالاتر استفاده کنید.
اگر پروژه شما کوچک است، بیش از حد پیچیده نشوید (over-engineer نکنید). اگر به استریمینگ (streaming) نیاز دارید، این الگو باعث ایجاد تأخیر (latency) میشود. ابزار مناسب را متناسب با مقیاس خود انتخاب کنید.
شما چگونه پایداری ارائهدهنده را مدیریت میکنید؟ آیا به یک ارائهدهنده متکی هستید یا یک لایه جایگزین (fallback layer) میسازید؟
انجمن یادگیری اختیاری: https://t.me/GyaanSetuAi