Constrained Generation
🎯 Trigger Conditions
Use when asked about constrained generation, output validation, or guaranteeing specific output formats.
📚 Prerequisites
dspypackage installed- Output schema defined
- Validation mechanism chosen
🛠️ Constraint Patterns
1. Output Schema Constraints
import dspy
from pydantic import BaseModel, Field
class AnswerSchema(BaseModel):
answer: str = Field(description="The answer")
confidence: float = Field(ge=0.0, le=1.0)
sources: list[str] = Field(default_factory=list)
# Use with DSPy
class ConstrainedGeneration(dspy.Module):
def __init__(self):
self.generator = dspy.Predict("question -> answer, confidence, sources")
self.validator = dspy.PydanticValidator(AnswerSchema)
def forward(self, question):
result = self.generator(question=question)
validated = self.validator(result)
return validated
2. Regex Constraints
import re
import dspy
class RegexConstraint(dspy.Module):
def __init__(self, pattern):
self.pattern = pattern
self.generator = dspy.Predict("question -> raw_output")
self.regex = re.compile(pattern)
def forward(self, question):
raw = self.generator(question=question).raw_output
match = self.regex.search(raw)
if match:
return match.group(0)
else:
return self.regenerate(question)
def regenerate(self, question, max_attempts=3):
for _ in range(max_attempts):
raw = self.generator(question=question).raw_output
match = self.regex.search(raw)
if match:
return match.group(0)
return None
3. Conditional Constraints
class ConditionalConstraint(dspy.Module):
def __init__(self):
self.generator = dspy.Predict("question -> output")
self.validator = OutputValidator()
def forward(self, question):
output = self.generator(question=question).output
# Apply constraints
if self.validator.is_valid(output):
return output
else:
return self.constraint_satisfy(question, output)
def constraint_satisfy(self, question, output):
# Iteratively satisfy constraints
while not self.validator.is_valid(output):
output = self.regenerate_with_constraints(question, output)
return output
4. Structured Output
class StructuredOutput(dspy.Module):
def __init__(self):
self.generator = dspy.Predict("question -> json_output")
def forward(self, question):
json_str = self.generator(question=question).json_output
return parse_json(json_str)
# Use with strict JSON mode
dspy.settings.configure(json_mode=True)
⚠️ Pitfalls
- Over-constraint: Too many constraints reduce flexibility
- Performance: Validation adds computational cost
- Complexity: Complex constraints are hard to maintain
- Fallback: Need fallback strategies for constraint failures