0Pricing
AI Prompt Engineering · Lekcja

Definiowanie sygnatur i modułów

Składnia sygnatur, ChainOfThought, ReAct i niestandardowe moduły DSPy.

Definiowanie sygnatur i modułów to bezpłatna lekcja AI Prompt Engineering na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Prompt Engineering, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Sygnatury są typowanymi kontraktami

Sygnatura DSPy to klasa Python deklarująca wejścia i wyjścia pojedynczego kroku rozumowania. Można traktować ją jak kontrakt typowanej funkcji dla wywołania LLM.

Docstring staje się opisem zadania. Adnotacje pól informują DSPy, co należy wygenerować. Nie piszą Państwo rzeczywistego tekstu promptu — DSPy wyprowadza go z tej deklaracji.

Definiowanie podstawowej sygnatury

Minimalna sygnatura dziedziczy po dspy.Signature i oznacza pola jako InputField lub OutputField. Docstring klasy zawiera instrukcję zadania.

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']

Wiele pól wyjściowych

Sygnatury mogą zawierać wiele pól wyjściowych. DSPy poprosi model o wygenerowanie wszystkich tych pól w jednym wywołaniu. Jest to przydatne podczas wyodrębniania informacji ustrukturyzowanych.

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)

Moduł Predict

dspy.Predict to najprostszy moduł. Przyjmuje sygnaturę i bezpośrednio prosi LM o wygenerowanie wyjścia. Nie dodaje żadnego schematu rozumowania — tworzy jedynie ustrukturyzowany prompt zgodny z sygnaturą.

Proszę używać Predict, gdy zadanie jest proste i nie wymaga jawnych kroków rozumowania.

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

Moduł ChainOfThought

dspy.ChainOfThought rozszerza sygnaturę o pośrednie pole reasoning. Model najpierw zapisuje swoje rozumowanie, a następnie tworzy ostateczną odpowiedź.

Rozwiązanie to konsekwentnie poprawia dokładność w przypadku problemów wieloetapowych, bez konieczności samodzielnego pisania instrukcji promptu chain-of-thought.

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

Moduł ReAct

dspy.ReAct implementuje pętlę Reason + Act. Model naprzemiennie wykonuje kroki rozumowania i wywołuje narzędzia, dzięki czemu moduł doskonale nadaje się do agentów, którzy muszą wyszukiwać, obliczać lub pobierać dane.

Przekazują Państwo listę narzędzi (funkcji Pythonu z docstringami), a DSPy automatycznie obsługuje ich przeplatanie.

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)

Łączenie modułów w programy

Prawdziwa siła DSPy ujawnia się przy łączeniu modułów w programy wieloetapowe. Należy utworzyć klasę dziedziczącą po dspy.Module, zdefiniować podmoduły w __init__ i zaimplementować forward(), aby połączyć je w całość.

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)

Skrócona składnia sygnatury inline

W prostych przypadkach DSPy akceptuje sygnaturę w postaci ciągu znaków: 'input1, input2 -> output1, output2'. Jest to wygodne podczas szybkiego prototypowania, gdy nie chcą Państwo definiować pełnej klasy.

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)

Opisy pól mają znaczenie

Parametr desc w InputField i OutputField jest uwzględniany w wygenerowanym prompcie. Dobre opisy precyzyjnie ukierunkowują model.

Proszę traktować desc jak dokumentację na poziomie pola, która pojawia się w prompcie obok nazwy pola.

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

Zapisywanie i wczytywanie programów

Po optymalizacji należy zapisać skompilowany program, aby nie trzeba było uruchamiać optymalizacji za każdym razem. DSPy serializuje zoptymalizowany stan do pliku 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)

Assertions do ograniczania wyjścia

Assertions DSPy pozwalają deklarować ograniczenia dotyczące wyjść. Jeśli model naruszy ograniczenie, DSPy automatycznie ponowi próbę, przekazując informację zwrotną korygującą — nie trzeba ręcznie implementować logiki ponawiania.

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

Sprawdzenie wiedzy: ChainOfThought

Co dodaje dspy.ChainOfThought w porównaniu z dspy.Predict, gdy używa się tej samej sygnatury?

Podsumowanie: sygnatury i moduły

Sygnatury DSPy to typowane deklaracje klas opisujące, co powinien robić krok LLM — jego wejścia, wyjścia i instrukcję w docstringu. Moduły takie jak Predict, ChainOfThought i ReAct implementują różne strategie rozumowania wokół sygnatury. Łączą Państwo wiele modułów wewnątrz klasy dziedziczącej po dspy.Module, aby tworzyć potoki wieloetapowe. Wartości pola desc pomagają ukierunkować model w automatycznie generowanym prompcie, a Assertions wymuszają ograniczenia wyjścia dzięki automatycznym ponowieniom.

Często zadawane pytania

Czy lekcja „Definiowanie sygnatur i modułów” jest bezpłatna?

Tak — pełny tekst „Definiowanie sygnatur i modułów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Prompt Engineering, przejdź na CoddyKit PRO. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Co nauczysz się w „Definiowanie sygnatur i modułów”?

Składnia sygnatur, ChainOfThought, ReAct i niestandardowe moduły DSPy. Ćwiczysz AI Prompt Engineering z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Prompt Engineering?

Nie wymagamy żadnego doświadczenia. AI Prompt Engineering w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Definiowanie sygnatur i modułów”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Prompt Engineering?

Tak. Każda lekcja AI Prompt Engineering zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wprowadzenie do frameworka DSPy
  2. Definiowanie sygnatur i modułów
  3. Kompilowanie i optymalizowanie promptów
  4. Ewaluacja potoków DSPy
← Powrót do AI Prompt Engineering