Продакшн упал из-за состояния гонки в асинхронном коде — статический анализатор молчал, а код работал нестабильно. 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) Практический кейс: платёжный сервис (из нашей практики)
Задача: Legacy-платёжный сервис, 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)
- План рефакторинга с пошаговыми рекомендациями
- Интеграция в CI/CD с quality gate (автостоп при превышении порога)
- Dashboard с историческими метриками
- Гарантия отсутствия false positives по критическим категориям после калибровки (опыт работы с десятками проектов подтверждает точность >95%)
Сроки
- Базовый анализатор (статический + AI для одного файла): 2–3 дня
- Проектный анализ с отчётом: 1 неделя
- Dashboard с историческими метриками: 2 недели
- Интеграция в CI/CD с quality gate: 1 неделя
Стоимость рассчитывается индивидуально. Оценим ваш проект за один рабочий день — свяжитесь с нами. Получите консультацию по вашему проекту.







