Эволюция промптов вместо RL под капотом фреймворка GEPA
Настройка системных инструкций и агентов обычно превращается в бесконечную ручную подгонку текста. Поправишь одну формулировку — улучшишь логику, но сломаешь форматирование вывода. Применять для такой подгонки обучение с подкреплением вроде GRPO выходит слишком дорого: алгоритмам требуются десятки тысяч прогонов, а вся обратная связь сводится к одной цифре оценки.
На днях я разобрал репозиторий GEPA (Genetic-Pareto). Проект развивают исследователи из Беркли и Стэнфорда, предлагая принципиально иной подход к оптимизации любых текстовых параметров.
В чём идея проекта
Классические оптимизаторы смотрят на систему как на чёрный ящик: на выходе получают числовой балл и пытаются угадать, куда двигаться дальше. GEPA работает иначе. Фреймворк передаёт нейросети весь лог выполнения — ошибки, выводы профилировщика, стек-трейсы и промежуточные рассуждения.
Модель анализирует эти данные так же, как разработчик во время отладки. Она видит конкретную причину сбоя и предлагает точечные исправления. Затем включается генетический алгоритм с учётом фронта Парето: система сохраняет те варианты текста, которые лучше всего справляются с разными подмножествами задач.
Что умеет фреймворк
Подход открывает возможность автоматической настройки самых разных элементов:
- Промпты для отдельной модели или цепочки в DSPy и LangChain
- Архитектура агентов и набор их навыков
- Правила планирования задач и конфигурационные файлы
- Описания инструментов для протокола MCP
В тестах авторов модель GPT-4.1 Mini после сотни итераций подтянула точность на математическом бенчмарке AIME с 46.6% до 56.6%. Инженеры Databricks использовали GEPA, чтобы снизить расходы на работу своих агентов в 90 раз без потери качества.
Как устроен процесс оптимизации
Работа фреймворка закольцована в пять последовательных шагов:
- Выбор кандидата из фронта Парето. Система берет вариант, показавший максимальный результат на определенной группе тестов.
- Запуск на небольшом наборе данных. В процессе собираются все логи выполнения и ошибки.
- Рефлексия. Модель-рефлектор читает текстовые логи сбоев и формулирует диагностику.
- Мутация. Создается новая версия промпта или кода с учетом прошлых ошибок всех предков.
- Принятие решения. Новый кандидат добавляется в общий пулл, если он показал реальное улучшение.
Вся диагностика в терминологии авторов называется Действенной Побочной Информацией (Actionable Side Information). В текстовой оптимизации она выполняет роль градиента из привычного машинного обучения.

Как написать код
Поставить библиотеку можно из PyPI:
pip install gepa
У проекта есть простой API под названием optimize_anything. С его помощью можно подбирать не только промпты, но и любой текстовый артефакт:
import gepa.optimize_anything as oa
from gepa.optimize_anything import GEPAConfig, EngineConfig, optimize_anything
def evaluate(candidate: str) -> float:
result = run_my_system(candidate)
oa.log(f"Output: {result.output}")
oa.log(f"Error: {result.error}")
return result.score
result = optimize_anything(
seed_candidate="Начальный текст инструкции или кода",
evaluator=evaluate,
objective="Уменьшить количество ошибок форматирования вывода",
config=GEPAConfig(engine=EngineConfig(max_metric_calls=100)),
)
Логи, отправленные через oa.log(), как раз и попадают в модель-рефлектор для поиска ошибок. Если вы уже используете DSPy, там инструмент доступен из коробки как dspy.GEPA.
Когда подбор через GEPA действительно оправдан
Метод показывает себя лучше всего в следующих сценариях:
- Запуск агентов с множеством внешних инструментов
- Маленькие обучающие датасеты, когда есть лишь 5-10 примеров
- Закрытые модели без доступа к весам через API
- Дорогие или медленные вызовы, включая компиляцию кода и симуляции
Там, где RL требует 5000–25000 прогонов для сходимости, этому алгоритму обычно хватает 100–500 проверок.
Что в итоге
Фреймворк закрывает болезненную тему ручной подгонки текстовых инструкций. Приятно, что инструмент уже интегрировали в MLflow, Pydantic AI и Google ADK, так что тащить кучу лишнего кода в свой проект не придется. Начать стоит с короткого туториала в документации или запуска optimize_anything на паре ваших самых проблемных промптов.