وقتی پنج ایجنت کدنویس همزمان کار میکنن
خلاصهٔ کاملتر
نویسنده قبلاً یه سرویس ساخته بود که با GitHub Copilot SDK آسیبپذیری وابستگیهای مخزنها رو خودکار وصله میکرد: هر ایجنت یه فایندینگ میگرفت، کوچکترین تغییر امن رو میزد و یه pull request باز میکرد. تو این مقاله اومده که وقتی همین کار از یه حلقهٔ ترتیبی به یه استخر پنج ورکری رسید، بچ ۳۰ مخزنی از حدود ۴۶ دقیقه به حدود ۱۲ دقیقه رسید — ولی جایگزینکردن حلقه آسونترین بخش ماجرا بود.
به گفتهٔ نویسنده، مدل ذهنی درست اینه که یه سشن ایجنت یه بارکاره، نه یه ریکوئست. یه سشن Copilot میتونه چند دقیقه زنده بمونه، ترنسکریپت نگه داره، شل اجرا کنه، چکاوت رو تغییر بده، سابپروسس بسازه و اعتبارنامهای داشته باشه که باهاش برنچ و PR ساخته میشه. از همینجا سه تصمیم باید از هم جدا بمونه: ایزولاسیون هر جاب، سقف همزمانی، و پایداری هویت جاب.
اجرای ترتیبی داشت یه اشکال رو پنهون میکرد: پرامپت همهٔ مخزنها رو تو مسیر ثابت /tmp/agent-workdir کلون میکرد. با دو ایجنت همزمان، یه نصب میتونه lockfile جاب دیگه رو بازنویسی کنه، درست وقتی که اون جاب میخواد کامیتش کنه. حالا خود سرویس یه مسیر یکتا میسازه و بهعنوان دیتای جاب به ایجنت میده:
const safeName = `${repository}-${branch}`.replace(/[^a-zA-Z0-9_-]+/g, "-");
const workdir = `/tmp/agent-${safeName}-${randomUUID()}`;همین منطق برای پورت، نام برنچ، کلید کش و فایل موقت هم صدق میکنه؛ هر مقدار ثابتی که دو جاب بتونن ازش استفاده کنن، تبدیل به state مشترک میشه. نویسنده اضافه میکنه که مسیر یکتا مرز امنیتی نیست و کد مخزن هنوز یه سندباکس دورریختنی میخواد. پاکسازی هم باید بیقید و شرط باشه: کد اولیه فقط بعد از موفقیت سشن رو قطع میکرد، پس یه استثنا باعث نشت سشن و رانتایم میشد — جاش تو بلاک finally ـه.
سقف همزمانی هم باید صریح باشه. اجرای Promise.all روی کل لیست، اندازهٔ ورودی رو تبدیل به سیاست زیرساخت میکنه:
await Promise.all(repositories.map(fixRepository));سی تا جاب شاید جواب بده، ۳۰۰ تا حافظه رو تموم میکنه یا به ریتلیمیت میخوره. نویسنده بهجاش از یه استخر کوچیک ورکر با سقف مشخص استفاده کرده و میگه عدد امن رو کمیابترین منبع تعیین میکنه — حافظه، دیسک، توکن و درخواست ارائهدهنده، عملیات سورسکنترل و دامنهٔ خرابی قابلقبول — نه تعداد CPU.
سقف محلی هم فقط تا وقتی یه پروسه داری معنی داره؛ با چهار رپلیکا و سقف پنج، عملاً ۲۰ سشن زنده میشه. پس مالکیت جاب میره تو یه صف یا جدول پایدار با claim اتمیک، lease و کلید idempotency تا ریتری، PR تکراری نسازه. نویسنده میگه زمان کل بچ برای تیونکردن استخر کافی نیست و باید صف، حافظهٔ پیک، throttling و هزینهٔ هر جاب جدا دیده بشه؛ ۳.۸ برابر شدن سرعت هم یه اندازهگیری عملیاتیه، نه بنچمارک.
نکات کلیدی:
- بچ ۳۰ مخزنی: حدود ۴۶ دقیقه ترتیبی در برابر حدود ۱۲ دقیقه با پنج ورکر (نزدیک ۳.۸ برابر)
- هر جاب فضای کار یکتا میخواد؛ مسیر ثابت یعنی state مشترک
- پاکسازی باید تو finally باشه تا خطا باعث نشت سشن و رانتایم نشه
- سقف همزمانی رو کمیابترین منبع تعیین میکنه، نه CPU
- با چند رپلیکا سقف محلی کافی نیست: صف پایدار، lease و کلید idempotency لازمه




