- BrainTools - https://www.braintools.ru -

Тысяча конфликтов и одна LLM: как мы автоматизировали переход на новые версии Chromium

Тысяча конфликтов и одна LLM: как мы автоматизировали переход на новые версии Chromium - 1

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

В одном обновлении сходятся около 10 000 коммитов апстрима и примерно 1500 наших изменений. В процесс вовлекаются десятки разработчиков, а суммарные трудозатраты команды на один цикл составляют несколько человеко‑месяцев.

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

Речь не про сценарий «вставить одну ошибку [1] в чат и получить фикс». Здесь мы имеем дело с регулярным обновлением большого форка: тысячи проблем нужно разбирать пакетно, с учётом контекста апстрима и наших изменений.

В этой статье расскажем, как встроили LLM‑агента в процесс перехода на новые версии Chromium и что из этого получилось.


Что происходит при мердже Chromium — и почему это системная нагрузка

Яндекс Браузер использует код проекта Chromium, который выпускает новую мажорную версию примерно раз в четыре недели. При этом Браузер — не просто сборка Chromium: поверх апстрима у нас большой слой собственных изменений и функций, которых в исходном проекте нет (думаю, этот фильтр [2] по статьям нашей команды говорит сам за себя).

Поэтому обновление — это не один коммит, а стыковка двух активно развивающихся кодовых баз: апстрима Chromium и нашего кода поверх него.

На практике каждый мердж проходит в два шага. В упрощённом виде весь процесс выглядит так:

Схема процесса мерджа Chromium и последующей починки

Схема процесса мерджа Chromium и последующей починки

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

Конфликты возникают потому, что мы активно дорабатываем код Chromium и оптимизируем в том числе те части, которые приходят к нам из апстрима. Например, у нас есть собственные изменения в рендеринге страниц и работе движка — из‑за этого правки нередко пересекаются с апстримом. Про один из таких кейсов мы подробно рассказывали в отдельной статье [3] про ускорение запуска браузера.

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

Именно эта двухступенчатая структура и превращает мердж в регулярную системную нагрузку.

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

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

Например, если в одном и том же месте менялась логика [4] с обеих сторон, система не понимала, как их совместить, и либо выбирала одну из версий, либо оставляла конфликт [5] нерешённым.

Конфликт из реального мерджа: в апстриме изменился стиль именования (SCREAMING_SNAKE_CASE → camelCase), а в нашем коде осталась старая версия. Такие изменения нельзя корректно объединить простыми правилами — старый авторезолв в таких случаях не справлялся

Конфликт из реального мерджа: в апстриме изменился стиль именования (SCREAMING_SNAKE_CASEcamelCase), а в нашем коде осталась старая версия. Такие изменения нельзя корректно объединить простыми правилами — старый авторезолв в таких случаях не справлялся

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

После разрешения VCS‑конфликтов работа не заканчивается. Даже при формально корректно объединённом коде остаётся более тысячи уникальных ошибок компиляции, а с учётом повторений их число вырастает в 2–10 раз.

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

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

Почему это не просто задача для Cursor или Copilot

Современные AI‑ассистенты хорошо помогают в точечных задачах: починить одну ошибку компиляции, разрешить один конфликт, дописать функцию. Но обновление Chromium — это не разовая задача, а регулярный процесс на масштабе большого форка. В одном цикле — больше тысячи конфликтов, тысячи сообщений компилятора и десятки разработчиков, которых приходится отвлекать на ручную работу.

Интерактивный ассистент работает по схеме «увидел проблему → передал контекст → получил ответ». Для нескольких ошибок этого достаточно. Но при сотнях конфликтных файлов такой подход не масштабируется: человек остаётся в процессе на каждом шаге и вручную передаёт данные.

Проблема не только в масштабе, но и в контексте. По сообщению компилятора или конфликтному фрагменту ассистент видит только локальный код. Он не учитывает, какой коммит Chromium изменил API, зачем в этом месте есть наши изменения и какую версию нужно сохранить при объединении. Например, если в апстриме переименовали сущность, а в нашем коде остались обращения к старому имени, без обращения к истории изменений корректное решение неочевидно.

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

Этап 1. Как мы научили LLM разруливать конфликты кода

Работу над этим этапом мы начали вместе с Вадимом Петровым @Lof [6], чья команда отвечает за производительность Яндекс Браузера. В рамках мерджа он занимался архитектурой решения и первыми экспериментами с LLM‑резолвом.

Конфликты здесь — обычное дело: мы меняем код Chromium, а апстрим в тех же местах продолжает двигаться. В каждом обновлении их набирается тысячи, и на разбор уходит несколько дней.

Старая авторезолвилка закрывала примерно половину самых простых случаев. Всё остальное приходилось разбирать руками — особенно там, где нужно не выбрать одну сторону, а аккуратно объединить изменения. 

Почему «LLM в лоб» не взлетела

Первый наивный подход был максимально прямолинейным: скормить модели целый файл и попросить «починить конфликты». Это не сработало. На реальных файлах качество резко проседало. В Chromium встречаются файлы на десятки тысяч строк. И это не фигура речи: в Chromium есть файлы [7] на 20 тысяч строк кода C++. Если отправить такой файл целиком в модель, он просто «забивает» контекст — качество ответов резко падает.

Поэтому команда ушла от идеи «скормить всё» и перешла к локальному контексту конфликта: небольшие файлы подавали целиком, а для больших находили блоки с конфликтами и добавляли ограниченный контекст до и после (определённое число строк), после чего уже отправляли этот фрагмент в LLM вместе с промптом. 

От человеческих резолвов к обобщённым правилам

Дальше мы пошли по классическому инженерному пути: собрали реальные кейсы, где старая авторезолвилка не справлялась, а человек справлялся, и превратили их в размеченный набор примеров. Данные разделили на train — часть для обучения [8] модели — и бенчмарк, на котором проверяли качество решений.

Train разбили на блоки одинакового размера и для каждого блока просили LLM вывести «не более 10 общих правил решения конфликтов» на основе человеческих резолвов. Получившиеся правила прогнали через суммаризацию, чтобы объединить и убрать дубли, а в финальный промпт добавили «пролог и эпилог» из заранее подготовленного «банка памяти» по браузеру. Так получился промпт, который стабильно работает на локальном контексте.

Как оценивали качество: байтовое совпадение и LLM‑оценка («judge») по двум аспектам:

  1. Точное совпадение с человеческим резолвом (byte‑to‑byte). На бенчмарке 63% решений полностью совпали с тем, как конфликт решал разработчик, — и это на наборе достаточно сложных кейсов.

  2. «Смысловая» проверка через LLM‑as‑a-judge. Для каждого конфликта заранее описали набор аспектов корректного решения: убраны маркеры, сохранены локальные правки, учтены изменения апстрима и так далее. Модель проверяла, какие аспекты выполнены; эту метрику назвали correctness. По ней получился 81% успешных решений.

Чтобы judge не «фантазировал», отдельно проверили, что он почти не даёт ложных срабатываний.

Как встроили в процесс: автомердж и меньше ревьюеров

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

Автомердж: если решение LLM совпадало с тем, что сгенерировала бы старая авторезолвилка, код вливали сразу, без участия человека. В 98% таких случаев после этого не требовалось дополнительных правок.

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

Пример конфликта исправленного LLM

Пример конфликта исправленного LLM

В итоге на одном из прогонов из 1300 конфликтов 30% были влиты полностью автоматически, ещё примерно половина — после одобрения одним ревьюером. Это дало экономию примерно половины ресурсов разработчиков на этом участке. 75% конфликтов удалось исправить за один день вместо двух. На схеме выглядит это так:

Тысяча конфликтов и одна LLM: как мы автоматизировали переход на новые версии Chromium - 5

Конфликты — только начало: основная нагрузка в ошибках компиляции 

Даже после того, как конфликты успешно разрешены, работа не заканчивается. Следующий этап — компиляция — показывает, что код по‑прежнему часто не собирается.

После одного мерджа возникает сопоставимый объём уникальных ошибок компиляции — счёт идёт на тысячи сообщений компилятора. На каждую платформу приходится 500–600, часть пересекается между ними.

Причины появления этих ошибок связаны с расхождениями между кодовыми базами:

  • изменения API;

  • удаление и переименование сущностей;

  • архитектурные изменения;

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

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

По оценке команды, около 40–50% ошибок можно отнести к типовым или относительно простым сценариям. Однако даже такие ошибки в сумме образуют значительную нагрузку: их много, и каждая требует времени.

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

Этап 2. Агент для починки ошибок компиляции

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

Упрощённая схема работы LLM-агента при исправлении ошибки компиляции

Упрощённая схема работы LLM‑агента при исправлении ошибки компиляции

Поэтому одного запроса к LLM недостаточно. Чтобы починить ошибку, нужно найти релевантное изменение в Chromium, понять, что именно поменялось, и учесть локальный контекст репозитория.

От хаоса к типам ошибок

Сначала мы разобрали сами ошибки. Взяли данные прошлых мерджей и сгруппировали их по причинам.

Оказалось, что 10 крупнейших кластеров покрывают около 99% всех ошибок компиляции. Вместо хаотичного набора фейлов появилась типология — с ней уже можно работать системно.

После этого метрики начали считать отдельно по каждому кластеру. Стало видно, где именно решение проседает, а где работает стабильно.

Поиск причины и сокращение итераций

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

За основу мы взяли идею агентской архитектуры из TRAE [9] — одного из лидеров SWE‑bench [10] — и написали собственную версию поиска. Это позволило не начинать с нуля и сохранить гибкость.

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

В наивной версии HitRate@5 (доля случаев, когда нужное изменение попадало в топ-5 результатов поиска) была 32%: агент часто начинал не с той причины.

После доработок показатель вырос до 57%. То есть уже в половине случаев агент с высокой вероятностью находил нужное изменение.

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

Параллельно оптимизировали промпты и эвристики. В первых версиях агент мог делать до 60 итераций на одну ошибку — прогоны получались долгими и нестабильными. После оптимизации число итераций сократилось примерно до 20, а интегральная метрика выросла с 57% до 78%.

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

Генерация патчей

После того как причина найдена, агент формирует план изменений и переходит к генерации патчей.

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

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

Такой подход снижает классические проблемы [11] LLM‑агентов — Lost‑in‑the‑Middle и размывание внимания [12] в длинном контексте — и позволяет чинить разные ошибки параллельно.

Ноду генерации реализовали на базе Aider [13]: в нём уже есть эвристики на случай некорректной правки. В итоге патчи получаются быстрее и стабильнее.

Планирование правок и контроль качества

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

Мы проверяем три вещи:

  • ошибка компиляции действительно исчезла;

  • новые ошибки из‑за правки не появились;

  • изменение соответствует нашим внутренним критериям качества.

Первый пункт проверяется локальной сборкой. Второй и третий — через LLM‑as‑a-judge. В итоговом бенчмарке считаем взвешенную сумму успешно исправленных ошибок по каждому кластеру.

Финальную оценку считаем как взвешенную метрику по кластерам — чтобы видеть не только среднюю температуру, но и просадки по конкретным типам проблем.

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

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

Агент повторяет тот же сценарий:

  • собирает выбранный таргет и парсит ошибки;

  • предлагает чинить только те компоненты, за которые отвечает разработчик;

  • запускает параллельную починку и сохраняет логи рассуждений.

Пример простой ошибки компиляции
../../base/file_descriptor_store.cc:41:11: error: no member named 'IsValid' in 'base::ScopedGeneric<int, base::internal::ScopedFDCloseTraits>'
   41 |   if (!fd.IsValid()) {
      |        ~~ ^
1 error generated.

Найденные RAG ревизии Chromium:

  • 3ca38fa [14] — Remove GenericScopedHandle::IsValid in favor of is_valid

  • 53e1b04 [15] — Remove GenericScopedHandle:IsValid

  • 4ec6c20 [16] — Convert to UNSAFE_TODO in chrome/browser/ash

  • 967c368 [17] — Convert to UNSAFE_TODO in ui

  • 0057c55 [18] — Revert “Convert to UNSAFE_TODO in chrome/browser/ash”

Сгенерированный патч
--- before-src/base/file_descriptor_store.cc
+++ after-src/base/file_descriptor_store.cc
@@ -38,7 +38,7 @@
     const std::string& key,
     base::MemoryMappedFile::Region* region) {
   base::ScopedFD fd = MaybeTakeFD(key, region);
-  if (!fd.IsValid()) {
+  if (!fd.is_valid()) {
     DLOG(FATAL) << "Unknown global descriptor: " << key;
   }
   return fd;
Пример сложной ошибки компиляции
In file included from ../../third_party/blink/renderer/core/xml/xpath_parser.cc:1:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/core/precompile_core.h:27:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/core/dom/document.h:64:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/bindings/core/v8/script_promise.h:36:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/bindings/core/v8/idl_types.h:14:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/heap/heap_traits.h:10:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/heap/collection_support/heap_vector.h:14:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/heap/heap_allocator_impl.h:9:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h:20:
In file included from ../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/heap/trace_traits.h:15:
../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/wtf/key_value_pair.h:45:1: error: [blink-gc] Class 'KeyValuePair<cppgc::internal::BasicMember<blink::TreeScope, cppgc::internal::WeakMemberTag, cppgc::internal::DijkstraWriteBarrierPolicy>, unsigned long>' requires a trace method.
   45 | struct KeyValuePair {
      | ^
../browser/client/src/out/Debug/../../third_party/blink/renderer/platform/wtf/key_value_pair.h:58:3: note: [blink-gc] Untraced field 'key' declared here:
   58 |   KeyTypeArg key;
      |   ^

Найденные RAG ревизии Chromium:

  • 196602e [19] — Move wtf/hash_table.h and wtf/key_value_pair.h to “blink” namespace

  • 89ed85a [20] — Move wtf/type_trails.h to “blink” namespace

  • 95b180c [21] — Move wtf/hash_{functions,traits}.h to “blink” namespace

  • 07be4f1 [22] — Replace “WTF::” with “blink::” in mojo/public/

  • 7f876aa [23] — Remove forward declarations of WTF::String except for wtf/forward.h

Результат рассуждений агента

I see the issue now! The file has GC_PLUGIN_IGNORE_FILE("crbug.com/428987863") which was supposed to ignore GC plugin checks, but the error is still occurring. This suggests that either:

  1. The GC_PLUGIN_IGNORE_FILE is not working as expected, or

  2. The namespace change from WTF to blink has affected how the GC plugin processes this file

Looking at the upstream changes, the KeyValuePair was moved from WTF namespace to blink namespace. This likely means that the GC plugin now treats it as a blink object that needs proper tracing, whereas before it might have been ignored as a WTF utility.

The solution is to add a proper Trace method to the KeyValuePair struct that traces both key and value fields when they contain traceable objects.

Сгенерированный патч
--- before-src/third_party/blink/renderer/platform/wtf/key_value_pair.h
+++ after-src/third_party/blink/renderer/platform/wtf/key_value_pair.h
@@ -31,6 +31,7 @@
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/gc_plugin.h"
 #include "third_party/blink/renderer/platform/wtf/type_traits.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
 
 // Templates in this file are instantiated many times with different types.
 // Adding the regular GC_PLUGIN_IGNORE annotations to fields in the templates
--- before-src/third_party/blink/renderer/platform/wtf/key_value_pair.h
+++ after-src/third_party/blink/renderer/platform/wtf/key_value_pair.h
@@ -56,6 +56,11 @@
   KeyValuePair(KeyValuePair<OtherKeyType, OtherValueType>&& other)
       : key(std::move(other.key)), value(std::move(other.value)) {}
 
+  void Trace(Visitor* visitor) const {
+    visitor->Trace(key);
+    visitor->Trace(value);
+  }
+
   KeyTypeArg key;
   ValueTypeArg value;
 };

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

Веб-интерфейс агента исправления ошибок компиляции

Веб‑интерфейс агента исправления ошибок компиляции

Решение не стало «волшебной кнопкой» — 100% сценариев оно не закрывает. Но в зоне типовых и повторяющихся ошибок эффект оказался ощутимым.

Что получилось уже сейчас (и что ещё в процессе)

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

Для этапа разрешения конфликтов мы оценивали, сколько ручной работы уходит именно на этот участок мерджа. Речь не о сокращении сроков всего процесса, а о том, сколько усилий удалось снять с команды на этом шаге. По этой метрике автоматизация сократила трудозатраты примерно на 50%. Обычно этот этап занимает несколько дней работы всей команды, так что снижение в два раза — ощутимый эффект.

Кроме того, мы отслеживаем, как часто разработчики принимают автоматические правки. Сейчас этот показатель держится на уровне около 76%.

С компиляцией картина похожая, но масштаб больше. На ранних версиях инструмент исправлял 50–60% ошибок из датасета прошлых мерджей. После добавления агентского поиска и планирования доля выросла примерно до 80%.

В реальной работе инструмент автоматически закрывает около 70% переданных ему ошибок — то есть среди задач, которые мы отдаём агенту, а не среди всех ошибок мерджа.

Например, при мердже Chromium версии 144 по тем ошибкам, где запускался агент, автоматически удалось исправить 78,55% кейсов.

На исправление одной ошибки уходит примерно 100 секунд, при этом ошибки в разных файлах обрабатываются параллельно. По логам это дало экономию времени на починке около 32%.

В итоге автоматизация даёт эффект в обоих этапах:

  • при разрешении конфликтов трудозатраты сократились примерно в два раза;

  • при починке компиляции — примерно на треть.

Решение пока не покрывает все сценарии, но качество постепенно растёт по мере уточнения кластеров и метрик.

Что мы из этого поняли, или Где LLM действительно помогает

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

В этих условиях модель оказалась практичнее, чем разрастающийся зоопарк правил. Любая детерминированная логика быстро начинает обрастать частными случаями, усложняется и всё равно не покрывает крайние сценарии. С LLM получилось по‑другому: мы описываем поведение [24] через примеры, собираем метрики, смотрим, где просадка — и докручиваем именно этот участок.

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

Важно и то, как это внедряли. Просто «подключить модель» не сработало бы. Сначала появился рабочий инструмент, которым удобно пользоваться локально. Потом — ранний доступ для команды, сбор обратной связи, доработка. И только после этого — масштабирование. Агент встроен в привычный процесс мерджа и не ломает его: разработчик по‑прежнему видит, что происходит, может посмотреть логи и проверить патч.

И главное: мы не сократили саму длительность мерджа — он по‑прежнему занимает те же несколько недель. Но удалось заметно снизить объём ручной работы внутри процесса.

По сути, мы сняли с команды часть рутинных задач и высвободили время на более содержательную работу — развитие новых возможностей Яндекс Браузера.

Автор: pavor84

Источник [25]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/30225

URLs in this post:

[1] ошибку: http://www.braintools.ru/article/4192

[2] этот фильтр: https://habr.com/ru/search/?q=%5B%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0+%D1%8F%D0%BD%D0%B4%D0%B5%D0%BA%D1%81.%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80%D0%B0%5D&target_type=posts&order=date

[3] в отдельной статье: https://habr.com/ru/companies/yandex/articles/907440/

[4] логика: http://www.braintools.ru/article/7640

[5] конфликт: http://www.braintools.ru/article/7708

[6] @Lof: https://www.braintools.ru/users/lof

[7] файлы: https://source.chromium.org/chromium/chromium/src/+/main:content/browser/renderer_host/render_frame_host_impl.cc

[8] обучения: http://www.braintools.ru/article/5125

[9] TRAE: https://github.com/bytedance/trae-agent

[10] SWE‑bench: https://www.swebench.com/

[11] классические проблемы: https://arxiv.org/abs/2510.16720v1

[12] внимания: http://www.braintools.ru/article/7595

[13] Aider: https://github.com/Aider-AI/aider

[14] 3ca38fa: https://source.chromium.org/chromium/chromium/src/+/3ca38fad42effb156a9cbe716271a4d0abd82862

[15] 53e1b04: https://source.chromium.org/chromium/chromium/src/+/53e1b04bc1437009060f7ce332959a33afe79d9c

[16] 4ec6c20: https://source.chromium.org/chromium/chromium/src/+/4ec6c20848a367d8f26d6b91e77421452a9739aa

[17] 967c368: https://source.chromium.org/chromium/chromium/src/+/967c368f01062a9d008fcc301843899a01167bff

[18] 0057c55: https://source.chromium.org/chromium/chromium/src/+/0057c55c86fa5e97316ed3da8ffe6cbf0add6c6e

[19] 196602e: https://source.chromium.org/chromium/chromium/src/+/196602e92248114d73de96807f388cb24231fe49

[20] 89ed85a: https://source.chromium.org/chromium/chromium/src/+/89ed85a77a8fba7098f5f2cf6df729ac8eda41ed

[21] 95b180c: https://source.chromium.org/chromium/chromium/src/+/95b180c026e2746507737758324241945ad5bf42

[22] 07be4f1: https://source.chromium.org/chromium/chromium/src/+/07be4f1135932262f03c8b608f70dd99e239903b

[23] 7f876aa: https://source.chromium.org/chromium/chromium/src/+/7f876aa2ae743f53a75ac9f9e6297e70dc561ba8

[24] поведение: http://www.braintools.ru/article/9372

[25] Источник: https://habr.com/ru/companies/yandex/articles/1021478/?utm_campaign=1021478&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100