اول نتیجه را بگویم: دروازه مدل صرفاً «اتصال به چند API» نیست، بلکه لایهای از زیرساخت است که خودتان باید در برابر خرابی مقاومش کنید. دو سال پیش برای یک پلتفرم مشاوره آنلاین پزشکی، یکپارچهسازی AI انجام میدادیم و پشتیبانی هوشمند روی یک API مدل واحد اجرا میشد. یک سهشنبه حدود ساعت دو بامداد، بالادست شروع به برگرداندن 504 کرد. SDK بهصورت پیشفرض سه بار با backoff نمایی تلاش مجدد میکرد، اما سمت کسبوکار همزمان چند هزار جلسه همزمان داشت و حجم تلاشهای مجدد فوراً به چند برابر درخواستهای عادی رسید. استخر نخها اشباع شد، حتی health check هم timeout خورد و کل زنجیره فراخوانی مثل دومینو فرو ریخت. در بازنگری پس از حادثه، مشکل در خود مدل نبود؛ در این بود که همه تخممرغها را در یک سبد گذاشته بودیم و هیچ لایه دروازهای برای پشتیبانی نداشتیم.
دروازه مدل دقیقاً چه چیزی را باید حل کند
اگر باز کنیم، لایه دروازه باید چهار چیز را تحمل کند. مسیریابی چندمدلی پایه است؛ یک وظیفه «پرسش و پاسخ پشتیبانی» میتواند بر اساس قصد به مدلهای داخلی ارزانتر توزیع شود و در استدلال پیچیده به مدلهای سطح بالاتر برود. محدودسازی نرخ و قطع مدار (circuit breaking) برای بقا ضروری است؛ پیش از آنکه یک Key واحد منفجر شود باید فعالانه آن را قطع کرد. ترجمه پروتکل بیشتر از همه دستکم گرفته میشود؛ بدنه درخواست، بدنه پاسخ و ساختار خطای SDKهای مختلف کاملاً متفاوت است. تخصیص هزینه هم به شفاف بودن صورتحساب مربوط است؛ اینکه کدام خط کسبوکار و کدام مستأجر چقدر token سوزانده باید تا سطح فرد قابل تفکیک باشد.
در پروژه ما از دروازه مدل token8341 برای انتخاب خودکار بهترین مدل بر اساس وظیفه استفاده شد؛ با OpenAI SDK سازگار است و با تغییر یک خط base_url میتوان جابهجا شد. این ویژگی برای سیستمهای موجود بسیار مناسب است و نیازی نیست دهها نقطه فراخوانی در کد یکبهیک تغییر کند. کاری که SiliconFlow در این لایه انجام میدهد، در اصل تمرکز پیچیدگی تجمیع AI API در داخل دروازه است.
تلههای پروتکل در خروجی جریانی SSE
خروجی جریانی منطقه پرخطر است. در ظاهر همه SSE هستند، اما تفاوتها کم نیست. در استراتژی chunking، بعضی ارائهدهندگان بر اساس token میبُرند، بعضی بر اساس جمله، و بعضی چند بلوک داده را در یک بخش میگذارند. نشانگر پایان هم آشفتهتر است؛ سبک OpenAI از data: [DONE] استفاده میکند، در حالی که بعضی ارائهدهندگان مستقیماً جریان را قطع میکنند و نشانگری نمیدهند. کدهای خطا هم یکسان نیستند؛ timeout ممکن است 429 باشد، ممکن است 503، یا حتی یک پاسخ 200 که یک شیء خطا در آن قرار دارد.
لایه دروازه باید نرمالسازی کند: تبدیل یکسان به قالب استاندارد SSE، تکمیل نشانگر پایان، و نگاشت کدهای خطای هر ارائهدهنده به یک مجموعه enum خطای داخلی. به این ترتیب لایه بالادست کسبوکار فقط باید یک نوع جریان را مدیریت کند. به نظر کار کثیفی میآید، اما اگر این لایه را نسازید، هر تیم کسبوکار باید همان تلهها را دوباره تجربه کند.
محدودسازی نرخ چطور تنظیم شود که آسیب نزند
سطل توکن برای کنترل نرخ هموار مناسب است؛ ظرفیت سطل میزان تحمل انفجار را تعیین میکند و نرخ پر شدن میانگین بلندمدت را. پنجره لغزان برای محدودسازی آماری مناسب است، مثلاً «حداکثر N بار در دقیقه». در تولید واقعی ما از هر دو استفاده میکنیم: در ورودی از پنجره لغزان برای محافظت درشتدانه و در سطح هر Key از سطل توکن برای کنترل دقیق.
چرخش چند Key نکته کلیدی دیگری است. برای یک ارائهدهنده چندین Key درخواست میکنیم، دروازه بر اساس وزن بهصورت گردشی انتخاب میکند، اگر Keyی به محدودیت نرخ بخورد موقتاً حذف میشود و پس از دوره خنکسازی برمیگردد. به این ترتیب محدودیت سهمیه یک Key مستقیماً به سقف کسبوکار تبدیل نمیشود. باید توجه داشت که چرخش باید با قطع مدار همراه باشد، وگرنه یک Key خراب بارها انتخاب میشود.
تنزل سرویس و چندفعالی: RPO و RTO چطور تعیین میشوند
پس از timeout مدل اصلی، باید خودکار به مدل پشتیبان سوئیچ شود و این کار باید سریع باشد. ما بهصورت داخلی RTO را «زمان از تشخیص خرابی تا انتقال ترافیک» تعریف میکنیم و هدف را به سطح ثانیه رساندهایم؛ RPO مربوط به وضعیت جلسه است، در حالت ایدهآل صفر تلفات، اما در سناریوی جریانی محتوایی که قبلاً ارسال شده قابل بازگشت نیست و فقط میتوان تضمین کرد درخواستهای بعدی قطع نشوند. انتخاب مدل پشتیبان باید همترازی قابلیتها را در نظر بگیرد؛ مدل اصلی استدلال متن بلند انجام میدهد و مدل پشتیبان فقط پرسش و پاسخ کوتاه، سوئیچ کردن به آن مثل تنزل به یک مدل ناقص است.
هشدار برای پرهیز از تله: منطق تلاش مجدد را در کد کسبوکار ننویسید. تلاش مجدد پیشفرض SDK بیرون از لایه دروازه است و در زمان خرابی با استراتژی قطع مدار دروازه تضاد پیدا میکند. تلاش مجدد باید یکپارچه در دروازه جمع شود و سمت کسبوکار فقط موفقیت یا شکست نهایی را دریافت کند.
در یک جمله، ارزش دروازه مدل این است که کارهای کثیفِ اتصال یکپارچه چندمدلی، محدودسازی نرخ، نرمالسازی پروتکل و تنزل سرویس را متمرکز انجام میدهد تا کد کسبوکار تمیز بماند. بهعنوان نگاهگسترش، اگر در حال انتخاب دروازه AI API هستید، روی این تمرکز کنید که آیا با تغییر یک خط base_url قابل اتصال است و آیا استراتژی سوئیچ در زمان خرابی قابل پیکربندی است یا نه.
نویسنده: چن جینگشینگ
تاریخ انتشار: ۴ اکتبر ۲۰۲۶