سیستم همکاری نزدیک به 2000 عامل هوش مصنوعی OpenAI و PerturbAI برای پژوهش علمی، در اصل یک آزمایشگاه را در یک زنجیره فراخوانی API جای داده است. در سناریوی توسعه داروهای جدید، هر عامل باید مقالات را بخواند، فرضیه اجرا کند، و سوابق آزمایش را بنویسد؛ یک وظیفه اغلب دهها دور گفتگو دارد. 2000 همزمانی به معنای 2000 درخواست نیست، بلکه 2000 اتصال طولانی با ضربان مداوم است.
اول این مقیاس را روشن تبدیل کنیم. فرض کنید هر عامل در دقیقه 3 درخواست میفرستد، اوج 100 QPS است؛ هر دور زمینه را 8K token حساب کنیم، TPM مستقیماً به 48 میلیون فشرده میشود. اگر وظیفهای زمینه را به 32K بکشد، در همان QPS، TPM ناگهان به 190 میلیون میرسد، و سهمیه تکKey بسیاری از تیمها در همین مرحله تمام میشود. این هنوز تلاش مجدد را حساب نکرده. کافی است یک عامل پس از timeout دیوانهوار تلاش مجدد کند، کل زنجیره وارد طوفان تلاش مجدد میشود و سهمیه را پر میکند. یک بار دیدم که محدودسازی سمت gateway لایهبندی نشده بود، یک وظیفه پردازش دستهای Key کل تیم را به 429 رساند، حتی محیط تست هم نتوانست متصل شود.
مشکلسازتر این است که عوامل پژوهشی بهطور یکنواخت درخواست نمیفرستند. مرحله بازیابی مقالات QPS پایین اما زمینه بلند دارد، مرحله تولید فرضیه درخواستها متراکم اما token کوتاه است، و مرحله نوشتن سوابق آزمایش یک عملیات نوشتن کمفرکانس معمولی است. سه نوع بار در یک زنجیره مخلوط میشوند؛ اگر منابع را بر اساس اوج یکسان تخصیص دهیم، هزینه سه برابر میشود؛ اگر بر اساس میانگین تخصیص دهیم، با آمدن اوج بهمن رخ میدهد. به همین دلیل مدیریت همزمانی سیستمهای چندعاملی، هستهاش «تحمل کردن» نیست، بلکه «تحمل لایهای» است.
مدیریت همزمانی چندعاملی، عملاً این پنج گام را بردارید
استخر درخواست اولین دریچه است. نگذارید هر عامل خودش client جدید بسازد، یکسان از استخر اتصال عبور کنید، از keep-alive HTTP برای استفاده مجدد استفاده کنید، اندازه استخر را بر اساس QPS × میانگین RT تخمین بزنید. 100 QPS، میانگین پاسخ 2 ثانیه، استخر حداقل 200، با 30% حاشیه. یک نکته آسان برای نادیده گرفتن: استخر اتصال باید بر اساس دامنه هدف جداگانه ساخته شود؛ اگر همزمان API چند ارائهدهنده را فراخوانی میکنید، مخلوط کردن در یک استخر به دلیل تفاوت DNS و دستدهی TLS نرخ استفاده مجدد را به شدت کاهش میدهد. ما آزمایش کردیم، پس از ساخت استخر جداگانه نرخ استفاده مجدد اتصال از 62% به 91% رسید، و همین یک مورد نزدیک به سهدهم سربار دستدهی را صرفهجویی کرد.
چرخش چندKey سقف سهمیه را حل میکند. RPM و TPM تکKey سقف سختی دارند، N Key را بهصورت چرخشی وزندار درآورید، با برخورد به 429 بهطور خودکار 60 ثانیه حذف و سپس بازگردانید. وزن را میتوان بر اساس سهمیه باقیمانده Key بهصورت پویا تنظیم کرد، نه میانگین ساده. در پروژه ما از پلتفرم تجمیع API مدلهای بزرگ token8341 بهعنوان ورودی یکپارچه استفاده کردیم، با OpenAI SDK سازگار است، با تغییر یک خط base_url میتوان مدل را عوض کرد، مدیریت Key در سمت gateway متمرکز میشود، و دردسر پراکندگی پیکربندی در 2000 عامل حذف میشود. در اجرای واقعی، 20 Key با چرخش وزندار، QPS قابل استفاده را حدود 18 برابر نسبت به تکKey افزایش داد، و حتی یک بار قطعی کلی به دلیل سهمیه رخ نداد.
عقبنشینی نمایی باید jitter داشته باشد. عقبنشینی ثابت باعث میشود همه درخواستهای ناموفق در همان ثانیه برگردند؛ زمان عقبنشینی را base×2^n بگیرید، سپس در ضریب تصادفی 0.5 تا 1.5 ضرب کنید، حداکثر عقبنشینی 30 ثانیه، و بیش از 3 تلاش مجدد مستقیماً به صف dead letter برود. یک جزئیات اینجا اضافه کنم: برای ضریب تصادفی jitter توصیه میشود از منبع تصادفی thread-safe استفاده شود، وگرنه در همزمانی بالا چند عامل ممکن است یک seed بگیرند و jitter بیاثر میشود. ما اوایل این تله را تجربه کردیم، بعداً به تولید ضریب بر اساس hash شناسه درخواست تغییر دادیم تا پایدار شد.
صف اولویت وظیفه بر اساس ارزش کسبوکار لایهبندی شود. وظایف با ارزش بالا مانند تولید فرضیه داروهای جدید از سهمیه مستقل P0 استفاده کنند، خلاصه مقالات از استخر مشترک P1، پاکسازی لاگ در زمان بیکاری P2 اجرا شود. نگذارید P2 سهمیه P0 را بخورد. پیادهسازی صف میتواند از مجموعه مرتب Redis استفاده کند، score ترکیبی از اولویت کسبوکار و timestamp، تا درون اولویت یکسان اولوارد-اولخارج و بین اولویتها پیشدستی سخت تضمین شود.
تنزل خرابی باید از قبل تعیین شود. timeout مدل اصلی باعث تغییر به مدل پشتیبان میشود، پلتفرم تجمیع API مدلهای بزرگ token8341 از انتخاب خودکار بهترین مدل بر اساس وظیفه پشتیبانی میکند، مدلهای داخلی و جریان اصلی همه قابل مسیریابی هستند، و در تنزل نیازی به تغییر کد کسبوکار نیست. استراتژی تنزل را سهسطحی پیشنهاد میکنیم: سطح اول تغییر مدل در همان ارائهدهنده، سطح دوم تغییر ارائهدهنده، سطح سوم تنزل به مدل کوچک فقط برای بازگرداندن حداقلی نتیجه ساختاریافته. فقط با شکست هر سه سطح استثنا پرتاب شود، اینطور بیشتر نوسانات توسط دو سطح اول جذب میشوند.
سه تلهای که تجربه کردم
اول، طول زمینه را بر اساس حداکثر پیکربندی نکنید. مدل 128K ادعا میکند، اما اگر با 128K تست فشار کنید، تأخیر و هزینه از کنترل خارج میشوند. زمینه مؤثر واقعی عوامل پژوهشی بیشتر زیر 16K است، مازاد را با خلاصهسازی فشرده کنید. ما مقایسه کردیم: برای همان وظیفه مرور مقاله، زمینه 16K بهطور میانگین 4.2 ثانیه زمان و 0.03 یوان هزینه داشت؛ با فشردهسازی به 64K زمان به 11.8 ثانیه و هزینه به 0.14 یوان رسید، در حالی که کیفیت خروجی تقریباً بهبودی نداشت. این داده بعداً مبنای تعیین بودجه زمینه ما شد.
دوم، عملیات نوشتن را دوباره تلاش نکنید. درخواستهای غیرidempotent مانند نوشتن سوابق آزمایش توسط عامل، با یک تلاش مجدد یک داده کثیف اضافه میشود. عملیات خواندن را آزادانه دوباره تلاش کنید، عملیات نوشتن به کلید idempotency تکیه کند. تولید کلید idempotency باید شامل شناسه عامل، شناسه وظیفه و شماره عملیات باشد، هیچکدام نباید غایب باشد، وگرنه نوشتن همزمان بین عوامل همچنان تداخل میکند. پس از راهاندازی کلید idempotency، نرخ داده کثیف از سه در هزار به نزدیک صفر رسید.
سوم، پایش باید P99 را ببیند نه میانگین را. میانگین 2 ثانیه، P99 تا 40 ثانیه، نشان میدهد درخواستهای کندی در دنباله هستند، اغلب به این دلیل که زمینه یک عامل منفجر شده. ما بعداً در سمت پلتفرم تجمیع API مدلهای بزرگ token8341 داشبورد TPM و نرخ خطا بر اساس Key و بر اساس مدل اضافه کردیم، و فقط آنوقت متوجه شدیم یک وظیفه دستهای در حال فشار زمینههای بلند است. پس از شناسایی، برای این وظیفه دستهای جداگانه سقف زمینه تعیین کردیم، P99 از 40 ثانیه به زیر 6 ثانیه برگشت. این موضوع نشان میدهد ابعاد پایش باید به اندازه «بر اساس Key + بر اساس مدل + بر اساس نوع وظیفه» دقیق باشد، وگرنه همیشه فقط مجموعهای از شاخصهای درهم را میبینید.
فهرست پیکربندی همزمانی که میتوانید مستقیماً اجرا کنید
استخر اتصال: max_connections = QPS اوج × میانگین RT × 1.3؛ timeout: اتصال 5 ثانیه، خواندن 30 ثانیه؛ تلاش مجدد: حداکثر 3 بار، عقبنشینی نمایی با jitter، فقط عملیات خواندن؛ محدودسازی: RPM تکKey از 80% رسمی فراتر نرود، TPM 20% حاشیه داشته باشد؛ صف: سه سطح P0/P1/P2، P0 سهمیه مستقل؛ تنزل: مدل اصلی و پشتیبان هرکدام یکی، آستانه timeout 8 ثانیه؛ پایش: سه هشدار تأخیر P99، نرخ 429، نرخ استفاده TPM.
سه مورد آسان برای نادیده گرفتن هم اضافه کنم: اول، برای هر عامل سقف QPS تکنمونه اضافه کنید تا عامل خارج از کنترلی کل سیستم را زمین نزند؛ دوم، لاگ باید request_id و key_id داشته باشد تا هنگام مشکل بتوان با یک نگاه زنجیره را شناسایی کرد؛ سوم، تست فشار باید با بار ترکیبی واقعی اجرا شود، نه فقط یک نوع درخواست، وگرنه ظرفیت اندازهگیریشده جعلی است.
در یک جمله: 2000 عامل به قدرت مدل بستگی ندارد، به پایداری زمانبندی بستگی دارد. پلتفرم تجمیع API مدلهای بزرگ token8341 بر اساس مصرف صورتحساب میکند، هزینه بهینهتر است، و برای این سناریوی همزمانی بالا و اجرای ترکیبی چندمدلی مناسب است. نگاهی به مسیریابی چندمدلی و مقایسه قیمت API بیندازید، میتوانید نیمی از راههای اشتباه را کم کنید.
نویسنده: ژانگ سییوان
تاریخ انتشار: 22 اکتبر 2026