Легасі-проект на Python з 40% дублювання коду та відсутністю type hints — знайома картина. Senior-розробник розуміє, що потрібно виправити, але 80% часу йде на механічне переписування. Ми беремо цю механіку на себе, залишаючи людині архітектурні рішення та рев’ю. Наш досвід показує: AI-рефакторинг у 5–10 разів швидший за ручний, а з тестовою страховкою — безпечніший. Замовте пробний рефакторинг одного файлу — за 1 день отримаєте результат і переконаєтеся в якості.
Типовий легасі-проект на Python страждає від трьох проблем. Перша — відсутність анотацій типів. Друга — функції завдовжки в 200 рядків. Третя — дублювання коду на 40%. Senior-розробник витрачає тижні на ручне виправлення, але результат все одно містить помилки. AI-рефакторинг вирішує це завдання за дні. Вартість рефакторингу одного файлу розраховується індивідуально.
Чому AI-рефакторинг швидший за ручний?
AI обробляє рутину за секунди: додає type hints, виділяє функції, усуває дублікати. Людина контролює результат, а не виконує механічну роботу. Це скорочує час рефакторингу з тижнів до днів. Середня економія на проекті становить до 80% бюджету.
Види рефакторингу та підходи
- Структурний рефакторинг (extract method, move class, rename) — добре піддається автоматизації, точність AI висока.
- Патерновий рефакторинг (перехід з callbacks на async/await, додавання dependency injection) потребує контексту — AI справляється при правильному промпті.
- Архітектурний рефакторинг (monolith → microservices, God Object → SRP) — AI генерує план і чернетку, фінальні рішення за людиною.
| Тип рефакторингу | Роль AI | Роль людини | Типовий час |
|---|---|---|---|
| Структурний | 90% роботи | Рев’ю | 1–2 дні |
| Патерновий | 70% роботи | Доробка контексту | 3–5 днів |
| Архітектурний | 50% роботи (план + чернетка) | Прийняття рішень | 1–3 тижні |
Рефакторинг — це зміна внутрішньої структури програми без зміни її зовнішньої поведінки. Ми дотримуємося цього принципу, використовуючи AI для автоматизації.
Як тестова страховка гарантує збереження функціональності?
Ми впровадили систему safe-refactor: перед змінами запускаються всі тести. Якщо після рефакторингу тести падають, зміни автоматично відкочуються. Це робить процес безпечнішим за ручний — людські помилки виключені на 90%. Код-рев’ю залишається за senior-розробником.
Async migration та type hints — приклади
def migrate_to_async(source_file: str) -> str:
"""Мігрує синхронний код на async/await"""
source = Path(source_file).read_text()
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=8096,
system="""Мігруй Python код з синхронного на async/await.
Правила:
- requests → httpx.AsyncClient
- time.sleep(n) → asyncio.sleep(n)
- threading.Thread → asyncio.create_task
- queue.Queue → asyncio.Queue
- Додай async/await до функцій, які роблять I/O
- Залиш синхронними функції без I/O (чисті обчислення)
- Заміни for loop на asyncio.gather де функції незалежні""",
messages=[{"role": "user", "content": f"Мігруй на async/await:\n\n```python\n{source}\n```\n\nПоверни тільки код."}])
text = response.content[0].text
if "```python" in text:
return text.split("```python")[1].split("```")[0].strip()
return text
def add_type_hints(source_file: str) -> str:
"""Додає анотації типів до функцій"""
source = Path(source_file).read_text()
tree = ast.parse(source)
unannotated = []
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
has_annotations = (
any(arg.annotation for arg in node.args.args) or
node.returns is not None
)
if not has_annotations:
unannotated.append(node.name)
if not unannotated:
return source
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=8096,
messages=[{"role": "user", "content": f"""Додай анотації типів Python (PEP 484) до функцій: {', '.join(unannotated)}
Правила:
- Використовуй from __future__ import annotations для forward references
- Для Optional використовуй X | None (Python 3.10+)
- Для колекцій: list[str], dict[str, int], tuple[int, ...]
- Для невідомих типів використовуй Any з typing
```python
{source}
Поверни повний файл з доданими анотаціями."""}]
)
text = response.content[0].text
if "python" in text: return text.split("python")[1].split("```")[0].strip()
return text
<details>
<summary>Приклад рефакторингу з тестовою страховкою</summary>
```python
def safe_refactor(
source_file: str,
refactoring_type: str,
test_file: str = None,
) -> dict:
"""Виконує рефакторинг тільки якщо тести проходять"""
source = Path(source_file).read_text()
refactorer = CodeRefactorer()
if test_file and Path(test_file).exists():
result = subprocess.run(
["python", "-m", "pytest", test_file, "-v", "--tb=short"],
capture_output=True, text=True
)
if result.returncode != 0:
return {"success": False, "error": "Tests failing before refactoring", "test_output": result.stdout}
refactoring = refactorer.refactor(source, refactoring_type)
backup_file = source_file + ".bak"
Path(backup_file).write_text(source)
Path(source_file).write_text(refactoring["refactored"])
if test_file and Path(test_file).exists():
result = subprocess.run(
["python", "-m", "pytest", test_file, "-v", "--tb=short"],
capture_output=True, text=True
)
if result.returncode != 0:
Path(source_file).write_text(source)
return {
"success": False,
"error": "Tests failing after refactoring — rolled back",
"changes": refactoring["changes"],
"test_output": result.stdout,
}
return {
"success": True,
"changes": refactoring["changes"],
"risks": refactoring["risks"],
"backup": backup_file,
}
Практичний кейс: Django-моноліт
Ситуація: Django-проект, 6 років розробки, 45 000 рядків. Три проблеми: немає type hints, багато дублювання в view-функціях, 12 God Object класів.
Застосовані рефакторинги (за 3 тижні):
-
add_type_hintsдля всіхviews.py— автоматично, 2 години -
extract_functionдля view-функцій > 50 рядків — автоматично + рев’ю, 1 тиждень -
remove_duplicationв сервісному шарі — автоматично, 3 дні
Результати:
- Type annotations coverage: 12% → 87%
- Середня довжина функції: 68 рядків → 23 рядки
- Дублювання коду (SonarQube metric): -43%
- Час онбордингу нового розробника: 3 тижні → 1.5 тижні
Один God Object (OrderService, 1800 рядків) потребував ручного архітектурного рішення — AI запропонував 3 варіанти декомпозиції, розробники обрали оптимальний.
Що входить в роботу
- Аналіз кодової бази та вибір типів рефакторингу
- Розробка промптів під конкретний стек (Python, Django, FastAPI)
- Реалізація safe-refactor з тестовою страховкою та backup
- Batch-обробка всіх файлів (або вибірково)
- Рев’ю змін нашим senior-розробником
- Документація змін та навчання команди
- Підтримка протягом місяця після впровадження
Процес роботи
- Аналітика — скануємо кодову базу, виявляємо проблемні місця (відсутність типів, довгі функції, дублювання).
- Проектування — визначаємо пріоритети, обираємо типи рефакторингу, налаштовуємо промпти під ваш стек.
- Реалізація — запускаємо AI-рефакторинг з тестовою страховкою, автоматично відкочуємо зміни при падінні тестів.
- Тестування — прогоняємо всі тести, перевіряємо метрики якості коду.
- Деплой — застосовуємо зміни в репозиторій, надаємо повний звіт.
Строки орієнтовно
| Етап | Строк |
|---|---|
| Базовий рефакторинг одного типу для файлу | 1–2 дні |
| Система safe refactor з тестовою страховкою | 3–5 днів |
| Batch-рефакторинг всієї кодової бази | 2–3 тижні |
| Інтеграція в IDE як команда | 1 тиждень |
Гарантуємо збереження функціональності — якщо після рефакторингу тести падають, відкочуємо зміни. Зв’яжіться з нами, щоб обговорити ваш проект: оцінимо обсяг робіт за 1 робочий день. Також надаємо сертифікат про проведені зміни та звіт по метриках.
Замовте оцінку проекту — ми підготуємо детальний план та розрахуємо вартість.







