جلسه ۵ از ۱۱، بخش ۱: طراحی ایجنت
معماری، هماهنگی و ارتباط در سیستمهای چندایجنتی
در این جلسه
در جلسهی ۳ از چند ایجنت استفاده کردیم. این جلسه دربارهی طراحی سیستم چندایجنتی است. اول یک هشدار: دو متن مشهور در این حوزه ظاهراً حرف متضاد میزنند.
- Anthropic در گزارش سیستم تحقیق چندایجنتی نوشت که یک ایجنت راهبر با چند زیرایجنت موازی، در ارزیابی داخلی تحقیق، حدود ۹۰٪ بهتر از یک ایجنت تنها عمل کرد. هزینهاش هم بالا بود: سیستم چندایجنتی حدود ۱۵ برابر یک چت معمولی توکن مصرف میکرد.
- Cognition در مقالهی ایجنت چندتایی نسازید استدلال کرد که ایجنتهای موازی بدون کانتکست مشترک تصمیمهای ضمنی متناقض میگیرند. پیشنهادش این بود که کانتکست، و نه فقط پیامها، کامل به اشتراک گذاشته شود و تا جای ممکن یک ایجنت خطی بماند.
هر دو درستاند و تفاوت در نوع کار است. تحقیق گسترده از کاوش موازی و مستقل سود میبرد. ساختن یک برنامهی منسجم از تصمیمهای پراکنده آسیب میبیند. این جلسه ابزار تشخیص این دو را میدهد.
کی کار را بین چند ایجنت تقسیم کنیم؟#
چهار دلیل خوب:
- تخصص: مدل، پرامپت یا ابزار متفاوت برای هر نقش
- ایزولهسازی: سطح دسترسی متفاوت، مثلاً فقط یک ایجنت حق نوشتن دارد
- موازیسازی: زیرکارهای مستقل همزمان اجرا شوند
- مدیریت کانتکست: لازم نیست هر ایجنت کل مسیر را ببیند
اگر هیچکدام صدق نمیکند، یک ایجنت کافی است.
سه گراف پشت هر معماری#
هر سیستم چندایجنتی را میشود با سه گراف توصیف کرد:
- گراف کنترل: چه کسی هماهنگ میکند؟ یک ناظر، یک سلسلهمراتب یا هیچکس. ممکن است حین اجرا با handoff عوض شود.
- گراف ارتباط: پیام مستقیم، پخش همگانی یا فضای کار مشترک
- گراف کار: تجزیه از ابتدا توسط برنامهریز، با مزایده، یا بهشکل خودجوش از قواعد محلی
هشت معماری#
| معماری | ایده | نمونه | نقطهضعف |
|---|---|---|---|
| ناظر و کارگر | یکی برنامه میریزد، میسپارد و یکپارچه میکند | محقق، کدنویس و بازبین زیر یک ناظر | ناظر گلوگاه است و کانتکستش از همه سریعتر رشد میکند |
| سلسلهمراتبی | ناظرها زیرناظر دارند | مدیر ویژگی ← سرپرست backend و frontend ← API، DB، UI، تست | خطاها در هر سطح تقویت میشوند |
| pipeline یا DAG | مراحل ثابت با قرارداد نوعدار | فاکتور: OCR ← استخراج ← تطبیق با سفارش ← تأیید ← ثبت | راه برگشت ندارد |
| تختهسیاه | هماهنگی از طریق حالت مشترک | ایجنتهای ویژگی، refactor و تست روی یک مخزن git | سازگاری، همروندی، منشأ داده |
| کمیته یا مناظره | پیشنهاد و بحث، بعد داور یا رأی | دو مصحح انشا و یک داور | توافق بدون استقلال: همان مدل، همان نقطهی کور |
| بازار یا مزایده | ایجنتها روی کار پیشنهاد قیمت میدهند | مسیریاب GPU: ارزانترین پیشنهاد زیر ۵ ثانیه برنده است | پیشنهادهای خوداظهاری ممکن است اغراقآمیز باشند |
| ازدحام (swarm) | بدون هماهنگکنندهی دائمی؛ مذاکرهی مستقیم | رباتهای انبار | ارتباط از مرتبهی n²؛ در محصول کمیاب |
| توپولوژی پویا | ایجنتها حین کار اضافه، حذف یا جابهجا میشوند | ربات پشتیبانی که هنگام تشدید مشکل، ایجنت صورتحساب و لاگ اضافه میکند | هر اجرا شکل متفاوتی دارد؛ بازتولید خطا سخت است |
چند جزئیات از اسلایدها:
- ناظر و کارگر: کارگرها فقط زیرکار خودشان را میبینند. ناظر هر نتیجه را دوباره میخواند و برای همین کانتکستش از همه سریعتر رشد میکند.
- pipeline: ارزانترین معماری برای اشکالزدایی است، چون خطا در یک مرحله محدود میشود. اما راه برگشت ندارد: مرحلهی چهارم نمیتواند از مرحلهی اول منبع بهتری بخواهد. یک توصیهی عملی: یک یال «تلاش دوباره» بهتر از یک ایجنت اضافه است.
- سلسلهمراتبی: برای کارهایی که خودشان سلسلهمراتبی تجزیه میشوند مناسب است، مثل ساختن یک سیستم ذخیرهسازی، موتور کوئری و تست. سؤال سخت این است که تجزیه در کدام سطح انجام شود و چقدر کانتکست از هر مرز عبور کند.
- تختهسیاه: ایجنتها بدون سیمکشی دوباره میآیند و میروند و حالت مشترک ماندگار و قابل بازبینی است. فضای مشترک میتواند پایگاه داده، پایگاه دادهی برداری، فایلسیستم، مخزن git یا یک گراف کار باشد. چالشها: سازگاری، همروندی، منشأ داده، نسخهبندی و پاک کردن دادهی بیاستفاده.
- کمیته: کارهای قضاوتمحور را بهتر میکند، به شرطی که داورها واقعاً مستقل باشند.
- بازار: ایجنتهای ناهمگن (مدل، ابزار، ماشین، هزینه و تخصص متفاوت) و کار بدون برنامهریز مرکزی به ارزانترین ایجنت توانا میرسد. در مثال مسیریاب GPU، سه پیشنهاد هست: A100 با ۰٫۲۰ دلار و ۳ ثانیه، T4 با ۰٫۰۵ دلار و ۱۰ ثانیه، H100 با ۰٫۴۰ دلار و ۱ ثانیه. قاعده «ارزانترین زیر ۵ ثانیه» است، پس A100 برنده میشود. T4 ارزانتر است ولی از حد زمان رد میشود.
- ازدحام: هماهنگکنندهای نیست که گلوگاه شود یا خراب شود و کار با آمدن و رفتن همتایان ادامه پیدا میکند. به پروتکل برای کشف، آدرسدهی، هماهنگسازی، پایان کار و اعتماد نیاز دارد.
- توپولوژی پویا: ظرفیت سیستم با سختی کار بزرگ میشود و تیکتهای ساده ارزان میمانند.
سیستمهای واقعی ترکیبیاند. ناظری که یک DAG پویا از کارها میسازد، ایجنتهای کدنویس، محقق، تستنویس و بازبین زیر دستش دارد، git حافظهی مشترکشان است و هر وقت لازم شد دوباره برنامهریزی میکند. این ترکیبی از سلسلهمراتب، تختهسیاه و pipeline است.
جدول جمعبندی اسلاید، با سه گرافی که بالاتر گفتیم:
| نوع | معماری | ایدهی اصلی | مناسب برای | نقطهضعف |
|---|---|---|---|---|
| متمرکز | ناظر و کارگر | یک برنامهریز، چند کارگر | زیرکارهای جداشدنی | گلوگاه شدن برنامهریز |
| متمرکز | سلسلهمراتبی | ناظرهایی که ناظر دارند | تقسیم بازگشتی | تقویت خطا |
| متمرکز | pipeline یا DAG | هر مرحله به بعدی میدهد | مراحل مرتب و روشن | انتشار خطا |
| متمرکز | بازار | ایجنتها روی کار پیشنهاد میدهند | تخصیص پویا | پیشنهاد بد |
| غیرمتمرکز | تختهسیاه | فضای کار مشترک | یک محصول مشترک | حالت کهنه |
| غیرمتمرکز | کمیته | جواب، بعد آشتی | تصمیمهای قضاوتی | تفکر گروهی |
| غیرمتمرکز | ازدحام | گفتگوی مستقیم بدون کنترلگر | مذاکرهی محلی | پیامهای n² |
| ترکیبی | توپولوژی پویا | ساختار حین کار عوض میشود | ساختار ناشناخته | اشکالزدایی سخت |
و اینکه هر معماری کار، کنترل و ارتباط را چطور تعیین میکند:
| معماری | کار چطور تقسیم میشود | کنترل | ارتباط |
|---|---|---|---|
| ناظر و کارگر | ناظر از اول تقسیم میکند | یک ناظر | ستارهای، از طریق ناظر |
| سلسلهمراتبی | در هر سطح دوباره تقسیم میشود | ناظرهای تودرتو | درختی، فقط والد و فرزند |
| pipeline | مراحل در زمان طراحی ثابتاند | خود ترتیب کنترل است | مرحله به مرحله |
| تختهسیاه | از حالت مشترک پدید میآید | بدون مرکز | غیرمستقیم، از طریق فضای کار |
| کمیته | یک کار، موازی تکرار میشود | داور تصمیم میگیرد | بین همتایان، بعد به داور |
| بازار | اعلام میشود و با پیشنهاد برداشته میشود | حراجگزار | پخش همگانی، پیشنهادها برمیگردند |
| ازدحام | محلی مذاکره میشود | بدون هماهنگکنندهی دائمی | همه با همه |
| توپولوژی پویا | با سخت شدن کار دوباره تقسیم میشود | با ورود ایجنتها جابهجا میشود | پویا حین اجرا |
تجزیهی کار#
یک کار پیچیده را در محورهای مختلفی میشود شکست:
| محور | مثال |
|---|---|
| داده | هر ایجنت زیرمجموعهای از رکوردها |
| تخصص | امنیت، کارایی، دسترسپذیری |
| مرحله | برنامهریزی، پیادهسازی، تست، بازبینی |
| فرضیه | توضیحهای رقیب برای یک باگ |
| ابزار | وب، دیتابیس، اجرای کد |
| اختیار | حوزههای مدیریتی جدا |
مثلاً یک PR با ۲۰۰ فایل را اول بر اساس فایلها و بعد بر اساس تخصص تقسیم کنید.
زیرکار خوشتعریف#
بیشتر خرابیهای چندایجنتی از زیرکار بد تعریفشده شروع میشوند. هر زیرکار باید اینها را مشخص کند:
objective: مقالههای ۲۰۲۶ دربارهی سیستمهای ذخیرهسازی برای LLM را پیدا کن
inputs: فهرست کنفرانسها در venues.md
exclude: بهینهسازی کوئری پایگاه داده (موضوع ایجنت دیگری است)
tools: [web_search, web_fetch] # بدون دسترسی نوشتن
output_schema: [title, date, contribution, eval_scale, primary_source_url]
done_when: دستکم ۱۰ مقاله با منبع اصلی، یا فهرست کنفرانسها تمام شد
budget: 40 فراخوانی ابزار، 10 دقیقه
depends_on: []
نسخهی بدِ همین کار فقط این است: «دربارهی سیستمهای ذخیرهسازی تحقیق کن».
اندازهی کار: نه خیلی بزرگ، نه خیلی کوچک#
کار خیلی بزرگ موازیسازی کمی میدهد و کار خیلی کوچک سربار زمانبندی و ارتباط را غالب میکند. یک تقریب ساده برای تأخیر:
T_multi ≈ T_planning + T_critical_path + T_communication + T_merge
موازیسازی فقط وقتی سود دارد که کار ترتیبیِ صرفهجوییشده از مجموع این سربارها بیشتر باشد. مثلاً ۲۰ جستجوی یکخطی را در ۴ زیرکار دستهبندی کنید، نه ۲۰ ایجنت.
تجزیهی ایستا و پویا#
- ایستا: کارها از قبل معلوماند (پنج PDF را خلاصه کن)
- پویا: کار جدید از کشفها ساخته میشود (یک لینک خراب، یک جستجوی تازه میسازد)
- بازگشتی: کارگرها خودشان کار میسپارند
- فرصتطلبانه: ایجنت بیکار کار بعدی را برمیدارد
تجزیهی پویا حتماً به محدودیت تعداد، بودجه، حد عمق و شرط پایان نیاز دارد، وگرنه واگذاری منفجر میشود.
خرابیهای رایج تجزیه#
| خرابی | نمونه |
|---|---|
| همپوشانی | دو ایجنت یک مقاله را خلاصه میکنند |
| شکاف | «۲۰۲۰ تا ۲۰۲۳» و «۲۰۲۵ تا ۲۰۲۶»؛ ۲۰۲۴ جا افتاد |
| وابستگی پنهان | قیمتگذاری به اندازهگیری نیاز دارد و این حین اجرا کشف میشود |
| خروجی ناسازگار | یکی متن آزاد میدهد و دیگری JSON |
| عقبمانده | شش ایجنت در ۲۰ ثانیه تمام میکنند و یکی ۴ دقیقه طول میکشد |
| گم شدن کانتکست کلی | هر بخش درست است اما گزارش نهایی با خودش تناقض دارد |
ارتباط بین ایجنتها#
ارتباط چهار بُعد دارد:
- توپولوژی: چه کسی با چه کسی حرف میزند
- رسانه: پیام، حافظهی مشترک، فایل، پایگاه داده
- کانال: نقطهبهنقطه، پخش همگانی، انتشار و اشتراک (pub/sub)، تختهسیاه، درخواست و پاسخ، تحویل فایل؛ مثالها در جدول زیر
- قالب و معنا: واگذاری، گزارش، پرسش، handoff، لغو
سه رسانهی اصلی: ارسال پیام (پیام صریح روی یک صف یا گذرگاه)، حافظهی مشترک (یک شیء حالت در همان پروسه، مثل فهرست کار مشترک)، و فایل یا محصول (مثلاً notes.md که یک ایجنت مینویسد و ایجنت نویسنده میخواند).
| کانال | مثال |
|---|---|
| نقطهبهنقطه | برنامهریز به کدنویس |
| پخش همگانی | «build شکست خورد»، به همه |
| انتشار و اشتراک | هر ایجنتی که مشترک موضوع «تیکت جدید» است واکنش نشان میدهد |
| تختهسیاه | یک دفترچهی مشترک برای یافتهها |
| درخواست و پاسخ | پرسیدن از ایجنت بازیابی و منتظر ماندن |
| تحویل فایل | نوشتن report.md که ایجنت بعدی میخواند |
قاعدهی کلی: توپولوژی را از وابستگیهای کار بگیرید، برای هر پیوند یک رسانه داشته باشید، پخش همگانی را فقط وقتی همه باید بدانند به کار ببرید، و مسیریابی را بر اساس فیلدهای کنترلی انجام دهید، نه متن آزاد. هر انتخاب بین تأخیر، کانتکست و قابلیت اطمینان مصالحه میکند.
محتوا با زبان طبیعی، کنترل با ساختار#
زبان طبیعی انعطافپذیر اما مبهم است. پیام ساختیافته قابل اعتبارسنجی اما محدود است. راهحل این است که هر دو را داشته باشید و کنترل را از محتوا جدا کنید:
{
"task_id": "T17",
"type": "result",
"status": "complete",
"claim": "The regression began after commit X",
"confidence": 0.82,
"evidence": ["log:2391", "commit:X"],
"artifact": "analysis/T17.json",
"requires_response": false
}
و برای کنترل، یک پاکت جدا از محتوا:
{"id": "msg-381", "task_id": "t-17", "from": "planner", "to": "researcher", "type": "DELEGATE", "payload": { }}
به جای اینکه همه چیز در یک رشته باشد: {"message": "some text"}.
نوع پیام از مجموعهای است که runtime میشناسد: DELEGATE، QUERY، REPORT، HANDOFF، UPDATE، CANCEL، ACK، ERROR، COMPLETE. به این ترتیب runtime میتواند پیام را بدون پرسیدن از LLM مسیریابی کند، دوباره بفرستد یا کار را متوقف کند.
ارتباط یعنی سیستم توزیعشده#
یک مثال: ایجنت A به ایجنت B پیام میدهد «۸ instance GPU بخر» و timeout میگیرد. آیا B خرید را انجام داد؟ A نمیداند. دوباره بفرستد و خطر خرید دوباره را بپذیرد، یا رها کند؟
اینها همان مسائل کلاسیک سیستمهای توزیعشدهاند:
- خرابی جزئی: ایجنت کند است یا مرده؟
- همروندی و غیرقطعی بودن
- سازگاری نسخهها و مصالحههای شبیه CAP
- نبودن ساعت سراسری
- شبکهی غیرقابلاعتماد: تأخیر، گم شدن، جابهجایی و تکرار پیام
- اشکالزدایی روی لاگهای پراکنده با ساعتهای ناهمگام
راهحلها هم کلاسیکاند: کلید idempotency روی task_id، مسیر جبران یا بازگشت، و پیشبینی خرید تکراری در حسابداری.
چالشهای چندایجنتی که از سیستمعامل و سیستمهای توزیعشده آشنا هستند:
- زمانبندی: چه کسی بعد اجرا شود و تا کی
- مدیریت حالت: checkpoint، حافظه، منشأ، نسخهبندی
- تخصیص منابع: مدلها، CPU، منابع مشترک
- جریان درخواست از پیش معلوم نیست: سیستم نمیتواند مصرف را پیشبینی کند
و با LLM جعبهسیاه، سختتر#
| مشکل | نمونه |
|---|---|
| از دست رفتن اطلاعات | خلاصه چیزی را که کارگر میدانست حذف میکند |
| آلودگی کانتکست | جزئیات مهم زیر حجم پیامها دفن میشود |
| اطلاعات کهنه | B بر اساس X=3 عمل میکند در حالی که X=5 شده |
| باورهای متعارض | A میگوید امن است، B میگوید آسیبپذیر |
| مالکیت گمشده | هر ایجنت فکر میکند کار مال دیگری است |
| حلقهی ارتباطی | A از B میپرسد، B از C، و C از A |
| مشاهدهپذیری | چرا شکست خورد؟ |
پروتکلها: A2A و MCP#
A2A (Agent-to-Agent) ارتباط بین ایجنتهاست. هر سرور A2A یک Agent Card منتشر میکند که با GET /.well-known/agent-card.json خوانده میشود:
{
"name": "Travel Agent",
"description": "Plans business travel",
"skills": [{ "id": "book-flight" }],
"supportedInterfaces": [ ... ],
"capabilities": { "streaming": true },
"securitySchemes": { ... }
}
فراخواننده از آن هویت ایجنت، مهارتهایی که ادعا میکند، endpointها، قابلیتها (streaming، push) و روش احراز هویت را میفهمد. سه مفهوم اصلی دارد:
- Message: یک نوبت بین کلاینت و ایجنت
- Task: واحد کار حالتدار با شناسه و چرخهی عمر
- Artifact: خروجی کار، مثل PDF برنامهی سفر
یک پیام کار را شروع میکند و کار نتیجهاش را بهشکل artifact برمیگرداند. مثال: «یک پرواز به بوستون رزرو کن» یک Task میسازد (task-42) که از working به completed میرسد و artifactهایش PDF برنامهی سفر و دادهی رزرو است.
یک مثال بزرگتر از اسلایدها، برای این درخواست: «تحلیل کن آیا شرکت X باید زیرساخت استنتاجش را به GPUهای Y ببرد». یک ایجنت تحقیق، ایجنتهای مالی، جستجو و کدنویسی را از روی Agent Card آنها پیدا میکند. بعد از هر کدام چیزی میخواهد: هزینهی GPU را تخمین بزن، بنچمارکها را پیدا کن، آنها را اجرا کن. روند همیشه یکی است: کشف قابلیتها، فرستادن پیام و ساختن Task، گرفتن بهروزرسانی، و برگشت Artifact. سؤالهای پیگیری به همان Task میپیوندند؛ مثلاً ایجنت میپرسد «کدام تاریخ؟» و جواب «۳ اکتبر» در همان Task ادامه پیدا میکند.
چرخهی عمر Task این حالتها را دارد: submitted، working، input-required، auth-required، completed، failed، rejected و canceled. برای کارهای طولانی هم سه روش پیگیری هست: polling برای کار کوتاه، streaming برای خروجی تعاملی و webhook برای کار چندساعته.
A2A ارتباط را استاندارد میکند، نه هماهنگی را
اینکه کار چطور تقسیم شود، به چه کسی سپرده شود و کی متوقف شود، هنوز کار هارنس شماست.
| MCP | A2A | |
|---|---|---|
| انتزاع اصلی | قابلیت یا ابزار | ایجنت یا کار |
| رابطه | ایجنت با سرویس | ایجنت با ایجنت |
| واحد کار | یک فراخوانی ابزار | یک کار طولانی |
| کشف | tools، resources، prompts | قابلیتهای ایجنت |
| حالت درونی | رابط قابلیت | ترجیحاً پنهان |
| تشبیه | دستگاه یا API | RPC بین سرویسها |
این دو رقیب نیستند: یک ایجنت راهدور در A2A ممکن است خودش بیست سرور MCP را صدا بزند.
اصول طراحی#
- بپرسید آیا اصلاً چند ایجنت لازم است. اغلب یک ایجنت کافی است.
- توپولوژی را از وابستگیهای کار بگیرید و ارتباط را کمینه کنید. شبکهی کاملاً متصل تقریباً هیچوقت پیشفرض خوبی نیست؛ ارتباط بیشتر فشار کانتکست را بالا میبرد بیآنکه اطلاعات مفیدی اضافه کند.
- نقطههای از دست رفتن اطلاعات را پیدا کنید، بهویژه گرههای تجمیع.
- مرزهای مهار خرابی را مشخص کنید تا خرابی یک ایجنت کل سیستم را متوقف نکند.
پرسشهایی برای فکر کردن#
- در معماری کمیته، اگر هر سه داور یک مدل باشند، رأی اکثریت چه چیزی را واقعاً اضافه میکند؟ چطور استقلال واقعی بسازید؟
- در مثال خرید GPU، idempotency را دقیقاً کجا پیاده میکنید: در ایجنت A، در ایجنت B یا در خود API خرید؟