Портфоліо Послуги Компанія Контакти Блог Оцінити проєкт
uaruen
Мнемозіна впорядковує книгу, документи та карту залежностей у мармуровому архіві.
Технології

ШІ для legacy-коду: як дослідити, задокументувати й рефакторити систему

Іван Дейнека
Іван Дейнека
Засновник BotLabs
· Оновлено 10 хв читання
Ключове: Як вивчати незнайомий legacy-код із ШІ: скласти карту системи, зафіксувати поведінку тестами, документувати гіпотези й рефакторити малими кроками.

Коротка відповідь: так, ШІ допомагає з legacy-кодом, але переважно на етапі знайомства із системою. Він швидко пояснює, що робить функція, звідки береться виклик, які таблиці читаються і які зовнішні сервіси задіяні. Він може запропонувати чернетку документації і невеликі зміни. Але будь-яке пояснення моделі — це гіпотеза про код, а не знання про бізнес. А збереження поведінки після рефакторингу треба підтверджувати незалежними перевірками, а не відповіддю тієї самої моделі «так, поведінка не змінилася».

Тому безпечна послідовність така: спочатку скласти карту системи, потім зафіксувати спостережувану поведінку тестами, і лише після цього змінювати код невеликими частинами. Ця стаття допоможе вирішити, які задачі віддати ШІ, як відрізнити підтверджений факт від припущення в документації, які докази вимагати перед прийняттям рефакторингу і в яких випадках варто зупинитися.

Що ШІ може дізнатися з коду

Код зберігає багато відповідей, які людині довго шукати вручну. ШІ добре справляється з такими задачами:

  • Ланцюжки викликів. Хто викликає цю функцію, що вона викликає далі, де закінчується обробка запиту.
  • Залежності. Які бібліотеки, модулі та зовнішні сервіси використовуються і в яких місцях.
  • Дані. Які таблиці, файли чи черги читаються і змінюються, які поля беруть участь у розрахунку.
  • Ймовірне призначення. Коротке пояснення «ця функція, схоже, розраховує знижку для оптових клієнтів» на основі назв, коментарів і логіки.

Останній пункт — найризикованіший. Код показує, що відбувається, але не завжди чому. Якщо у функції є умова «якщо регіон дорівнює 7, не нараховувати комісію», модель може правдоподібно пояснити, що це пільга для певного регіону. Насправді це може бути тимчасовий виняток під давню домовленість з одним партнером, який давно не діє, або обхід помилки в іншій системі. Таких бізнес-домовленостей у коді немає, і ШІ їх не відновить. Їх знають люди: власники процесу, бухгалтерія, служба підтримки, іноді лише архів листування.

Чи пришвидшить ШІ саму роботу — окреме питання, на яке немає універсальної відповіді. В одному рандомізованому дослідженні на початку 2025 року 16 досвідчених розробників виконали 246 задач у знайомих їм проєктах відкритого коду. Коли ШІ-інструменти дозволялися, задачі в середньому займали на 19% більше часу, хоча самі учасники до початку очікували прискорення на 24%, а після завершення вважали, що прискорилися на 20%. Це був знімок можливостей тодішніх інструментів у конкретних умовах, а не оцінка всіх команд чи сучасних систем; автори згодом позначили цей результат як застарілий. У наступній оцінці, опублікованій у 2026 році, повторити вимірювання стало складніше: частина розробників відмовлялася працювати без ШІ, а 30–50% опитаних повідомили, що не подавали в дослідження деякі задачі, які не хотіли виконувати без ШІ. Нові оцінки показують радше прискорення, але автори називають ці дані дуже слабким доказом. Висновок для legacy-проєкту простий: не плануйте строки, спираючись на чуже середнє, і не покладайтеся на відчуття команди — вимірюйте на своїх задачах.

Як відновити карту системи

Перед будь-якими змінами потрібна карта: що в системі є і що в ній найважливіше. ШІ допомагає її скласти, але кожен пункт карти перевіряє людина.

Точки входу. Звідки в систему приходять запити: веб-сторінки, API, планувальник задач, обробники черг, імпорт файлів. Попросіть ШІ знайти всі місця, де реєструються маршрути, задачі за розкладом чи обробники повідомлень, а потім звірте зі списком із конфігурації сервера і планувальника. Задачі, які запускаються зовні, наприклад з системного планувальника на іншому сервері, у коді можуть узагалі не бути видно.

Критичні операції. Які дії пов’язані з грошима, юридичними документами, персональними даними, складськими залишками. Тут ШІ може запропонувати список кандидатів, але визначити, що критично, мають власники процесу.

Зовнішні сервіси. Платіжні системи, служби доставки, облікові програми, поштові розсилки. Для кожного — що система відправляє, що отримує і що станеться, якщо сервіс не відповідає.

Власники даних. Хто вирішує, як має працювати розрахунок, хто відповідає за таблицю чи довідник. Якщо власника немає, це вже важлива знахідка.

Де зберігається стан. База даних, файли, кеш, змінні середовища, налаштування в адміністративній панелі. Особливо небезпечні місця, де поведінка залежить від даних, яких немає в репозиторії.

Зручний формат карти — таблиця з колонками «компонент», «що робить», «звідки відомо» і «хто підтвердив». Остання колонка спочатку переважно порожня, і це нормально: так видно, скільки знань ще не перевірено.

Як фіксувати поведінку

Головний ризик рефакторингу legacy-коду — втратити поведінку, про яку ніхто не знав, але від якої хтось залежить. Захист від цього — характеризаційні тести. Вони фіксують не те, як система повинна працювати, а те, як вона працює зараз. Якщо поточна поведінка дивна, тест її однаково фіксує, а питання «чи це помилка» виноситься окремо.

Як це виглядає на практиці:

  1. Обрати функцію або сценарій, який будете змінювати.
  2. Зібрати набір входів: типові значення, межі діапазонів, порожні й некоректні дані, від’ємні числа, дуже великі значення. ШІ добре пропонує граничні випадки, які людина могла б пропустити.
  3. Запустити поточний код на цих входах у дозволеному середовищі і записати фактичні результати. Саме запустити, а не попросити модель передбачити результат.
  4. Оформити ці пари «вхід → результат» як тести.
  5. Дані для тестів знеособити: реальні імена, телефони, номери рахунків у тестових наборах не потрібні.

Окремо зафіксуйте побічні ефекти: які записи з’являються в базі, які листи відправляються, які файли створюються. Для зовнішніх сервісів знадобляться заглушки, але їх варто будувати на основі реальних записаних відповідей, а не на здогадках про те, як сервіс мав би відповідати.

Як писати документацію

Документацію legacy-системи найлегше зіпсувати впевненими формулюваннями. Згенерований текст «функція розраховує бонус лояльності» виглядає як знання, хоча насправді це припущення моделі за назвою змінної. Через рік ніхто не згадає, що ці слова ніхто не перевіряв.

Тому кожен факт у документації має бути прив’язаний до доказу: файлу, функції, тесту, спостереження чи підтвердження конкретної людини. Непідтверджені твердження позначаються як гіпотези. Пропонований шаблон для опису функції чи модуля:

ПолеЩо записатиПриклад
ПризначенняЩо робить, з позначкою «підтверджено» або «гіпотеза»Гіпотеза: розраховує знижку для оптових клієнтів
ВходиПараметри, джерела даних, налаштуванняСума замовлення, тип клієнта, таблиця тарифів
ВиходиЩо повертає, у якому форматіЦіле число копійок
Побічні ефектиЗаписи в базу, листи, виклики сервісівЗаписує рядок у журнал знижок
ПідтвердженняЧим підтверджено кожен пунктХарактеризаційні тести на 14 входах; власник процесу підтвердив поріг суми
НевідомеЩо з’ясувати не вдалосяЧому для регіону 7 знижка не нараховується

Поле «невідоме» — не формальність. Воно показує, де рефакторинг особливо небезпечний, і дає конкретний список питань для власників процесу. ШІ можна попросити заповнити шаблон, але з окремою вимогою: для кожного пункту вказати, на якому рядку коду ґрунтується твердження. Пункти без такої прив’язки автоматично йдуть у колонку гіпотез.

Як проводити рефакторинг

Рефакторинг legacy-коду з ШІ проходить безпечніше, якщо діяти дрібними кроками:

  • Один тип зміни за крок. Окремо перейменування, окремо винесення функції, окремо оновлення синтаксису. Змішаний diff складно перевірити.
  • Малий diff. Зміну, яку рецензент не може повністю зрозуміти за один перегляд, краще розбити.
  • Тести на межі до зміни. Характеризаційні тести мають проходити до і після.
  • Перевірка сумісності. Формати даних, API для інших систем, поведінка під навантаженням.
  • План відкату. Як швидко повернути попередню версію, якщо проблема проявиться вже після випуску.

Окремо про самоперевірку моделі. В одному неперевіреному препринті 2026 року дослідники провели 1980 викликів моделей для модернізації 60 фрагментів Python 2 на сучасний код, використавши 11 моделей із 7 сімейств. Результат кожної зміни перевіряли строгим поведінковим тестом. У фрагментах із семантичними пастками поведінка змінювалася в 39,7% спроб, у контрольних фрагментах без пасток — у 7,0%. Потім кожна модель оцінювала, чи зберегла вона поведінку. Із 262 випадків зміненої поведінки 83, тобто 31,7%, та сама модель оцінила як коректні. Різниця між моделями була величезною: від 0% таких пропусків у п’яти моделях до 100% в одній. Частина моделей прямо описувала відмінність між Python 2 і 3, яка зламала їхній код, і тут же заявляла, що поведінку збережено.

Це дослідження мало чіткі межі: це короткі фрагменти однієї мови і один тип задачі, а не повні корпоративні системи. Воно не дає частоти помилок для вашого проєкту. Але його практичний висновок прямо стосується legacy: переконливе пояснення моделі не замінює незалежної перевірки поведінки.

Навчальний приклад: ділення під час переходу з Python 2 на Python 3

Це навчальний приклад для ілюстрації методу. У Python 2 оператор / для двох цілих чисел виконує ділення з округленням униз: 7 / 2 дає 3, а -7 / 2 дає -4. У Python 3 той самий оператор завжди виконує звичайне ділення: 7 / 2 дає 3.5. Але є дві умови, які змінюють картину. Якщо в модулі Python 2 є рядок from __future__ import division, оператор / уже там працює як у Python 3. А якщо хоча б один операнд дробовий, Python 2 теж повертає дробовий результат: 7.0 / 2 дає 3.5.

Тепер подивіться на типові «виправлення». Залишити / як є — для цілих чисел результат зміниться з 3 на 3.5. Механічно замінити на // — для цілих чисел поведінка збережеться, але якщо в цю функцію колись приходили дробові значення, 7.0 // 2 дасть 3.0 замість колишніх 3.5. Обгорнути в int(a / b) — для від’ємних чисел вийде -3 замість колишніх -4, бо int відкидає дробову частину, а не округлює вниз.

Тому від автора зміни, людини чи ШІ, варто вимагати три речі:

  1. Вихідну поведінку, отриману запуском старого коду на кількох входах: додатні й від’ємні цілі, дробові, нуль у знаменнику, а також перевірку, чи є в модулі імпорт division з __future__.
  2. Очікуваний контракт: які типи реально приходять у функцію в робочій системі і чи має результат лишитися цілим.
  3. Тест після зміни, який проходить на тих самих входах з тими самими результатами.

Відповідь «я врахував різницю між Python 2 і 3» доказом не є. Доказ — таблиця входів і результатів до і після.

Коли зупинитися

Не кожну частину legacy-системи варто рефакторити з ШІ навіть дрібними кроками. Є ситуації, які потребують окремого розбору з власниками процесу і, можливо, окремого плану робіт.

Невідомі розрахунки. Якщо функція рахує гроші, податки, нарахування чи штрафи, а ніхто не може пояснити правила, спочатку потрібне з’ясування правил, а не нова версія коду.

Міграція даних. Зміна структури таблиць чи форматів зберігання зачіпає не лише код, а й накопичені дані. Помилку в міграції складно відкотити, якщо нові дані вже записалися в новому форматі.

Зовнішні побічні ефекти. Відправка платежів, листів клієнтам, документів у державні системи. Такі дії неможливо «скасувати» відкатом коду.

Немає відтворюваної перевірки. Якщо поведінку неможливо зафіксувати тестами, наприклад через відсутність тестового середовища або залежність від даних, до яких немає доступу, будь-який рефакторинг стає ставкою наосліп.

У цих випадках ШІ все ще корисний: для карти, пояснень, переліку питань і чернетки тестів. Але рішення про зміну коду переноситься до моменту, коли з’явиться перевірка.

Підсумок і перші кроки

ШІ скорочує шлях до розуміння legacy-системи, але не робить це розуміння автоматично правильним. Пояснення моделі — гіпотеза, документація без прив’язки до доказів — ризик, а рефакторинг без незалежної перевірки поведінки — ставка, навіть якщо модель упевнена.

Що можна зробити на своєму проєкті:

  1. Скласти з ШІ карту системи: точки входу, критичні операції, зовнішні сервіси, місця зберігання стану. Позначити, хто підтвердив кожен пункт.
  2. Вибрати один невеликий модуль і написати для нього характеризаційні тести на знеособлених даних, запускаючи реальний код.
  3. Задокументувати модуль за шаблоном «призначення, входи, виходи, побічні ефекти, підтвердження, невідоме».
  4. Виконати перший рефакторинг одним типом змін і малим diff, з планом відкату.
  5. Скласти список зон «стоп»: невідомі розрахунки, міграції, незворотні зовнішні дії, місця без перевірки. Для кожної — окреме питання власнику процесу.
  6. Порівняти фактичні витрати часу з очікуваннями, щоб наступні оцінки спиралися на ваші дані.

Якщо потрібно визначити межі такого технічного пілоту — з якого модуля почати, які критерії перевірки поведінки зафіксувати, хто підтримуватиме інтеграції після змін, — команда BotLabs може розібрати з вами вашу систему і запропонувати реалістичний перший крок.

Часті запитання

Можна, але це суттєво підвищує ризик втратити невідому поведінку. Тести, написані після переписування, перевіряють нову версію коду, а не те, як система працювала раніше. Якщо стара функція мала неочевидну особливість, наприклад особливе округлення чи виняток для певних клієнтів, тести після переписування її вже не зафіксують. Безпечніше спочатку отримати достатні незалежні перевірки важливих контрактів на старому коді і лише потім змінювати його.

Чесно позначати їх як невідомі або як гіпотези. Підтверджені факти прив’язувати до коду, результатів тестів, спостережень у дозволеному середовищі або до слів конкретного власника процесу. Гіпотези збирати в окремий список питань і проходити його з людьми, які працюють із процесом: бухгалтерією, підтримкою, продажами. Згенероване ШІ пояснення не перетворюється на знання лише тому, що записане в документацію.

Як помічник на окремих етапах — можливо: для карти залежностей, пояснень, чернеток тестів і невеликих перетворень. Але можливість великої міграції визначається не моделлю, а тим, чи є у вас перевірки поведінки, чи зрозумілі залежності між частинами системи, як мігрують дані і чи є план відкату для кожного етапу. Без цього навіть дуже точний помічник не зробить міграцію безпечною.

Отримати консультацію

15 хв · консультація фахівця

Консультація з legacy-пілоту

За 15 хвилин із технічним фахівцем BotLabs обговоримо один legacy-модуль, відомі бізнес-правила й можливість перевірити його поведінку. Визначимо, які підтвердження потрібні до зміни коду та з чого почати підготовку пілоту.

15 хвилин із фахівцем.

КОНСУЛЬТАЦІЯ ДЛЯ БІЗНЕСУ
LEGACY-МОДУЛЬ → ПЕРЕВІРКИ ПОВЕДІНКИ → НАСТУПНИЙ КРОК

Legacy-модуль
Перевірки поведінки

15 хвилин із фахівцем: оберемо межі модуля й перевірки поведінки, потрібні до рефакторингу.

технічна консультація15 хв · консультація фахівця
… натисніть, щоб підтримати
Поділитись: Telegram LinkedIn Facebook
Іван Дейнека
Іван Дейнека
Засновник BotLabs
Іван Дейнека — засновник BotLabs Agency. Понад 8 років працює з цифровими продуктами та автоматизацією бізнесу.
← Назад до блогу

Рекомендовані статті

Пілот для legacy-модуля15 хвилин із фахівцем.Отримати консультацію