中文翻译暂不可用,显示俄语原文。

Объясните концепцию «программируемых промптов» (DSPy programs). Как это связано с MIPRO?

Краткий тезис

DSPy (Declarative Self-improving Python) — это фреймворк, который превращает создание цепочек вызовов LLM из ручного написания промптов в программирование с типизированными модулями. Программируемые промпты (DSPy programs) — это композиция таких модулей, где каждый модуль декларирует, что нужно сделать, а не как именно формулировать запрос. MIPRO (Multi-prompt Instruction Proposal Optimizer) — один из ключевых оптимизаторов DSPy, который автоматически настраивает и промпты, и примеры few-shot для всей программы сразу, а не для каждого узла по отдельности.


1. Термин: Программируемые промпты (DSPy programs)

Программируемые промпты — это подход, при котором сложный рабочий процесс с LLM описывается в виде программы на Python с использованием модулей DSPy. Каждый модуль (например, dspy.Predict, dspy.ChainOfThought) параметризуется полями ввода/вывода (типизированными сигнатурами) и не содержит жёстко заданного текста промпта. Вместо этого DSPy автоматически генерирует эффективные промпты на этапе компиляции.

  • Традиционный подход: разработчик вручную пишет промпт, подбирает формулировки, few-shot примеры, экспериментирует.
  • DSPy-подход: разработчик определяет сигнатуру (например, question -> answer) и логику (например, цепочку «извлечение → рассуждение → ответ»), а детали промпта и примеры подбирает оптимизатор (MIPRO, BootstrapFewShot и др.).

2. Как DSPy отличается от традиционного промпт-инжиниринга

АспектТрадиционный промпт-инжинирингDSPy programs
ФокусРучное написание текста промптаОпределение логики и типов данных
ИзменяемостьЛюбое изменение промпта требует ручной правки и тестированияИзменение сигнатуры или модуля автоматически перестраивает промпт
Few-shot примерыРазметка вручную, риск переобученияАвтоматический подбор примеров через оптимизатор
ВоспроизводимостьСлабый контроль версий (промпт как текст)Чёткий код Python, версионируется в git
ОптимизацияОтдельная для каждого шагаГлобальная оптимизация всей программы (MIPRO)

3. Основные компоненты DSPy

3.1 Сигнатура (Signature)

Это описание полей ввода и вывода модуля, например "question -> answer". Сигнатуры могут содержать много полей с описанием семантики (через docstrings). Пример:

class GenerateAnswer(dspy.Signature):
    """Ответь на вопрос, используя предоставленный контекст."""
    context = dspy.InputField(desc="relevant passages")
    question = dspy.InputField(desc="user query")
    answer = dspy.OutputField(desc="concise answer")

3.2 Модуль (Module)

Базовый строительный блок. dspy.Predict — простой call|вызов LLM с заданной сигнатурой. dspy.ChainOfThought добавляет шаг рассуждения. Модули могут комбинироваться в композитные модули.

class RAG(dspy.Module):
    def __init__(self, retriever):
        self.retrieve = dspy.Retrieve(k=3)
        self.generate = dspy.ChainOfThought(GenerateAnswer)

    def forward(self, question):
        context = self.retrieve(question).passages
        answer = self.generate(context=context, question=question)
        return answer

3.3 Программа (Program)

Программа — это экземпляр модуля высшего уровня (например, RAG). Её можно скомпилировать (оптимизировать) с помощью dspy.Compiler]] и затем использовать как обычную функцию.


4. Пример программы на DSPy

Допустим, мы создаём систему ответов на вопросы по документам.

import dspy
from dspy.datasets import HotPotQA

# Настройка LM
lm = dspy.OpenAI(model='gpt-3.5-turbo')
dspy.settings.configure(lm=lm)

# Определяем сигнатуру
class Answer(dspy.Signature):
    context, question = dspy.InputField(), dspy.InputField()
    answer = dspy.OutputField()

# Создаём модуль-программу
class SimpleRAG(dspy.Module):
    def __init__(self):
        self.retrieve = dspy.Retrieve(k=3)
        self.generate = dspy.ChainOfThought(Answer)

    def forward(self, question):
        context = self.retrieve(question).passages
        return self.generate(context=context, question=question)

# Компиляция (оптимизация)
rag = SimpleRAG()
compiled_rag = dspy.Compiler(rag)
compiled_rag.compile(
    trainset=train_data,
    metric=dspy.metric.answer_exact_match,
    optimizer='MIPRO'  # используем MIPRO
)

# Инференс
answer = compiled_rag("Какая столица Франции?")

5. Что такое MIPRO?

MIPRO (Multi-prompt Instruction Proposal Optimizer) — это оптимизатор для DSPy, который одновременно улучшает все промпты и few-shot примеры в программе. В отличие от простых подходов (BootstrapFewShot, которые подбирают только примеры), MIPRO использует байесовскую оптимизацию по графу программы.

Ключевые идеи:

  • Векторизация промптов: каждый промпт представляется как набор параметров (инструкция, порядок полей, стиль).
  • Surrogate model (суррогатная модель) предсказывает качество программы по этим параметрам.
  • Итеративный отбор проб: MIPRO перебирает комбинации промптов, оценивает на validation set и обновляет суррогатную модель.
  • Результат — согласованный набор промптов для всех модулей, дающий максимальную метрику (например, F1, EM).

6. Как MIPRO работает: пошаговая схема

  1. Инициализация: берутся инструкции по умолчанию, сгенерированные DSPy на основе сигнатур.
  2. Пробоотбор (candidate generation): для каждого модуля генерируются несколько альтернативных инструкций (через LLM или шаблоны).
  3. Оценка программы: на validation set запускается полная программа с текущим набором инструкций; считается метрика.
  4. Построение суррогатной модели: Gaussian Process или Random Forest, которая предсказывает метрику для комбинаций.
  5. Оптимизация acquisition function: выбирается следующая комбинация инструкций для оценки (баланс exploration/exploitation).
  6. Повторение (обычно 10–50 итераций) до сходимости или лимита.
  7. Итоговый набор: инструкции и few-shot примеры (отбираются отдельно) фиксируются.

7. Связь DSPy и MIPRO

MIPRO является одним из оптимизаторов (compiler backends) в DSPy. Он тесно интегрирован:

  • DSPy предоставляет: структуру программы, сигнатуры, типы данных, метрики, трейсинг.
  • MIPRO использует: эту структуру для декомпозиции задачи оптимизации — каждый модуль рассматривается как отдельная «ручка» (knob), которую можно настроить.
  • Результат: после компиляции с MIPRO, программа готова к продакшену — промпты не нужно трогать вручную, они оптимальны для данной задачи и модели.

Без DSPy MIPRO не имел бы смысла, так как не было бы формального описания программы. Без MIPRO DSPy оставался бы только фреймворком для быстрого прототипирования, но не для автоматической оптимизации.


8. Преимущества подхода

  • Глобальная оптимизация: учитываются взаимодействия между модулями (например, как изменение промпта retrieval влияет на качество final answer).
  • Автоматизация: не нужно тратить часы на ручное A/B-тестирование промптов.
  • Воспроизводимость: код программы + данные компиляции = полностью воспроизводимый пайплайн.
  • Адаптация под модель: MIPRO подбирает инструкции, специфичные для используемой LLM (например, GPT-4 vs Llama).

9. Ограничения и когда использовать

ОграничениеКомментарий
Затраты на компиляциюMIPRO требует десятков прогонов программы, что дорого для больших LLM
Сложность отладкиЕсли программа имеет баги, оптимизатор может «выучить» плохие паттерны
Чувствительность к метрикеНеобходима чёткая метрика оценки (например, точный ответ, релевантность)
Размер validation setНужен репрезентативный датасет (100+ примеров)

Используйте DSPy + MIPRO, когда:

  • У вас есть повторяющийся пайплайн из 3+ вызовов LLM.
  • Вы хотите автоматизировать настройку промптов для разных доменов.
  • Ваша постановка задачи стабильна (не меняется ежедневно).

10. Сравнение с другими подходами

ПодходРучной промпт-инжинирингLangChain (с шаблонами)DSPy + MIPRO
Сложность написанияНизкая (простые задачи)Средняя (цепочки)Средняя (нужны сигнатуры)
АвтоматизацияНетЧастичная (шаблоны)Полная (оптимизация)
Качество результатаЗависит от экспертаХорошее при ручной настройкеСтабильно высокое после компиляции
ГибкостьЛюбой текстОграничена шаблонамиМодули расширяемы

Пет-проект для закрепления

Задача: Разработать классификатор тональности отзывов с обоснованием. Программа состоит из двух модулей: 1) извлечение ключевых фраз, 2) классификация на positive/negative/neutral. Используйте DSPy и MIPRO.

Инструменты: Python, DSPy, OpenAI API (или локальная модель через Ollama), датасет (например, SST-2 или Amazon Reviews).

Шаги:

  1. Установите DSPy: pip install dspy-ai.
  2. Создайте сигнатуры:
    • ExtractKeyPhrases(review -> key_phrases).
    • ClassifySentiment(key_phrases, review -> sentiment).
  3. Скомпонуйте модуль SentimentPipeline.
  4. Подготовьте trainset (50 примеров с метками) и valset (20 примеров).
  5. Запустите компиляцию с optimizer='MIPRO', метрика accuracy.
  6. Протестируйте на новых отзывах.
  7. Сравните с ручным промптом: какой accuracy и как изменились инструкции?

Ожидаемый результат: После компиляции программа должна показывать более высокую точность, чем ручной промпт (например, 85% против 75%). Вы увидите, как оптимизатор изменил формулировки инструкций для каждого модуля.


Связь с другими вопросами

ВопросТема
106DSPy в общем: отличие от LangChain
108BootstrapFewShot vs MIPRO
109Роль компилятора в DSPy
110Сравнение DSPy с fine-tuning
98Оптимизация промптов через Gradient-based search

Навигация