У обычного CI понятный договор с разработчиком: тест упал, потому что конкретное ожидание не выполнилось. У модели другой результат: она предполагает, почему это произошло и что поможет. Когда оба ответа выглядят одинаковой зелёной галочкой, начинается путаница.

Поэтому AI в CI/CD стоит вводить с вопроса: какую проверяемую работу он снимет с человека? Прочитать длинный лог, найти связанное изменение, предложить пропущенный сценарий, собрать небольшой патч — у каждой задачи свой результат и свой уровень доступа.

Ниже — вариант процесса для GitLab. Принципы пригодятся и на других платформах. Если термин «агент» пока означает для вас любой запрос к модели, сначала полезно разобраться, как устроены AI-агенты: для разового анализа диффа может хватить обычного workflow.

Три задачи, с которых есть смысл начинать

ЗадачаЧто получает AIЧто возвращаетКак проверить пользу
Разбор паденияЛог конкретной проверки, дифф, версия окруженияПричину или гипотезу и следующий шагШаг воспроизводит проблему или помогает её локализовать
Ревью MRИзменения, требования, связанные фрагменты кодаЗамечание с файлом, сценарием и последствиемРазработчик воспроизводит дефект или подтверждает нарушение требования
АвтофиксПодтверждённую проблему, разрешённые файлы, команды проверкиПатч и результаты проверокНа новом коммите проходит исходный сценарий и обязательный CI

Для первого запуска я бы выбрал разбор падений. Там проще заметить пользу: вместо нескольких экранов лога разработчик получает первую содержательную гипотезу. Ошибочную гипотезу можно отбросить, не откатывая изменения в коде.

Автоматическое ревью сложнее: замечания нужно отбирать. «Добавьте обработку ошибок» ничего не даёт без конкретного пути, на котором ошибка теряется. Автофикс требует ещё одного решения — какие изменения система вправе предлагать самостоятельно.

Готовые интеграции уже существуют. Например, Claude Code для GitLab CI/CD умеет работать с задачами и MR; на дату проверки документация отмечает интеграцию как beta. Выбор инструмента не снимает с команды обязанности определить права и критерий приёмки.

Практический пример: монорепозиторий с тремя фронтендами

В репозитории IT-X проверки фронтенда запускаются матрицей для лендинга, админки и платформы. У Go-бэкенда отдельный job со сборкой, статическими проверками и тестами. Это существующая структура CI, на которой удобно показать возможное внедрение AI. Описанный ниже агент — пример проектирования, а не отчёт о запущенной у нас автоматизации.

Предположим, после изменения API падает проверка типов платформы. Полезный разбор должен связать три вещи: изменившийся ответ API, тип клиента и компонент, который читает поле. Пересказ «TypeScript не нашёл свойство» уже есть в логе.

Хороший результат выглядел бы так:

Гипотеза: API теперь возвращает { items, total },
а клиент по-прежнему ожидает массив.

Проверить: тип ответа клиента и место, где вызывается .map().
Исправление: согласовать клиент с контрактом API.
Не обходить ошибку приведением типа к any.
Проверка: type-check и сборка затронутого фронтенда.

Это учебный сценарий. Его ценность в том, что ответ задаёт проверку, а не просит поверить в диагноз. Если нужного обработчика нет в контексте, агент должен указать, какого файла ему не хватает.

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

Собираем контекст: пример GitLab CI

Сначала нужен воспроизводимый вход: какой коммит анализировали, с какой базой сравнивали, какой дифф получили. Фраза «проверь текущий MR» этого не фиксирует.

Ниже — job для сбора входных данных, без вызова модели. Его можно добавить в существующий stage test. Пример рассчитан на обычный MR pipeline внутри одного проекта; он исключает fork и merged results pipelines.

ai_review_input:
  stage: test
  image: node:22
  before_script: []
  variables:
    GIT_DEPTH: "0"
    GIT_SUBMODULE_STRATEGY: none
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID && $CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
  script:
    - |
      set -eu
      test -n "$CI_MERGE_REQUEST_DIFF_BASE_SHA"
      mkdir -p review-input
      printf '%s\n' "$CI_COMMIT_SHA" > review-input/head-sha.txt
      printf '%s\n' "$CI_MERGE_REQUEST_DIFF_BASE_SHA" > review-input/base-sha.txt
      git diff --no-ext-diff --no-textconv \
        "$CI_MERGE_REQUEST_DIFF_BASE_SHA" "$CI_COMMIT_SHA" \
        > review-input/changes.patch
  artifacts:
    expire_in: 1 day
    paths:
      - review-input/

В справочнике переменных GitLab CI_MERGE_REQUEST_DIFF_BASE_SHA обозначает базу диффа, а CI_COMMIT_SHA — коммит запуска. Для merged results pipeline анализируемым коммитом будет результат слияния; такой режим требует отдельного учёта исходного SHA ветки. Поэтому пример ограничен detached pipeline.

Следующий шаг — передать дифф и нужные фрагменты файлов доверенному сервису анализа. Сервису понадобятся адаптер выбранной модели, ограничение размера входа и формат ответа. Если дифф не помещается в лимит, результатом должен быть явный статус «пропущено» или разбиение на проверяемые части. Незаметно отрезанный конец файла делает выводы ненадёжными.

В сборщике не нужно запускать установку зависимостей и скрипты проекта. Ключ модели лучше держать в отдельном окружении анализа, чья конфигурация не берётся из проверяемой ветки. Даже внутренний MR может менять CI и выполняемый код; условие в rules само по себе не создаёт границу доверия.

Если отчёт сохраняется артефактом отдельного AI-job, artifacts:when: always позволяет загрузить созданные файлы и при обычной ошибке job. При таймауте GitLab не гарантирует такую загрузку. allow_failure: true делает сбой рекомендательной проверки неблокирующим; его нельзя трактовать как успешное ревью. Поведение обоих параметров описано в справочнике CI YAML.

Что требовать от AI-ревьюера

Я бы ограничил первый проход тремя типами проблем: нарушение требования, ошибка поведения и пропущенная проверка доступа. Стиль уже проверяет линтер; комментарий модели про название переменной редко оправдывает отдельное уведомление.

Для каждой находки полезен единый формат:

Коммит: SHA, к которому относится замечание.
Место: файл и строки.
Сценарий: при каком вводе или событии проявляется проблема.
Последствие: что получает пользователь или система.
Основание: связанный код, требование или результат проверки.
Проверка: как подтвердить или опровергнуть находку.

Представьте повторную доставку вебхука. Замечание «нужна идемпотентность» слишком общее. Полезная версия указывает: обработчик дважды создаст запись при одном event_id, потому что проверка существования и вставка разделены, а уникального ограничения нет. Проверить это можно двумя одновременными запросами с одинаковым событием.

Если агент не видел схему базы, он не может уверенно утверждать, что ограничения нет. Тогда это вопрос для проверки. Такое различие стоит явно заложить в промпт для работы с кодом.

После нового push замечания должны оставаться привязаны к старому SHA. Перед публикацией отчёта сервис сверяет актуальный head MR с проанализированным: если ветка ушла вперёд, помечает результат устаревшим и заказывает новый проход.

Автофикс: небольшой патч и конечное число попыток

Разрешение менять код лучше выдавать под конкретный класс задач. Например, обновить обращение к полю в клиенте после подтверждённого изменения API. Формулировка «сделай пайплайн зелёным» оставляет агенту слишком много способов добиться результата.

Для пилота я бы задал такой договор:

  • одна подтверждённая проблема и одна попытка исправления;
  • список разрешённых путей, проверяемый программно по полученному диффу;
  • отдельный разбор любых изменений тестов, CI, зависимостей и миграций;
  • сохранение исходного воспроизведения, чтобы исправление проверяли прежним сценарием;
  • повторный обязательный CI для коммита с патчем;
  • патч или отдельный MR как результат, решение о слиянии — у ревьюера.

Это стартовые ограничения, которые можно пересмотреть по результатам пилота. Их смысл — сделать цену неудачной попытки понятной.

Проверять патч нужно вне окружения, где агент его создавал. В окружении проверки запускается код из ветки, поэтому туда не передают ключ модели и учётные данные для публикации MR. Публикацию выполняет отдельный доверенный компонент после проверки путей, размера патча и актуальности SHA.

Автофикс также не должен бесконечно запускать сам себя. Иначе каждый push агента порождает новый анализ, новый патч и ещё один push. Идентификатор исходной задачи и счётчик попыток храните вне промпта: ограничение должен обеспечивать процесс.

Где схема ломается

Инструкции попадают в контекст из проверяемых файлов. Комментарий в коде может просить «для диагностики» прочитать переменные окружения. Это prompt injection: текст, который нужно анализировать, пытается управлять анализатором. Документация Claude Code по безопасности описывает защитные механизмы и ответственность за проверку действий. Практическая граница — доступные инструменты, сеть и секреты: промпт не заменяет ограничения окружения.

Внешнему MR достаются внутренние секреты. В GitLab запуск pipeline из fork в родительском проекте использует конфигурацию из ветки fork, но ресурсы и переменные родительского проекта. GitLab прямо предупреждает о риске кражи секретов до слияния. Перед таким запуском нужно проверить конфигурацию; подробности — в документации MR pipelines. Для анализа внешнего кода проще организовать отдельный доверенный сервис, который получает данные без исполнения ветки.

Агент убирает симптом. Тест мешает, и агент меняет ожидание; тип не сходится, и появляется any; проверка доступа возвращает ошибку, и её обходят. Сравнивайте исправление с исходным требованием. Зелёный тест, у которого изменили смысл, проверяет уже другую задачу.

Таймаут превращается в «проблем не найдено». У отчёта должны различаться состояния: анализ выполнен без находок, выполнен с находками, завершился ошибкой, пропущен, устарел. Фразу «замечаний нет» можно показывать только после состоявшегося анализа всего заявленного объёма.

Ревью становится шумом. Если модель комментирует каждый файл, человек вынужден проверять ещё и ревьюера. Ограничьте число замечаний и запретите публиковать находку без сценария. Когда подтверждений нет, молчание полезнее списка предположений.

Как проверить пользу за две недели

Возьмите один репозиторий, один тип задач и период пилота. До запуска зафиксируйте, что считаете полезным замечанием и сколько времени готовы тратить на его проверку. Период в две недели — удобная организационная рамка; для выводов важнее набрать сопоставимые задачи.

Собирайте пять показателей:

  1. Время от падения CI до подтверждённой причины или от открытия MR до содержательного ревью.
  2. Долю подтверждённых находок среди опубликованных замечаний.
  3. Время, потраченное разработчиками на ложные замечания.
  4. Дефекты, найденные человеком или после слияния и пропущенные AI.
  5. Стоимость полного цикла: модель, runner, повторные запуски и проверка результата человеком.

Сравнивайте похожие изменения: короткую правку текста бессмысленно ставить рядом с переписанным механизмом авторизации. Сохраняйте версию модели и инструкций, чтобы после обновления понимать, почему изменилось качество.

Если сервис анализа работает на вашем оборудовании, добавьте к замерам память, время загрузки модели и очередь запросов. Методика пилота и расчёта стоимости есть в разборе локального запуска моделей для кода.

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

Разобрать такой процесс для своего проекта можно с ментором IT-ХОЗЯЕВА: выбрать первый сценарий, определить доступы и критерии пилота. Больше практики работы с AI-инструментами — на странице вайбкодинга.