Définir des signatures et des modules
Syntaxe des signatures, ChainOfThought, ReAct et modules DSPy personnalisés.
Définir des signatures et des modules est une leçon AI Prompt Engineering gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Prompt Engineering, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Prompt Engineering comprend 4 leçons au total.
Les signatures sont des contrats typés
Une signature DSPy est une classe Python qui déclare les entrées et les sorties d'une étape de raisonnement. Considérez-la comme le contrat typé d'une fonction pour votre appel à un LLM.
La chaîne de documentation devient la description de la tâche. Les annotations des champs indiquent à DSPy ce qu'il doit produire. Vous n'écrivez jamais le texte réel de l'invite : DSPy le déduit de cette déclaration.
Définir une signature de base
Une signature minimale dérive de dspy.Signature et annote les champs avec InputField ou OutputField. La chaîne de documentation de la classe fournit l'instruction de la tâche.
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']Plusieurs champs de sortie
Les signatures peuvent comporter plusieurs champs de sortie. DSPy invitera le modèle à tous les produire lors d'un seul appel. Cela est utile pour extraire des informations structurées.
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)Le module Predict
dspy.Predict est le module le plus simple. Il reçoit une signature et demande directement au LM de produire la sortie. Aucun échafaudage de raisonnement n'est ajouté : seule une invite structurée correspondant à la signature est utilisée.
Utilisez Predict lorsque la tâche est simple et ne nécessite pas d'étapes de raisonnement explicites.
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) # positiveLe module ChainOfThought
dspy.ChainOfThought enrichit la signature avec un champ intermédiaire reasoning. Le modèle expose d'abord son raisonnement, puis produit la réponse finale.
Cela améliore régulièrement l'exactitude pour les problèmes à plusieurs étapes, sans que vous ayez à rédiger d'instructions d'invite de raisonnement par étapes.
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 milesLe module ReAct
dspy.ReAct met en œuvre la boucle Raisonnement + Action. Le modèle alterne entre les étapes de raisonnement et les appels d'outils, ce qui le rend idéal pour les agents qui doivent effectuer des recherches, des calculs ou récupérer des données.
Vous fournissez une liste d'outils (des fonctions Python accompagnées de chaînes de documentation), et DSPy gère automatiquement leur alternance.
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)Composer des modules pour former des programmes
La véritable puissance vient de la composition de modules en programmes à plusieurs étapes. Dérivez une classe de dspy.Module, définissez les sous-modules dans __init__ et implémentez forward() pour les relier.
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)Raccourci de signature intégrée
Pour les cas simples, DSPy accepte une chaîne de signature intégrée : 'input1, input2 -> output1, output2'. Cela est pratique pour réaliser rapidement un prototype sans définir une classe complète.
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)Les descriptions des champs sont importantes
Le paramètre desc de InputField et OutputField est inclus dans l'invite générée. De bonnes descriptions orientent précisément le modèle.
Considérez desc comme la documentation au niveau du champ qui apparaît dans l'invite à côté du nom du champ.
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 automaticallyEnregistrer et charger des programmes
Après l'optimisation, vous enregistrez le programme compilé afin de ne pas avoir à relancer l'optimisation à chaque fois. DSPy sérialise l'état optimisé dans un fichier 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 pour les contraintes de sortie
Les assertions de DSPy vous permettent de déclarer des contraintes sur les sorties. Si le modèle enfreint la contrainte, DSPy réessaie automatiquement en fournissant un retour correctif : aucune logique manuelle de nouvelle tentative n'est nécessaire.
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 resultVérification des connaissances : ChainOfThought
Qu'ajoute dspy.ChainOfThought par rapport à dspy.Predict lorsque la même signature est utilisée ?
Récapitulatif : signatures et modules
Les signatures DSPy sont des déclarations de classes typées qui décrivent ce qu'une étape de LLM doit faire : entrées, sorties et instruction sous forme de chaîne de documentation. Des modules comme Predict, ChainOfThought et ReAct mettent en œuvre différentes stratégies de raisonnement autour d'une signature. Vous composez plusieurs modules dans une sous-classe de dspy.Module pour créer des chaînes de traitement à plusieurs étapes. Les valeurs desc des champs orientent le modèle dans l'invite générée automatiquement, et les assertions imposent des contraintes de sortie avec de nouvelles tentatives automatiques.
Questions Fréquemment Posées
La leçon « Définir des signatures et des modules » est-elle gratuite ?
Oui — le texte complet de « Définir des signatures et des modules » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Prompt Engineering, passe à CoddyKit PRO. Le cours AI Prompt Engineering comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Définir des signatures et des modules » ?
Syntaxe des signatures, ChainOfThought, ReAct et modules DSPy personnalisés. Tu pratiques AI Prompt Engineering avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Prompt Engineering ?
Aucune expérience préalable n'est requise. AI Prompt Engineering sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Définir des signatures et des modules » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Prompt Engineering ?
Oui. Chaque leçon AI Prompt Engineering inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Introduction au framework DSPy
- Définir des signatures et des modules
- Compiler et optimiser les prompts
- Évaluer les pipelines DSPy