Яндекс Браузер — не просто сборка открытого Chromium, а крупный форк с собственным слоем изменений: доработки рендеринга, оптимизации движка, уникальные функции. Chromium при этом выпускает новую мажорную версию примерно раз в четыре недели. Каждое такое обновление означает стыковку двух активно развивающихся кодовых баз: около 10 000 коммитов апстрима накладываются на примерно 1500 внутренних изменений Яндекса.

Процесс мерджа устроен в два шага. Сначала снимаются VCS-конфликты — текстовые пересечения правок в одних и тех же файлах. Затем запускается сборка, и здесь всплывает второй класс проблем: изменения API, переименования, удалённые сущности, архитектурные перестройки. Формально код объединён, но компилятор с этим не согласен. Число уникальных ошибок компиляции после мерджа превышает тысячу, а с учётом повторений вырастает в 2–10 раз.

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

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

Почему не подошли готовые ИИ-ассистенты вроде Cursor или Copilot — вопрос масштаба и контекста одновременно. Интерактивный ассистент работает по схеме «увидел проблему — передал контекст — получил ответ». Для нескольких ошибок этого достаточно, но при сотнях конфликтных файлов человек остаётся в процессе на каждом шаге. Кроме того, по сообщению компилятора или конфликтному фрагменту ассистент видит только локальный код: он не знает, какой коммит Chromium изменил API, зачем в этом месте стоят внутренние изменения Яндекса и какую версию нужно сохранить при объединении. Без обращения к истории изменений корректное решение неочевидно.

Первый наивный подход — скормить модели целый файл и попросить «починить конфликты» — провалился сразу. В Chromium встречаются файлы на 20 000 строк C++. Такой объём просто переполняет контекстное окно модели, и качество ответов резко падает. Команда перешла к локальному контексту конфликта: небольшие файлы подавались целиком, для больших находились блоки с конфликтными маркерами и к ним добавлялось ограниченное число строк до и после — именно этот фрагмент отправлялся в LLM вместе с промптом.

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

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