Продакшн впав через стан гонки в асинхронному коді — статичний аналізатор мовчав, а код працював нестабільно. AI-аналіз знайшов проблему за секунди. Знайома картина: лінтери знаходять синтаксис, але пропускають логічні помилки та архітектурні діри. Ми розробляємо AI-аналізатори коду, які працюють на рівні семантики. Вони не замінюють звичні інструменти на кшталт ruff або SonarQube, а доповнюють їх — ловлять те, що приховано від статики.
Як AI-аналіз перевершує статичний?
Статичні аналізатори (ruff, SonarQube, ESLint) знаходять синтаксичні порушення та відомі антипатерни. AI-аналіз працює на рівень вище: розуміє семантику коду, бачить архітектурні проблеми, помічає невідповідність між іменем функції та її поведінкою, виявляє приховані залежності. Це не заміна лінтеру — це наступний шар аналізу.
| Характеристика | Статичний аналізатор | AI-аналіз |
|---|---|---|
| Область покриття | Синтаксис, відомі патерни | Семантика, архітектура, приховані баги |
| Глибина аналізу | Поверхневий | Контекстний, з розумінням бізнес-логіки |
| Адаптивність | Правила фіксовані | Навчається на проекті |
| Хибні спрацьовування | Часто | Нижче за рахунок контексту |
За нашими даними, AI-аналіз виявляє в 3 рази більше критичних проблем, ніж статичний аналіз самостійно. На думку експертів, статичні аналізатори знаходять лише 20% логічних помилок — решта залишається прихованою до продакшену. AI-аналіз закриває цю прогалину.
| Тип проблеми | Приклади | Як знаходить AI |
|---|---|---|
| Архітектурні | God Object, циклічні залежності | Аналіз графа викликів та структури класів |
| Приховані баги | Race condition, off-by-one | Семантичне розуміння потоків керування |
| Безпека | SQL injection, хардкод ключів | Розпізнавання вразливих патернів та контексту |
| Продуктивність | N+1 запити, блокування в async | Оцінка часової складності та асинхронних ланцюжків |
Архітектура аналізатора
Реалізація складається з двох рівнів: швидкий статичний прохід та глибокий AI-аналіз. Код нижче демонструє типову реалізацію. На практиці ми адаптуємо промпти під стек проекту та використовуємо fine-tuned моделі для кращої точності.
from anthropic import Anthropic import ast import subprocess from pathlib import Path from dataclasses import dataclass from typing import Literal import json client = Anthropic() @dataclass class QualityIssue: file: str line: int | None severity: Literal["critical", "major", "minor", "info"] category: str title: str description: str recommendation: str class CodeQualityAnalyzer: def analyze_file(self, file_path: str) -> list[QualityIssue]: """Повний аналіз файлу: статичний + AI""" source = Path(file_path).read_text() # Рівень 1: швидкий статичний аналіз static_issues = self._run_static_analysis(file_path, source) # Рівень 2: AI-аналіз для глибоких проблем ai_issues = self._run_ai_analysis(file_path, source) return static_issues + ai_issues def _run_static_analysis(self, file_path: str, source: str) -> list[QualityIssue]: """ruff + radon для complexity метрик""" issues = [] # Запускаємо ruff result = subprocess.run( ["ruff", "check", "--output-format=json", file_path], capture_output=True, text=True ) if result.stdout: for item in json.loads(result.stdout): issues.append(QualityIssue( file=file_path, line=item["location"]["row"], severity="minor", category="style", title=item["code"], description=item["message"], recommendation="See ruff documentation", )) # Cyclomatic complexity через radon result = subprocess.run( ["radon", "cc", "-j", file_path], capture_output=True, text=True ) if result.stdout: data = json.loads(result.stdout) for funcs in data.values(): for func in funcs: if func.get("complexity", 0) > 10: issues.append(QualityIssue( file=file_path, line=func.get("lineno"), severity="major" if func["complexity"] > 15 else "minor", category="complexity", title=f"High complexity: {func['name']}", description=f"Cyclomatic complexity: {func['complexity']} (threshold: 10)", recommendation="Decompose into smaller functions", )) return issues def _run_ai_analysis(self, file_path: str, source: str) -> list[QualityIssue]: """AI-аналіз архітектурних та семантичних проблем""" response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, system="""Ти — senior code reviewer. Аналізуй код на: 1. АРХІТЕКТУРНІ ПРОБЛЕМИ: порушення SOLID, God Object, Feature Envy 2. ПРИХОВАНІ БАГИ: race conditions, off-by-one, неправильна обробка None 3. БЕЗПЕКА: SQL injection, XSS, незахищені credentials 4. ПРОДУКТИВНІСТЬ: N+1 queries, блокуючі операції в async, memory leaks 5. СЕМАНТИКА: невідповідність імені та поведінки, misleading comments Поверни JSON масив проблем: [{ "line": <number або null>, "severity": "critical|major|minor|info", "category": "architecture|bug|security|performance|semantics", "title": "<короткий заголовок>", "description": "<що саме не так>", "recommendation": "<як виправити>" }] """, messages=[{ "role": "user", "content": f"Проаналізуй якість коду:\n\n```python\n{source[:5000]}\n```" }] ) text = response.content[0].text try: # Витягуємо JSON start = text.find("[") end = text.rfind("]") + 1 issues_data = json.loads(text[start:end]) return [QualityIssue( file=file_path, line=item.get("line"), severity=item.get("severity", "info"), category=item.get("category", "general"), title=item.get("title", ""), description=item.get("description", ""), recommendation=item.get("recommendation", ""), ) for item in issues_data] except Exception: return [] Приклад виведення аналізатора
Типовий звіт містить для кожного файлу: кількість критичних, major та minor проблем, а також json-масив з деталями. Наприклад: ``` [ { "file": "payment_service.py", "severity": "critical", "category": "security", "title": "Hardcoded API key", "description": "API ключ знайдено у вихідному коді", "recommendation": "Винести в змінні середовища" } ] ```Оцінка технічного боргу
Технічний борг — це не просто метрика, а реальні витрати на підтримку. Пропускаючи його, ви ризикуєте втратити тижні на багфікси. AI-аналіз допомагає його виміряти та пріоритизувати.
class TechDebtAnalyzer: def analyze_module(self, module_path: str) -> dict: """Оцінює технічний борг модуля""" source = Path(module_path).read_text() response = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": f"""Оціни технічний борг цього модуля. Поверни JSON: {{ "debt_score": <0-100, де 100 = максимальний борг>, "estimated_hours": <оцінка годин на рефакторинг>, "top_issues": [ {{"category": "...", "description": "...", "impact": "high|medium|low"}} ], "quick_wins": ["<що можна покращити за 30 хв>"], "requires_redesign": <true/false> }} Код: ```python {source[:4000]} ```""" }] ) text = response.content[0].text start = text.find("{") end = text.rfind("}") + 1 return json.loads(text[start:end]) def generate_refactoring_plan(self, module_path: str, debt_report: dict) -> str: """Генерує план рефакторингу на основі аналізу боргу""" response = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": f"""На основі аналізу технічного боргу склади план рефакторингу. Звіт: {json.dumps(debt_report, ensure_ascii=False, indent=2)} Формат: пріоритизований список завдань з оцінкою часу та очікуваним результатом. Групуй за: Quick Wins (< 2год), Medium Tasks (2–8год), Major Refactoring (> 8год).""" }] ) return response.content[0].text Dashboard метрики якості
Метрики можна візуалізувати в Grafana або власній dashboard. AI-аналіз не тільки знаходить проблеми, а й відстежує динаміку — ви бачите, чи покращується код після кожного спринту.
def generate_quality_report(project_root: str) -> dict: """Генерує звіт про якість всього проекту""" analyzer = CodeQualityAnalyzer() all_issues = [] file_metrics = {} for py_file in Path(project_root).rglob("*.py"): if any(skip in str(py_file) for skip in ["migrations", "__pycache__", ".venv"]): continue issues = analyzer.analyze_file(str(py_file)) all_issues.extend(issues) file_metrics[str(py_file)] = { "critical": len([i for i in issues if i.severity == "critical"]), "major": len([i for i in issues if i.severity == "major"]), "minor": len([i for i in issues if i.severity == "minor"]), } # Топ проблемних файлів worst_files = sorted( file_metrics.items(), key=lambda x: x[1]["critical"] * 10 + x[1]["major"] * 3 + x[1]["minor"], reverse=True )[:10] return { "total_issues": len(all_issues), "by_severity": { "critical": len([i for i in all_issues if i.severity == "critical"]), "major": len([i for i in all_issues if i.severity == "major"]), "minor": len([i for i in all_issues if i.severity == "minor"]), }, "by_category": {}, "worst_files": worst_files, "quality_score": calculate_quality_score(all_issues, len(file_metrics)), } def calculate_quality_score(issues: list, file_count: int) -> float: """Єдиний скор якості коду (0-100)""" if file_count == 0: return 100.0 penalty = sum({ "critical": 10, "major": 3, "minor": 1, "info": 0, }.get(i.severity, 0) for i in issues) # Нормалізуємо за кількістю файлів score = max(0, 100 - penalty / file_count) return round(score, 1) Практичний кейс з нашої практики: платіжний сервіс
Задача: Наш клієнт — великий платіжний сервіс, 15000 рядків Python, 4 роки без рефакторингу. Перед додаванням нових платіжних провайдерів — аудит якості.
Результати AI-аналізу за 2 години:
- 3 критичні проблеми безпеки (hardcoded API keys в тестах, що потрапили в репозиторій, SQL без параметризації в одному місці, логування даних карт в debug режимі)
- 12 архітектурних проблем (God Object PaymentProcessor з 2800 рядків, циклічні імпорти)
- 47 проблем з обробкою помилок
Пріоритизація:
- Sprint 1: критичні security issues (3 дні)
- Sprint 2: декомпозиція PaymentProcessor (2 тижні)
- Sprint 3: error handling + тести (1 тиждень)
Якість коду до/після: score 31/100 → 72/100 після трьох спринтів. Команда скоротила час на код-рев'ю на 40%.
Без AI-аналізу ручний аудит зайняв би 3–5 днів одного senior-розробника. AI-аналіз прискорює аудит в 5–10 разів без втрати глибини. Зв'яжіться з нами — отримайте демонстрацію аналізатора на вашому коді.
Чому AI-аналіз економить тижні розробки?
Ручний аудит коду — дороге задоволення. Senior-розробник витрачає 3–5 днів на проект 15K рядків. AI-аналіз робить ту ж роботу за 2 години, причому знаходить проблеми, які людина могла пропустити через втому. Крім того, AI не залежить від людського фактора: він завжди послідовний і документує кожне зауваження. На практиці команда отримує готовий звіт з оцінкою трудовитрат на виправлення — не потрібно витрачати час на аналіз аналітика.
Що входить в роботу
- Статичний аналіз коду (ruff, SonarQube, ESLint) для швидкої перевірки синтаксису та стилю
- AI-аналіз архітектурних та семантичних проблем з класифікацією за severity
- Оцінка технічного боргу з пріоритизацією (Quick Wins, Medium, Major)
- План рефакторингу коду на основі AI-аналізу
- Інтеграція в CI/CD з quality gate (автостоп при перевищенні порогу)
- Dashboard з історичними метриками
- Гарантія відсутності false positives за критичними категоріями після калібрування (досвід роботи з десятками проектів підтверджує точність >95%)
Строки
- Базовий аналізатор (статичний + AI для одного файлу): 2–3 дні
- Проектний аналіз зі звітом: 1 тиждень
- Dashboard з історичними метриками: 2 тижні
- Інтеграція в CI/CD з quality gate: 1 тиждень
Вартість рішення починається від $2,000 за базовий аудит, а економія на рефакторингу складає $10,000+. Ми — команда з 6-річним досвідом у AI, виконали понад 25 проектів з аналізу коду. Отримайте консультацію по вашому проекту.
За результатами внутрішнього тестування на 20 проектах точність детекції критичних проблем становить 95%.
Додатково: використовуйте AI для автоматичного code review. Наш аналізатор коду Python підтримує останні версії. Ми враховуємо цикломатичну складність як один з показників. Семантичний аналіз коду дозволяє знаходити логічні помилки.







