تصور کنید برنامهنویسی هستید که در ۲۵ اوت ۲۰۲۶، تلاش میکند ۵۰۰ اسکریپت را به یک موتور ثبت وقایع (Logging) ساختاریافته جدید بهروزرسانی کند. هدف این بود که فراخوانهای قدیمی ثبت وقایع به سیستمی منتقل شوند که از کانالهای ثبت وقایع منحصربهفرد برای ردیابی و مشاهدهپذیری (Observability) از طریق ابزارهایی مانند Grafana، Loki، Tempo و Alloy استفاده میکند. برای تسریع این فرآیند، توسعهدهنده ۱۰ عامل (Agent) — شبیه به دستیاران دیجیتالی که میتوانند دستورات پیچیده را بفهمند و اجرا کنند — را بهصورت موازی به کار گرفت. اما نتیجه بهجای سرعت، ایجاد یک هرجومرج هماهنگی بود؛ چرا که موازیسازی عاملهای هوش مصنوعی اغلب بیش از آنکه سرعت را افزایش دهد، سربار هماهنگی ایجاد میکند، زیرا زیر-عاملها با تکرار استدلالها و پیچیده کردن مدیریت وضعیت (State Management)، مانع پیشرفت واقعی شدند.
این شکست نشاندهنده یک تنش رو به رشد در جریانهای کاری عاملمحور (Agentic) است: این فرض غلط که تعداد بیشتر عاملها لزوماً به معنای سرعت بیشتر است. طبق گزارش وبسایت dev.to، در بسیاری از محیطهای عملیاتی، توسعهدهندگان با مدلهای زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن کتابها جواب میدهد — بهگونهای برخورد میکنند که گویی کارگرانی همهمنظوره هستند که میتوانند همزمان هم وظیفه «یافتن» و هم وظیفه «اصلاح» را بر عهده بگیرند. اما همانطور که این مورد نشان میدهد، استفاده از یک مدل با قدرت استدلال بالا برای کارهای حسابداری قطعی (Deterministic Bookkeeping)، یک اشتباه معماری هزینهبر است. در این پروژه، موتور ثبت وقایع جدید از پیش از طریق یک مسیر include مشترک در دسترس بود، به این معنی که تنها وظیفه باقیمانده، بهروزرسانی خستهکننده صدها اسکریپت موجود بود.
شکست رویکرد چندعاملی
استراتژی اولیه ساده بود: تقسیم ۵۰۰ فایل به دستههای ۵۰تایی و سپردن هر دسته به یک مدل کوچک. هر عامل موظف بود فراخوانهای قدیمی ثبت وقایع را بیابد، آنها را با یک API جدید جایگزین کند و در حالی که منطق کسبوکار (Business Logic) را حفظ میکند، کانالهای ثبت وقایع منحصربهفردی را اختصاص دهد.
به نقل از گزارش dev.to، این روش شکست خورد زیرا عاملها مجبور به انجام کارهای تکراری و زائد بودند. هر یک از عاملها مجبور بود بهطور مستقل ساختار مخزن کد (Repository) را دوباره کشف کند، بفهمد چه چیزهایی نیاز به تغییر دارد و بهطور جداگانه درباره نام کانالها تصمیم بگیرد. این فرآیند «کشف مجدد»، تبدیل به هزینه اصلی عملیات شد. عاملها صرفاً در حال مهاجرت کد نبودند؛ آنها در حال کشف دوباره مخزن و ردیابی پیشرفت خود بهصورت موازی بودند که این امر منجر به ناکارآمدی گستردهای شد. این چالشها در پروژههای بزرگتر منجر به ایجاد راهکارهایی مانند معماری RepoModernizer شده است تا از کرش کردن عاملها در مهاجرتهای طولانی جلوگیری کند.
سه گلوگاه مشخص در این فرآیند شناسایی شد:
- وضعیت جریان کار (Workflow State): پنجرههای متنی (Context) مدلهای زبانی برای ردیابی اینکه کدام فایلها «در انتظار»، «در حال پردازش»، «تکمیل شده»، «ناموفق» یا «باید نادیده گرفته شوند» طراحی نشدهاند. این کار وظیفه یک فایل JSON، پایگاهداده یا یک صف وظایف (Task Queue) است، نه یک پرامپت. این نیاز به حفظ تداوم حافظه در جابهجایی بین ابزارها، در چارچوبهایی مانند Agent Modpack برای جلوگیری از ریسکهای بازنشانی نقشها بررسی شده است.
- سربار کشف (Discovery Overhead): عاملها توکنهای بسیار زیادی را صرف جستوجوی دستورات ثبت وقایع کردند. این فرآیند شامل باز کردن فایل، درک آن، جستوجوی لاگها، یافتن فراخوانهای قدیمی، بررسی بستر (Context) و تصمیمگیری درباره تغییرات بود. این در حالی است که یک دستور ساده در ترمینال میتوانست دقیقاً مکانهای مورد نیاز را شناسایی کند، مثلاً:
ExampleScript.py:42یاExampleScript.py:164. - تصمیمات قطعی (Deterministic Decisions): مدلها چرخههای استدلالی خود را صرف تولید نامهای منحصربهفرد برای کانالها کردند (مثلاً تبدیل
ExampleScript.pyبهexample_channel)؛ کاری که به هیچ هوشی نیاز ندارد. تولید کانال میتواند کاملاً قطعی باشد: مسیر فایل $
ightarrow$ مولد کانال $
ightarrow$ نقشه کانالهای تأییدشده.
تفکیک «کار» از «استدلال»
نقطه عطف زمانی رخ داد که توسعهدهنده بین «کار» و «استدلال» تمایز قائل شد. مهاجرت ۵۰۰ فایل، در واقع تنها یک مسئله استدلالی واحد داشت: «چگونه یک لاگ قدیمی به API جدید نگاشت شود؟». کار تکرار شده بود، اما استدلال ثابت بود: یافتن لاگ قدیمی، جایگزینی با API شناختهشده، استفاده از کانال مشخص و حفظ سایر موارد.
در مقابل، یک مسئله استدلالی واقعی — مثل عیبیابی یک جهش تأخیر (Latency Spike) — نیاز به بررسی فرضیات مختلف دارد. در آنجا، یک توسعهدهنده ممکن است نیاز داشته باشد بررسی کند که آیا علت مشکل دیتابیس است، یا کش (Cache)، شبکه، زیرساخت AWS یا کد اپلیکیشن. در چنین مواردی، زیر-عاملها بینهایت ارزشمند هستند زیرا میتوانند مسیرهای مستقل را بهطور همزمان بررسی کنند. یک عامل میتواند دیتابیس را بررسی کند در حالی که عامل دیگر شبکه را چک میکند و در نهایت نتایج سنتز میشوند. در پروژه مهاجرت اسکریپتها، توسعهدهنده در حال موازیسازی «کار» بود، نه «استدلال».
معماری بهینهشده
برای اصلاح مسیر، یک مرحله پیشپردازش اضافه شد تا تمام تصمیمات قطعی پیش از فراخوانی مدل حذف شوند. بهجای اینکه از عاملها خواسته شود همه چیز را کشف کنند، ابتدا مخزن کد پیشپردازش شد تا مشخص شود کدام فایلها حاوی لاگهای قدیمی هستند، کدامها هیچ لاگی ندارند، فراخوانها در کجا قرار دارند و هر فایل چه کانالی را تخصیص داده است.
این خط لوله (Pipeline) جدید از یک توزیع سختگیرانه پیروی میکرد:
۱. سیاهه (Inventory): اسکریپتی تمام فایلهای حاوی ثبت وقایع قدیمی را شناسایی کرد.
۲. نگاشت (Mapping): یک مولد قطعی، یک نقشه کانالهای تأییدشده برای هر فایل ایجاد کرد.
۳. نمایهسازی (Indexing): تمام دادهها در یک فایل index.json ذخیره شد تا وضعیت بهصورت خارجی ردیابی شود. این فایل شامل ورودیهایی مانند این بود: { "file": "ExampleScript.py", "status": "pending", "legacy_log_count": 4, "channel": "example_channel" }.
با سپردن مرحله کشف به ابزارهای سنتی، وظیفه مدل بهشدت کوچک شد. بهجای دستور «کاوش و مهاجرت»، عامل یک بسته دقیق دریافت میکرد:
- فایل:
ExampleScript.py - کانال:
example_channel - مکانهای لاگ قدیمی: ۴۷، ۸۲، ۱۱۹، ۱۵۳
- مهاجرتهای مورد انتظار: ۴ مورد
- وظیفه: جایگزینی دستورات ثبت وقایع شناسایی شده با پیادهسازی ساختاریافته. منطق کسبوکار را تغییر نده، کانال تخصیص یافته را عوض نکن و کدهای غیرمرتبط را دست نزن.
این تغییر، تمرکز مدل را کاملاً به وظیفه استدلالی منتقل کرد: اطمینان از اینکه معنای لاگ حفظ شده و در عین حال از API جدید استفاده شود. با استفاده از یک جلسه واحد در Claude Code بهجای ۱۰ عامل، هماهنگیهای بینعاملی و تکرار دستورات حذف شد. برای مثال، در سناریوهای حساستر، استفاده از لایههای حفاظتی در Claude Code برای جلوگیری از فجایع دیتابیس در زمان اتوماسیون اهمیت دوچندانی مییابد. جریان کار به یک حلقه بهینه تبدیل شد: index.json $
ightarrow$ فایل بعدی در انتظار $
ightarrow$ آمادهسازی بستر فایل (مکانها، کانال، قوانین) $
ightarrow$ عامل واحد $
ightarrow$ تأیید (Pass/Fail) $
ightarrow$ تکمیل/بازبینی.
چارچوبی برای ارکستراسیون عاملها
این تجربه منجر به یک درخت تصمیم برای زمان استفاده واقعی از زیر-عاملها شد. پرسش اصلی این نیست که «چند وظیفه دارم؟»، بلکه این است که «چند مسئله استدلالی مستقل دارم؟».
اگر وظیفه قطعی است، باید از اسکریپت استفاده شود. اگر استدلال لازم است اما این استدلال مستقل نیست، یک جلسه واحد با عامل برتر برتر است. زیر-عاملها تنها زمانی باید مستقر شوند که مزیت استدلال موازی، بیشتر از هزینه تکرار بستر، هماهنگی و سنتز نتایج باشد. موارد استفاده معتبر عبارتند از:
- پژوهشهای مستقل: عاملهای مختلف که حوزههای معماری متفاوتی را بررسی میکنند؛ مثلاً عامل A روی معماری AWS، عامل B روی معماری دیتابیس، عامل C روی مشاهدهپذیری و عامل D روی امنیت.
- فرضیات متضاد: یک عامل تئوری دیتابیس را تست میکند در حالی که عامل دیگر تئوری شبکه را برای حل یک مشکل عملکرد بررسی میکند.
- دیدگاههای متنوع: عاملهای مجزا که کد را برای اهداف تحلیلی مختلف بررسی میکنند: صحت (Correctness)، امنیت، عملکرد و قابلیت نگهداری.
- پیادهسازی ویژگیهای مجزا: کار روی اجزای کاملاً جداگانه (API، Worker، زیرساخت، مشاهدهپذیری) که رابطهای آنها از پیش تعریف شده و وابستگی (Coupling) آنها پایین است.
هزینه هماهنگی
هر عامل اضافی، یک «مالیات» بر سیستم تحمیل میکند. زیر-عاملها رشتههای موازی رایگان نیستند؛ آنها بستر (Context)، دستورات، فراخوانی ابزار، استدلال، هماهنگی، سنتز نتایج و مدیریت خطاهای خاص خود را به همراه میآورند.
از نظر مفهومی، یک عامل واحد از بستر مشترک و استدلال متوالی استفاده میکند. در مقابل، $N$ عامل به $N$ برابر بستر، $N$ برابر استدلال، بهعلاوه هزینه هماهنگی و سنتز نیاز دارند. فرمول سود زیر-عاملها به این صورت است: $\text{استدلال موازی ذخیره شده} - \text{بستر تکراری} - \text{هزینه هماهنگی} - \text{هزینه سنتز}$. اگر نتیجه این فرمول کوچک باشد، سیستم چندعاملی صرفاً یک ماشینآلات غیرضروری است.
در نهایت، مهاجرت ۵۰۰ فایل ثابت کرد که «وضعیت خارجی» بر «حافظه مدل» برتری دارد. مدل هرگز نباید مسئول حسابداری، شمارش یا حفظ وضعیت جریان کار باشد. اینها وظایفی برای ابزارهای قطعی هستند. توسعهدهنده آموخت که تعداد فایلها تعیینکننده تعداد عاملها نیست؛ ۵۰۰ فایل میتوانند تنها یک الگوی استدلالی واحد باشند.
این تغییر دیدگاه نشان میدهد که موج بعدی بهرهوری عاملمحور، نه از افزایش تعداد عاملها، بلکه از مرزبندی بهتر بین پیشپردازش قطعی و استدلال LLM حاصل خواهد شد. اصل کلی روشن است: صرفاً به این دلیل که کار قابل تقسیم است، موازیسازی نکنید. زمانی موازی کنید که «استدلال» قابل تقسیم باشد. صد تبدیل قطعی را بهتر است یک اسکریپت انجام دهد و صد وظیفه استدلالی کوچک را بهتر است یک عامل با بستر مناسب مدیریت کند. تنها زمانی که چندین تحقیق دشوار و مستقل دارید، باید چندین زیر-عامل ایجاد کنید.
گام بعدی شما
- در پروژههای خود، ابتدا تمام تصمیمات قطعی (Deterministic) را با اسکریپتهای پایتون یا Bash حذف کنید و فقط بخشهای نیازمند تحلیل را به LLM بسپارید.
- برای مدیریت وضعیت (State) عاملها، بهجای تکیه بر حافظه مدل، از یک فایل JSON یا دیتابیس ساده برای ردیابی پیشرفت استفاده کنید.
- پیش از افزایش تعداد عاملها، بررسی کنید آیا مسئله شما «تکرار یک استدلال» است یا «استدلالهای مستقل متعدد».
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو