Гайд · TNWS AI
Как оптимизировать инструкции DSPy через GEPA без утечки тестового набора
Разделяем примеры, метрику и reflection LM перед компиляцией GEPA; оцениваем итог на отдельном отложенном наборе.
Задача и применимость
Актуальный поисковый вопрос: «как разделить train val test для оптимизации dspy GEPA». Не спутать прогресс на данных оптимизатора с улучшением на новых пользовательских вопросах. Материал основан на текущем официальном руководстве DSPy, проверенном 20 сентября 2026 года, и предназначен для Python 3.10+ с совместимым установленным dspy. У разных провайдеров разные доступные модели, лимиты и права: укажите собственный реально работающий provider/model в переменных окружения. Фиксируйте установленную версию пакета при повторении опыта, поскольку API может меняться.
Как устроено решение
Официальное руководство DSPy GEPA показывает отдельный reflection_lm, auto="light", num_threads и вызов compile с trainset и valset. Train служит материалом для предложений улучшения; val помогает выбирать кандидата; final test сохраняют отдельно. Даже если оптимизатор сам перебрал удачные инструкции на первых четырёх примерах, это не доказательство, что шестой или новый пользовательский вопрос решается лучше. Именно поэтому статья делает сравнение на двух ранее не использованных вопросах.
Порядок действий
- Подготовьте независимые размеченные train, val и test по одной схеме question/answer.
- Определите метрику до просмотра кандидатов и убедитесь, что она отражает нужное качество.
- Настройте доступные LM для рабочей программы и, при необходимости, для рефлексии.
- Запустите dspy.GEPA(...).compile(program, trainset=train, valset=val).
- Сравните исходную и оптимизированную версии на test, который не участвовал ни в одном из предыдущих шагов.
Для сетевого запуска установите пакет командой pip install dspy, подготовьте свой доступ к модели и задайте DSPY_MODEL в форме provider/model и DSPY_API_KEY в окружении. Исключение — код, который только проверяет локальные настройки без сетевого вызова. Шаблон ниже содержит вымышленные входные данные и не включает секретов; перед запуском сверьте, что выбранная вами модель подходит для задачи и разрешена правилами провайдера.
Готовый пример программы
import os
import dspy
lm = dspy.LM(os.environ["DSPY_MODEL"], api_key=os.environ["DSPY_API_KEY"])
dspy.configure(lm=lm)
examples = [
dspy.Example(question=q, answer=a).with_inputs("question")
for q, a in [("Столица Франции?", "париж"), ("Столица Италии?", "рим"),
("Столица Испании?", "мадрид"), ("Столица Германии?", "берлин"),
("Столица Польши?", "варшава"), ("Столица Японии?", "токио")]
]
train, val, test = examples[:2], examples[2:4], examples[4:]
def metric(example, prediction):
return float(prediction.answer.strip().lower() == example.answer)
baseline = dspy.Predict("question -> answer")
optimizer = dspy.GEPA(metric=metric, reflection_lm=lm, auto="light", num_threads=2)
optimized = optimizer.compile(baseline, trainset=train, valset=val)
evaluator = dspy.Evaluate(devset=test, metric=metric)
print("До:", evaluator(baseline), "После:", evaluator(optimized))
Вход и ожидаемый результат
Вход — шесть вымышленных учебных карточек со столицами: две обучающие, две валидационные, две отложенные. Ожидаемый результат — два численных показателя на вопросах о Польше и Японии; никакого гарантированного роста мы не обещаем. При равных или худших показателях не объявляйте успех оптимизации и проверьте расширенный независимый набор.
Проверка качества, а не только запуска
Шесть примеров слишком мало для вывода об общем качестве: код демонстрирует границы разделения, не готовый benchmark. GEPA вызывает языковые модели многократно, так что реальные затраты, длительность и лимиты зависят от конкретного провайдера; прежде чем запускать на большой выборке, оцените их в своей учётной записи. Не используйте один и тот же test для постоянной ручной подстройки критерия: после многих таких правок он превращается во вторую валидацию и теряет независимость.
При оптимизации инструкции до запуска запишите базовую оценку неизменённой программы и состав всех наборов. Обучающие случаи доступны оптимизатору, валидационные служат выбору варианта, а тестовые должны оставаться закрытыми до завершения выбора; перенос удачного тестового вопроса в тренировку превращает итоговую метрику в самообман. Зафиксируйте модель, семплирование и критерии корректности, поскольку даже одинаковая программа может выдавать различающиеся ответы. Для небольшого русскоязычного FAQ уделите внимание контрастным формулировкам одного смысла и случаям, когда источник не содержит ответа. Если улучшение наблюдается только на знакомых вопросах, не называйте его доказанным улучшением для новых пользователей.
Особые случаи и границы
При смене model_id фиксируйте отдельную пару исходной и оптимизированной программы. Метод может изменить инструкции и примеры, но не создаёт новых фактов, отсутствующих у базовой модели или внешних источников. Для частного FAQ метрика должна учитывать корректный отказ при отсутствии контекста: иначе GEPA может научиться выдавать короткий уверенный ответ на всё. Если итог на test ухудшился, сохраняйте baseline для отката, исследуйте ошибки построчно и расширяйте покрытие тренировочных случаев без раскрытия персональных данных.
Критерии приёмки
- train, val и test не пересекаются по вопросам.
- Оценка после оптимизации сделана на отложенном test.
- Результат интерпретируется как опыт, а не гарантированное улучшение.
Если критерий не выполнен, сначала разделите четыре причины: доступ к модели, контракт полей, поведение самого модуля и правильность предметного ответа. Один успешно выполненный Python-вызов подтверждает только часть этих условий. Сохраняйте минимальный безопасный пример и сравнивайте версии по одинаковым вопросам; не используйте реальные имена клиентов, токены или закрытые документы для отладки в общих журналах. Когда сценарий требует инференса, точные формулировки ответов и затраты зависят от выбранной модели, поэтому в статье заданы проверяемые свойства, а не выдуманные гарантии.
Типичные ошибки и чего не делать
- Не включайте test в trainset ради красивого балла.
- Не обещайте известную стоимость или выигрыш GEPA до запуска.
- Не оптимизируйте неверно определённую метрику.
Частые вопросы
Зачем отдельный valset?
Он помогает выбрать кандидата в процессе оптимизации.
Вызывает ли GEPA модель дополнительно?
Да, генерирует и проверяет варианты.
Гарантирован ли рост качества?
Нет, его измеряют на независимом наборе.
Официальные источники
Частые вопросы
Зачем отдельный valset?
Он помогает выбрать кандидата в процессе оптимизации.
Вызывает ли GEPA модель дополнительно?
Да, генерирует и проверяет варианты.
Гарантирован ли рост качества?
Нет, его измеряют на независимом наборе.
Читайте также
Как дать DSPy ReAct только читающий инструмент для ответа по справке
Подключаем read-only функцию словаря к ReAct, ограничиваем число итераций и проверяем источник ответа.
Как задать простой русскоязычный вопрос через DSPy Predict и Signature
Пишем сигнатуру question -> answer и проверяем поля Prediction на безопасном тесте справочного ответа.
Как подключить языковую модель к DSPy и проверить первый вызов
Подключаем DSPy к доступной модели через переменные окружения и отделяем ошибку соединения от ошибки сигнатуры.
Комментарии
Пока тихо. Скажите первое слово