انتقال یک سیستم چندایجنت از یک پروتوتایپ محلی به محیط عملیاتی (Production)، چالشهای متفاوتی را به همراه دارد. زمانی که ایجنتها ساعتها برای دریافت بازخورد انسانی متوقف میشوند یا ورکرها به دلایل مختلف کرش میکنند، حلقههای رویداد درونحافظهای دیگر پاسخگو نیستند و وضعیت برنامه از دست میرود. در مقیاسهای بزرگ، مدیریت اجرای پایدار (Durable Execution) و تضمین بازگشتپذیری سیستم حیاتی است.
این درس به شما نشان میدهد چطور با الگوهایی مثل چکپوینتگذاری در هر ابرگام، صفهای کاری ناهمگام و الگوهای مدیریت تراکنش نظیر Outbox، سیستمهایی تابآور در برابر خطا بسازید. همچنین بررسی میکنیم که چگونه با رعایت اصل «شروع ساده» بر پایهی FastAPI و Postgres، از پیچیدگیهای زودرس معماری دوری کنید.
مقیاسپذیری سیستمهای چندایجنت تا هزاران اجرای همزمان نیازمند اجرای پایدار (Durable Execution) است؛ یعنی صفهای کاری بههمراه چکپوینتها، تا هر ورکر بتواند پس از هر خرابی (Crash)، اجرای متوقفشده را از سر بگیرد؛ مشروط بر اینکه مدیریت اجاره (Lease)، اثرات جانبی بیاثر در تکرار (Idempotent) و بازپخش قطعی (Deterministic Replay) برقرار باشند. محیط اجرای LangGraph نمونهی مرجع این الگوست: این محیط پس از هر ابرگام (Super-step) یک چکپوینت با کلید
thread_idثبت میکند (بهطور پیشفرض در Postgres)؛ با کرش ورکر، اجاره آزاد میشود و ورکر دیگری کار را ادامه میدهد. ایجنتها میتوانند تا زمان دریافت ورودی از انسان، بدون محدودیت زمانی منتظر بمانند. پلتفرم MegaAgent (مقاله arXiv:2408.09955) بهازای هر ایجنت یک صف تولیدکننده-مصرفکننده با سه وضعیت (بیکار / در حال پردازش / پاسخ) و هماهنگی دو لایهای (گفتوگوی درونگروهی + گفتوگوی مدیریتی برونگروهی) پیاده کرد. برای استریمینگ خروجی مدلهای زبانی، فایبر/کدهای ناهمگام (Async) ساختار نخ-بهازای-هر-کار (Thread-per-job) را شکست میدهند؛ نخها 99% مواقع بیکار و منتظر توکنها میمانند، در حالی که فایبرها در وقفههای I/O کنترل را با همکاری واگذار میکنند. در نقطهی مقابل، اشپریت بدی در مقالهی «Scaling Agentic Software» استدلال میکند که تا زمانی که بار کاری خلاف آن را ثابت نکرده، فقط ترکیب FastAPI + Postgres و نه هیچچیز دیگر کفایت میکند؛ معماریهای ساده فراتر از حد انتظار پیش میروند. این درس یک لاگ چکپوینت پایدار، یک صف کاری بهازای هر ایجنت با گذار وضعیت، یک دموی مقایسهی نخ و ناهمگامی میسازد و قاعدهی واقعگرایانهی «شروع ساده» را تثبیت میکند.
صورت مسئله
پیشنمونهی یک سیستم چندایجنت با سه ایجنت در یک حلقهی رویداد درونحافظهای روی یک لپتاپ بهخوبی کار میکند. حالا سیستم را به محیط عملیاتی (Production) میبرید:
- ایجنتها گاهی ساعتها اجرا میشوند (پژوهشهای طولانی، انتظار برای مداخلهی انسان در چرخه یا Human-in-the-loop).
- فرایندهای ورکر کرش میکنند و با راهاندازی مجدد، وضعیت از دست میرود.
- اوج بار کاری 10 برابر میانگین است؛ به مقیاسپذیری افقی نیاز دارید.
- کاربران بهازای هر بار اجرای ایجنت هزینه میپردازند؛ برای صدور صورتحساب به تضمین معنایی دقیقاً یکبار اجرا (Exactly-once) نیاز دارید.
حلقهی رویداد درونحافظهای هیچکدام از این کارها را انجام نمیدهد. در زیرساخت سیستم به یک لایهی اجرای پایدار نیاز دارید. گزینههای استاندارد سال 2026 عبارتاند از:
- موتور جریان کاری (Workflow engine) با قابلیت چکپوینت (مانند Temporal یا محیط اجرای LangGraph).
- صف پیام بههمراه مخزن وضعیت (ترکیب Postgres با SQS یا RabbitMQ).
- فریمورکهای مدل اکتور (مانند الگوی تولیدکننده-مصرفکنندهی MegaAgent بهازای هر ایجنت).
- ترکیب دستساز FastAPI بههمراه Postgres (طبق استدلال بدی).
در این درس، نمونهی مینیاتوری هر یک را پیادهسازی میکنیم.
مفاهیم
الگوی اجرای پایدار
یک موتور اجرای پایدار، کل وضعیت برنامه را پس از هر «گام» (در اصطلاح LangGraph: ابرگام) ذخیره میکند. هنگام کرش:
worker crashes mid-step
-> lease timeout
-> another worker picks up the thread_id
-> resumes from last checkpoint
-> no duplicate side effects
پیشنیازهای کارکرد این الگو:
- وضعیت سریالپذیر (Serializable). تمام وضعیت ایجنت باید قابلذخیره باشد. کلوژرهای (Closures) تابعی با اتصالات فعال پایگاهداده باقی نمیمانند.
- ازسرگیری قطعی (Deterministic resume). با فرض یکسان بودن وضعیت و ورودیها، ایجنت باید کنشهای یکسانی تولید کند (یا برای فراخوانی مدلهای زبانی، تصمیمگیری را به یک مرجع حقیقت یا اوراکل بیرونیِ قطعی بسپارد).
- اثرات جانبی بیاثر در تکرار. فراخوانیهای بیرونی (فراخوانی ابزارها یا Tool calls، پرداختها) باید بیاثر در تکرار باشند یا از کلید حذف تکرار (Deduplication key) استفاده کنند.
محیط LangGraph بعد از هر ابرگام یک چکپوینت مینویسد؛ Temporal بعد از هر فعالیت (Activity) وضعیت را ذخیره میکند؛ Restate از ژورنالهای رویدادمحور (Event-sourced) بهره میبرد. هر سه، یک الگو را پیادهسازی میکنند.
محیط اجرای مبتنی بر «چکپوینت بهازای هر گام»
محیط اجرای LangGraph نمونهی عملی این سازوکار است: هر ایجنت یک thread_id دارد؛ وضعیت در قالب یک دیکشنری نوعدار (Typed dict) نگهداری میشود؛ و هر ابرگام یک ردیف در جدول چکپوینتها ثبت میکند. هنگام ازسرگیری، محیط اجرا بهجای شروع از صفر، برنامه را از آخرین چکپوینت بازپخش میکند. ایجنتها میتوانند با فراخوانی interrupt() برای دریافت ورودی از انسان متوقف شوند؛ محیط اجرا وضعیت را ذخیره و ورکر را آزاد میکند. بهمحض رسیدن ورودی، هر ورکر دیگری میتواند ادامهی کار را دست بگیرد.
این رویکرد، طراحی مرجع محیطهای عملیاتی در آوریل 2026 است.
صف بهازای هر ایجنت در MegaAgent
مقاله arXiv:2408.09955 آزمایشی را در مقیاس بالا شرح میدهد: هزاران ایجنت همزمان درون یک کلاستر. معماری سیستم:
agent i:
state ∈ {Idle, Processing, Response}
in_queue <- messages addressed to agent i
out_queue -> replies + side effects
coordinators:
intra-group chat (agents in the same group)
inter-group admin chat (high-level routing)
هماهنگی دو لایهای باعث میشود گفتوگوهای درونگروهی متراکم و گفتوگوهای برونگروهی سبک بمانند؛ این همان الگویی است که هزینهها را در مقیاس هزاران ایجنت خطی نگه میدارد.
مقایسهی معماری ناهمگام با «یک نخ بهازای هر کار»
فراخوانیهای مدلهای زبانی وابسته به ورودی/خروجی (I/O-bound) هستند. نخی که منتظر توکن بعدی میماند، 99% زمان بیکار است. هر نخ حدود 1MB حافظهی RAM مصرف میکند؛ در 10,000 فراخوانی همزمان، فقط 10GB فضا صرف پشتهها (Stacks) میشود.
فایبرها (کتابخانهی asyncio در Python، گوروتینها در Go، کتابخانهی tokio در Rust) هنگام درگیری با I/O، پردازنده را با همکاری واگذار میکنند. در این حالت همان 10,000 فراخوانی بهراحتی درون یک فرایند جا میگیرند. در مقیاس ایجنتهای مبتنی بر مدل زبانی، معماری ناهمگام دیگر یک بهینهسازی ساده نیست؛ بلکه خودِ معماری است.
استثنا: پسپردازشهای وابسته به پردازنده (CPU-bound) مثل ساخت امبدینگ یا ترفندهای توکنایزر، همچنان نیازمند نخها یا فرایندها هستند. لایهی I/O خود را از لایهی CPU جدا کنید.
دیدگاه متقابل اشپریت بدی
مقاله «Scaling Agentic Software» (نوشتهی اشپریت بدی، 2026) استدلال میکند که بیشتر تیمها قبل از اندازهگیری دقیق بار کاری، سیستم را بیشازحد پیچیده (Over-engineer) میکنند. رویکرد پیشفرض و عملگرایانه:
- FastAPI + Postgres.
- ثبت هر اجرای ایجنت در قالب یک ردیف؛ بهروزرسانی درجا با هماهنگی خوشبینانه (Optimistic concurrency).
- اجرای وظایف پسزمینه با
pg_notifyیا یک ورکر ساده در Celery. - سیاست تلاش مجدد (Retry) در کدهای برنامه.
برای بارهای کمتر از حدود 100 اجرای همزمانِ ایجنت با وظایف مهارپذیر، این ساختار اغلب تمام نیاز شما را برطرف میکند. سیستم را فقط زمانی ارتقا دهید که در عمل به سقف ظرفیت خود برسد.
قاعده این است: فقط زمانی به سراغ فریمورکهای اجرای پایدار بروید که با مشکل مشخصی روبهرو شوید که معماریهای ساده از پس حل آن برنمیآیند. استفادهی زودهنگام از این ابزارها، وقت شما را صرف تشریفاتی میکند که خروجی مفیدی ندارند.
تضمین معنایی دقیقاً یکبار اجرا (Exactly-once)
برای اجرای ایجنتهای پولی، باید به «دقیقاً یکبارِ موثر» برسید (تحویلِ حداقل یکبار + مصرفکنندهی بیاثر در تکرار). اقدامات مهندسی:
- کلید حذف تکرار بهازای هر اجرا. این کلید را در تمام فراخوانیهای دارای اثر جانبی بگنجانید.
- الگوی اوتباکس (Outbox pattern). اثرات جانبی ابتدا در یک جدول نوشته میشوند، سپس فرایندی جداگانه آنها را اجرا میکند. هر دو گام باید بیاثر در تکرار باشند.
- تراکنشهای جبرانی (Compensating transactions). اگر اثر جانبی با موفقیت اجرا شود اما ثبت رهگیری آن شکست بخورد، یک تراکنش جبرانی را زمانبندی کنید.
این الگوها در مهندسی پایگاهداده استاندارد هستند و ربطی به مدلهای زبانی ندارند. سهم مدل زبانی در این میان فقط کُندی فراخوانیهاست؛ بقیهی موارد مسائل استاندارد سیستمهای توزیعشده هستند.
استقرار رنگینکمانی (Rainbow deployment)
سیستم تحقیقاتی چندایجنت Anthropic از «استقرار رنگینکمانی» استفاده میکند: چند نسخهی مختلف از محیط اجرای ایجنت همزمان کار میکنند تا هنگام دیپلوی کد، نیازی به متوقف کردن ایجنتهای طولانیمدت نباشد. نسخههای جدید را بهشکل قناری (Canary) روی بخشی از ترافیک ببرید؛ نسخههای قدیمی را هم تنها پس از پایان کار ایجنتهایشان از مدار خارج کنید.
این رویکرد برای سیستمهای پایدارِ حالتدار (Stateful) با چرخهی عمر بالا استاندارد است؛ تفاوتش در سال 2026 این است که ایجنتها میتوانند ساعتها زنده بمانند، بنابراین چرخههای استقرار باید خود را با این واقعیت وفق دهند.
چکلیست استاندارد برای محیط عملیاتی
- وضعیت پایدار (چکپوینتها، اسنپشاتها، یا اوتباکس همراه با لاگ قابلبازپخش).
- اثرات جانبیِ بیاثر در تکرار.
- لایهی ورودی/خروجیِ ناهمگام برای فراخوانی مدلهای زبانی.
- تحویل حداقل یکبار با حذف دادههای تکراری.
- استقرار رنگینکمانی یا قناری برای بارهای کاری حالتدار.
- مشاهدهپذیری: ردگیری محاسبات (Trace) بهازای هر ایجنت، ممیزی ابرگامها و شمارندهی تلاشهای مجدد.
پیادهسازی
فایل code/main.py موارد زیر را پیادهسازی میکند:
CheckpointStore— لاگ ذخیرهی چکپوینت مبتنی بر SQLite با کلیدهای thread_id. هر ابرگام یک ردیف جدید اضافه میکند.run_with_checkpoint(agent, thread_id)— شبیهسازی کرش در میانهی اجرا؛ ورکر دوم کار را از آخرین چکپوینت ادامه میدهد.AgentQueue— ماشین وضعیت با سه حالت بیکار / در حال پردازش / پاسخ بههمراه یک صف کاری کوچک بهازای هر ایجنت.demo_async_vs_threads()— اجرای 500 «فراخوانی شبیهسازیشدهی مدل زبانی» بهصورت همزمان از طریق asyncio و threadها؛ گزارش زمان واقعی اجرا و برآورد اوج حافظهی مصرفی.
اجرا:
python3 code/main.py
خروجی مورد انتظار: ازسرگیری موفق چکپوینت پس از کرش شبیهسازیشده؛ نسخهی ناهمگام 500 فراخوانی همزمان را در کمتر از 1 ثانیه مدیریت میکند، در حالی که نسخهی مبتنی بر نخ چند ثانیه طول میکشد و بهازای هر واحد همزمانی چندین برابر حافظهی بیشتری مصرف میکند.
بهکارگیری
فایل outputs/skill-scaling-advisor.md برای انتخاب گزینهی اجرای پایدار راهنمایی میدهد: FastAPI + Postgres، محیط اجرای LangGraph، موتور Temporal یا راهحلهای دستساز اختصاصی؛ که بر اساس حجم بار کاری، نیاز به ماندگاری وضعیت و چرخههای استقرار تنظیم شده است.
آمادهسازی برای پروداکشن
اقدامات استاندارد برای مقاومسازی در محیط عملیاتی:
- شروع ساده (قاعدهی بدی). با ترکیب FastAPI + Postgres شروع کنید، مگر اینکه ناتوانی آن را در عمل اندازه بگیرید.
- پیش از بهینهسازی، همهچیز را بسنجید. هیستوگرام تاخیر در هر اجرا، زمان مصرفی در هر گام، تعداد تلاشهای مجدد و دستهبندی خطاها.
- الگوی اوتباکس برای اثرات جانبی. بهویژه برای پرداختها و فراخوانیهای API بیرونی.
- استقرار رنگینکمانی. هرگز اجرای ایجنتهای فعال را حین استقرار متوقف نکنید.
- استفاده از موتورهای اجرای پایدار (Temporal / LangGraph / Restate) فقط در صورت: برخورد با مسائل خاص مانند انتظار چندساعته برای ورودی انسان، هماهنگی بینمنطقهای (Cross-region) یا سناریوهای پیچیدهی جبران خسارت و تلاش مجدد.
- معماری ناهمگام برای لایهی I/O. نخها فقط برای پردازشهای پسزمینهی وابسته به CPU باشند.
تمرینها
- اسکریپت
code/main.pyرا اجرا کنید. تایید کنید که ازسرگیری چکپوینت کار میکند؛ سپس تفاوت سرعت همزمانی در مدلهای async و thread را اندازه بگیرید. - یک جدول اوتباکس بسازید: هر فراخوانی ابزار باید ابتدا در جدول اوتباکس نوشته شود، سپس یک وظیفه یا گوروتین مجزا آن را اجرا کند. با دوبار اجرای فراخوانی ابزار، بیاثر بودن آن در تکرار را بیازمایید.
- یک استقرار رنگینکمانی را شبیهسازی کنید: دو نسخهی همزمان از محیط اجرا داشته باشید؛ نیمی از thread_idهای جدید را به هر کدام هدایت کنید؛ مطمئن شوید که نخهای در حال اجرا روی نسخهی قدیمی قطع نمیشوند.
- مستندات محیط اجرای LangGraph (لینک در بخش زیر) را بخوانید. مشخص کنید پیادهسازی کدام ویژگیها در نسخهی دستساز با FastAPI + Postgres به بیشترین زمان نیاز دارد. آیا این دلیل موجهی برای مهاجرت است یا میتوانید آن را به تعویق بیندازید؟
- بخش 3 از مقالهی MegaAgent (arXiv:2408.09955) را مطالعه کنید. هماهنگی دو لایهای (گفتوگوی درونگروهی + گفتوگوی مدیریتی برونگروهی) بهروشنی توضیح داده شده است. طرحی رسم کنید که نشان دهد چطور میتوان این ساختار را روی یک صف پیام با دو دستهبندی صف پیاده کرد.
اصطلاحات کلیدی
| اصطلاح | در گفتوگوها | معنای دقیق فنی |
|---|---|---|
| اجرای پایدار (Durable execution) | «ذخیرهی وضعیت برنامه» | موتور وضعیت را پس از هر ابرگام ذخیره میکند؛ بازیابی پس از کرش قطعی است. |
| ابرگام (Super-step) | «مرز تراکنش» | واحد کاری مستقل میان دو چکپوینت؛ اصطلاحی در LangGraph. |
| شناسه نخ (thread_id) | «شناسهی اجرای ایجنت» | کلیدی که چکپوینتها و منطق ازسرگیری را به هم پیوند میدهد. |
| بیاثر در تکرار (Idempotency) | «تلاش مجدد بدون ریسک» | تکرار اجرای یک اثر جانبی، همان نتیجهی اجرای نخست را در پی دارد. |
| الگوی اوتباکس (Outbox pattern) | «جداسازی اثرات جانبی» | ثبت نیت (Intent) در جدول پایگاهداده؛ مجری مجزا آن را انجام داده و وضعیت انجام را ثبت میکند. |
| تحویل حداقل یکبار (At-least-once delivery) | «احتمال وجود موارد تکراری» | معناشناسی صف پیام؛ مصرفکننده با کلید حذف تکرار عملاً یکبار کار را انجام میدهد. |
| استقرار رنگینکمانی (Rainbow deploy) | «همپوشانی نسخهها» | اجرای همزمان چند نسخهی محیط اجرا هنگام انجام کارهای طولانیمدت. |
| فایبر ناهمگام (Async fiber) | «واگذاری با همکاری» | همزمانی در سطح کاربر؛ برای بارهای I/O-bound در مقایسه با نخها بسیار کمهزینه است. |
| چکپوینت (Checkpoint) | «اسنپشات از وضعیت» | وضعیت سریالشده در مرز یک ابرگام؛ کلید اصلی برای ازسرگیری فرایند. |
برای مطالعهی بیشتر
- LangChain — The runtime behind production deep agents — طراحی محیط اجرای LangGraph
- MegaAgent — صف تولیدکننده-مصرفکننده برای هر ایجنت؛ هماهنگی دو لایهای در مقیاس هزاران ایجنت همزمان
- Matrix — فریمورک نامتمرکز مبتنی بر صفهای پیام بهعنوان بستر هماهنگی
- Temporal docs — موتور جریان کاری مرجع برای اجرای پایدار
- Anthropic — Multi-agent research system — تجربیات محیط عملیاتی از جمله استقرار رنگینکمانی
