Продакшн упал из-за состояния гонки в асинхронном коде — статический анализатор молчал, а код работал нестабильно. 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 неделя
Стоимость рассчитывается индивидуально. Оценим ваш проект за один рабочий день — свяжитесь с нами. Получите консультацию по вашему проекту.







