فاز 16 · درس 9

معماری ازدحام (Swarm) در سیستم‌های چندایجنت

نوع
مفهومی و ساختنی
زمان
حدود 75 دقیقه
زبان‌ها
Python (stdlib, `threading`, `queue`)
پیش‌نیاز
فاز 16 · 05 (الگوی ناظر / Supervisor)، فاز 16 · 04 (مدل اولیه)
طرحی انتزاعی از چندین گوی درخشان خودکار که هرکدام بدون هدایتگر مرکزی، مکعب‌هایی از داده را از یک کانال نوری مشترک برمی‌دارند
فهرست مطالب
  1. صورت مسئله
  2. مفاهیم پایه
  3. ساختار کلی
  4. چه زمانی ازدحام مناسب است؟
  5. چه زمانی ازدحام شکست می‌خورد؟
  6. فریم‌ورک Matrix (مقالهٔ arXiv:2511.21686)
  7. معماری ازدحام در فریم‌ورک‌های گرافی
  8. سناریوهای شکست: قحطی وظایف و تمرکز بیش‌ازحد بار کاری
  9. پیوند با مسیریابی مبتنی بر محتوا
  10. پیاده‌سازی عملی
  11. کاربرد عملی
  12. چک‌لیست پروداکشن
  13. تمرین‌ها
  14. اصطلاحات کلیدی
  15. برای مطالعه‌ی بیشتر

وقتی تعداد ایجنت‌ها در یک سیستم فراتر از چند ورکر محدود می‌رود، الگوی ناظر مرکزی (Supervisor) خود به گلوگاه اصلی تبدیل می‌شود. تمام تصمیم‌ها، تخصیص وظایف و کنترل جریان باید از کانال یک برنامه‌ریز بگذرد و افت کارایی یا کُندی آن، تمام اجزای سیستم را معطل نگه می‌دارد.

معماری ازدحام (Swarm Architecture) این چالش را با حذف هماهنگ‌کننده حل می‌کند. در این الگو، ورکرها بدون وابستگی به تصمیم مرکزی، وظایف را به‌صورت ناهمگام از یک گذرگاه رویداد یا صف مشترک برمی‌دارند و پردازش می‌کنند؛ رویکردی که برای تسک‌های مستقل پرشمار با مدت‌زمان‌های متغیر بهترین بازدهی را دارد.

در این درس یاد می‌گیرید که چه زمانی استفاده از الگوی ازدحام به مقیاس‌پذیری سیستم کمک می‌کند، چگونه پدیده‌هایی مثل قحطی تسک‌ها (Starvation) را مدیریت کنید و چه بهایی از منظر قطعیت رفتار و ردگیری داده‌ها در ازای این مقیاس‌پذیری می‌پردازید.

در مقایسه با الگوی ناظر (Supervisor): اینجا هیچ تصمیم‌گیرنده‌ی مرکزی در کار نیست. ایجنت‌ها گذرگاه رویداد (Event bus) مشترکی را می‌خوانند، کارها را به‌صورت ناهمگام (Asynchronous) برمی‌دارند و نتایج را ثبت می‌کنند. LangGraph رسماً از «معماری ازدحام» (Swarm Architecture) برای محیط‌های غیرمتمرکز و پویا پشتیبانی می‌کند. فریم‌ورک Matrix (مقالهٔ arXiv:2511.21686) هم جریان کنترل و هم جریان داده را به‌صورت پیام‌های سریال‌شده‌ای نشان می‌دهد که از صف‌های توزیع‌شده رد می‌شوند تا گلوگاه هماهنگ‌کننده (Orchestrator) به‌کل حذف شود. بده‌بستان این الگو کاملاً روشن است: قطعیت رفتار و قابلیت ردگیری محاسبات (Traceability) فدای مقیاس‌پذیری می‌شوند. معماری ازدحام به درد وظایفی می‌خورد که زیرمسئله‌های مستقل زیادی دارند، نه وظایفی که به یک برنامه‌ی منسجم واحد نیازمندند.

صورت مسئله

الگوی ناظر نهایتاً برای چند ورکر (Worker) جواب می‌دهد؛ اما اگر صدها ورکر داشته باشیم چه؟ خودِ ناظر گلوگاه سیستم می‌شود؛ چون تک‌تک تصمیم‌ها درباره‌ی اینکه چه کسی چه کاری انجام دهد، باید از زیر دست یک ایجنت بگذرد. کافی است یک مرحله از برنامه‌ریزی کُند پیش برود تا کل سیستم معطل بماند.

معماری‌های ازدحام این طراحی را زیرورو می‌کنند. به‌جای اینکه برنامه‌ریز مرکزی کارها را پخش کند، خود ورکرها وظایف را از یک صف مشترک برمی‌دارند. «هماهنگی» در دل منطق گذرگاه رویداد تعبیه شده است. هیچ هماهنگ‌کننده‌ای وجود ندارد و سیستم تا زمانی که صف ظرفیت داشته باشد، مقیاس می‌پذیرد.

مفاهیم پایه

ساختار کلی

                ┌──── shared queue ────┐
                │                      │
       ┌────────┼────────┐  ◄──────┬───┘
       ▼        ▼        ▼         │
     Worker  Worker  Worker   Worker
      A       B       C        D
       │        │        │         │
       └────────┴────────┴─────────┘
                 │
                 ▼
            results pool

هیچ هماهنگ‌کننده‌ای در کار نیست. هر ورکر این چرخه را تکرار می‌کند: وظیفه‌ای را بیرون بکش، پردازش کن، نتیجه را بنویس (و در صورت نیاز، کارهای بعدی را به صف اضافه کن).

چه زمانی ازدحام مناسب است؟

  • وظایف مستقل پرشمار: جمع‌آوری داده از وب (Scraping)، تبدیل داده‌ها یا دسته‌بندی آن‌ها؛ وظایفی که به یکدیگر وابسته نیستند.
  • کارهایی با مدت‌زمان متغیر: اگر پردازش برخی وظایف 100 میلی‌ثانیه و برخی دیگر 10 ثانیه زمان ببرد، سیستم ازدحام بار کاری را خودبه‌خود متعادل می‌کند؛ چون ورکرهای سریع بلافاصله کارهای بعدی را برمی‌دارند. در مقابل، یک ناظر مجبور است مدت‌زمان هر کار را از قبل حدس بزند.
  • اولویت نرخ پردازش (Throughput) بر قطعیت: زمانی که کل زمان اتمام کارها اهمیت دارد، نه رعایت دقیق و خط‌به‌خط ترتیب اجرا.

چه زمانی ازدحام شکست می‌خورد؟

  • جریان‌های کاری وابسته به ترتیب: اگر گام 3 به خروجی گام 2 نیاز داشته باشد، در معماری ازدحام این ریسک وجود دارد که گام 3 پیش از تمام شدن گام 2 شروع شود.
  • وظایفی با برنامه‌ی جامع و یکپارچه: مسائل پژوهشی پیچیده نیازمند برنامه‌ریز هستند. دسته‌ای از ایجنت‌های پژوهشگر در یک ازدحام، فقط فکت‌های مستقل و پراکنده تولید می‌کنند، نه گزارشی منسجم و یکدست.
  • دیباگ کردن: وقتی لاگ مرکزی وجود نداشته باشد و کارها ناهمگام پیش بروند، بازتولید یک باگ به‌شدت پرهزینه خواهد بود.

فریم‌ورک Matrix (مقالهٔ arXiv:2511.21686)

مقالهٔ Matrix در سال 2025 ایده‌ی ازدحام را به اوج منطقی خود رساند: هم جریان کنترل و هم جریان داده، پیام‌هایی سریال‌شده روی صف‌های توزیع‌شده هستند. هیچ هماهنگ‌کننده‌ی مرکزی وجود ندارد. تحمل‌پذیری در برابر خطا از بادوام بودن (Durability) پیام‌ها حاصل می‌شود. چالش مقیاس‌پذیری هم به‌جای سیستم، مستقیماً به کارگزار پیام (Message broker) محول شده است.

دستاورد این مقاله: ارائه‌ی یک مدل برنامه‌نویسی که در آن هماهنگی چند ایجنت، به‌جای پاسخ به «ناظر در گام بعد کدام ایجنت را برگزیند؟»، به این تبدیل می‌شود که «این ایجنت مشترک کدام موضوع پیام (Message topic) شود؟». با این رویکرد، معماری سیستم شبیه به یک شبکه‌ی رویدادی مبتنی بر انتشار/اشتراک (Pub/sub) خواهد بود.

معماری ازدحام در فریم‌ورک‌های گرافی

مستندات 2025 فریم‌ورک LangGraph صراحتاً «معماری ازدحام» را یکی از الگوهای چندایجنت معرفی می‌کنند: ایجنت‌ها نودها هستند، اما یال‌ها گرافی جهت‌دار و دارای حلقه تشکیل می‌دهند و هر نودی از استخر ایجنت‌ها شانس فعال شدن دارد. هر ورکر بر اساس شرط‌های کاری مشخص از میان وظایف موجود دست به انتخاب می‌زند، نه با تخصیص دستوری از سمت ناظر.

سناریوهای شکست: قحطی وظایف و تمرکز بیش‌ازحد بار کاری

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

راهکارهای کاهش اثر:

  • استفاده از صف‌های اولویت‌دار با افزایش تدریجی اولویت به مرور زمان (Aging): افزایش اولویت کار بر اساس مدت‌زمان انتظار در صف.
  • تخصصی کردن ورکرها: گماردن برخی ورکرها صرفاً برای انجام کارهای «طولانی».
  • فشار معکوس (Back-pressure): محدود کردن نرخ ورود وظایف سریع به داخل صف.

ازدحام به‌شکلی طبیعی با مسیریابی مبتنی بر محتوا (درس 22) چفت می‌شود. به‌جای داشتن یک صف عمومی، برای هر نوع پیام صفی اختصاصی تعریف کنید. ورکرهای متخصص فقط در صفِ نوع کار خودشان ثبت‌نام می‌کنند. این شیوه، پایه و اساس معماری‌های گذرگاه پیام برای مقیاس‌پذیری تا هزاران ایجنت است.

سرقت کار (WORK STEALING)مبتنی بر کشش (pull)، نه push
WORK STEALINGA swarm has no central dispatcher. Tasks land on a shared queue and idle workers pull the next unit off it themselves. Coordination lives in the queue semantics, so the system scales until the queue does. The price is determinism: you trade a single coherent plan for throughput.صفw0w1w2کارگران وظایف را از صف مشترک برمی‌دارند · هیچ هماهنگ‌کننده‌ای تصمیم نمی‌گیرد چه کسی چه کاری انجام دهد
یک ازدحام (swarm) فاقد توزیع‌کننده مرکزی است. وظایف وارد یک صف مشترک می‌شوند و کارگران بی‌کار، خودشان واحد بعدی را بیرون می‌کشند (pull). هماهنگی در معناشناسی صف نهفته است، بنابراین سیستم تا جایی که صف گنجایش داشته باشد مقیاس‌پذیر خواهد بود. بهای آن از دست رفتن قطعیت است: شما یک برنامه منسجم واحد را فدای نرخ پردازش (throughput) می‌کنید.

پیاده‌سازی عملی

کد code/main.py یک ازدحام با 4 ترد ورکر می‌سازد که وظایف را از یک queue.Queue مشترک بیرون می‌کشند. وظایف مدت‌زمان‌های متغیری دارند (بعضی تند، بعضی کُند). این دمو سه حالت را مقایسه می‌کند:

  • خط مبنای متوالی (Sequential baseline): یک ورکر همه‌ی وظایف را پشت‌سرهم پردازش می‌کند.
  • تخصیص ثابت: هر وظیفه از ابتدا به یک ورکر مشخص سپرده می‌شود (رویکردی مشابه ناظر).
  • ازدحام: ورکرها کارها را از یک صف مشترک برمی‌دارند.

ازدحام بار پردازشی را به‌طور خودکار متعادل می‌کند؛ درحالی‌که در تخصیص ثابت، اگر وظیفه‌ی سنگینی به یک ورکر بیفتد، بقیه‌ی ورکرهای سریع بیکار می‌مانند.

اجرا:

python3 code/main.py

خروجی برنامه تعداد وظایف پردازش‌شده توسط هر ورکر (توزیع نامتوازن اما بهینه‌ی ازدحام) و زمان واقعی سپری‌شده (Wall-clock time) را نمایش می‌دهد.

کاربرد عملی

فایل outputs/skill-swarm-fit.md مشخص می‌کند که آیا یک وظیفه باید با الگوی ازدحام حل شود یا ناظر. معیارهای ورودی عبارت‌اند از: میزان استقلال وظایف، تفاوت در مدت‌زمان پردازش، نیاز به رعایت ترتیب و سهولت در دیباگ.

چک‌لیست پروداکشن

  • صف اولویت‌دار همراه با کهنه‌گی (Aging): جلوگیری از معطل ماندن کارهای طولانی در صف.
  • ورکرهای بی‌اثر در تکرار (Idempotent): اگر کاربری یا ورکری وسط کار کرش کند، ممکن است وظیفه دوباره برداشته شود؛ بنابراین رفتار ورکرها باید بی‌اثر در تکرار باشد.
  • صف بادوام (Durable): برای محیط عملیاتی (پروداکشن) از Kafka، Redis Streams یا صف‌های مبتنی بر دیتابیس استفاده کنید. ابزار queue.Queue تنها در حافظه (In-memory) نگهداری می‌شود.
  • مشاهده‌پذیری به ازای هر وظیفه: هر وظیفه باید یک شناسه‌ی ردگیری (Trace ID) داشته باشد و هر ورکر شروع و پایان کار را با همان شناسه لاگ کند.
  • اعمال فشار معکوس: اگر سرعت پر شدن صف از سرعت خالی شدن آن بیشتر شد، سرعت تولیدکننده را کم کنید.

تمرین‌ها

  1. اسکریپت code/main.py را اجرا کنید. روی یک بار کاری با مدت‌زمان متغیر، سرعت ازدحام چقدر بیشتر از حالت متوالی است؟ در قیاس با تخصیص ثابت چطور؟
  2. یک نوع صف اولویت‌دار اضافه کنید (با استفاده از queue.PriorityQueue). اولویت را بر اساس فیلد «اهمیت» (Importance) وظیفه تعیین کنید. ببینید آیا زیر بار کاری مداوم، وظایف کم‌اهمیت معطل می‌مانند یا خیر.
  3. یک ابزار تشخیص تمرکز بار کاری (Hot-spotting) بسازید: هربار که یک ورکر 3 برابر بیشتر از کُندترین ورکر کار انجام داد، لاگی بیندازد. این اتفاق چه پیامی درباره‌ی نحوه‌ی توزیع مدت‌زمان وظایف دارد؟
  4. چکیده و بخش 3 مقاله‌ی Matrix (arXiv:2511.21686) را بخوانید. یک بده‌بستان مشخص را که Matrix به دست آورده (بهره‌وری در مقیاس‌پذیری) و یک مورد را که فدا کرده (قابلیت ردگیری محاسبات، قطعیت) مشخص کنید.
  5. دموی ازدحام را طوری دستکاری کنید که از یک queue.Queue با ساختار تاپل‌های (payload ,task_type) استفاده کند و هر ورکر فقط وظایف هم‌نوع خودش را بردارد. وقتی ماهیت وظایف ناهمگن است، چه قواعد مسیریابی منطقی به نظر می‌رسند؟

اصطلاحات کلیدی

اصطلاح اصطلاح رایج معنای فنی دقیق
معماری ازدحام (Swarm architecture) «ایجنت‌های غیرمتمرکز» ورکرها وظایف را از یک صف مشترک بیرون می‌کشند؛ هیچ هماهنگ‌کننده‌ی مرکزی وجود ندارد.
گذرگاه رویداد (Event bus) «ایجنت‌ها سابسکرایب تاپیک‌ها می‌شوند» کارگزار پیامی که وظایف را بر اساس نوع یا محتوا میان ورکرها مسیریابی می‌کند.
قحطی (Starvation) «تسک اصلاً اجرا نمی‌شود» کارِ کم‌اولویت به دلیل سرازیر شدن مداوم کارهای پراهمیت‌تر، هیچ‌وقت برداشته نمی‌شود.
تمرکز بار کاری (Hot-spotting) «یک ورکر دارد خفه می‌شود» توزیع نامتعادل بار طوری که بیشترین حجم کار فقط روی دوش یک ورکر می‌افتد.
فشار معکوس (Back-pressure) «سرعت تولیدکننده را کم کن» سازوکاری که هنگام سرریز شدن ظرفیت صف، به بخش بالادستی دستور توقف یا کُند شدن تولید می‌دهد.
ورکر بی‌اثر در تکرار (Idempotent worker) «دوباره اجرا کردنش بی‌خطر است» اجرای دوباره‌ی یک تسک، تغییری در نتیجه ایجاد نمی‌کند. برای زمانی که ورکرها حین اجرا کرش می‌کنند حیاتی است.
صف بادوام (Durable queue) «در برابر قطعی سرور امن است» صفی که روی دیسک یا فضای ذخیره‌سازی توزیع‌شده (Replicated) ذخیره می‌شود و با کرش کردن ورکر از دست نمی‌رود.
فریم‌ورک Matrix «ازدحام تمام‌عیار تبادل پیام» هم جریان داده و هم جریان کنترل در قالب پیام‌های سریال‌شده روی صف‌های توزیع‌شده جریان دارند.

برای مطالعه‌ی بیشتر

سؤالات متداول

تفاوت اصلی معماری ازدحام با الگوی ناظر (Supervisor) چیست؟

در الگوی ناظر، یک ایجنت مرکزی کارها را زمان‌بندی و به ورکرها محول می‌کند؛ اما در معماری ازدحام هیچ هماهنگ‌کننده مرکزی وجود ندارد و ورکرها خودشان وظایف را مستقیماً از یک صف مشترک برمی‌دارند.

معماری Swarm برای چه نوع تسک‌هایی نامناسب است؟

برای کارهایی با مراحل وابسته به‌هم و ترتیبی، پژوهش‌های نیازمند گزارش جامع واحد، و فرایندهایی که قطعیت خط‌به‌خط و دیباگ ساده برایشان حیاتی است، معماری ازدحام گزینه نامناسبی است.

چگونه می‌توان از معطل ماندن کارهای طولانی (Queue starvation) در ازدحام جلوگیری کرد؟

با بهره‌گیری از صف‌های اولویت‌دار با کهنه‌گی تدریجی (Aging)، تخصیص ورکرهای ویژه برای کارهای طولانی، و اعمال فشار معکوس (Back-pressure) روی ورودی تسک‌های سریع.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.