DSPy: как автоматически оптимизировать промпты и LLM-программы вместо ручного prompt engineering
DSPy · prompt optimization · GEPA · MIPROv2 · Ollama

DSPy: как автоматически оптимизировать промпты и LLM-программы вместо ручного prompt engineering

Большинство LLM-проектов долго живёт в режиме «поменяем ещё пару строк в system prompt и посмотрим». DSPy предлагает другой подход: описать задачу как программу, задать примеры и функцию качества, а instructions и few-shot demonstrations подбирать алгоритмически. Это особенно интересно там, где prompt уже стал частью production-логики и его нужно улучшать воспроизводимо, а не «на глаз».

3.3.1 stable актуальная стабильная версия от 21 августа 2026 года
Python 3.10–3.14 текущий пакет требует Python ≥3.10 и <3.15
MIT основной framework лицензируется по MIT
Programming, not prompting

DSPy отделяет «что должна сделать модель» от конкретного текста prompt

В обычном prompt engineering developer вручную редактирует instructions, добавляет examples, меняет порядок полей и снова тестирует. В DSPy задача сначала выражается через Signature и Module, а prompt становится параметром программы, который можно оптимизировать по данным.

Signatureчто входит и что должно выйти
→
ModulePredict · ChainOfThought · ReAct
→
Optimizermetric + examples
→
Compiled Programоптимизированные instructions/demos
01 Декларативная задача

Вы описываете входы и выходы, а не пишете длинную окончательную формулировку prompt вручную.

02 Метрика становится частью разработки

Optimizer пытается улучшить именно измеряемое качество, а не «сделать prompt красивее».

03 Prompt можно компилировать

Инструкции и few-shot demonstrations подбираются из training/evaluation loop.

04 Модель можно заменить

DSPy работает поверх разных providers и локальных OpenAI-compatible backends.

Не путать три разных подхода

DSPy не заменяет ни fine-tuning, ни agent framework

ПодходЧто меняетсяКогда полезен
Ручной prompt engineeringТекст instructionsМало кейсов, быстрое прототипирование
DSPyInstructions, demonstrations, структура LM-programЕсть metric и набор реальных примеров
Fine-tuningWeights моделиНужно устойчиво изменить поведение самой модели
Pydantic AIRuntime/agent architectureTools, typed outputs, MCP, durable execution
Stable 3.3.1

Установка

python -m venv .venv

# Windows PowerShell
.\.venv\Scripts\Activate.ps1

pip install dspy==3.3.1

Пакет dspy-ai сейчас оставлен как compatibility alias. Для нового проекта официально устанавливается именно dspy.

Stable 3.3.1

Основная версия для статьи и production-экспериментов.

Pre-release 3.4.0b1

Опубликована 11 сентября 2026 года, но PyPI прямо помечает её как pre-release.

Не ставьте beta только ради «самой новой цифры».

В 3.4 уже меняется LM-интерфейс и добавляются новые ReActV2/MCP возможности. Для обычного проекта разумнее сначала использовать stable 3.3.1.

Минимальный DSPy program

Вместо длинного prompt — короткая signature

import dspy

lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)

qa = dspy.ChainOfThought(
    "question -> answer"
)

result = qa(
    question="Почему автомат может отключаться при коротком замыкании?"
)

print(result.answer)

Здесь "question -> answer" — compact signature. DSPy сам формирует interaction с LM через adapter. Но пока это ещё не «самообучение»: мы просто описали программу.

Настоящая сила DSPy появляется после добавления metric и examples.

Без evaluation optimizer не знает, что именно означает «лучше».

Signatures

Сложную задачу лучше описывать typed-классом, а не строкой

import dspy

class ClassifyTicket(dspy.Signature):
    """Classify a support request."""

    message: str = dspy.InputField()
    category: str = dspy.OutputField(
        desc="One of: network, power, camera, other"
    )
    urgency: int = dspy.OutputField(
        desc="Integer from 1 to 5"
    )

classifier = dspy.Predict(ClassifyTicket)

Signature задаёт контракт между Python program и LM: какие поля входят, какие должны выйти и что они означают. Конкретная prompt-formulation остаётся внутренней частью adapter/optimizer.

InputField Контекст задачи

Текст, история, image и другие supported field types.

OutputField Ожидаемый результат

Можно задавать descriptions и typed structured values.

Docstring Семантика задачи

Короткое описание вместо огромной system-инструкции.

Modules

Signature отвечает «что», Module — «как выполнять LM-step»

dspy.Predict Прямое предсказание

Самый простой module вокруг signature.

dspy.ChainOfThought Добавляет reasoning field

Подходит для задач, где модели полезен промежуточный reasoning step.

dspy.ReAct Reason + Act + tools

Agent loop для задач с функциями/инструментами.

dspy.RLM Новый code/reasoning-oriented path

В 3.3.1 разработчики рекомендуют его вместо deprecated CodeAct/ProgramOfThought для нового кода.

CodeAct и ProgramOfThought уже deprecated в 3.3.1.

Release notes указывают их планируемое удаление в DSPy 3.5. Новую архитектуру лучше на них не строить.

Самый важный компонент optimization

Metric определяет, чему DSPy на самом деле будет учиться

def metric(example, prediction, trace=None):
    expected = example.category.strip().lower()
    actual = prediction.category.strip().lower()

    return 1.0 if expected == actual else 0.0

Если metric считает только exact match, optimizer будет искать prompts, которые повышают exact match. Если нужен более сложный критерий — например, правильность ответа плюс обязательная ссылка на источник — metric должна проверять именно это.

Simple Exact match

Подходит для категорий, enum и коротких structured outputs.

Composite Несколько правил

Правильность + формат + наличие обязательных полей.

Model-based LLM judge

Гибче, но дороже и сам может ошибаться.

GEPA feedback Score + текстовая обратная связь

GEPA использует feedback, чтобы понимать причину провала кандидата.

Плохая metric = оптимизированная ошибка.

DSPy очень хорошо может улучшить именно тот показатель, который вы задали, даже если он плохо отражает реальную полезность продукта.

Optimizers

Какой optimizer выбрать для первого эксперимента

Мало примеров BootstrapFewShot

Автоматически собирает demonstrations, которые проходят metric.

Больше данных BootstrapFewShotWithRandomSearch

Ищет более удачные combinations few-shot examples.

Instructions + demos MIPROv2

Предлагает instructions и few-shot examples, затем ищет комбинацию через Bayesian Optimization.

Текущая официальная документация предлагает начинать примерно так: при очень малом наборе примеров — BootstrapFewShot; при большем наборе — random-search вариант; для более дорогой instruction optimization — MIPROv2 или GEPA.

Optimization — это дополнительные LM calls.

Чем больше candidates, trials и evaluation examples, тем выше стоимость облачного provider или время локального inference.

MIPROv2

DSPy может одновременно искать инструкцию и few-shot demonstrations

import dspy

optimizer = dspy.MIPROv2(
    metric=metric,
    auto="light",
)

optimized = optimizer.compile(
    classifier,
    trainset=trainset,
)

optimized.save(
    "classifier_optimized.json"
)

MIPROv2 сначала генерирует candidate demonstrations и instructions, затем использует Bayesian Optimization для поиска удачной комбинации. Для быстрого старта есть presets light, medium и heavy.

0-shot Можно оптимизировать только instructions

Few-shot demos можно отключить, если prompt должен оставаться zero-shot.

Few-shot Можно оптимизировать demonstrations вместе с instructions

Это один из основных сценариев MIPROv2.

MIPROv2 не гарантирует улучшение на новых данных.

Trainset и dev/test set нужно разделять, иначе optimizer легко переобучить на примеры, по которым вы его оцениваете.

GEPA

Reflection optimizer использует не только score, но и объяснение ошибки

GEPA поддерживает population of candidate programs, оценивает их на validation set и просит reflection LM предложить изменения на основе execution traces и текстового feedback от metric.

def feedback_metric(example, prediction, trace=None):
    score = 1.0 if prediction.category == example.category else 0.0

    if score:
        feedback = "Classification is correct."
    else:
        feedback = (
            f"Expected {example.category}, "
            f"but received {prediction.category}."
        )

    return dspy.Prediction(
        score=score,
        feedback=feedback,
    )


optimizer = dspy.GEPA(
    metric=feedback_metric,
    auto="light",
)

optimized = optimizer.compile(
    classifier,
    trainset=trainset,
)

В документации DSPy подчёркивается: GEPA умеет работать и с обычным числовым score, но конкретный natural-language feedback даёт reflection-модели больше информации о причинах ошибки.

GEPA — не «модель сама себя магически улучшает».

Вы по-прежнему задаёте dataset, metric, evaluation budget и LM. Автоматизирована именно часть поиска более удачных instructions/program variants.

Локальная LLM

DSPy официально показывает Ollama как local laptop backend

import dspy

lm = dspy.LM(
    "ollama_chat/qwen3",
    api_base="http://localhost:11434",
    api_key="",
)

dspy.configure(lm=lm)

predict = dspy.ChainOfThought(
    "question -> answer"
)

result = predict(
    question="Что такое автоматическая оптимизация промптов?"
)

print(result.answer)

Для другого OpenAI-compatible local server можно использовать openai/... model prefix и свой api_base. В официальных docs пример с SGLang указывает endpoint вида http://localhost:7501/v1.

Слабая локальная модель может плохо оптимизировать prompts для самой себя.

Optimizers, особенно reflection/instruction generation, могут требовать более сильной proposer/teacher model, чем конечная дешёвая модель в production.

Agents and tools

DSPy умеет строить ReAct-программы, а tool-use тоже можно оценивать и оптимизировать

import dspy

def get_voltage() -> float:
    """Return demo mains voltage."""
    return 231.4

agent = dspy.ReAct(
    "question -> answer",
    tools=[get_voltage],
)

result = agent(
    question="Какое сейчас демонстрационное напряжение?"
)

print(result.answer)

DSPy 3.3.x также улучшает MCP compatibility. В beta 3.4.0b1 новый ReActV2 получил расширенную async MCP integration, но это уже pre-release функция и для stable-инструкции её лучше не считать обязательной.

Optimizer может улучшать не только один prompt.

DSPy-program может состоять из нескольких LM steps, retrieval, tools и agent loop. Metric при этом оценивает результат всей программы.

После optimization

Скомпилированную программу можно сохранить и использовать без повторной оптимизации

optimized.save(
    "./dspy_program/program.json",
    save_program=False,
)

JSON state — предпочтительный вариант для обычного сохранения оптимизированных instructions/demonstrations и state. DSPy также умеет сохранять whole program через cloudpickle.

JSON Предпочтительно

Безопаснее для переноса state между окружениями.

Pickle / cloudpickle Только доверенные файлы

Нужен для whole-program serialization, но способен выполнять код при загрузке.

Security

DSPy оптимизирует LLM-программы, но вокруг него остаётся обычная Python attack surface

1 Не загружать чужой pickle

Pickle/cloudpickle способны выполнить arbitrary Python code при deserialize.

2 JSON для переносимого state

Если whole-program serialization не нужна, лучше сохранять обычное состояние.

3 Tools имеют реальные side effects

ReAct tool должен сам проверять permissions и arguments.

4 PythonInterpreter — отдельная граница доверия

Исполняемый model-generated code нельзя приравнивать к простому text generation.

5 Provider endpoint содержит данные

Local DSPy не делает cloud LM локальной — prompts уходят туда, куда указывает backend.

6 Pin stable version

3.4.0b1 — beta. Для production не смешивайте stable и beta API без причины.

В 3.2.1 усилили безопасность cache

Release 3.2.1 отдельно отмечает изменение для dspy.Embedder, связанное с предотвращением arbitrary code execution через повреждённые или вредоносные cache files. Stable 3.3.1 уже включает более новую ветку.

Whole Program Saving использует cloudpickle.

Официальная документация прямо предупреждает: загружать такие программы можно только из доверенного источника. Для обычного оптимизированного state предпочитайте JSON.

Ограничения

DSPy автоматизирует поиск prompt/program configuration, но не отменяет экспериментальную работу

01Нужна хорошая metric

Framework не знает бизнес-цель лучше вас.

02Нужны реальные examples

Пять искусственных примеров могут оптимизировать совсем не production behavior.

03Optimization стоит денег/времени

MIPROv2 и GEPA делают много дополнительных model evaluations.

04Есть риск overfitting

Train/dev/test нужно разделять так же, как в ML.

05Provider behavior отличается

Оптимизированная программа для одной модели не гарантированно лучшая для другой.

06Framework быстро развивается

3.4 уже содержит переходные изменения, а 3.5 планирует удаление deprecated API.

DSPy особенно полезен после появления повторяемой оценки.

Если вы ещё не можете написать 20–50 реальных test cases и объяснить, что считается хорошим ответом, возможно, рано автоматизировать prompt optimization.

Практические сценарии

Где DSPy может дать больше пользы, чем очередной ручной rewrite prompt

01 Классификация заявок

Есть labelled cases и чёткая accuracy metric.

02 RAG question answering

Можно оптимизировать query generation, reasoning и answer stage по одной общей metric.

03 Structured extraction

Метрика проверяет полноту и правильность извлечённых полей.

04 Agent tool-use

Можно оценивать конечный результат, а не вручную тюнинговать каждый agent prompt.

05 Маленькая production model

Сильная teacher/proposer model помогает подобрать instructions для более дешёвой model.

06 Prompt regression testing

Оптимизация идёт вместе с dataset/evaluation вместо случайных ручных экспериментов.

Первоисточники

DSPy: stable version, optimizers, Ollama и безопасное сохранение

Материал проверен 21 сентября 2026 года.

Stable package — dspy 3.3.1 от 21 августа 2026 года. 3.4.0b1 от 11 сентября — pre-release и сознательно не используется как baseline статьи.

Вывод

DSPy нужен тогда, когда prompt перестал быть текстом и стал оптимизируемой частью программы

Для одного разового вопроса DSPy избыточен. Но если есть repeatable task, реальные examples и измеримая metric, framework позволяет заменить ручное «покрутим system prompt» на воспроизводимый optimization loop.

Особенно интересна связка: локальная или облачная LLM как backend, DSPy — для signatures/modules и optimization, отдельный evaluation set — для контроля regression, а Langfuse или другой OTel-инструмент — для production observability.

FAQ

Частые вопросы про DSPy

Что такое DSPy простыми словами?

Python framework, в котором LLM-pipeline описывается как программа, а prompts и few-shot examples можно автоматически оптимизировать по metric и набору примеров.

DSPy сам обучает модель?

Не обязательно. Основной сценарий — оптимизация prompts/demonstrations без изменения weights. Есть также optimizers для fine-tuning, но это отдельный режим.

Можно ли использовать Ollama?

Да. Официальные docs показывают dspy.LM("ollama_chat/...", api_base="http://localhost:11434").

Что выбрать: MIPROv2 или GEPA?

MIPROv2 ищет instructions и demonstrations через proposal/search. GEPA использует reflection и особенно выигрывает от metric с текстовым feedback. Выбор нужно проверять на своём dev set.

Нужны ли сотни примеров?

Нет для первого эксперимента. Официальная документация предлагает BootstrapFewShot даже при примерно десяти examples. Более дорогие optimizers требуют больше данных, чтобы снизить риск overfitting.

DSPy заменяет Pydantic AI?

Нет. DSPy сфокусирован на программировании и optimization LM behavior. Pydantic AI больше про production agent runtime: typed outputs, tools, dependencies, MCP и durability.

Можно ли сохранить оптимизированную программу?

Да. Для обычного state предпочтителен JSON. Whole-program saving использует cloudpickle и должен загружаться только из доверенного источника.

Что актуально: dspy или dspy-ai?

Для нового проекта устанавливайте dspy. dspy-ai сейчас является compatibility alias.

Какая версия актуальна?

На 21 сентября 2026 года stable — DSPy 3.3.1. 3.4.0b1 существует, но это beta/pre-release.

LLM quality engineering

Prompt уже меняли десятки раз и непонятно, действительно ли стало лучше?

Следующий шаг — собрать реальный evaluation set, формализовать metric и только после этого сравнивать ручной prompt, DSPy optimization и fine-tuning.