JetBrains Research
Исследования имеют решающее значение для прогресса и инноваций, поэтому в JetBrains мы увлечены как научными, так и рыночными исследованиями
Исследования
TL;DR
Библиотека оптимизации агентов Koog (Koog Agents Optimization Library) — это исследовательская библиотека, разработанная в JetBrains Research для оптимизации промптов агентов Koog. С ее помощью вы пишете первую версию каждой инструкции, отмечаете шаги, требующие настройки, предоставляете библиотеке обучающий набор и задаете способ оценки вывода агента. Затем библиотека запускает ваш агент, учится на результатах и возвращает улучшенные инструкции в виде отдельного файла JSON, который вы можете прочитать, проверить и зафиксировать в системе контроля версий (commit). Переписывать самого агента не требуется.
В примерах из этой статьи используется GEPA, оптимизатор промптов, который учится на ошибках и успехах вашего агента. В этой статье мы покажем примеры работы на бенчмарке конфиденциальности PUPA. GEPA повысила результат нашего агента с 81,19 до 94,22.
👉 Библиотека оптимизации агентов Koog (GitHub)
Агент для оптимизации
Koog — это фреймворк JetBrains на Kotlin для создания агентов. Он рассматривает агента как программу: вы объявляете поток управления в виде типизированного графа из узлов и ребер, и каждый шаг может содержать собственный промпт, инструменты и модель.
У нас есть полноценный агент, написанный на нем: наш порт PAPILLON, конвейер конфиденциальности, который GEPA использует в качестве одного из своих бенчмарков. Он работает на , наборе данных пользовательских запросов, содержащих личные данные. Агент должен ответить на такой запрос с помощью большой внешней модели, не передавая ей эти личные данные, поэтому он переписывает вопрос без этих данных, отправляет эту версию и формирует ответ на основе полученного результата.
Для выполнения этой работы нужны всего три шага: первый переписывает вопрос, второй вызывает большую модель, а третий пишет ответ. Все остальное — вспомогательный код. Два из этих трех шагов содержат написанную человеком инструкцию, и именно их вы хотели бы передать на откуп оптимизатору.
Пометка шага как оптимизируемого
Библиотека добавляет один билдер. Замените subgraphWithTask на optimizableSubgraphWithTask для шагов, которые вы хотите настроить, и вынесите инструкцию из строки, в которой она была скрыта:
Когда шаг помечен как «оптимизируемый», сам граф остается неизменным. Инструкция просто переместилась в собственный параметр, где оптимизатор может найти ее и заменить. Если артефакт для загрузки отсутствует, шаг выполняется на основе написанного вами текста.
Запуск оптимизатора
GEPA запускает ваш агент на обучающем наборе, показывает второй модели, что пошло не так, и просит предложить лучшую инструкцию. Затем библиотека тестирует эту инструкцию и повторяет процесс снова и снова в рамках заданного бюджета. На протяжении этих раундов она держит в активном состоянии несколько кандидатов в инструкции одновременно, чтобы не отбросить вариант, который выигрывает только на самых сложных задачах.
Оптимизатору от автора агента требуется одна вещь: функция, которая для завершенного запуска возвращает оценку и краткую сводку того, как все прошло. Оценка определяет, какие кандидаты выживают, а текст читает вторая модель. В данном случае этот текст представляет собой одну строку чисел:
Эта строка вместе с тем, что шаг получил на вход и выдал на выходе, — это все, с чем GEPA пришлось работать при написании инструкции в следующем разделе.
Остальное — это всего два вызова:
train записывает артефакт, а loadOptimizedAgent считывает его и выдает вам копию вашего агента, работающего с новыми инструкциями. Каждый оптимизатор в библиотеке имеет те же два метода, поэтому переключение между ними не затрагивает окружающий код.
Что написала GEPA
Шаг, который удаляет личные данные, начинался с такой инструкции:
Учитывая частный пользовательский запрос, создайте запрос с сохранением конфиденциальности для мощной внешней LLM. LLM может оказывать помощь, не узнавая конфиденциальную информацию о пользователе.
Учитывая частный пользовательский запрос, создайте запрос с сохранением конфиденциальности для мощной внешней LLM.
LLM может оказывать помощь, не узнавая конфиденциальную информацию о пользователе.
Две строки, намеренно расплывчатые. В них ничего не говорится о том, какая степень маскировки данных будет достаточной.
К концу работы этот же шаг выполнял инструкцию длиной 4456 символов. Вот три ее фрагмента:
Каждая деталь в приведенной выше инструкции появилась в результате работы, а не была написана нами. Вы бы вряд ли сели писать словарь заполнителей (placeholder vocabulary), правило об именах профессоров и кодах курсов или общую стратегию в конце. В этой стратегии сформулирован компромисс, о котором мы никогда не упоминали: свести утечку к нулю, но оставить достаточно деталей для выполнения работы.
Результаты
Мы хотели узнать, действительно ли наша GEPA в Koog делает то, что должна, поэтому мы запустили ее на бенчмарках, которые использует сам проект, и проверили, стали ли агенты работать лучше.
В качестве примера возьмем , бенчмарк, на котором работает описанный выше агент. Его базовый показатель уже составлял 81,19 с небольшим потенциалом для роста, но оптимизация все равно улучшила его на 13 пунктов — до 94,22. Оба числа представляют собой среднее значение по результатам пяти запусков, и прирост статистически значим.
С остальными бенчмарками, а также с тем, как наши показатели соотносятся с оригинальной реализацией, можно ознакомиться в документации.
Еще три оптимизатора
Помимо GEPA, библиотека реализует еще три оптимизатора за тем же интерфейсом:
- BootstrapFewShot извлекает демонстрации из ваших успешных запусков. Эта библиотека не делает никаких вызовов LLM, кроме запуска вашего собственного агента, что делает ее самым дешевым вариантом для первого знакомства.
- MIPROv2 выполняет поиск по инструкциям и демонстрациям.
- ACE наращивает «базу знаний» из идей, которая сопровождает системный промпт — это полезно, когда нужно, чтобы агент накапливал знания, а не просто подбирал лучшие формулировки инструкций.
Переключение между ними сводится к использованию одного конструктора; вызовы train и loadOptimizedAgent вокруг него остаются прежними. Написание собственного оптимизатора означает реализацию тех же двух методов, и все четыре наших варианта вписываются в эту схему без каких-либо обходных путей.
Где найти проект
Библиотека, ее документация и полные результаты бенчмарков находятся в репозитории с открытым исходным кодом. Поддержка оптимизируемых подграфов, на которую она опирается, в настоящее время находится в форке Koog; мы ожидаем, что она попадет в основной репозиторий (upstream).











