команда · модели

Какая модель ищет проблемы, а какая их судит

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

Роли хотят противоположного. Генератору нужны широта и дешевизна: модель, предложившая десять замечаний, из которых три — шум, свою работу сделала. Судье нужно упрямство: модель, отвергающая всё, чего не может доказать по коду. Укажите одну модель в роли генератора и судьи — и второй проход в основном согласится с первым, а это ровно то поведение, которого вы бы и хотели избежать.

Перед началом: речь про блок llm в .reviewgate/config.yml — справочник конфига перечисляет все ключи, а эта страница про то, какие из них заполнять и зачем. Какая схема действует у вас сейчас и откуда она взялась, покажет reviewgate doctor.

Состав схемы ревью

РольСколькоЧто видитЧто решает
generatorsодин или большедифф, а если включили — и файлы целикомчто может быть не так: он предлагает, не более
judgesноль, один или двафайлы каждого замечания целиком, файлы, которые они импортируют, и точные строки, которые заменил бы готовый фикскакие предложения уцелеют и с каким уровнем
arbiterноль или одинтолько замечания, по которым судьи разошлиськто из судей прав

Без конфига вы получаете минимум из этой таблицы: один генератор, ноль судей. Всё найденное приходит к вам непроверенным — для черновика на своей машине нормально, для MR или PR маловато.

Что даёт второй генератор

Два генератора не голосуют. Их замечания объединяются с дедупом, поэтому второй добавляет то, что первый пропустил, а не подтверждает найденное. Разные вендоры здесь ценнее, чем старшая модель от того же самого вендора: обученные по-разному модели пропускают разное, в этом весь смысл пары. Есть и вторая причина: код, который написал ИИ-агент, не должна проверять та же модель — она повторит собственные ошибки. Два генератора разных вендоров гарантируют, что хотя бы один смотрит на дифф чужими глазами.

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

Что даёт второй судья

Два судьи как раз голосуют. Где согласны — вердикт принят. Где разошлись — замечание уходит арбитру, а если арбитра нет, спорное замечание консервативно снимается. На более ранних замерах расколы случались по-настоящему: в трёх прогонах из пяти судьи разошлись — в одном по четырём замечаниям, в двух других по одному и по двум.

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

Что мы измерили и чего это не доказывает

Восемнадцать прогонов, 7 и 22 сентября 2026 года: шесть схем по три прогона, один и тот же дифф в 31 строку. Дифф выбран такой, где правильный ответ известен заранее — четыре настоящих дефекта: дробные центы, почта клиента в строке лога, налог, посчитанный до скидки, и поиск кода купона в обычном объекте, где находятся и унаследованные свойства прототипа. В четырёх нижних строках к паре «sonnet-5 + судья opus-5» добавлен второй генератор — его и сравниваем.

СхемаЗамечанийИз 4 дефектовЦенаВремя
один генератор, без судьи3,02,70,10 $67 с
генератор + судья3,73,00,21 $109 с
+ DeepSeek flash3,03,00,23 $210 с
+ opus-5 (старшая, тот же вендор)4,33,30,39 $154 с
+ gpt-5.6-terra (другой вендор, тот же ярус)4,33,30,26 $128 с
+ gpt-5.6-sol (другой вендор, старшая)5,34,00,27 $198 с

Судья полноты не добавляет — он только снимает и понижает, найти он ничего не может. Разница между 2,7 без судьи и 3,0 с ним — разброс генератора между прогонами: четвёртый дефект нашёл один прогон из трёх, и нашёл его генератор. Это не разочарование, а разделение труда: судья работает на точность, а не на поиск. В трёх прогонах «генератор + судья» он не снял ни одного из 11 кандидатов, а в двух понизил уровень; снимать он начинает, когда генераторов два, — дубли и догадки второго.

Второй генератор другого вендора добавляет полноту — если он не слабее первого. Слабый DeepSeek flash не добавил ничего: его два-три замечания за прогон либо совпадали с замечаниями sonnet-5, либо снимались судьёй. gpt-5.6-terra — того же яруса, что sonnet-5, — дал ровно столько же, сколько старшая модель того же вендора opus-5: 4,3 замечания и 3,3 известных дефекта, но на 33 % дешевле и быстрее. Старшая модель другого вендора, gpt-5.6-sol, нашла все четыре дефекта в каждом из трёх прогонов — 5,3 замечания против 4,3 у opus-5, и на 30 % дешевле.

Второй генератор стоит центы, а платите вы временем. Terra и sol добавили к прогону по 5–6 центов, opus-5 — 18; в секундах — 19, 89 и 45: второй генератор идёт после первого, а не параллельно с ним, и его время прибавляется целиком. Разброс у времени больше, чем у цены: sol отвечал от 38 до 152 секунд, DeepSeek — от 51 до 161.

Чего это не доказывает: три прогона на схему, один дифф, один язык — это замер, а не исследование. Читайте его как «вот что получилось на нашем репозитории», а не как рейтинг моделей. Судья во всех схемах один, opus-5, — в схеме, где он же второй генератор, он оценивал и собственных кандидатов. Цены Anthropic и DeepSeek — по их прайс-листам на 23 сентября 2026 года, у DeepSeek пиковый тариф; цены моделей GPT-5.6 — из прайс-листа OpenRouter на день замера. Сверьтесь с прайс-листом своего провайдера.

Три места, где находится схема, и они склеиваются не так, как вы ожидаете

Схема может прийти из командного конфига (.reviewgate/config.yml), из вашего личного или из окружения инсталляции. Правила у источников разные, и на этой разнице ошибаются.

Между командным конфигом и окружением роли разрешаются независимо. Прогон вполне законно может идти с генераторами из config.yml, судьями из окружения и арбитром оттуда же. Такую комбинацию никто нигде не записывал — она собирается по одной роли.

Ваша личная схема берётся целиком и переопределяет командную. Стоит объявить в личном конфиге хотя бы одну роль — например, только generators, — и вся тройка придёт оттуда, включая роли, которых вы не писали. Нет судей в личном файле значит нет судей вообще, а не панель команды. Локальный прогон после этого выглядит дешевле и чище, чем ревью в MR или PR, и разница не баг: вы сменили схему, а репозиторий тот же.

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

терминал
reviewgate review --refs main --team-llm

--team-llm снимает вашу личную схему на один прогон. Удаление ключей ролей из личного конфига снимает её насовсем. А прогон через командный сервер ревью и так всегда идёт командной схемой: бот ваш файл не читает никогда.

Роль может назвать вендора — backend: deepseek, — но бэкенд это имя записи в каталоге инсталляции, а не адрес и не секрет. Ключи лежат в окружении инсталляции; конфиг в репозитории может только сослаться на них. Это тот самый инвариант, благодаря которому клон чужого репозитория не отправит ваш дифф на чужой endpoint по чужому конфигу.

Единственное правило, которое действительно важно

Судья должен быть сильнее генератора. Поставьте судьёй модель послабее — и она снимет хорошие замечания, за которыми не может проследить, зато согласится с уверенной чепухой: вы платите за второй проход, который делает результат хуже. Эффект сильнее всего, когда судья не только сильнее, но и от другого вендора: логика та же, что у второго генератора, — он не разделяет с генератором его слепые пятна. Всё остальное в этом разделе — предпочтения; это — правило.

Вторая полезная привычка: добавляя второго генератора, берите другого вендора, а не старшую модель того же, — и не слабее первого. Вы покупаете другие слепые пятна, а у двух моделей одного семейства они общие; в таблице выше это видно: terra дала столько же, сколько opus-5, но дешевле, а sol нашла больше всех.

.reviewgate/config.yml
llm:
  generators:
    - model: claude-sonnet-5          # the main pair of eyes
    - backend: openrouter             # a second vendor, no weaker than the first
      model: openai/gpt-5.6-sol
  judges:
    - model: claude-opus-5            # verifies against whole files
    - backend: openrouter             # a judge from another vendor: other blind spots
      model: openai/gpt-5.6-sol
  arbiter:
    model: claude-fable-5-1           # called only where the two judges disagree

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

Во что обходится каждая роль

Судья — самая дорогая роль в схеме, и прогоны выше доказывают это: 0,21 $ с ним против 0,10 $ без него, то есть 53 % счёта. Второй рычаг — объём: судья читает файлы целиком, поэтому его доля растёт с размером файлов, в которые попали замечания, а не с размером диффа.

Локальный вариант. Здесь два разных случая. Одиночная модель на своём железе — вроде qwen3-coder:30b на рабочей станции — ничего не стоит за прогон, но работает в несколько раз медленнее облачной пары и по качеству ей не ровня: на том же диффе она не нашла ни одного из четырёх известных дефектов. Это вариант для энтузиаста, не для команды. Компания в закрытом контуре может поставить модели посильнее — открытые DeepSeek, Qwen и им подобные, — и тогда схема «генератор + судья» работает и без облака; платите вы не за прогон, а один раз — за железо и развёртывание нескольких моделей, и это заметные деньги. Относитесь к локальным моделям как к ответу на «код не может покидать периметр», а не как к дешёвой версии того же самого.

Когда что-то пошло не так

Ваш локальный прогон и бот расходятся на одной и той же ветке. Почти всегда это личная схема: она заменяет командную тройку целиком, то есть у вас с ботом разные схемы. Проверьте reviewgate doctor — он покажет, откуда взялась каждая роль, — затем либо уберите ключи ролей из личного конфига, либо разово прогоните с --team-llm.

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

Прогон отказывается стартовать с home_llm_config. Ваша личная схема объявлена, но в ней нет генераторов. Инструмент не станет тихо одалживать генераторов на стороне — так собралась бы конфигурация, которой никто не задумывал. Допишите генератор, уберите ключи ролей или обойдите разово через --team-llm.

Арбитр настроен и никогда не появляется. Без судей он вырезается из прогона; ровно при одном судье остаётся и не зовётся. Оба случая сообщаются заметкой — читайте их, потому что по одному конфигу ключ выглядит живым.

Роль игнорируется. Запись роли без model и без backend никого не адресует и отбрасывается с заметкой. То же — с именем backend, которого нет в каталоге инсталляции.

Второй генератор не дал ничего. Скорее всего, он не ответил — не уложился в таймаут или вернул ошибку, — и ансамбль схлопнулся до ответивших моделей; в журнале прогона это строка «failed — skipping it (fail-open)». Блок диагностики показывает каждый вызов с его длительностью и итогом — так «модель ничего не нашла» отличают от «модель не ответила». По умолчанию он выключен: включите diagnostics и повторите прогон.

Дальше