English translation is not available yet. Showing Russian content.

Объясните концепцию «сигнатуры» (Signature) в DSPy. Чем она отличается от традиционного промпта?

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

Сигнатура в DSPy — это декларативное описание структуры входа и выхода языковой модели (например, question: str -> answer: str), которое не содержит конкретных инструкций на естественном языке. В отличие от традиционного промпта, где разработчик вручную пишет каждое слово инструкции, сигнатура задаёт только типы полей и их семантику, а DSPy автоматически превращает её в оптимизируемый промпт. Это делает разработку более модульной, тестируемой и позволяет применять автоматическую оптимизацию (например, подбор формулировок, few-shot примеров).


1. Термин: Сигнатура (Signature) в DSPy

Сигнатура — это ключевая абстракция фреймворка DSPy (Declarative Self-improving Python). Она определяет что должна сделать модель, а не как это сказать. Сигнатура состоит из:

  • Входных полей (input fields) — например, question: str, context: List[str].
  • Выходных полей (output fields) — например, answer: str, rationale: str.
  • Необязательного описания (desc) для каждого поля, которое помогает DSPy понять семантику.

Пример минимальной сигнатуры:

class QA(Signature):
    question: str = InputField()
    answer: str = OutputField()

DSPy трактует эту сигнатуру как «модель должна по вопросу сгенерировать ответ». На основе этой структуры DSPy самостоятельно строит промпт, подбирает стиль, добавляет few-shot примеры и даже может переформулировать описание полей для повышения качества.


2. Термин: Традиционный промпт (Hard‑coded Prompt)

Традиционный промпт — это жёстко заданная текстовая инструкция, которую разработчик пишет вручную. Например:

Ответь на вопрос, используя следующий контекст. Если контекст не содержит ответа, скажи "Я не знаю". Вопрос: {question}
Контекст: {context}

Проблемы такого подхода:

  • Хрупкость: небольшое изменение формулировки может сильно повлиять на результат.
  • Трудоёмкость: нужно вручную тестировать и переписывать инструкции.
  • Сложность оптимизации: нет автоматического подбора примеров или переформулировок.
  • Зависимость от конкретной модели: промпт, работающий для GPT‑4, может плохо работать для Llama 3.

3. Сравнение сигнатуры и традиционного промпта

КритерийСигнатура (DSPy)Традиционный промпт
Что задаётсяСтруктура и типы данных (поля)Текстовая инструкция на естественном языке
Степень детализацииВысокоуровневая (декларативная)Низкоуровневая (императивная)
ОптимизацияАвтоматическая (DSPy подбирает формулировки, few‑shot, температуру)Ручная (каждая правка — эксперимент)
ПереиспользованиеЛегко: можно наследовать сигнатуры, комбинироватьОграниченно: промпты обычно уникальны под задачу
ТестируемостьВысокая: легко подменять поля, менять типыНизкая: тесты привязаны к конкретному тексту
Зависимость от моделиСлабая: оптимизатор адаптирует промпт под модельСильная: промпт пишется под конкретную модель
Сложность для простых задачИзбыточна (простой вопрос можно решить промптом)Интуитивно понятна

4. Как DSPy использует сигнатуру для построения промпта

Когда вы определяете сигнатуру и передаёте её в модуль DSPy (например, dspy.Predict), происходит следующее:

  1. Анализ сигнатуры: DSPy извлекает список входных и выходных полей, их типы, описания.
  2. Генерация шаблона промпта: Создаётся базовый промпт вида:
    Complete the following task: Input: {field1}, {field2} → Output: {field3}.
  3. Оптимизация: Оптимизатор (например, BootstrapFewShot, MIPROv2) может:
    • Переформулировать описания полей (desc).
    • Подобрать несколько примеров (few‑shot) на основе обучающих данных.
    • Настроить температуру и другие параметры генерации.
  4. Выполнение: Модуль запускает модель с финальным промптом, передавая значения полей.

Пример кода:

import dspy

class QA(Signature):
    question: str = InputField(desc="Вопрос пользователя на русском")
    answer: str = OutputField(desc="Ответ на вопрос")

predict = dspy.Predict(QA)
result = predict(question="Какова столица Франции?")
print(result.answer)  # Париж

В этом примере разработчик не писал ни единой инструкции — только описал поля.


5. Роль сигнатуры в оптимизации (DSPy Optimizers)

Оптимизаторы в DSPy — это алгоритмы, которые автоматически улучшают промпт, сгенерированный на основе сигнатуры. Они используют:

  • BootstrapFewShot: отбирает лучшие примеры из обучающей выборки и добавляет их в промпт.
  • MIPROv2: подбирает не только примеры, но и формулировки описаний полей с помощью байесовской оптимизации.
  • SignatureOptimizer: изменяет саму структуру сигнатуры (добавляет/удаляет поля) на основе метрик.

Без сигнатуры такая оптимизация невозможна — у фреймворка нет «точки опоры», чтобы понять, какие части промпта можно менять.


6. Типы сигнатур

ТипПримерКогда использовать
Встроенные (built‑in)dspy.ChainOfThought, dspy.ProgramOfThoughtДля стандартных рассуждений (CoT, PoT)
Простые кастомныеclass MyQA(Signature): ...Любая задача с фиксированными полями
Составные (композиция)Одна сигнатура может содержать другую (через dspy.Module)Для сложных многошаговых процессов

DSPy также позволяет задавать сигнатуры без классов — через строковый синтаксис:

signature = "context: List[str], question: str -> answer: str"

7. Преимущества сигнатур перед традиционными промптами

  • Декларативность: вы описываете задачу на уровне данных, а не на уровне слов.
  • Модульность: сигнатуры можно наследовать (class NewQA(QA):), добавлять новые поля.
  • Версионирование: сигнатура — это код, её легко отслеживать в Git.
  • Автоматическая оптимизация: DSPy может менять формулировки промпта без участия человека.
  • Переносимость: одна и та же сигнатура может использоваться с разными моделями (GPT, Claude, Llama), оптимизатор адаптирует промпт под конкретную модель.

8. Ограничения и когда традиционный промпт всё ещё нужен

  • Креативные задачи: если нужно сгенерировать стихотворение в строгом стиле или имитировать конкретного автора, описание полей может не дать нужного качества — лучше написать промпт вручную.
  • Высокая чувствительность к формулировке: некоторые задачи (например, извлечение данных в JSON) требуют точных инструкций; сигнатура может сгенерировать слишком вольный промпт.
  • Простые одношаговые запросы: для быстрого прототипирования традиционный промпт проще и не требует установки DSPy.
  • Совместимость с legacy кодом: если у вас уже есть сотни работающих промптов, переписывать их на сигнатуры неоправданно дорого.

9. Связь с другими концепциями DSPy

  • Модули (dspy.Predict, dspy.ChainOfThought) — это обёртки, которые принимают сигнатуру и запускают модель с автоматически сгенерированным промптом.
  • Телепромтеры (Teleprompters) — так в DSPy называются оптимизаторы; они работают именно с сигнатурами.
  • Примеры (dspy.Example) — размеченные данные, которые оптимизатор использует для few‑shot обучения, опираясь на сигнатуру.
  • Метрики — функции оценки, которые оптимизатор максимизирует, меняя промпт в рамках сигнатуры.

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

Задача: реализовать классификатор отзывов (позитивный/негативный) на русском языке с помощью DSPy, используя сигнатуру и автоматическую оптимизацию.

Инструменты:

  • Python 3.10+
  • Библиотеки: dspy, datasets (можно взять любой датасет отзывов).
  • Модель: через API (OpenAI, Together) или локальная (через transformers).

Шаги:

  1. Создайте сигнатуру SentimentSignature:
    class SentimentSignature(Signature):
        review: str = InputField(desc="Текст отзыва")
        sentiment: str = OutputField(desc="Позитивный или негативный")
    
  2. Загрузите размеченные данные (например, 1000 отзывов с метками).
  3. Создайте модуль dspy.Predict(SentimentSignature).
  4. Используйте оптимизатор BootstrapFewShot с обучающей выборкой:
    optimizer = dspy.BootstrapFewShot(metric=lambda gold, pred: gold.sentiment == pred.sentiment)
    optimized_predict = optimizer.compile(predict, trainset=trainset)
    
  5. Оцените точность на тестовой выборке до и после оптимизации.
  6. Выведите промпт, который DSPy сгенерировал для первой итерации и после оптимизации.

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

  • Вы увидите, что без ручного написания инструкций модель достигает точности >85%.
  • Промпт после оптимизации будет содержать тщательно подобранные few‑shot примеры и более чёткие описания полей.
  • Вы сможете переключиться на другую модель (например, заменить gpt‑4 на claude‑3), просто изменив настройки в dspy.settings, и точность останется высокой благодаря адаптации промпта.

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

ВопросТема
101Основы DSPy, философия «промпт как код»
103Механизмы автоматической оптимизации промптов
104Связь сигнатур с модулями Predict, ChainOfThought
105Переносимость сигнатур между моделями
106Сигнатуры для retrieval и генерации
107Конкретный оптимизатор, тесно работающий с сигнатурами

Навигация