Перейти к содержимому
arckep.ru — все нейросети в одном месте без VPN Перейти
>AISTUDY_
Поддержать
AUTHORСвежий выпуск №024 → Куда внедрять агентов: фронт или тыл

Модуль 2.9 · Урок 2

Урок 2: Code Review с агентом

Практика
2.9 / Урок 2 из 4

Чему вы научитесь

  • Использовать AI для автоматического pre-review PR
  • Определять, что может проверять агент, а что — только человек
  • Настраивать git hooks для автоматического ревью перед коммитом
  • Создавать эффективные промпты для code review
  • Интегрировать AI review в CI/CD pipeline

Проблема: человеческие ревьюеры переутомлены

Типичный день ревьюера:

  • 20 PR в очереди
  • Каждый PR — 200-500 строк кода
  • Нужно искать баги, уязвимости, нарушения стиля, проблемы производительности
  • Результат: поверхностный ревью, баги проходят в продакшн

Решение: AI pre-review находит 70-80% проблем до human review. Ревьюер может сосредоточиться на архитектуре и бизнес-логике.

Готовые AI-инструменты для code review (2025-2026)

ИнструментТипЧто умеет
CodeRabbitGitHub/GitLab appАвто-ревью PR, walkthrough summary, line-by-line suggestions. Бесплатный тир есть (с лимитами).
SourceryGitHub app / VS CodeFocused code review, меньше шума, on-prem вариант
Claude CodeCLIВстроенный ревью через pre-commit hooks или вручную
GitHub CopilotIDE + GitHubInline suggestions и agent-powered code review для PR.

Команды сообщают о значительном снижении времени на ручное ревью при использовании CodeRabbit.

Ниже показано, как настроить собственный AI-ревью через Claude Code (без внешних сервисов).

graph LR
    A["Разработчик<br/>открывает PR"] -->|git push| B["[AI] Claude AI<br/>pre-review"]
    B -->|находит 70% проблем| C["Комментарий с<br/>проблемами"]
    C -->|dev исправляет| D["Human reviewer<br/>проверяет<br/>архитектуру"]
    D -->|[+] одобрено| E["Merge to main"]

Часть 1: Что может проверять агент

Таблица: AI vs Human

КатегорияAI можетHuman проверяетПримечание
Синтаксис/нарушения стиля[+] 100%Автоматически находит все
Потенциальные баги[+] 80%[+] Финальная проверкаМожет пропустить edge cases
Уязвимости безопасности[+] 70%[+] ОбязательноSQL injection, XSS, etc.
Производительность O(n)[+] 90%[+] ОбсуждениеМожет предложить улучшение
Мёртвый код[+] 95%[+] ИногдаUnused imports, переменные
Тесты достаточны[+] 60%[+] КритичноМожет не понять coverage intent
Бизнес-логика верна[-] 0%[+] 100%Требует контекста продакта
Архитектурное решение[-] 10%[+] 100%Нужна история проекта
API согласованность[+] 85%[+] ИногдаМожет найти breaking changes
Документация полна[+] 80%[+] ФинальноМожет предложить дополнения

Что НЕ может агент

  • Бизнес-требования: “Эта функция решает задачу X продакта?” — только человек
  • Архитектурные решения: “Должна ли это быть microservice?” — только человек
  • Trade-off’ы: “Скорость vs надёжность” — только человек с контекстом
  • Историческое знание: “Почему мы не используем Y?” — нужна память проекта
  • UX/DX интеграция: “Будет ли это удобно для фронтенда?” — нужно обсуждение

Часть 2: Настройка автоматического pre-review

Вариант 1: Git Hook (локально)

Файл .git/hooks/pre-commit:

#!/bin/bash

# pre-commit hook для автоматического review перед коммитом

echo "[AI] Запуск AI-review перед коммитом..."

# Получаем список изменённых файлов
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)

if [ -z "$CHANGED_FILES" ]; then
    echo "[-] Нет файлов для коммита"
    exit 1
fi

# Создаём diff для review
DIFF=$(git diff --cached)

# Вызываем Claude Code для review
claude "Проведи code review для следующего diff:

$DIFF

Проверь на:
1. Синтаксические ошибки
2. Потенциальные баги (null checks, edge cases)
3. Уязвимости безопасности (injection, XSS)
4. Нарушения стиля (PEP8, ESLint)
5. Мёртвый код (unused imports, variables)
6. Проблемы производительности (N+1 queries, O(n²))

Формат ответа:
## Баги найдены: [ДА/НЕТ]
[список с line numbers]

## Уязвимости: [ВЫСОКИЙ/СРЕДНИЙ/НИЗ/НЕТ]
[список]

## [+] Хороший код: [1-3 примера]

## Рекомендации: [1-3 пункта]" > /tmp/review.txt

# Показываем результат
cat /tmp/review.txt

# Если нашлись критические проблемы, останавливаем commit
if grep -q "ВЫСОКИЙ" /tmp/review.txt; then
    echo ""
    echo "[!]  Найдены проблемы безопасности ВЫСОКОГО уровня."
    echo "Исправьте перед коммитом или используйте --no-verify для пропуска."
    exit 1
fi

exit 0

Установка:

chmod +x .git/hooks/pre-commit

Вариант 2: GitHub Actions (в CI)

Файл .github/workflows/ai-review.yml:

name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  ai-review:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Get PR diff
        id: diff
        run: |
          git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-branch
          git diff origin/main...pr-branch > /tmp/pr.diff

      - name: Run Claude AI Review
        env:
          CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}
        run: |
          # Здесь вызов Claude через API или CLI
          claude "Проверь этот PR diff на баги, уязвимости, стиль..." > /tmp/review.md

      - name: Post review as comment
        uses: actions/github-script@v9
        with:
          script: |
            const fs = require('fs');
            const review = fs.readFileSync('/tmp/review.md', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## [AI] AI Code Review\n\n${review}`
            });

Часть 3: Эффективные промпты для review

Шаблон базовый

Проведи code review для этого фрагмента кода:

[КОД]

Фокусируйся на:
1. Безопасность
2. Производительность
3. Читаемость
4. Тестируемость

Формат:
- Баги: [список или "не найдено"]
- Уязвимости: [или "не найдено"]
- Производительность: [или "окей"]
- [+] Что хорошо: [1-2 примера]

Шаблон с контекстом (лучше)

Код ревью для PR #123: "Добавить кэширование в getUserData"

КОНТЕКСТ:
- Это legacy REST API, мигрируем на GraphQL
- Пики трафика: 10k req/sec в часы пик
- DB response time: 200ms в среднем
- Кэш TTL: 5 минут

КОД:
[КОД]

Проверь на:
1. Race conditions (кэш vs DB)
2. Cache invalidation правильность
3. Memory leak'и при большом кэше
4. Security (утечка приватных данных через кэш)

Приоритет: безопасность > производительность > чистота кода

Пример: Реальный код с проблемами

Файл user_service.py:

# Плохой код для review
user_cache = {}

def get_user(user_id):
    """Получить пользователя по ID"""
    # BUG #1: нет проверки user_id на валидность
    if user_id in user_cache:
        return user_cache[user_id]

    # BUG #2: нет обработки ошибок DB
    db = Database()
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")

    # BUG #3: SQL injection!
    # BUG #4: неограниченный рост кэша (memory leak)
    user_cache[user_id] = user

    # BUG #5: возвращаем весь объект, включая пароль
    return user
def update_user(user_id, data):
    """Обновить пользователя"""
    # BUG #6: не инвалидируем кэш после обновления
    db = Database()
    db.query(f"UPDATE users SET ... WHERE id = {user_id}")

Хороший ревью от Claude:

## [AI] AI Code Review

### Уязвимости: КРИТИЧЕСКИЙ

1. **SQL Injection (строка 13)** — прямое подставление user_id в SQL
   ```python
   # [-] ОПАСНО
   user = db.query(f"SELECT * FROM users WHERE id = {user_id}")

   # [+] ИСПРАВИТЬ
   user = db.query("SELECT * FROM users WHERE id = ?", (user_id,))

Баги

  1. Memory leak в кэше — неограниченный рост user_cache

    # [-] НЕПРАВИЛЬНО
    user_cache[user_id] = user  # Растёт бесконечно
    
    # [+] ИСПРАВИТЬ - используй LRU cache
    from functools import lru_cache
    
    @lru_cache(maxsize=10000)
    def get_user(user_id):
        ...
  2. Несогласованность кэша — при update_user кэш не инвалидируется

    # РАНЬШЕ: update_user не чистит кэш
    # ТЕПЕРЬ: после обновления нужно
    user_cache.pop(user_id, None)
  3. Нет проверки валидности — user_id может быть None или string

    # [+] ДОБАВИТЬ
    if not isinstance(user_id, int) or user_id <= 0:
        raise ValueError(f"Invalid user_id: {user_id}")

[!] Data Leakage

На строке 20 возвращаем весь объект user, включая пароль:

# [-] НЕПРАВИЛЬНО
return user  # Содержит user['password']!

# [+] ИСПРАВИТЬ
return {k: v for k, v in user.items() if k != 'password'}

[+] Что хорошо

  • Попытка использовать кэш (идея правильная)
  • Отдельные функции для get и update (разделение ответственности)

Рекомендации

  1. Перевести на lru_cache из functools
  2. Использовать parameterized queries везде
  3. Добавить логирование при cache miss (для мониторинга)
  4. Написать unit-тесты для cache invalidation

## Часть 4: Интеграция в workflow команды

### Сценарий: день ревьюера с AI

```mermaid
flowchart LR
  A["09:00 PR"] --> B["09:01 AI-review"]
  B --> C["09:03 Исправления"]
  C --> D["09:05 Re-check"]
  D --> E["09:30 Human review"]
  E --> F["09:35 Merge"]
09:00 - Dev открывает PR #250

09:01 - CI запускает AI-review (1 сек)

09:02 - Claude оставляет комментарий:
        "Найдена уязвимость: SQL injection на строке 45"

09:03 - Dev видит комментарий, исправляет код

09:05 - Dev пушит изменения, AI-review запускается снова

09:06 - AI: "[+] SQL injection исправлена. Осталось добавить тесты."

09:30 - Human reviewer смотрит PR:
        - Синтаксис? [+] (проверил AI)
        - Безопасность? [+] (проверил AI)
        - Бизнес-логика? [+] (проверяет human)
        - Архитектура? [+] (проверяет human)

09:35 - Одобрено и merged

Checklist для интеграции

  • Установлен git hook pre-commit или GitHub Actions
  • Настроены критические уровни (CRITICAL, HIGH) для блокировки
  • AI-review комментарии не скрывают human-comments
  • Ревьюеры обучены: AI находит баги, они решают — архитектура
  • Метрики отслеживаются: % PR с AI-comments, % issues найденных AI

Антипаттерн: Слепое доверие к AI

[-] Неправильно:

# AI сказал "всё ок" → merge without human review
if ai_review == "no issues":
    merge_to_main()  # ОПАСНО!

[+] Правильно:

AI-review находит тактические проблемы (баги, уязвимости)
Human-review проверяет стратегические проблемы (архитектура, бизнес)

Попробуйте сами

Задача: Настроить AI-review для своего репозитория.

  1. Вариант 1 (быстро): Установить git hook:

    chmod +x .git/hooks/pre-commit
    git add -A && git commit -m "test: trigger AI review"
    # Посмотреть результат в терминале
  2. Вариант 2 (production): GitHub Actions:

    • Скопировать .github/workflows/ai-review.yml
    • Push в main
    • Открыть PR, посмотреть AI-comment
  3. Тестирование: Добавить намеренный баг:

    # Плохой код
    sql_query = f"SELECT * FROM users WHERE id = {user_input}"

    Запустить AI-review → должна найти SQL injection

Ключевые выводы

  1. AI для тактики: Баги, уязвимости, стиль — это работа AI
  2. Human для стратегии: Архитектура, бизнес-логика, trade-off’ы — это работа человека
  3. 70% проблем: AI находит легко, 30% требуют контекста
  4. Faster feedback: Pre-review происходит за 1-2 сек вместо часов ожидания
  5. Лучше код: Разработчик получает feedback до human-review, код приходит в лучшем виде

Следующий урок

В уроке 3 мы разберём мультиагентные workflow: как использовать несколько AI-агентов для разных задач одновременно, DevSquad паттерн, и когда это действительно нужно.

Мы размещаем рекламу, так как это позволяет нам готовить для вас свежие материалы и покрывать наши расходы. Рекламодателей выбираем адекватных.

Скачать урок

Есть идея или нашли ошибку?

// Обсуждение

Можно писать анонимно. Укажите email, чтобы получать уведомления об ответах.