چرا از تکیه بر یک ارائهدهنده واحد هوش مصنوعی دست کشیدم
من یک چتبات بلادرنگ برای یک انجمن گفتگو ساختم. فقط از OpenAI API استفاده کردم. ساده به نظر میرسید.
سه هفته بعد، در ساعات اوج مصرف با خطای 5xx مواجه شدم. چتبات من از کار افتاد. کاربران عصبانی بودند. متوجه شدم که نمیتوانم برای اپلیکیشنهای عملیاتی (production) تنها به یک ارائهدهنده اعتماد کنم.
با یک ارائهدهنده واحد با چندین مشکل روبرو شدم:
- محدودیت نرخ درخواست (Rate limits)
- اتمام زمان انتظار (Timeouts)
- قطعی کامل سرویس
ارائهدهندههای دیگر را امتحان کردم، اما همگی فرمتها و روشهای احراز هویت متفاوتی داشتند. کد من به مجموعهای آشفته از دستورات switch-case تبدیل شد.
به سیستمی نیاز داشتم تا:
- ارائهدهندههای مختلف را استانداردسازی کند
- در صورت شکست یکی، بهطور خودکار تلاش مجدد (retry) انجام دهد
- پاسخها را کش (cache) کند
- از وابستگی شدید به یک فروشنده (vendor lock-in) جلوگیری کند
از کتابخانههای شخص ثالث دوری کردم چون بیش از حد انعطافناپذیر بودند. در عوض، یک سیستم جایگزین (fallback) سفارشی با استفاده از یک طراحی ساده ساختم.
ابتدا، یک رابط (interface) مشترک برای تمام ارائهدهندهها ایجاد کردم. این کار اجازه میدهد هر مدل هوش مصنوعی با همان کد کار کند.
سپس، یک کلاس مسیریاب (router class) ساختم. این کلاس ارائهدهندهها را به ترتیب امتحان میکند. برای مدیریت شکستها، از روش exponential backoff و کش ساده استفاده میکند.
منطق کار به این صورت است:
- تعریف یک کلاس پایه انتزاعی (abstract base class) برای ارائهدهندههای هوش مصنوعی.
- پیادهسازی کلاسهای خاص برای OpenAI و سایر ارائهدهندگان.
- استفاده از یک مسیریاب برای پیمایش در لیست ارائهدهندگان.
- اگر یک ارائهدهنده با شکست مواجه شد، مسیریاب منتظر میماند و بعدی را امتحان میکند.
این سیستم در طول سه قطعی اخیر، پروژه من را نجات داد. این سیستم شفاف و ساده باقی میماند.
اگر با هوش مصنوعی برنامهنویسی میکنید، این نکات را به خاطر بسپارید:
- در محیط عملیاتی (production) به جای یک دیکشنری محلی، از Redis برای کش کردن استفاده کنید.
- برای نظارت بر هزینهها، قابلیت ردیابی هزینه را اضافه کنید.
- برای پاسخهای سریعتر، پشتیبانی از حالت ناهمگام (asynchronous) را پیادهسازی کنید.
- هدرهای "Retry-After" را برای مدیریت بهتر محدودیتهای نرخ درخواست تجزیه (parse) کنید.
اگر پروژهتان کوچک است، بیش از حد آن را پیچیده نکنید (over-engineer). اما اگر سرویس شما به پایداری (uptime) وابسته است، یک سیستم جایگزین (fallback) بسازید.
شما در پروژههای خود چگونه قابلیت اطمینان ارائهدهنده را مدیریت میکنید؟ آیا از یک لایه جایگزین استفاده میکنید یا به یک فروشنده تکیه میکنید؟