0Pricing
AI Prompt Engineering · Урок

Определение сигнатур и модулей

Синтаксис сигнатур, ChainOfThought, ReAct и пользовательские модули DSPy.

«Определение сигнатур и модулей» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.

Сигнатуры — типизированные контракты

signature DSPy — это класс Python, объявляющий входные и выходные данные шага рассуждения. Представляйте его как типизированный контракт функции для вызова LLM.

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

Определение базовой сигнатуры

Минимальная сигнатура наследует dspy.Signature и помечает поля как InputField или OutputField. Строка документации класса содержит инструкцию для задачи.

import dspy

class QASignature(dspy.Signature):
    """Answer the question based on the given context."""
    context: str = dspy.InputField(desc='Relevant background text')
    question: str = dspy.InputField(desc='The question to answer')
    answer: str = dspy.OutputField(desc='A concise answer')

# Inspect what DSPy sees
print(QASignature.instructions)  # The docstring
print(list(QASignature.input_fields.keys()))   # ['context', 'question']
print(list(QASignature.output_fields.keys()))  # ['answer']

Несколько выходных полей

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

import dspy

class EntityExtraction(dspy.Signature):
    """Extract named entities from the text."""
    text: str = dspy.InputField()
    people: list[str] = dspy.OutputField(desc='List of person names mentioned')
    organizations: list[str] = dspy.OutputField(desc='List of organization names')
    locations: list[str] = dspy.OutputField(desc='List of place names')

extractor = dspy.Predict(EntityExtraction)
result = extractor(text='Elon Musk founded SpaceX in Hawthorne, California.')
print(result.people, result.organizations, result.locations)

Модуль Predict

dspy.Predict — самый простой модуль. Он принимает сигнатуру и напрямую просит LM создать выходные данные. Дополнительная структура рассуждений не добавляется — используется только структурированный промпт, соответствующий сигнатуре.

Используйте Predict, когда задача проста и не требует явных шагов рассуждения.

import dspy

class Classify(dspy.Signature):
    """Classify the sentiment of the review."""
    review: str = dspy.InputField()
    sentiment: str = dspy.OutputField(desc='positive, negative, or neutral')

# Predict wraps the signature with a direct prompt
classifier = dspy.Predict(Classify)
result = classifier(review='The food was amazing and the service was excellent!')
print(result.sentiment)  # positive

Модуль ChainOfThought

dspy.ChainOfThought дополняет сигнатуру промежуточным полем reasoning. Сначала модель записывает ход рассуждений, а затем создаёт окончательный ответ.

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

import dspy

class MathSolver(dspy.Signature):
    """Solve the math problem."""
    problem: str = dspy.InputField()
    answer: str = dspy.OutputField(desc='The numerical answer')

# ChainOfThought adds a 'reasoning' step automatically
solver = dspy.ChainOfThought(MathSolver)
result = solver(problem='If a train travels 60 mph for 2.5 hours, how far does it go?')
print(result.reasoning)  # Step-by-step reasoning
print(result.answer)     # 150 miles

Модуль ReAct

dspy.ReAct реализует цикл «Рассуждение + действие». Модель чередует шаги рассуждения и вызовы инструментов, поэтому этот модуль идеально подходит для агентов, которым требуется искать, выполнять calculate или получать данные.

Вы передаёте список инструментов (функций Python со строками документации), а DSPy автоматически управляет их чередованием.

import dspy

def search_web(query: str) -> str:
    """Search the web and return relevant results."""
    # In production, call a real search API
    return f'Search results for: {query}'

def calculate(expression: str) -> str:
    """Evaluate a mathematical expression."""
    return str(eval(expression))

class ResearchQA(dspy.Signature):
    """Answer the question using web search and calculation as needed."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

agent = dspy.ReAct(ResearchQA, tools=[search_web, calculate])
result = agent(question='What is 15% of 847?')
print(result.answer)

Объединение модулей в программы

Настоящая сила проявляется при объединении модулей в многошаговые программы. Создайте подкласс dspy.Module, определите вложенные модули в __init__ и реализуйте forward(), чтобы связать их между собой.

import dspy

class RetrieveAndAnswer(dspy.Module):
    def __init__(self):
        super().__init__()
        self.retrieve = dspy.Retrieve(k=3)  # Retrieves top-3 passages
        self.generate = dspy.ChainOfThought('context, question -> answer')

    def forward(self, question):
        passages = self.retrieve(question).passages
        context = '\n'.join(passages)
        return self.generate(context=context, question=question)

# This is a complete RAG pipeline in ~10 lines
rag = RetrieveAndAnswer()
result = rag(question='What are the main causes of climate change?')
print(result.answer)

Сокращённая запись сигнатуры в строке

Для простых случаев DSPy принимает строковую сигнатуру в сокращённой форме: 'input1, input2 -> output1, output2'. Это удобно для быстрого создания прототипов без определения полноценного класса.

import dspy

# Full class signature
class Translate(dspy.Signature):
    """Translate text to French."""
    text: str = dspy.InputField()
    translation: str = dspy.OutputField()

# Equivalent inline shorthand
translator_v1 = dspy.Predict(Translate)
translator_v2 = dspy.Predict('text -> translation')  # Less metadata

# Both work the same way
result = translator_v1(text='Hello world')
print(result.translation)

Описания полей важны

Параметр desc в InputField и OutputField включается в созданный промпт. Хорошие описания помогают точно направить модель.

Представляйте desc как документацию на уровне поля, которая появляется в промпте рядом с именем поля.

import dspy

class Summarize(dspy.Signature):
    """Summarize the article for a busy executive."""
    article: str = dspy.InputField(
        desc='The full article text to summarize'
    )
    summary: str = dspy.OutputField(
        desc='3-5 bullet points highlighting key decisions and numbers'
    )
    confidence: float = dspy.OutputField(
        desc='Your confidence in the summary accuracy from 0.0 to 1.0'
    )

summarizer = dspy.Predict(Summarize)
# DSPy constructs a prompt using all the desc values automatically

Сохранение и загрузка программ

После оптимизации сохраните скомпилированную программу, чтобы не запускать оптимизацию заново при каждом использовании. DSPy сериализует оптимизированное состояние в JSON-файл.

import dspy

class QA(dspy.Signature):
    """Answer questions accurately."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

program = dspy.ChainOfThought(QA)

# After optimization, save the compiled state
program.save('optimized_qa.json')

# Load it later without re-running optimization
loaded_program = dspy.ChainOfThought(QA)
loaded_program.load('optimized_qa.json')

result = loaded_program(question='What is the speed of light?')
print(result.answer)

Утверждения для ограничения выходных данных

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

import dspy

class ShortAnswer(dspy.Signature):
    """Answer in at most 10 words."""
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

class ConstrainedQA(dspy.Module):
    def __init__(self):
        super().__init__()
        self.predict = dspy.Predict(ShortAnswer)

    def forward(self, question):
        result = self.predict(question=question)
        # Assert: answer must be at most 10 words
        dspy.Assert(
            len(result.answer.split()) <= 10,
            'The answer must be 10 words or fewer.'
        )
        return result

Проверка знаний: ChainOfThought

Что добавляет dspy.ChainOfThought по сравнению с dspy.Predict при использовании одной и той же сигнатуры?

Повторение: сигнатуры и модули

Сигнатуры DSPy — это объявления типизированных классов, описывающие, что должен делать шаг LLM: его входные и выходные данные, а также инструкцию в строке документации. Модули, такие как Predict, ChainOfThought и ReAct, реализуют разные стратегии рассуждения на основе сигнатуры. Вы объединяете несколько модулей внутри подкласса dspy.Module, чтобы создавать многошаговые конвейеры. Значения desc полей направляют модель в автоматически созданном промпте, а утверждения обеспечивают соблюдение ограничений выходных данных с помощью автоматических повторных попыток.

Часто задаваемые вопросы

Урок «Определение сигнатур и модулей» бесплатный?

Да — полный текст урока «Определение сигнатур и модулей» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.

Чему я научусь в уроке «Определение сигнатур и модулей»?

Синтаксис сигнатур, ChainOfThought, ReAct и пользовательские модули DSPy. Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать AI Prompt Engineering?

Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Определение сигнатур и модулей»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке AI Prompt Engineering?

Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Введение в фреймворк DSPy
  2. Определение сигнатур и модулей
  3. Компиляция и оптимизация запросов
  4. Оценка конвейеров DSPy
← Назад к AI Prompt Engineering