DSPy на практике: от сигнатур до оптимизации промптов

Как устроен DSPy: сигнатуры, модули, метрики и оптимизаторы. Примеры на Python, расчёт стоимости первого эксперимента и критерии выбора вместо ручных промптов.

Опубликовано

Автор
DSPy на практике: от сигнатур до оптимизации промптов

DSPy стоит попробовать, если вы регулярно решаете одну и ту же задачу с помощью ИИ, умеете оценивать результат, а ручная доработка промптов уже превратилась в постоянную работу. Фреймворк переносит эту работу в программу на Python и цикл оптимизации. Ниже — небольшой первый эксперимент, рассчитанный максимум на 100 одношаговых прогонов программы без учёта повторных попыток. Если в компании пока нет единого понимания, какой ответ считать правильным, сначала договоритесь об этом и лишь затем подключайте DSPy.

Информация проверена 15 октября 2026 года по актуальной документации DSPy, данным PyPI и тарифам Google на модели. В PyPI опубликован DSPy 3.4.1 от 12 октября 2026 года; требуется Python версии 3.10 или новее, но ниже 3.16. Пакет для установки — dspy. Метаданные пакета в PyPI.

Что такое DSPy и что в нём означает компиляция?

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

Представьте репетицию. Сигнатура задаёт задание, модуль определяет, как его исполнять, а метрика — по каким правилам оценивать результат. Оптимизатор что-то меняет, проверяет результат и сохраняет полезные изменения. Без правил оценки можно бесконечно репетировать по-разному, так и не поняв, стало ли лучше.

Сигнатуры задают условия задачи

Сигнатура описывает входные и выходные данные, а также инструкции к задаче. Запись "ticket -> category" означает, что на вход поступает обращение, а на выходе получается категория. Сигнатура в виде класса позволяет добавить типизированные поля и строку документации с описанием задачи. Выбор полей по-прежнему важен: оптимизатор не исправит расплывчатое понимание того, что бизнес считает «срочным». Документация по сигнатурам.

Модули DSPy определяют способ выполнения

Модуль реализует стратегию решения задачи. dspy.Predict — базовый блок для получения предсказания. dspy.ChainOfThought добавляет перед ответом поле с рассуждением. dspy.ReAct поддерживает цикл рассуждений и вызовов инструментов. Если одного шага модели недостаточно, модули можно объединять средствами Python. Документация по модулям.

Для распределения обращений в поддержку начните с Predict. Цикл вызовов инструментов ради классификации короткого сообщения лишь усложнит систему, прежде чем вы успеете убедиться, что он вообще нужен.

Компиляция здесь означает оптимизацию

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

Актуальная документация DSPy с первой программой для генерации хайку
DSPy: первый пример программы из актуальной документации

Руководство по DSPy: минимальный пример из документации

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

Установите проверенную версию в своём окружении Python:

Bash
python -m pip install 'dspy[litellm]==3.4.1'

Задайте в переменной окружения GEMINI_API_KEY действующий ключ API Google Gemini. Сохраните код в файл first_dspy.py и выполните python first_dspy.py:

Python
import os
import dspy

lm = dspy.LM(
    "gemini/gemini-2.5-flash-lite",
    api_key=os.environ["GEMINI_API_KEY"],
    engine="litellm",
)
dspy.configure(lm=lm)

haiku_signature = "subject -> haiku"
haiku_generator = dspy.Predict(haiku_signature)
result = haiku_generator(subject="computer science")
print(result.haiku)

Последние четыре строки — первая программа из актуальной документации. Настройка следует схеме подключения моделей в DSPy, но здесь используется Google Gemini 2.5 Flash-Lite, чтобы весь эксперимент ниже работал с одной недорогой моделью. Строка провайдера соответствует интеграции Gemini в LiteLLM; явный выбор бэкенда поддерживается API DSPy LM.

DSPy строит промпт по сигнатуре, отправляет его настроенной модели и извлекает поле haiku из ответа. Это пример получения ответа от модели, а не запуска оптимизации. Здесь не обещается ни конкретное стихотворение, ни улучшение качества.

Почему оптимизация промптов в DSPy требует метрики?

Без метрики нет осмысленной оптимизации. Метрика — функция, которая превращает предсказание в оценку. При распределении обращений она может сравнивать выбранную моделью категорию с меткой, утверждённой человеком. Для сгенерированного ответа может понадобиться система критериев или программная проверка правильности. Интерфейс метрик DSPy принимает вашу функцию оценки; фреймворк не решает за бизнес, какой результат нужно поощрять. Метрики и оценка.

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

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

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

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

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

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

Оптимизаторы DSPy: что есть в актуальной документации

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

В актуальном указателе API оптимизаторов перечислены именно эти названия: BetterTogether, BootstrapFewShot, BootstrapFewShotWithRandomSearch, BootstrapFinetune, BootstrapRS, COPRO, Ensemble, GEPA, InferRules, KNN, KNNFewShot, LabeledFewShot, MIPROv2 и SIMBA.

Не каждое название обозначает самостоятельный алгоритм поиска. BootstrapRS — псевдоним BootstrapFewShotWithRandomSearch, а KNN — вспомогательный компонент поиска для KNNFewShot. В актуальном руководстве по выбору также упоминается AvatarOptimizer для агентных программ, хотя в этом указателе API его нет. Подробности о семействе оптимизаторов, руководство по выбору.

Что нужно изменитьКакие названия стоит знатьС чего начать
Примеры в промптеLabeledFewShot, BootstrapFewShot, BootstrapFewShotWithRandomSearch / BootstrapRSСначала проверьте простой базовый вариант с примерами, затем переходите к перебору множества наборов.
Подбор примеров под каждый входKNNFewShot с помощью KNNПолезно, когда разным входным данным нужны разные примеры; добавляет поиск и работу во время выполнения.
ИнструкцииCOPRO, GEPAВыбирайте GEPA, если содержательная обратная связь об ошибках может направлять доработку.
Инструкции и демонстрацииMIPROv2, SIMBA, InferRulesРассмотрите их, если исходных примеров или правил недостаточно.
Веса модели или сочетание стратегийBootstrapFinetune, BetterTogetherНужны обоснованная причина обучать веса и модель, которая это поддерживает.
Объединение готовых вариантовEnsembleВ формировании ответа могут участвовать несколько программ, что увеличивает объём вычислений при получении ответа.

MIPROv2 предлагает инструкции и с помощью байесовской оптимизации — поиска с учётом предыдущих оценок — исследует сочетания инструкций и демонстраций. SIMBA работает с мини-батчами и предлагает правила или демонстрации. Это разные подходы, а не новые названия BootstrapFewShot. API MIPROv2, API SIMBA.

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

Ограничьте объём первого запуска оптимизации

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

DSPy BootstrapFewShot: небольшой пробный запуск

Подготовьте файлы train.jsonl, validation.jsonl и test.jsonl, в каждом — по 20 разных обращений, размеченных человеком. Каждая строка содержит JSON-объект с полями text и label; допустимые метки — billing, technical, account и other. Например, запрос на изменение адреса в счёте может получить метку billing. Нужны ваши собственные примеры, а не хайку из предыдущей программы.

Сохраните этот отдельный скрипт как optimize_tickets.py и запустите его, задав тот же ключ API:

Python
import json
import os
from typing import Literal
import dspy

lm = dspy.LM(
    "gemini/gemini-2.5-flash-lite",
    api_key=os.environ["GEMINI_API_KEY"],
    engine="litellm",
    cache=False,
)
dspy.configure(lm=lm)

class RouteTicket(dspy.Signature):
    """Choose the support queue responsible for the ticket's main request."""
    text: str = dspy.InputField()
    label: Literal["billing", "technical", "account", "other"] = (
        dspy.OutputField()
    )

def load_examples(path):
    with open(path, encoding="utf-8") as source:
        rows = [json.loads(line) for line in source if line.strip()]
    assert len(rows) == 20
    return [dspy.Example(**row).with_inputs("text") for row in rows]

train = load_examples("train.jsonl")
validation = load_examples("validation.jsonl")
test = load_examples("test.jsonl")
assert len({e.text for e in train + validation + test}) == 60

def correct_label(example, prediction, trace=None):
    return prediction.label == example.label

program = dspy.Predict(RouteTicket)
evaluate = dspy.Evaluate(
    devset=validation, metric=correct_label, num_threads=1
)
print("Baseline validation:", evaluate(program).score)

optimizer = dspy.BootstrapFewShot(
    metric=correct_label,
    max_bootstrapped_demos=4,
    max_labeled_demos=0,
    max_rounds=1,
)
optimized = optimizer.compile(program, trainset=train)
print("Optimized validation:", evaluate(optimized).score)

# Freeze this candidate before opening the final test results.
final_test = dspy.Evaluate(
    devset=test, metric=correct_label, num_threads=1
)
print("Baseline final test:", final_test(program).score)
print("Optimized final test:", final_test(optimized).score)
optimized.save("candidate_ticket_router.json")

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

Число прогонов в этом эксперименте складывается так:

  • Исходная программа на валидационной выборке: 20 прогонов программы.
  • Bootstrap на обучающей выборке: до 20 прогонов модели-учителя; их может быть меньше, если достаточно демонстраций успешно пройдут проверку раньше.
  • Оптимизированная программа на валидационной выборке: 20 прогонов программы.
  • Обе версии на итоговой тестовой выборке: 40 прогонов программы.

Всего получается до 100 одношаговых прогонов с учётом оценки; на саму компиляцию приходится не больше 20. Если каждый прогон требует одного успешного запроса к модели, нет повторных попыток и резервных вызовов при ошибках разбора ответа, это максимум 100 вызовов модели, решающей задачу. Предыдущая проверка с хайку считается отдельно. Оценка с помощью LLM, агентный цикл, повторные запросы или ещё одна попытка оптимизации изменят итоговое число.

Четыре архитектурных отсека: 20 прогонов исходной программы, до 20 прогонов bootstrap, 20 прогонов для сравнения и 40 для итогового теста
Пример бюджета первого эксперимента без повторных попыток и дополнительных шагов модели.

По опубликованным платным тарифам Google Standard для текстовых запросов к Gemini 2.5 Flash-Lite — $0.10 за миллион входных токенов и $0.40 за миллион выходных — 100 вызовов при допущении, что каждый в среднем содержит 1,000 входных и 100 выходных токенов, обойдутся в $0.014: 100,000 ÷ 1,000,000 × $0.10 + 10,000 ÷ 1,000,000 × $0.40. Тарифы Google.

Это лишь расчёт стоимости модели, а не фактический счёт или предел расходов. В предполагаемый объём входных данных должны входить форматирование DSPy и добавленные демонстрации; более длинные обращения, объёмные ответы и оплачиваемые токены рассуждения увеличат сумму. Расчёт не учитывает скидки за пакетную обработку или кэширование. Для учёта расходов нужны фактические данные об использовании у провайдера.

Что выбрать: фреймворк DSPy, ручные промпты или дообучение?

Используйте DSPy, когда нужен воспроизводимый способ улучшать программу с измеримым результатом. Оставьте промпт, написанный вручную, если он уже выполняет требования задачи. Рассматривайте дообучение, когда есть свидетельства, что изменения промптов недостаточно, а обучение модели укладывается в ограничения вашей среды развёртывания.

ПодходЧто меняетсяЗа что вы отвечаетеПодходящая первая задача
Промпты, написанные вручнуюЧеловек редактирует инструкции и примерыПостановка задачи и оценкаНебольшая стабильная задача с промптом, который уже справляется с ней
Оптимизация промптов в DSPyПрограмма подбирает инструкции или демонстрацииПрограмма на Python, примеры и метрикаРегулярная классификация, извлечение данных или генерация ответов, требующие систематического улучшения
ДообучениеВеса модели, обучаемые на данныхОбучающие данные, поддержка дообучения моделью и оценкаСтабильное поведение, ради которого оправдано обучать и поддерживать отдельный вариант модели

Эти методы совместимы. В DSPy есть BootstrapFinetune, а BetterTogether сочетает оптимизацию промптов и весов. Практическая разница в том, что именно вы меняете и поддерживаете, а не в том, какое название звучит технологичнее. Оптимизация промптов и весов.

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

Кому стоит внедрять DSPy, кому подождать, а кому обойтись без него?

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

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

Заказчикам нужны доказательства на примерах, которых система ещё не видела. Уточните, с каким базовым вариантом сравнивали результат, в каких случаях стало хуже, что теперь входит в рабочую программу и соблюдаются ли требования ко времени ответа. Название оптимизатора не заменяет критериев приёмки. Командам, которые выстраивают процесс оценки, также пригодится обзор Promptfoo на этом сайте.

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

Какие обещания о DSPy стоит воспринимать осторожно?

«Программирование вместо промптинга» не означает, что промпты исчезают. DSPy создаёт их и управляет ими; люди по-прежнему ставят задачу, разбирают ошибки и решают, приемлем ли результат.

«Компиляция» не означает, что модель чему-то научилась навсегда. При использовании оптимизаторов промптов результат обучения — инструкции или демонстрации. Для получения ответа всё равно нужна модель, а демонстрации занимают место в промпте. Полученное состояние можно сохранить в JSON и загрузить в новую программу. Сохранение и загрузка.

«Автоматическая оптимизация» не гарантирует автоматического выигрыша. Сравнивать нужно с вашим текущим подходом на ранее не использованных входных данных. Более высокая оценка при разработке может оказаться следствием переобучения, слишком снисходительного оценщика или набора данных, в котором нет дорогостоящих ошибок.

И ещё: число вызовов метрики не равно числу обращений к провайдеру. Параметр GEPA max_metric_calls ограничивает число вызовов оценки; рефлексия тоже обращается к модели, а сама оцениваемая программа может отправлять несколько запросов. Настройки auto не задают универсальную стоимость. Управление бюджетом GEPA.

Частые вопросы инженеров о DSPy

Как работает DSPy?

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

Готов ли DSPy к промышленному использованию?

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

Остаётся ли DSPy актуальным?

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

В чём основные различия между LangChain и DSPy?

LangChain — фреймворк для создания агентов с интеграциями моделей и инструментов. Особенность DSPy — описание задач для моделей и оптимизация программ по метрикам. Выбирайте под свою проблему: связать компоненты агента или систематически улучшать решение задачи с измеримой оценкой. Обзор LangChain.

Можно ли использовать DSPy для оптимизации промптов?

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

Кто создал DSPy?

DSPy разработали Omar Khattab и его коллеги. Репозиторий поддерживается в рамках Stanford NLP; авторы перечислены в библиографической ссылке на исследование, приведённой в описании пакета. Проект и авторы.

Как работает GEPA в DSPy?

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

Как расшифровывается название фреймворка DSPy?

DSPy расшифровывается как Declarative Self-improving Python — это указано в официальном описании пакета.

С чего начать на практике

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

Получайте практические разборы инженерии ИИ в рассылке.

Опубликовано
Категория
Build
Похожие статьи
Протокол ACP: как подключить ИИ-агента к привычной IDE

Протокол ACP: как подключить ИИ-агента к привычной IDE

Как протокол ACP подключает ИИ-агентов к редакторам: поддержка в Zed, JetBrains и Android Studio, отличия от MCP, работа сессий, адаптеры и разрешения.3 нояб. 2026 г.Build
Альтернативы Vercel в 2026 году: где разместить Next.js и ИИ-приложение

Альтернативы Vercel в 2026 году: где разместить Next.js и ИИ-приложение

Сравниваем шесть альтернатив Vercel для Next.js и ИИ-приложений: цены, бесплатные тарифы, совместимость, фоновые задачи и нюансы переезда на новый хостинг.3 нояб. 2026 г.Build
Альтернативы Vapi в 2026 году: что выбрать для голосовых агентов

Альтернативы Vapi в 2026 году: что выбрать для голосовых агентов

Альтернативы Vapi: сравнение Retell AI, Bland AI, ElevenLabs, Synthflow и Vida Global по полной стоимости звонков, телефонии, интеграциям и сложности перехода.3 нояб. 2026 г.Build
Browser Use: автоматизация браузера с ИИ — от установки до первого агента

Browser Use: автоматизация браузера с ИИ — от установки до первого агента

Как устроен Browser Use, какие модели он поддерживает и что даёт Cloud. Установка, первый запуск ИИ-агента, ограничения и проверка результатов работы.2 нояб. 2026 г.Build
Обзор Zernio: API для соцсетей, тарифы и ограничения

Обзор Zernio: API для соцсетей, тарифы и ограничения

Обзор Zernio для разработчиков: API для соцсетей, требования к аккаунтам, тарифы, вебхуки и MCP. Разбираем ограничения и сравниваем с Ayrshare и Postiz.1 нояб. 2026 г.Build
Airtable или Notion: что выбрать для команды

Airtable или Notion: что выбрать для команды

Airtable или Notion: сравниваем CRM, проекты, базы знаний, автоматизации, ИИ и клиентский доступ. Разбираем цены, лимиты и случаи, когда нужны оба сервиса.1 нояб. 2026 г.Build
Закрытие Google Jules: как сохранить работу и сменить агента

Закрытие Google Jules: как сохранить работу и сменить агента

Закрытие Google Jules: сроки, экспорт данных и перенос задач в Antigravity, Codex, Claude Code или GitHub Copilot. Что сохранить и как проверить новую среду.1 нояб. 2026 г.Build
smolagents: как устроены ИИ-агенты, выполняющие Python

smolagents: как устроены ИИ-агенты, выполняющие Python

Как smolagents выполняет действия на Python: инструменты, модели, песочницы и пример с Docker. Когда выбрать эту библиотеку, LangGraph или OpenAI Agents SDK.31 окт. 2026 г.Build
Рассылка

Одно письмо, каждое воскресенье.Работающие системы, а не горячие мнения.

Еженедельно. Без спама. Отписка в любой момент.