تیم Copilot Cowork چطور با ایجنتها از Python به Rust کوچ کرد
خلاصهٔ کاملتر
تیم Copilot Cowork تو مایکروسافت (یه لایهٔ اجرایی agentic که کارهای چندمرحلهای رو از طرف کاربر انجام میده) اولین commit رو ۱۳ ژانویه زد و ۱۶ ژوئن به عرضهٔ جهانی رسید. تو ۲۱ اکتبر، ۹ مهندس ۱۲۱۱ PR رو تو یه روز merge کردن. نویسنده میگه بیشتر کد رو ایجنتها نوشتن، ولی ایجنتها فقط میتونستن تغییر پیشنهاد بدن و تصمیم نهایی با آدمها بود.
درس اول اینه که قبل از کد، spec بنویس. تیم فهمید گلوگاه خود ایجنت نیست، اینه که دقیق ندونی چی میخوای. برای همین قانون گذاشتن که هیچ کدی بدون یه spec مارکداون نوشته نشه: تغییر چیکار میکنه، از کجا میفهمیم کار میکنه، و چی رو نباید خراب کنه. خیلی از specها اول بهصورت صوتی گفته میشن و ایجنت ازشون پیشنویس میسازه.
درس دوم: ایجنتهای باریک تو مرزهای مشخص. هر ایجنت تو کپی خودش از ریپو، روی یه تسک و از روی یه spec کار میکنه. تعداد PRهای ماهانه از ۲۵۷ تو ژانویه به ۲۷۵۴ تو مه رسید. مدل تو یه کانتینر بدون credential کاربر اجرا میشه و یه host مطمئن بیرون کانتینر هویت، policy و تأییدها رو مدیریت میکنه. یعنی مدل هر چیزی رو میتونه درخواست بده، ولی host تصمیم میگیره واقعاً چی اجرا بشه.
درس سوم: چکها باید ثابت کنن واقعاً چیزی رو چک کردن. چند تا بات review با هم رقابت میکردن و اولین review معمولاً تو حدود چهار دقیقه و نیم میرسه. ولی یه بار باتها تو یه بخش حساس هیچ مشکلی پیدا نکردن و آدمها چهار مشکل جدی پیدا کردن. یه چک اندازهٔ فایل هم همیشه سبز میموند، چون خروجیش به tail pipe میشد و exit code مال tail بود. از اون به بعد هر چک باید بگه چند تا فایل چک کرده و یه تست داشته باشه که عمداً failش کنه، چون ایجنتها بالاخره راهی پیدا میکنن که چک بدون تست کردن چیزی pass بشه.
درس چهارم و پنجم دربارهٔ حافظه و ساختار کده. قوانین تیم تو حدود ۳۰ فایل rule داخل ریپو نگه داشته میشه تا هر ایجنت اول کار بخونهشون. workspace مربوط به Rust هم از ۸۶ crate با زنجیرهٔ وابستگی ۱۳ سطحی، با یه قانون چهار نقشی (Contract، Kit، Implementation، Binary) بازسازی شد. وابستگیهای بین implementationها از ۲۱۶ به صفر رسید و زنجیرهٔ rebuild بعد از تغییر crate پایه از ۱۱ به ۳ کم شد. درس ششم اینه که هر حلقهٔ خودکار یه هدف قابل اندازهگیری، یه معیار که نباید بدتر بشه، و یه سقف تلاش داشته باشه. مثلاً یه harness که تستها رو سریعتر میکنه، زمان CI فایلهای تستی که دست زده بود رو از حدود ۱۷۷۰۰ ثانیه به ۱۷۰۰ رسوند.
مهاجرت به Rust همهٔ این درسها رو با هم امتحان کرد. Python تو بار بالا تا ۱۱.۹ ثانیه event loop رو قفل میکرد، ۱۶.۷٪ ساخت sessionها دقیقاً ۵ ثانیه طول میکشید (یعنی یه timeout پنهون) و تو یه هفته ۵۳۹ بار بهخاطر کمبود حافظه kill شد. تیم برای اطمینان از درستی port، رفتار کد Python رو تو حدود ۴۳۰ فایل JSON به اسم fixture ضبط کرد و تست Rust باید دقیقاً همون خروجی رو بده:
let fixture: Fixture = serde_json::from_str(FIXTURE).expect("fixture parses");
assert_eq!(fixture.cases.len(), 48, "the generator's full grid");
for case in fixture.cases {
assert_eq!(turn_running(&case.inputs()), case.expected);
}تعداد caseها اول چک میشه، چون replay روی صفر case هم pass میشه. ترافیک cluster به cluster منتقل شد و ۱۰ اکتبر تموم شد. stallها و تأخیر ۵ ثانیهای از بین رفتن، ولی دو مشکل هم پیش اومد: ترتیب رویدادها که Python بدون اینکه کسی مشخصش کرده باشه رعایت میکرد، و front door اول Rust که حدود شش برابر کندتر جواب میداد. نویسنده میگه درس اصلی اینه که توجه آدمها رو ببری سمت تصمیمهای مهم: چی بسازیم، مرزها کجاست، و آیا یه چک سبز واقعاً همون معنیای رو داره که نشون میده.
نکات کلیدی:
- از اولین commit تا GA جهانی حدود چهار ماه و نیم طول کشید (۱۳ ژانویه تا ۱۶ ژوئن).
- PRهای ماهانه از ۲۵۷ به ۲۷۵۴ رسید و تو هفتهٔ ۱۲ اکتبر ۴۵۸۱ PR merge شد.
- هر تغییر قبل از کد یه spec مارکداون داره: چیکار میکنه، چطور تست میشه، چی رو نباید خراب کنه.
- مدل بدون credential تو کانتینر اجرا میشه و همهٔ عملیات Microsoft 365 از یه host مطمئن رد میشه.
- هر چک باید تعداد فایلهای چکشده رو گزارش بده و یه تست داشته باشه که عمداً failش کنه.
- مهاجرت به Rust با حدود ۴۳۰ fixture ضبطشده از رفتار Python تأیید شد.




