# Pattern Constraint

> Constrained generation and output validation for DSPy

- Skill: `j33bs/pattern-constraint` (Agent Skill)
- Install (CLI): `npx skillmds@latest add j33bs/pattern-constraint`
- Raw SKILL.md: https://api.skillmd.com/api/skills/j33bs/pattern-constraint/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: j33bs (https://skillmd.com/u/j33bs)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/j33bs/pattern-constraint

---


# Constrained Generation

## 🎯 Trigger Conditions
Use when asked about constrained generation, output validation, or guaranteeing specific output formats.

## 📚 Prerequisites
- `dspy` package installed
- Output schema defined
- Validation mechanism chosen

## 🛠️ Constraint Patterns

### 1. Output Schema Constraints
```python
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
```python
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
```python
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
```python
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

## 📖 References
- [DSPy Constraints](https://dspy-docs.vercel.app/docs/patterns/constraints)
- [Output Validation](https://pydantic-docs.helpmanual.io/)

