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

В последние годы языковые модели всё активнее применяются для задач, связанных с программированием. Если раньше разработчики экспериментировали с решениями вроде Code Llama и Mistral, то в 2024 году на сцену вышло новое поколение специализированных моделей: DeepSeek Coder, Codestral, CodeQwen1.5 — это открыло гораздо больше возможностей для создания умных ассистентов, помогающих писать, править и анализировать код. В Яндексе мы развиваем собственную экосистему LLM‑инструментов для работы с кодом. Модели уже используются для автоматического ревью, встроены в IDE и помогают вносить масштабные правки в проекты.
Один из таких инструментов — генератор описаний для Pull Request. Он упрощает жизнь разработчикам: автоматически формирует понятные и информативные саммари для изменений в коде. Наша цель — сделать этот генератор ещё точнее и полезнее. Для этого мы искали оптимальную кодовую опенсорс‑LLM, которую можно развернуть локально, и подбирали эффективный промпт.
Меня зовут Дмитрий Успенский, я работаю в команде ML RnD Техплатформы Городских сервисов Яндекса, и в статье я расскажу, как мы применили подход LLM as a judge — когда сама языковая модель оценивает качество генераций и сравнивает между собой разные варианты описаний. Поделюсь опытом [1] определения критериев качества, сбора валидационного датасета, подбора промптов и выбора модели. Результаты оказались обнадёживающими: метод действительно позволяет улучшить генеративную систему без участия ручной разметки и асессоров.
Прежде чем двигаться дальше, давайте вспомним, как вообще устроена командная разработка ПО. Обычно каждый разработчик ведёт работу над своей задачей в отдельной ветке репозитория. Когда фича или фикс готовы, создаётся Pull Request — запрос на добавление изменений в основную ветку. После этого запускаются линтеры, проходят тесты, а сам код внимательно просматривают коллеги.
Чтобы другим участникам команды было проще разобраться в изменениях, автор PR’а должен составить описание: заголовок и краткое резюме с пояснением, что и зачем он сделал. Как подчёркивается в гайде по стилю PR [2]’ов Google [2]:
Что именно изменилось? — кратко, по сути, чтобы не приходилось вчитываться в код.
Почему это было сделано? — контекст и мотивация [3], особенно если решение неочевидное.
Но придумывать такие описания — дело не самое увлекательное. Особенно если только что погрузился в сложный код, а теперь нужно переключиться на обобщение и краткость. И вот тут в игру вступают языковые модели. В Яндексе мы разработали систему, которая автоматически генерирует описания для PR’ов — и уже интегрировали её в наш CI/CD.
В основе — русскоязычная языковая модель на 7 миллиардов параметров. Чтобы обучить её без использования внешних API (из‑за NDA на внутренний код), мы развернули локально DeepSeek Coder и с его помощью сгенерировали тренировочный датасет из реальных PR’ов. Этот подход позволил сохранить конфиденциальность и при этом получить достаточно данных для обучения [4].
Сейчас система генерации описаний поддерживает два режима работы:
В виде комментариев — описания добавляются как обычные комментарии к изменениям.
Единым блоком — текст размещается в отдельном разделе Pull Request’а.
Этой системой уже пользуются десятки команд, и каждую неделю через неё проходят тысячи PR’ов. Один запрос обрабатывается всего за три секунды — модель быстро анализирует изменения и автоматически добавляет итоговое описание в систему контроля версий.
Решение уже хорошо себя зарекомендовало, но мы не стоим на месте. В 2024 году появилось сразу несколько мощных опенсорс‑моделей, которые потенциально могут заметно улучшить качество генерации. Кроме того, современные языковые модели можно переиспользовать и для других задач — например, автоматического ревью кода.
Поэтому мы решили пойти дальше и серьёзно улучшить нашу систему: подобрать более подходящую модель и найти промпт, который даст наилучшие результаты. Причём не на глаз, а с объективной, воспроизводимой оценкой качества.
Прежде чем пытаться что‑то улучшать, нужно понять, что именно считать хорошим результатом. В нашем случае — что такое «хорошее описание» Pull Request’а. Мы решили начать с опроса самих разработчиков — ведь именно им каждый день приходится читать (и составлять) эти описания.
Мы подготовили пять реальных PR’ов и для каждого сгенерировали три варианта описания с помощью разных промптов:
базовый промпт — тот, что используется в текущей версии системы;
расширенный — с упором на технические детали;
структурированный — явно разделяющий цели и сделанные изменения.
Участников опроса просили выбрать лучший вариант и объяснить свой выбор. Такой подход позволил не просто выяснить, какой стиль им ближе, но и понять, почему именно он. На основе анализа ответов мы выделили ключевые характеристики хороших описаний:

Эти критерии стали для нас основой при оптимизации промптов и выборе модели. Мы сознательно ограничили их количество — чтобы задача не стала слишком размытой для автоматической оценки.
Чтобы проводить эксперименты не «на коленке», а действительно объективно, мы собрали собственный датасет — OpenPR. В него вошло 116 тысяч Pull Request’ов из более чем 50 известных опенсорс‑проектов, таких как Kubernetes, TensorFlow, Redis и других.
Наша цель была — охватить как можно больше типов проектов: инфраструктура, базы данных, фреймворки, библиотеки. И вот как мы это делали:
Парсили GitHub через API, отфильтровывая только активные репозитории, созданные до 2022 года (до широкого распространения Copilot); разные языки программирования: Python, Java, C++ и не только.
Чистили данные: убирали пустые diff’ы и описания, приводили формат к единому виду.
Структурировали всё по полочкам: заголовок PR’а, сообщения коммитов, изменения (diff), привязанные issues (если были).
Для финальной оценки моделей мы использовали отдельную валидационную выборку — она не участвовала в процессе оптимизации, чтобы обеспечить честные результаты.
После того как мы определились с критериями качества и собрали валидационный датасет, настало время заняться оптимизацией промпта. Для этого мы применили метод LLM as a judge — итеративный подход, при котором языковая модель сама оценивает результат своей работы и помогает выбрать лучший вариант.
В роли автоматического асессора мы протестировали две модели:
GPT-4 Omni показала себя недостаточно чувствительной к нюансам между вариантами описаний.
Claude Sonnet 3.5, наоборот, оказался более надёжным и чувствительным к тонким отличиям в стиле, структуре и информативности текста.
Мы зафиксировали тестовую выборку из 100 PR’ов из датасета OpenPR и начали итерации:
Вносили небольшое изменение в промпт.
Генерировали описания для всей выборки по двум версиям промпта: старому и новому.
Сравнивали пары описаний через Claude Sonnet.
Принимали или отклоняли изменения на основе сравнений.
Периодически проверяли результат вручную — чтобы убедиться, что модель не ушла куда‑то не туда.
В процессе мы заметили несколько интересных закономерностей:
Фиксированная структура (с заголовками и разбивкой по разделам) делает описание заметно более удобным.
Ссылки на конкретные элементы кода — функции, классы, переменные — ощутимо повышают ценность текста.
И, что неожиданно, эмодзи помогают воспринимать информацию быстрее и проще.
Вот как теперь выглядит наш улучшенный промпт:
Тебе на вход будет дан Pull Request, ты должна дать его описание.
Тело Pull Request будет дано в следующем формате:
1. Title — заголовок Pull Request
2. Commit messages — сообщения коммитов из Pull Request в порядке от завершающего к начальному
3. Diff — изменения в коде
Описание PR должно содержать:
- Задача, решаемая данным PR;
- Список описаний ключевых изменений.
Дополнительные требования:
- Описание должно содержать два раздела с заголовками: «Задача, решаемая данным PR», «Список описаний ключевых изменений»;
- Задача, решаемая данным PR, должна быть описана максимально коротко и просто для понимания. Длина описания не должна превышать 250 символов;
- Каждое описание ключевого изменения должно быть максимально коротким и простым для понимания. Его длина не должна превышать 250 символов. Стремись добавлять отсылки к коду там, где это возможно (имена функций, классов, переменных и т. д.). Каждое описание ключевого изменения должно начинаться с эмодзи, соответствующего его содержанию;
- Для описания ключевых изменений используй ненумерованный список.
Тело Pull Request:
1. Title: {message}
2. Commit messages: {commits}
3. Diff: {patch}
В сравнении с базовым промптом новая версия показала улучшение в 68% случаев (на отложенной выборке из 1000 PR’ов). Причём наибольший прирост качества был в PR’ах среднего и большого размера, где структурированный подход особенно важен.
После оптимизации промпта мы перешли к следующему этапу — сравнению различных языковых моделей для генерации описаний Pull Request’ов.
В качестве baseline мы использовали текущую систему на базе русскоязычной модели с 7 миллиардами параметров. Верхней границей качества служила GPT-4 Omni, которую мы брали как ориентир, хотя она и недоступна для локального развёртывания.
Для финального сравнения мы отобрали четыре продвинутые опенсорс‑модели, появившиеся в 2024 году:
DeepSeek‑Coder‑V2-Lite‑Instruct (16B)
Qwen2.5-Coder-14B‑Instruct
Qwen2.5-Coder-32B‑Instruct
Codestral-22B‑v0.1
Каждая из них запускалась локально и работала с тем же промптом, который мы оптимизировали на предыдущем этапе.
Мы использовали фиксированную тестовую выборку из 1000 Pull Request’ов из датасета OpenPR. Для оценки качества применяли метод попарного сравнения: каждый вариант описания сравнивался с другим при помощи Claude Sonnet 3.5, выступающего в роли автоматического асессора.
Такой подход позволяет сравнивать модели по принципу «честного боя»: на одном и том же входе, с тем же промптом и по единым критериям.
Результаты сравнения (процент случаев, когда модель генерировала лучшее описание):

Интересные наблюдения:
Все протестированные опенсорс‑модели значительно превзошли текущий baseline по качеству описаний.
DeepSeek‑Coder‑V2-Lite продемонстрировал лучший баланс между качеством генерации и потреблением ресурсов.
Qwen2.5-Coder-32B показал наивысшее качество, но требует существенно больше вычислительных мощностей.
Чтобы убедиться в надёжности результатов, мы провели несколько дополнительных проверок:
Сравнение одинаковых описаний между собой дало распределение оценок 57/43 — это говорит о приемлемом уровне шума в оценках со стороны LLM‑асессора.
Мы протестировали Qwen2.5-Coder-32B в роли альтернативного асессора (вместо Claude Sonnet). Результаты остались согласованными, что подтверждает воспроизводимость выводов.
Мы также протестировали квантизованную версию Qwen2.5-Coder-32B в формате GGUF (Q4_M). Несмотря на существенное сжатие, модель показала сопоставимое качество (76% улучшения по сравнению с baseline) при среднем времени генерации ~ 9,4 секунды на 1 PR.
Qwen2.5-Coder-32B — для максимального качества, если ресурсы позволяют.
DeepSeek‑Coder‑V2-Lite — отличный компромисс при ограниченных мощностях.
Qwen2.5-Coder-32B (Q4_M GGUF) — разумный вариант для продакшн‑сценариев, где важны стабильность и экономия ресурсов.
В процессе работы у нас возник закономерный вопрос: а насколько вообще можно доверять оценке качества, сделанной языковой моделью? Может быть, разумнее запустить A/B‑тест и узнать мнение реальных пользователей?
Чтобы ответить на этот вопрос, мы провели эксперимент: проверили, заметят ли разработчики умышленное снижение качества описаний. Для этого мы обрезали входные данные:
удалили половину diff’а;
удалили половину commit‑сообщений.
Дизайн эксперимента:
контрольная группа (80%) — стандартная система генерации;
тестовая группа (20%) — система с урезанным контекстом;
метрика: доля описаний, которые были отредактированы вручную;
охват: все PR’ы в режиме «отдельный блок»;
длительность: две недели.
Сначала мы убедились с помощью Claude Sonnet, что снижение качества действительно есть: оценка «хорошести» описаний упала с 93% до 75%, хотя тексты по‑прежнему выглядели правдоподобно.
Разработчики редактировали описания с одинаковой частотой в обеих группах. 90% описаний принимались без изменений, даже в тестовой группе с ухудшенным качеством. Ручной разбор подтвердил: в тестовой группе описания были хуже — но это не повлияло на пользовательское поведение [5].
Эксперимент показал важный эффект: разработчики склонны доверять автоматической системе и не перепроверяют критически сгенерированные описания. Это делает классический A/B‑тест неэффективным инструментом для оценки качества таких систем — особенно если ухудшения неявные, но значимые.
Поэтому особенно важно применять автоматические методы оценки, такие как LLM as a judge, которые способны последовательно и объективно сравнивать разные варианты генерации.
Мы начинали с простой и прагматичной задачи: улучшить существующую систему генерации описаний для Pull Request’ов. Базовая система уже работала на небольшой модели, но появление мощных опенсорс‑решений открыло путь к существенному росту качества.
Самый сложный вопрос оказался не техническим, а методологическим: как объективно измерить и доказать улучшение?
A/B‑тест с реальными пользователями не дал результата:
разработчики не замечали даже намеренно ухудшенных описаний, доверяя автоматической системе «по умолчанию».
Поэтому мы сделали ставку на подход LLM as a judge, использовав современные языковые модели как автоматических асессоров — последовательных, беспристрастных и чувствительных к нюансам.
На нашем пути было несколько ключевых этапов:
Определили критерии хорошего описания через опросы разработчиков.
Собрали датасет из 116 тысяч PR’ов из открытых репозиториев.
Провели итеративную оптимизацию промпта с LLM в роли оценщика.
Сравнили опенсорс‑модели между собой и с проприетарными решениями.
Что мы узнали:
Современные опенсорс‑модели (Qwen, DeepSeek, Codestral) могут конкурировать с GPT-4 в прикладных задачах вроде генерации описаний.
Автоматическая оценка с помощью LLM может быть более надёжной, чем человеческая, особенно при неочевидных различиях в качестве.
Оптимизация промптов должна опираться на объективные метрики, а не только на ощущения от «хорошего текста».
Наш подход к улучшению генеративных систем оказался не только эффективным, но и универсальным. Его можно применять и в других задачах, где требуется семантически точная генерация, таких как генерация технической документации, формулировка сообщений об ошибках, составление ответов на пользовательские запросы и автосоставление changelog’ов или release notes.
Автор: black_chick
Источник [6]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/15130
URLs in this post:
[1] опытом: http://www.braintools.ru/article/6952
[2] в гайде по стилю PR: https://google.github.io/eng-practices/
[3] мотивация: http://www.braintools.ru/article/9537
[4] обучения: http://www.braintools.ru/article/5125
[5] поведение: http://www.braintools.ru/article/9372
[6] Источник: https://habr.com/ru/companies/yandex/articles/907646/?utm_source=habrahabr&utm_medium=rss&utm_campaign=907646
Нажмите здесь для печати.