AI-ревью кода в GitHub Actions с Claude и Gemini

12 мин чтения·Matthieu·ci-cdgeminiclaudeai-code-reviewgithub-actions|

Настройте Claude Code Action и Gemini для автоматического ревью pull request'ов. Мультимодельные воркфлоу с разделением ролей, quality gate'ы для блокировки мержей при критических находках и защита от prompt injection.

AI-ревью кода перешло из стадии экспериментов в рабочий инструмент. Claude Code Action и Gemini Code Assist могут автоматически проверять каждый pull request, находя логические ошибки, уязвимости безопасности и пропущенную обработку ошибок, которые линтеры и статический анализ полностью пропускают.

В этом руководстве мы настроим обе модели на одном репозитории. Claude отвечает за ревью логики и безопасности. Gemini отвечает за стиль и документацию. Quality gate парсит уровни серьёзности обоих ревью и блокирует мержи при обнаружении критических проблем.

AIOps на VPS: управление сервером с помощью ИИ и open-source инструментов

Что находит AI-ревью кода, чего не находят линтеры?

Линтеры проверяют синтаксис и форматирование. Инструменты статического анализа вроде Semgrep ищут известные паттерны. AI-ревьюеры кода делают другое: они читают diff в контексте и рассуждают о том, что код делает. Они отмечают состояния гонки (race conditions), пропущенные пути обработки ошибок, небезопасные настройки по умолчанию и ошибки бизнес-логики, которые инструменты на основе паттернов обнаружить не могут.

Исследование Milvus протестировало пять AI-моделей на обнаружении реальных багов в продакшен-PR'ах. Лучшая отдельная модель нашла 53% багов. Когда несколько моделей проверяли один PR и обсуждали находки между раундами, показатель вырос до 80%. Самые сложные баги — те, что требуют системного понимания цепочек вызовов и распространения ошибок — достигли 100% обнаружения в режиме мультимодельных дебатов.

Именно это исследование объясняет, почему в этом руководстве используются две модели вместо одной.

Конкретные примеры того, что находит AI-ревью:

  • Невалидированный пользовательский ввод, проходящий через три вызова функций до попадания в запрос к базе данных
  • Отсутствующие null-проверки, когда функция возвращает Optional<T>, но вызывающий код предполагает, что она всегда успешна
  • Захардкоженные секреты в конфигурационных файлах, которые выглядят как плейсхолдеры, но являются настоящими учётными данными
  • Пробелы в обработке ошибок, где try/catch перехватывает общее исключение и молча проглатывает его
  • Состояния гонки в конкурентном коде, где разделяемое состояние модифицируется без синхронизации

Как настроить Claude Code Action для ревью pull request'ов?

Claude Code Action — это GitHub Action от Anthropic, которая запускает Claude на вашем GitHub-раннере. Она читает диффы PR'ов, оставляет инлайн-комментарии и может реализовывать исправления. Настройка занимает около пяти минут.

Установка приложения Claude GitHub

Перейдите на github.com/apps/claude и установите приложение на свой репозиторий или организацию. Предоставьте доступ к репозиториям, которые хотите проверять. Приложению нужны следующие разрешения:

  • Contents: Read
  • Pull Requests: Read & Write
  • Issues: Read & Write (опционально, для триажа issue)

Добавление API-ключа

В репозитории перейдите в Settings > Secrets and variables > Actions и создайте новый секрет:

  • Name: ANTHROPIC_API_KEY
  • Value: Ваш API-ключ Anthropic (начинается с sk-ant-)

Никогда не коммитьте API-ключи в репозиторий. Если нужен доступ на уровне организации, используйте секреты окружения вместо секретов репозитория.

Создание воркфлоу

Создайте .github/workflows/claude-review.yml:

name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - "src/**"
      - "lib/**"
      - "app/**"
      - "config/**"
    paths-ignore:
      - "**/*.md"
      - "**/*.txt"
      - "docs/**"

concurrency:
  group: claude-review-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  review:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
      pull-requests: write
      id-token: write

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}

            Review this pull request. Focus on:
            1. Security: injection flaws, auth bypass, hardcoded secrets, insecure defaults
            2. Logic errors: off-by-one, null dereference, race conditions, resource leaks
            3. Error handling: swallowed exceptions, missing retries, unclear error messages
            4. Performance: N+1 queries, unbounded loops, unnecessary allocations

            Skip cosmetic issues (formatting, naming style). Another reviewer handles those.

            Rate each finding as CRITICAL, HIGH, MEDIUM, or LOW.

            Use inline comments for specific code issues.
            Use a summary PR comment for overall assessment.

          claude_args: |
            --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"

Фильтр paths ограничивает ревью изменениями в исходном коде. PR'ы, затрагивающие только документацию, пропускают воркфлоу, что экономит на API. Блок concurrency отменяет текущие ревью при пуше нового коммита в тот же PR, чтобы не платить за анализ устаревшего кода.

Ограничение --allowedTools — это мера безопасности. Оно ограничивает Claude чтением диффов и публикацией комментариев. Claude не может изменять файлы, выполнять произвольные команды или получать доступ к другим репозиториям.

Как добавить ревью Gemini в тот же репозиторий?

Два варианта для ревью через Gemini: приложение GitHub Gemini Code Assist (управляется Google, без YAML) или GitHub Action run-gemini-cli (самостоятельное управление, полный контроль). В этом руководстве используется GitHub Action, потому что она даёт контроль над промптом и интегрируется с воркфлоу quality gate.

Получение API-ключа Gemini

Создайте ключ в Google AI Studio. Добавьте его как секрет репозитория:

  • Name: GEMINI_API_KEY
  • Value: Ваш API-ключ Gemini

Для корпоративного использования с аутентификацией Vertex AI смотрите документацию run-gemini-cli по настройке Workload Identity Federation.

Создание воркфлоу Gemini

Создайте .github/workflows/gemini-review.yml:

name: Gemini Code Review

on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - "src/**"
      - "lib/**"
      - "app/**"
      - "config/**"
    paths-ignore:
      - "**/*.md"
      - "**/*.txt"
      - "docs/**"

concurrency:
  group: gemini-review-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  review:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    permissions:
      contents: read
      pull-requests: write

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - uses: google-github-actions/run-gemini-cli@main
        with:
          gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
          prompt: |
            Review this pull request. Focus on:
            1. Code style: naming conventions, function length, complexity
            2. Documentation: missing docstrings, outdated comments, unclear variable names
            3. Test coverage: untested edge cases, missing assertions, test quality
            4. Maintainability: code duplication, tight coupling, violation of SOLID principles

            Skip security and logic analysis. Another reviewer handles those.

            Rate each finding as CRITICAL, HIGH, MEDIUM, or LOW.

            Post your review as a single PR comment with structured sections.

Экшен run-gemini-cli сейчас в бете, поэтому воркфлоу указывает на @main. Для продакшена закрепите конкретный SHA коммита (например, @abc1234), чтобы избежать неожиданных изменений при обновлении ветки main.

Зачем два отдельных воркфлоу?

Запуск Claude и Gemini в отдельных файлах воркфлоу означает, что они выполняются параллельно. Сбой одного не блокирует другой. Также можно временно отключить одну модель, не трогая другой воркфлоу.

Разделение ролей сделано намеренно. Claude склонен прослеживать цепочки вызовов сверху вниз и хорошо находит пробелы в обработке ошибок и уязвимости безопасности. Gemini силён в стиле кода, полноте документации и структурных паттернах. Пересечение — это нормально. Совпадение находок между моделями повышает уверенность в результатах.

Как работает мультимодельное ревью с Claude и Gemini вместе?

Описанная выше конфигурация с двумя воркфлоу уже реализует мультимодельное ревью. Обе модели проверяют один PR независимо и публикуют отдельные комментарии. Это самый простой паттерн, который хорошо работает для большинства команд.

Для команд, которым нужен единый вид, добавьте шаг агрегации. Этот третий воркфлоу запускается после завершения обоих ревью и публикует объединённую сводку:

name: AI Review Summary

on:
  workflow_run:
    workflows: ["Claude Code Review", "Gemini Code Review"]
    types: [completed]

jobs:
  aggregate:
    if: github.event.workflow_run.event == 'pull_request'
    runs-on: ubuntu-latest
    timeout-minutes: 5
    permissions:
      pull-requests: write
      actions: read

    steps:
      - name: Collect review comments
        id: collect
        uses: actions/github-script@v7
        with:
          script: |
            const pr_number = context.payload.workflow_run.pull_requests[0]?.number;
            if (!pr_number) return;

            const comments = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: pr_number,
            });

            const aiComments = comments.data.filter(c =>
              c.body.includes('CRITICAL') ||
              c.body.includes('HIGH') ||
              c.body.includes('MEDIUM')
            );

            const critical = aiComments.filter(c => c.body.includes('CRITICAL')).length;
            const high = aiComments.filter(c => c.body.includes('HIGH')).length;

            const summary = `## AI Review Summary\n\n` +
              `| Severity | Count |\n|----------|-------|\n` +
              `| CRITICAL | ${critical} |\n` +
              `| HIGH | ${high} |\n\n` +
              (critical > 0 ? '⛔ **Merge blocked:** Critical findings require human review.\n' :
               high > 0 ? '⚠️ High-severity findings detected. Review recommended before merge.\n' :
               '✅ No critical or high-severity findings.\n');

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: pr_number,
              body: summary,
            });

            core.setOutput('critical_count', critical);

      - name: Set status check
        if: steps.collect.outputs.critical_count > 0
        run: exit 1

Это отправная точка. Адаптируйте логику парсинга комментариев под конкретный формат, который генерируют ваши промпты. Ключевые слова серьёзности (CRITICAL, HIGH, MEDIUM) в промптах для ревью делают парсинг простым.

Как блокировать мержи, когда AI-ревью находит критические проблемы?

Воркфлоу агрегации выше устанавливает код выхода 1 при наличии критических находок. Чтобы сделать его блокировщиком мержей, настройте защиту ветки:

  1. Перейдите в Settings > Branches > Branch protection rules
  2. Выберите или создайте правило для основной ветки
  3. Включите Require status checks to pass before merging
  4. Найдите и добавьте «AI Review Summary» как обязательную проверку статуса
Серьёзность Действие Мерж заблокирован?
CRITICAL Проверка статуса не пройдена Да
HIGH Предупреждение в сводке Нет (рекомендательно)
MEDIUM Указано в сводке Нет
LOW Не включено в сводку Нет

Предупреждение: AI-ревьюеры генерируют ложные срабатывания (false positives). Если вы сделаете проверку статуса обязательной, разработчикам иногда придётся отклонять ошибочные находки. Оставьте CRITICAL как единственный блокирующий уровень. Если заблокируете ещё и HIGH — будьте готовы к трениям.

Чтобы обойти заблокированный мерж, мейнтейнер может использовать админский байпас на правиле защиты ветки, или вы можете добавить обработчик комментария /dismiss-ai-review, который перезапускает воркфлоу сводки с флагом принудительного прохождения.

Как уменьшить ложные срабатывания в AI-ревью кода?

Ложные срабатывания — главная жалоба команд, использующих AI-ревью кода. Шумные ревью быстро подрывают доверие. Три техники помогают.

Точно задать рамки промпта

Промпты выше уже это делают: Claude проверяет безопасность и логику, Gemini проверяет стиль и документацию. Модель, которую просят «проверить всё», генерирует больше шума, чем модель с конкретным мандатом.

Добавьте контекст проекта для дальнейшего снижения ложных срабатываний. Создайте файл CLAUDE.md в корне репозитория (Claude Code Action читает его автоматически):

# Project Context

This is a Django REST API. Python 3.12. PostgreSQL.

## Review Guidelines
- We use `rest_framework.exceptions` for all error handling. Do not flag bare `except` blocks in middleware.
- `settings.py` contains environment variable references, not hardcoded secrets. Do not flag `os.environ.get()` calls.
- We intentionally use `Any` type hints in the serializer layer. Do not flag these.
- Test files use `pytest` fixtures. Do not flag unused function parameters in test files.

Для Gemini создайте файл GEMINI.md в корне репозитория с аналогичным контекстом проекта.

Фильтрация файлов

Фильтры paths и paths-ignore в YAML воркфлоу предотвращают ревью файлов, которые создают шум:

paths-ignore:
  - "**/*.md"
  - "**/*.txt"
  - "**/*.lock"
  - "**/*.generated.*"
  - "migrations/**"
  - "vendor/**"
  - "dist/**"
  - "__snapshots__/**"

Лок-файлы, сгенерированный код, вендорированные зависимости и файлы миграций дают ложные срабатывания, потому что они сгенерированы машиной или следуют паттернам, которые модель не понимает в контексте.

Установка порога серьёзности

Если вы показываете в сводке только находки уровня CRITICAL и HIGH, шум уровней MEDIUM и LOW никогда не доходит до разработчика. Это лучший дефолт, чем показывать всё и просить разработчиков игнорировать шум.

Какие риски безопасности несёт AI-ревью кода на pull request'ах?

AI-ревьюеры кода обрабатывают недоверенный ввод. Дифф PR'а, сообщения коммитов, заголовки issue и содержимое файлов — всё это контролируется атакующим в open-source репозиториях или при принятии внешних контрибуций. Это создаёт риск инъекции промптов (prompt injection).

Атака Clinejection

В феврале 2026 года атакующий эксплуатировал бот триажа issue Cline через непрямую инъекцию промпта. Атака была простой: вредоносный заголовок GitHub issue содержал инструкции, замаскированные под сообщение об ошибке. Воркфлоу AI-агента интерполировал заголовок issue напрямую в промпт. Агент выполнил инжектированные инструкции, запустил npm install вредоносного пакета и вытащил ANTHROPIC_API_KEY из CI-окружения.

Атака скомпрометировала около 4 000 машин разработчиков до того, как вредоносный пакет был удалён.

Укрепление воркфлоу

Ограничьте права инструментов. Флаг --allowedTools в воркфлоу Claude выше ограничивает то, что Claude может делать. Он может читать диффы и публиковать комментарии. Он не может выполнять произвольные shell-команды, записывать файлы или получать доступ к секретам. Это самая эффективная мера защиты.

claude_args: |
  --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"

Без этого ограничения специально подготовленный дифф PR мог бы заставить Claude выполнять команды на раннере.

Никогда не интерполируйте недоверенный ввод в промпты. Не используйте ${{ github.event.issue.title }} или ${{ github.event.pull_request.body }} в поле prompt. Передавайте репозиторий и номер PR, а экшен пусть получает содержимое через GitHub API.

Осторожно с PR'ами из форков. PR'ы из форков по умолчанию выполняются с пониженными правами GITHUB_TOKEN, но ваши секреты всё равно доступны воркфлоу, если он запускается через pull_request_target. Используйте pull_request (не pull_request_target) для воркфлоу AI-ревью. Тогда PR'ы из форков не смогут получить доступ к вашим API-ключам, и ревью не запустится — это безопасное поведение по умолчанию.

on:
  pull_request:        # Safe: fork PRs cannot access secrets
    types: [opened, synchronize]
  # pull_request_target:  # Dangerous: fork PRs CAN access secrets

Ротируйте API-ключи. Если ключ утёк через CI-лог или скомпрометированный раннер, радиус поражения ограничен временем между ротациями. Ротируйте как минимум раз в квартал.

Проверяйте запуски воркфлоу. Периодически просматривайте вкладку Actions на предмет необычного времени выполнения или неожиданных вызовов инструментов. Ревью, которое занимает 45 минут вместо обычных 3, может указывать на манипуляцию моделью.

Сколько стоит AI-ревью кода за один pull request?

Стоимость масштабируется с размером PR. И Claude, и Gemini тарифицируют по обработанным токенам. Входные токены включают дифф PR, контекст файлов и ваш промпт. Выходные токены — это комментарии ревью.

Размер PR Типичный дифф (строки) Расчётные входные токены
Маленький 50–100 2 000–5 000
Средний 200–500 8 000–20 000
Большой 500–1 500 20 000–60 000

Количество токенов зависит от языка. Дифф на 200 строк Python потребляет меньше токенов, чем дифф на 200 строк Java, потому что Java более многословен.

Использование двух моделей удваивает стоимость в токенах, но не стоимость в евро, потому что ценообразование различается у провайдеров. Проверяйте актуальные тарифы за токен на странице цен Anthropic и странице цен Google AI. Оба используют потокенную тарификацию с разными ставками для входных и выходных токенов.

Для оценки месячного бюджета: умножьте средний размер PR (в токенах) на количество PR в месяц, затем умножьте на ставку за токен для каждой модели. Команда, мержащая 50 PR в неделю со средними диффами, может рассчитать:

weekly_cost = 50 * avg_tokens_per_pr * (claude_input_rate + gemini_input_rate)
              + 50 * avg_output_tokens * (claude_output_rate + gemini_output_rate)

Снижение затрат

  • Фильтры путей предотвращают ревью документации, лок-файлов и сгенерированного кода. Это самая большая экономия.
  • Отмена по concurrency останавливает анализ устаревших коммитов при новом пуше.
  • Пропуск черновых PR — не включайте ready_for_review в типы триггеров, добавляйте его только когда нужны ревью при переходе из черновика в готовность.
  • Используйте модели поменьше для ревью стиля. Gemini Flash дешевле Gemini Pro для проверок стиля и документации, где глубокие рассуждения не нужны.

Сравнение: инструменты AI-ревью кода

Характеристика Claude Code Action Gemini Code Assist CodeRabbit GitHub Copilot
Способ настройки GitHub Action (YAML) GitHub App или Action GitHub App Встроенный
Модель ценообразования За токен (API) За токен или бесплатный тариф Подписка за репозиторий Подписка за рабочее место
Инлайн-комментарии Да Да Да Да
Кастомные промпты Полный контроль Полный контроль (Action) Конфиг-файл Ограничено
Свой раннер Да Да (Action) Нет Нет
Мультимодельная поддержка Комбинируется Комбинируется Одна модель Одна модель
Открытый код Да (MIT) Да (Action) Нет Нет

Claude Code Action и экшен Gemini CLI — это open source, работающий на ваших собственных раннерах. Ваш код никогда не покидает вашу инфраструктуру, за исключением API-вызова к провайдеру модели. CodeRabbit и Copilot — это управляемые сервисы, где код обрабатывается на их инфраструктуре.

Какие ограничения у AI-ревью кода?

AI-ревью кода не заменяет человеческое ревью. Это первый проход, который ловит типичные проблемы и освобождает людей-ревьюеров для фокуса на архитектуре, дизайне и решениях бизнес-логики.

Ограничения окна контекста. Большие PR (более 1 500 изменённых строк) могут превысить окно контекста модели или привести к поверхностным ревью, потому что модель не может удержать весь дифф в контексте. Разбивайте большие PR на меньшие. Это хорошая практика независимо от AI-ревью.

Нет понимания рантайма. AI-ревьюеры видят статический код. Они не могут обнаружить проблемы, которые проявляются только в рантайме: утечки памяти под нагрузкой, зависящие от тайминга состояния гонки или деградацию производительности при масштабировании.

Ложные срабатывания неизбежны. Даже с точными промптами и файлами контекста проекта модели будут отмечать корректный код. Закладывайте 10–20% ложных срабатываний. Если показатель выше, ужесточите промпты и добавьте больше контекста в CLAUDE.md или GEMINI.md.

Нет институциональных знаний. Модель не знает негласных конвенций вашей команды, исторических решений или доменных паттернов, если вы не задокументируете их в файлах контекста. Вложите время в написание хороших файлов CLAUDE.md и GEMINI.md. Эта инвестиция окупается при каждом будущем ревью.

Детерминизм. Один и тот же PR, проверенный дважды, может дать разные находки. AI-ревью вероятностно. Не воспринимайте «нет находок» как «нет багов».

Устранение неполадок

Воркфлоу ревью Claude не запускается. Проверьте фильтр paths. Если ваш исходный код находится вне src/, lib/ или app/, скорректируйте пути под структуру вашего проекта. Также убедитесь, что приложение Claude GitHub установлено на репозитории.

Gemini возвращает пустые ревью. Убедитесь, что секрет GEMINI_API_KEY установлен и ключ валиден. Проверьте локально:

curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=YOUR_KEY" | head -20

Если видите список моделей, ключ работает.

Ревью занимает слишком много времени. Настройка timeout-minutes: 15 убивает воркфлоу при превышении 15 минут. Большие PR с более чем 1 000 строк могут занимать 5–10 минут. Если таймауты частые, ужесточите фильтр paths для уменьшения размера диффа.

Слишком много ложных срабатываний. Добавьте контекст проекта в CLAUDE.md и GEMINI.md. Будьте конкретны в паттернах, которые модель должна игнорировать. «Не отмечать X» эффективнее, чем «будь мягче».

Статус-чек завис в ожидании. Воркфлоу агрегации срабатывает при завершении workflow_run. Если один из двух воркфлоу ревью пропущен (потому что не изменились подходящие файлы), агрегация может не запуститься. Добавьте фильтр paths к воркфлоу агрегации, покрывающий объединение обоих воркфлоу ревью, или используйте отдельный статус-чек, который запускается всегда.


Авторское право 2026 Virtua.Cloud. Все права защищены. Данный контент является оригинальным произведением команды Virtua.Cloud. Воспроизведение, повторная публикация или распространение без письменного разрешения запрещены.

Готовы попробовать?

Разверните свой сервер за секунды. Linux, Windows или FreeBSD.

Смотреть тарифы VPS