Навигация
Помощник на языковых моделях
Разбор упавшей сборки и изменений пулл-реквеста языковой моделью: выбор поставщика, граница закрытого контура, учёт расхода и пределы
Появилось в 1.1.0. В версии 1.0.0 этой возможности нет — что меняется при переходе.
Помощник разбирает упавшие задачи CI по журналу и изменения пулл-реквеста. Модель выбирает администратор установки: свой узел внутри контура или облачный поставщик с OpenAI-совместимым интерфейсом. Возможность редакции Pro.
Настройка: Администрирование → Помощник ИИ.
Граница контура
Это первое, что нужно знать при развёртывании в закрытом контуре.
Ненастроенный или выключенный помощник не делает ни одного исходящего запроса. Отказ выдаётся до того, как собран запрос к модели: содержимое журнала никуда не уходит. Установка без настроенного поставщика ведёт себя ровно так, как если бы помощника в продукте не было.
Настроенный помощник обращается ровно по одному адресу - тому, что задал администратор. Автоматические переходы по 3xx запрещены: ответ чужого сервера не может увести содержимое запроса на другой хост.
| Поставщик | Схема | Адрес | Куда уходит содержимое |
|---|---|---|---|
| Свой узел | http или https |
любой, включая приватные диапазоны | внутрь контура |
| Облачный | только https |
обязан резолвиться в публичный адрес (защита от SSRF) | внешнему поставщику |
Приватные диапазоны разрешены только своему узлу: http://ollama:11434/v1 в сети docker резолвится в приватный адрес, и общий запрет закрыл бы именно тот случай, ради которого закрытый контур и разворачивают. Облачному поставщику http запрещён: исходный код уходил бы на чужую сторону открытым текстом.
Куда уходят запросы, видно в интерфейсе: в настройках и на кнопке разбора показан хост поставщика, а для облачного - предупреждение об уходе содержимого наружу.
Секреты CI в журнал не попадают: значения маскируемых переменных вырезаются при записи журнала, то есть ещё до того, как журнал может быть отдан модели.
Поставщики
Подходит любой сервер с интерфейсом POST {base_url}/chat/completions:
- Ollama -
http://узел:11434/v1, модель видаqwen2.5-coder:7b; - vLLM, llama.cpp server, LM Studio - свой адрес, модель по имени;
- облачные поставщики с тем же интерфейсом -
https://…/v1и ключ доступа.
Ключ доступа хранится зашифрованным (AES-256-GCM) и не возвращается ни в одном ответе API: интерфейс показывает лишь признак «задан». Пустое поле ключа при правке настроек означает «оставить прежний».
Кнопка «Проверить связь» опрашивает перечень моделей поставщика, сверяет с ним имя модели, а затем делает пробный обмен - одно слово и один разрешённый токен ответа. Пробный обмен нужен потому, что перечень моделей у части поставщиков открыт без ключа: без него проверка отвечала бы «поставщик доступен» там, где помощник затем отказывает с 401. Проверить можно до сохранения настроек.
Сколько ждать модель. «Ожидание ответа» - от 1 до 600 секунд, по умолчанию 180. Три минуты, а не одна: рассуждающая модель думает до ответа, а локальная на процессоре считает медленно. Если модель не уложилась, участник видит именно это - «модель не ответила за столько-то секунд», а не «поставщик недоступен».
Разбор упавшей задачи CI
На странице конвейера у упавшей задачи появляется кнопка «Разобрать сбой». Помощник получает контекст задачи (репозиторий, ветка, имя, стадия, код возврата, образ) и хвост журнала, а возвращает причину, объяснение и что сделать.
- Ответ помечен как машинный - читателю видно, что текст написан не человеком, и какой моделью.
- Журнал отдаётся хвостом: причина падения почти всегда в конце, а начало занято установкой зависимостей. Если журнал не поместился целиком, об этом сказано и модели, и читателю.
- Разбор доступен тем, у кого есть право записи в репозиторий. Права на чтение недостаточно намеренно: обращение тратит месячный предел владельца репозитория, и на публичном репозитории посторонний исчерпывал бы чужой предел одним циклом запросов.
- Успешная задача на разбор не отправляется.
Разбор изменений пулл-реквеста
Участник с правом записи нажимает «Разобрать изменения». Модель получает заголовок, описание, ветки и текст изменений, а ответ публикуется обычным комментарием с пометкой «Сгенерировано моделью».
- Комментарий обычный намеренно: иначе разбор не попал бы ни в ленту обсуждения, ни в ветки, ни в счётчик нерешённых. Пометку ставит сервер; объявить свой комментарий машинным клиент не может.
- Автор комментария - тот, кто запросил разбор: видно, по чьей просьбе он появился, а права на правку и удаление остаются обычными.
- Файлы отдаются модели целиком и по порядку, пока хватает объёма: половина патча - это выдуманный контекст, по которому модель делает выводы о коде, которого не видела. Двоичные и не поместившиеся файлы перечисляются отдельно.
- Запрос без изменений на разбор не отправляется.
Учёт расхода и пределы
Расход относится на владельца репозитория - пользователя или группу, ту же сторону, на которую считаются квоты хранилища. Не на того, кто нажал кнопку: разбор сборки командного репозитория - расход команды.
Окно учёта - календарный месяц. Умолчание задаётся в настройках помощника, переопределение владельца - в таблице расхода. Ноль означает «без ограничения», и переопределение важнее умолчания: ноль у владельца снимает предел установки, а не запрещает обращения.
Предел проверяется до обращения к модели: сколько токенов потребует очередной запрос, заранее не знает никто, поэтому правило звучит как «начать новое обращение нельзя», а не «оборвать на полуслове». Такой предел рассчитан на бюджет, а не на запрет: назначайте его исходя из месячной нормы. Если поставщик не сообщает расход, он оценивается по длине текстов.
Сверх месячного предела действует предел частоты - 10 обращений в минуту на клиента, общий для разбора сбоя, разбора изменений и проверки связи. Превышение - 429 с заголовком Retry-After.
Что видно в отказе. Подробность отказа поставщика уходит только администратору - в проверку связи и в журнал сервера. Тому, кто нажал «Разобрать сбой», возвращается код отказа без подробностей: поставщики возвращают в сообщениях префикс предъявленного ключа, а текст ошибки соединения содержит адрес узла модели.