
Цей матеріал згенеровано за допомогою штучного інтелекту та опубліковано без попередньої перевірки людиною. Він може містити помилки і не є професійною консультацією. Повідомити про проблему: info@delionsoft.com.
GitHub опублікував звіт про переписання середовища виконання агента Copilot — спільного двигуна, що лежить в основі Copilot CLI, додатка та SDK — з TypeScript на Node.js на Rust. Згідно з оригінальним звітом, результатом стало понад 800 000 рядків робочого коду на Rust, впровадженого через 128 пул-запитів у головну гілку, причому більшу частину коду написали агенти. Для решти нас цікавішим є не стільки вибір мови, скільки метод міграції.
Що сталося
Середовище виконання спочатку було написано на TypeScript, а SDK в підсумку було накладено поверх CLI, а не навпаки. Користувачі створювали клієнт, запускаючи підпроцес CLI та взаємодіючи з ним через JSON-RPC. Це означало, що кожен користувач SDK — C#, Python, Go, Java, Rust, TypeScript — доставляв середовище виконання другої мови, займав щонайменше приблизно 100 МБ робочої пам’яті, передавав кожну подію та операцію з файлами через межу процесу, втрачав сесію у разі аварійного завершення роботи Node та мав два процеси, за якими потрібно було стежити.
Метою була бібліотека без вбудованого TUI, яку можна було б вбудовувати в процес через C ABI, з низькими витратами на запуск та передбачуваним споживанням пам’яті. Rust було обрано саме з цих причин, а також завдяки інструментарію та стабільності ланцюга постачання; автори чітко зазначають, що це не є загальною рекомендацією щодо портування великих кодових баз TypeScript.
Міграція відбувалася на місці, компонент за компонентом, із атомарною заміною: кожен pull-запит замінював реалізацію на TypeScript на тонкий шім, що викликав код на Rust, і видаляв старий код у тому ж самому зміні. Основний код залишався готовим до випуску, існуючі наскрізні тести виконувалися на новому коді на кожному етапі, а невдалі обов’язкові тести блокували злиття. Вони навмисно уникли можливості гарячої заміни обох реалізацій, оскільки підсистеми, які найбільше виграли б від обережного паралельного переходу — наприклад, оркестрування сесій — саме ті, що мають спільний змінний стан та двонаправлені зворотні виклики, де підтримувати дві копії найскладніше.
Варто відзначити одну деталь: початковий обсяг робіт передбачав близько 130 000 рядків TypeScript. Автор оцінює, що фактично через процес перенесення пройшло приблизно 430 000 рядків виробничого коду, оскільки код постійно переносився з рівня TUI, а інші команди постійно об’єднували новий TypeScript упродовж усього процесу.
Чому це важливо
Заяви у заголовку — про одно- чи дворічний командний проєкт, який здебільшого виконав один розробник за кілька місяців, та про покращення продуктивності на кілька порядків — походять від самої команди і слід сприймати саме так. Однак структурний урок можна застосувати й до набагато менших кодових баз: допомога агентів змінює вартість переписання, а це означає, що архітектурний борг, який ви списали як постійний, тепер, можливо, варто переглянути. Це також підвищує цінність тих елементів, що роблять таку роботу безпечною, а саме: покриття тестами, диференціали, придатні для рецензування, та чіткі межі модулів.
Що робити
- Перш ніж розглядати будь-яке переписання за допомогою агента, перевірте, чи ваші наскрізні тести достатньо якісні, щоб слугувати «мердж-гейтом». Без цього інкрементальне перенесення не матиме запобіжного механізму.
- Віддавайте перевагу заміні на місці, компонент за компонентом, замість довготривалої гілки переписання. Збереження головної гілки в стані, придатному для випуску, усуває найгірший варіант збою, характерний для міграцій за принципом «біг-бангу».
- Перед перенесенням розділіть код за рівнями. Значна частина цих зусиль полягала у відокремленні середовища виконання від інтерфейсу користувача; ця робота корисна навіть у тому випадку, якщо ви ніколи не змінюватимете мову програмування.
- Визначайте обсяг робіт за графіком залежностей, а не за кількістю рядків. Компоненти зі спільним змінним станом потребуватимуть набагато більше ресурсів, ніж можна було б припустити, зважаючи на їхній розмір.
