"""
Pattern 087: Constraint Specification Pattern
Description:
The Constraint Specification pattern explicitly defines boundaries, rules, and
limitations that the LLM must adhere to when generating responses. This pattern
is crucial for controlling LLM behavior, ensuring compliance with requirements,
and preventing undesired outputs. Constraints can be content-based, format-based,
style-based, or domain-specific, and they guide the model toward appropriate
responses while filtering out inappropriate ones.
Constraint specification is essential for:
- Safety and compliance requirements
- Brand voice and style consistency
- Content appropriateness filtering
- Domain-specific requirements
- Length and complexity control
- Factual accuracy boundaries
Components:
1. Constraint Types
- Content constraints (what to include/exclude)
- Format constraints (structure and presentation)
- Style constraints (tone, formality, vocabulary)
- Length constraints (word/character limits)
- Domain constraints (topic boundaries)
- Safety constraints (harmful content prevention)
2. Constraint Expression
- Explicit rules ("must", "must not")
- Positive constraints (requirements)
- Negative constraints (prohibitions)
- Conditional constraints (if-then rules)
- Priority levels (strict vs flexible)
3. Enforcement Strategies
- Pre-generation (prompt engineering)
- Post-generation (validation and filtering)
- Iterative refinement (generate-validate-refine)
- Guardrails (safety layers)
- Fallback handling (when constraints violated)
4. Validation Methods
- Rule-based checking
- Pattern matching
- Content analysis
- Length verification
- Format validation
- Safety scoring
Use Cases:
1. Content Safety
- Prevent harmful content generation
- Filter inappropriate language
- Block sensitive topics
- Ensure age-appropriate content
- Compliance with platform policies
2. Brand Consistency
- Maintain brand voice
- Use approved terminology
- Follow style guidelines
- Consistent tone across content
- Corporate communication standards
3. Domain Expertise
- Stay within knowledge boundaries
- Acknowledge uncertainty
- Avoid medical/legal claims
- Respect professional standards
- Domain-specific terminology
4. Format and Structure
- Length limitations (tweets, abstracts)
- Structural requirements (sections, headings)
- Citation requirements
- Formatting rules (markdown, HTML)
- Template compliance
5. Legal and Compliance
- GDPR compliance (no PII without consent)
- HIPAA compliance (no PHI exposure)
- Copyright respect
- Regulatory requirements
- Terms of service adherence
LangChain Implementation:
LangChain supports constraint specification through:
- System messages with explicit rules
- Constitutional AI principles
- Output validators and filters
- Custom guardrails
- Retry mechanisms with corrections
Key Features:
1. Multi-Level Constraints
- Hard constraints (must be satisfied)
- Soft constraints (preferred but flexible)
- Conditional constraints (context-dependent)
- Hierarchical constraints (priority ordering)
2. Constraint Composition
- Multiple constraints simultaneously
- Constraint conflicts resolution
- Priority-based enforcement
- Constraint inheritance
3. Validation and Feedback
- Immediate validation
- Detailed violation reporting
- Correction suggestions
- Iterative improvement
4. Dynamic Constraints
- Context-aware constraints
- User-specific rules
- Time-based constraints
- Adaptive boundaries
Best Practices:
1. Clarity and Specificity
- State constraints explicitly
- Provide examples of violations
- Clarify edge cases
- Use concrete language
2. Prioritization
- Identify critical constraints
- Allow flexibility where possible
- Balance constraints with quality
- Avoid over-constraining
3. Testing
- Test constraint enforcement
- Try boundary cases
- Verify violation detection
- Check false positives
4. Documentation
- Document all constraints
- Explain rationale
- Provide violation examples
- Maintain constraint catalog
Trade-offs:
Advantages:
- Better control over outputs
- Improved safety and compliance
- Consistent brand voice
- Reduced inappropriate content
- Clear expectations
- Easier validation
Disadvantages:
- May limit creativity
- Can reduce output quality
- Increases complexity
- Requires careful design
- May need frequent updates
- Potential over-constraint
Production Considerations:
1. Constraint Management
- Centralized constraint definitions
- Version control for constraints
- Easy updates and modifications
- Constraint testing framework
- Documentation and examples
2. Performance Impact
- Validation overhead
- Retry costs for violations
- Caching validated outputs
- Efficient constraint checking
- Batch validation
3. User Experience
- Clear violation messages
- Suggestion for corrections
- Graceful degradation
- Transparency about constraints
- User constraint customization
4. Monitoring
- Track constraint violations
- Analyze violation patterns
- Measure enforcement effectiveness
- Identify constraint conflicts
- User feedback collection
5. Evolution
- Regular constraint reviews
- Adapt to new requirements
- Learn from violations
- Community feedback
- A/B test constraint changes
"""
import os
import re
from typing import List, Dict, Any, Optional, Callable
from dataclasses import dataclass
from enum import Enum
from dotenv import load_dotenv
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
load_dotenv()
class ConstraintType(Enum):
"""Types of constraints"""
CONTENT = "content"
LENGTH = "length"
STYLE = "style"
FORMAT = "format"
SAFETY = "safety"
DOMAIN = "domain"
class ConstraintSeverity(Enum):
"""Severity levels for constraints"""
STRICT = "strict" # Must be satisfied
MODERATE = "moderate" # Should be satisfied
FLEXIBLE = "flexible" # Nice to have
@dataclass
class Constraint:
"""Represents a single constraint"""
name: str
description: str
constraint_type: ConstraintType
severity: ConstraintSeverity
validation_func: Optional[Callable[[str], bool]] = None
violation_message: str = "Constraint violated"
@dataclass
class ConstraintConfig:
"""Configuration for constraint-based generation"""
max_retries: int = 3
temperature: float = 0.5
model_name: str = "gpt-3.5-turbo"
fail_on_violation: bool = False
class ConstraintSpecificationAgent:
"""
Agent that enforces constraints on LLM outputs.
This agent demonstrates:
1. Defining multiple types of constraints
2. Enforcing constraints during generation
3. Validating outputs against constraints
4. Handling constraint violations
"""
def __init__(self, config: Optional[ConstraintConfig] = None):
"""
Initialize constraint specification agent.
Args:
config: Configuration for constraint handling
"""
self.config = config or ConstraintConfig()
self.llm = ChatOpenAI(
model=self.config.model_name,
temperature=self.config.temperature
)
self.constraints: List[Constraint] = []
def add_constraint(self, constraint: Constraint):
"""Add a constraint to the agent"""
self.constraints.append(constraint)
def clear_constraints(self):
"""Remove all constraints"""
self.constraints = []
def _build_constraint_instructions(self) -> str:
"""Build constraint instructions for prompt"""
if not self.constraints:
return ""
instructions = ["You must follow these constraints:"]
for i, constraint in enumerate(self.constraints, 1):
severity_label = {
ConstraintSeverity.STRICT: "MUST",
ConstraintSeverity.MODERATE: "SHOULD",
ConstraintSeverity.FLEXIBLE: "IDEALLY"
}[constraint.severity]
instructions.append(f"{i}. {severity_label}: {constraint.description}")
return "\n".join(instructions)
def _validate_constraints(self, text: str) -> Dict[str, Any]:
"""
Validate text against all constraints.
Args:
text: Text to validate
Returns:
Validation results
"""
violations = []
for constraint in self.constraints:
if constraint.validation_func:
if not constraint.validation_func(text):
violations.append({
"constraint": constraint.name,
"severity": constraint.severity.value,
"message": constraint.violation_message
})
return {
"valid": len(violations) == 0,
"violations": violations,
"num_violations": len(violations)
}
def generate_with_constraints(
self,
prompt: str,
task_description: str = "Generate a response"
) -> Dict[str, Any]:
"""
Generate text while enforcing constraints.
Args:
prompt: User prompt
task_description: Description of task
Returns:
Generation result with validation info
"""
constraint_instructions = self._build_constraint_instructions()
template = ChatPromptTemplate.from_messages([
("system", """{task_description}
{constraints}
Ensure your response satisfies all constraints."""),
("human", "{prompt}")
])
chain = template | self.llm | StrOutputParser()
for attempt in range(self.config.max_retries):
# Generate
result = chain.invoke({
"task_description": task_description,
"constraints": constraint_instructions,
"prompt": prompt
})
# Validate
validation = self._validate_constraints(result)
if validation["valid"]:
return {
"success": True,
"text": result,
"attempts": attempt + 1,
"validation": validation
}
# If not last attempt, provide feedback for retry
if attempt str:
"""
Generate text with length constraints.
Args:
prompt: User prompt
max_words: Maximum word count
min_words: Optional minimum word count
Returns:
Generated text
"""
self.clear_constraints()
# Add length constraint
def validate_length(text: str) -> bool:
word_count = len(text.split())
if min_words and word_count max_words:
return False
return True
length_desc = f"between {min_words} and {max_words} words" if min_words else f"at most {max_words} words"
self.add_constraint(Constraint(
name="length",
description=f"Response must be {length_desc}",
constraint_type=ConstraintType.LENGTH,
severity=ConstraintSeverity.STRICT,
validation_func=validate_length,
violation_message=f"Length constraint violated (required: {length_desc})"
))
result = self.generate_with_constraints(prompt)
return result["text"] if result["success"] else result.get("error", "Generation failed")
def generate_with_style_constraint(
self,
prompt: str,
style: str = "professional"
) -> str:
"""
Generate text with style constraints.
Args:
prompt: User prompt
style: Desired style (professional, casual, formal)
Returns:
Generated text
"""
self.clear_constraints()
style_guidelines = {
"professional": "Use professional language, avoid slang, maintain objective tone",
"casual": "Use conversational language, contractions are fine, friendly tone",
"formal": "Use formal language, no contractions, academic or business tone",
"humorous": "Use humor and wit, light-hearted tone, creative wordplay"
}
guideline = style_guidelines.get(style.lower(), style_guidelines["professional"])
self.add_constraint(Constraint(
name="style",
description=guideline,
constraint_type=ConstraintType.STYLE,
severity=ConstraintSeverity.MODERATE
))
result = self.generate_with_constraints(
prompt,
task_description=f"Generate a {style} response"
)
return result["text"] if result["success"] else result.get("text", "")
def generate_with_content_constraints(
self,
prompt: str,
must_include: Optional[List[str]] = None,
must_exclude: Optional[List[str]] = None
) -> str:
"""
Generate text with content inclusion/exclusion constraints.
Args:
prompt: User prompt
must_include: Terms that must appear
must_exclude: Terms that must not appear
Returns:
Generated text
"""
self.clear_constraints()
# Inclusion constraint
if must_include:
def validate_inclusion(text: str) -> bool:
text_lower = text.lower()
return all(term.lower() in text_lower for term in must_include)
self.add_constraint(Constraint(
name="content_inclusion",
description=f"Must include these terms: {', '.join(must_include)}",
constraint_type=ConstraintType.CONTENT,
severity=ConstraintSeverity.STRICT,
validation_func=validate_inclusion,
violation_message=f"Required terms missing: {', '.join(must_include)}"
))
# Exclusion constraint
if must_exclude:
def validate_exclusion(text: str) -> bool:
text_lower = text.lower()
return not any(term.lower() in text_lower for term in must_exclude)
self.add_constraint(Constraint(
name="content_exclusion",
description=f"Must NOT include these terms: {', '.join(must_exclude)}",
constraint_type=ConstraintType.CONTENT,
severity=ConstraintSeverity.STRICT,
validation_func=validate_exclusion,
violation_message=f"Prohibited terms found: {', '.join(must_exclude)}"
))
result = self.generate_with_constraints(prompt)
return result["text"] if result["success"] else result.get("text", "")
def generate_with_format_constraint(
self,
prompt: str,
format_type: str = "bullet_points"
) -> str:
"""
Generate text with format constraints.
Args:
prompt: User prompt
format_type: Format type (bullet_points, numbered_list, paragraphs)
Returns:
Generated text
"""
self.clear_constraints()
format_descriptions = {
"bullet_points": "Use bullet points (- or •) for each item. No numbered lists.",
"numbered_list": "Use numbered list format (1. 2. 3. etc.). No bullet points.",
"paragraphs": "Write in paragraph form with clear topic sentences. No lists.",
"single_sentence": "Provide answer as a single, concise sentence."
}
description = format_descriptions.get(format_type, format_descriptions["bullet_points"])
self.add_constraint(Constraint(
name="format",
description=description,
constraint_type=ConstraintType.FORMAT,
severity=ConstraintSeverity.STRICT
))
result = self.generate_with_constraints(
prompt,
task_description=f"Generate response in {format_type} format"
)
return result["text"] if result["success"] else result.get("text", "")
def generate_with_safety_constraints(
self,
prompt: str
) -> str:
"""
Generate text with safety constraints.
Args:
prompt: User prompt
Returns:
Generated text
"""
self.clear_constraints()
safety_rules = [
"No harmful, hateful, or violent content",
"No personal attacks or discrimination",
"No illegal activities or advice",
"No explicit or inappropriate content",
"Respectful and inclusive language"
]
for rule in safety_rules:
self.add_constraint(Constraint(
name=f"safety_{safety_rules.index(rule)}",
description=rule,
constraint_type=ConstraintType.SAFETY,
severity=ConstraintSeverity.STRICT
))
result = self.generate_with_constraints(
prompt,
task_description="Generate a safe and appropriate response"
)
return result["text"] if result["success"] else "Unable to generate safe content for this prompt."
def demonstrate_constraint_specification():
"""Demonstrate constraint specification patterns"""
print("=" * 80)
print("CONSTRAINT SPECIFICATION PATTERN DEMONSTRATION")
print("=" * 80)
agent = ConstraintSpecificationAgent()
# Example 1: Length Constraints
print("\n" + "=" * 80)
print("EXAMPLE 1: Length Constraints")
print("=" * 80)
prompt = "Explain artificial intelligence"
print(f"\nPrompt: {prompt}")
print("\nConstraint: Maximum 50 words\n")
short_response = agent.generate_with_length_constraint(prompt, max_words=50)
print(f"Response ({len(short_response.split())} words):")
print(short_response)
print("\nConstraint: 80-120 words\n")
medium_response = agent.generate_with_length_constraint(prompt, max_words=120, min_words=80)
print(f"Response ({len(medium_response.split())} words):")
print(medium_response)
# Example 2: Style Constraints
print("\n" + "=" * 80)
print("EXAMPLE 2: Style Constraints")
print("=" * 80)
prompt = "Describe the benefits of exercise"
print(f"\nPrompt: {prompt}\n")
styles = ["professional", "casual", "formal"]
for style in styles:
print(f"\n{style.upper()} STYLE:")
print("-" * 40)
response = agent.generate_with_style_constraint(prompt, style=style)
print(response)
# Example 3: Content Inclusion/Exclusion
print("\n" + "=" * 80)
print("EXAMPLE 3: Content Constraints (Must Include/Exclude)")
print("=" * 80)
prompt = "Write about healthy eating habits"
must_include = ["vegetables", "protein", "hydration"]
must_exclude = ["diet pills", "supplements"]
print(f"\nPrompt: {prompt}")
print(f"Must include: {must_include}")
print(f"Must exclude: {must_exclude}\n")
response = agent.generate_with_content_constraints(
prompt,
must_include=must_include,
must_exclude=must_exclude
)
print("Response:")
print(response)
# Example 4: Format Constraints
print("\n" + "=" * 80)
print("EXAMPLE 4: Format Constraints")
print("=" * 80)
prompt = "List the steps to start a business"
print(f"\nPrompt: {prompt}\n")
formats = ["bullet_points", "numbered_list", "paragraphs"]
for fmt in formats:
print(f"\n{fmt.upper().replace('_', ' ')} FORMAT:")
print("-" * 40)
response = agent.generate_with_format_constraint(prompt, format_type=fmt)
print(response)
# Example 5: Multiple Constraints
print("\n" + "=" * 80)
print("EXAMPLE 5: Multiple Simultaneous Constraints")
print("=" * 80)
agent.clear_constraints()
# Add multiple constraints
agent.add_constraint(Constraint(
name="length",
description="Response must be 60-80 words",
constraint_type=ConstraintType.LENGTH,
severity=ConstraintSeverity.STRICT,
validation_func=lambda t: 60 <= len(t.split()) <= 80,
violation_message="Length must be 60-80 words"
))
agent.add_constraint(Constraint(
name="style",
description="Use professional, objective tone",
constraint_type=ConstraintType.STYLE,
severity=ConstraintSeverity.MODERATE
))
agent.add_constraint(Constraint(
name="content",
description="Must mention 'innovation' and 'technology'",
constraint_type=ConstraintType.CONTENT,
severity=ConstraintSeverity.STRICT,
validation_func=lambda t: "innovation" in t.lower() and "technology" in t.lower(),
violation_message="Must include 'innovation' and 'technology'"
))
prompt = "Describe the future of work"
print(f"\nPrompt: {prompt}")
print("\nConstraints:")
print("1. Length: 60-80 words")
print("2. Style: Professional, objective")
print("3. Content: Must mention 'innovation' and 'technology'\n")
result = agent.generate_with_constraints(prompt)
print(f"Success: {result['success']}")
print(f"Attempts: {result['attempts']}")
print(f"\nResponse ({len(result['text'].split())} words):")
print(result['text'])
# Example 6: Safety Constraints
print("\n" + "=" * 80)
print("EXAMPLE 6: Safety Constraints")
print("=" * 80)
safe_prompt = "Give advice on managing workplace conflicts"
print(f"\nPrompt: {safe_prompt}")
print("\nApplying safety constraints...\n")
response = agent.generate_with_safety_constraints(safe_prompt)
print("Response:")
print(response)
# Summary
print("\n" + "=" * 80)
print("CONSTRAINT SPECIFICATION SUMMARY")
print("=" * 80)
print("""
Constraint Specification Pattern Benefits:
1. Control: Precise control over LLM outputs
2. Compliance: Ensures regulatory and policy adherence
3. Consistency: Maintains brand voice and standards
4. Safety: Prevents inappropriate content
5. Quality: Enforces quality standards
6. Integration: Easier to integrate with systems
Constraint Types Demonstrated:
1. Length Constraints: Word/character limits
2. Style Constraints: Tone, formality, voice
3. Content Constraints: Required/prohibited terms
4. Format Constraints: Structure and presentation
5. Safety Constraints: Harmful content prevention
6. Multiple Constraints: Combined requirements
Constraint Severity Levels:
- STRICT: Must be satisfied (violations cause failure)
- MODERATE: Should be satisfied (violations logged)
- FLEXIBLE: Nice to have (soft preferences)
Enforcement Strategies:
1. Pre-generation: Include constraints in prompt
2. Validation: Check outputs against rules
3. Iteration: Retry with feedback on violations
4. Fallback: Alternative approach when constraints can't be met
Best Practices:
1. Be explicit and specific with constraints
2. Prioritize constraints (strict vs flexible)
3. Provide examples of acceptable outputs
4. Test constraint enforcement thoroughly
5. Handle violations gracefully
6. Monitor constraint effectiveness
7. Update constraints based on feedback
Common Use Cases:
- Content moderation (safety)
- Brand consistency (style)
- Legal compliance (domain rules)
- Format standardization (structure)
- Length requirements (summaries, tweets)
- Quality control (standards)
Production Considerations:
- Balance constraints with creativity
- Allow appropriate flexibility
- Provide clear violation messages
- Implement retry mechanisms
- Monitor constraint violation rates
- A/B test constraint effectiveness
- Document all constraints clearly
- Version control constraint rules
Constraint Design Tips:
1. Start with essential constraints only
2. Add constraints incrementally
3. Test against diverse inputs
4. Avoid over-constraining
5. Make constraints measurable
6. Provide violation feedback
7. Allow for constraint evolution
When to Use Constraints:
- Safety-critical applications
- Regulated industries
- Brand-sensitive content
- System integration requirements
- Quality assurance needs
- Compliance requirements
Trade-offs:
✅ Better control and safety
✅ Consistent outputs
✅ Easier validation
❌ May limit creativity
❌ Requires careful design
❌ Can be overly restrictive
""")
print("\n" + "=" * 80)
print("Pattern 087 (Constraint Specification) demonstration complete!")
print("=" * 80)
if __name__ == "__main__":
demonstrate_constraint_specification()
Agentic Design Pattern: Constraint Specification
Pattern 087: Constraint Specification – Line-by-Line Explanation
Overview
This document provides a detailed line-by-line explanation of the Constraint Specification pattern implementation.
Pattern Description
Pattern 087: Constraint Specification Pattern
Description: The Constraint Specification pattern explicitly defines boundaries, rules, and limitations that the LLM must adhere to when generating responses. This pattern is crucial for controlling LLM behavior, ensuring compliance with requirements, and preventing undesired outputs. Constraints can be content-based, format-based, style-based, or domain-specific, and they guide the model toward appropriate responses while filtering out inappropriate ones.
Constraint specification is essential for:
- Safety and compliance requirements
- Brand voice and style consistency
- Content appropriateness filtering
- Domain-specific requirements
- Length and complexity control
- Factual accuracy boundaries
Components: 1. Constraint Types – Content constraints (what to include/exclude) – Format constraints (structure and presentation) – Style constraints (tone, formality, vocabulary) – Length constraints (word/character limits) – Domain constraints (topic boundaries) – Safety constraints (harmful content prevention)
2. Constraint Expression
- Explicit rules ("must", "must not")
- Positive constraints (requirements)
- Negative constraints (prohibitions)
- Conditional constraints (if-then rules)
- Priority levels (strict vs flexible)
3. Enforcement Strategies
- Pre-generation (prompt engineering)
- Post-generation (validation and filtering)
- Iterative refinement (generate-validate-refine)
- Guardrails (safety layers)
- Fallback handling (when constraints violated)
4. Validation Methods
- Rule-based checking
- Pattern matching
- Content analysis
- Length verification
- Format validation
- Safety scoring
Use Cases: 1. Content Safety – Prevent harmful content generation – Filter inappropriate language – Block sensitive topics – Ensure age-appropriate content – Compliance with platform policies
2. Brand Consistency
- Maintain brand voice
- Use approved terminology
- Follow style guidelines
- Consistent tone across content
- Corporate communication standards
3. Domain Expertise
- Stay within knowledge boundaries
- Acknowledge uncertainty
- Avoid medical/legal claims
- Respect professional standards
- Domain-specific terminology
4. Format and Structure
- Length limitations (tweets, abstracts)
- Structural requirements (sections, headings)
- Citation requirements
- Formatting rules (markdown, HTML)
- Template compliance
5. Legal and Compliance
- GDPR compliance (no PII without consent)
- HIPAA compliance (no PHI exposure)
- Copyright respect
- Regulatory requirements
- Terms of service adherence
LangChain Implementation: LangChain supports constraint specification through: – System messages with explicit rules – Constitutional AI principles – Output validators and filters – Custom guardrails – Retry mechanisms with corrections
Key Features: 1. Multi-Level Constraints – Hard constraints (must be satisfied) – Soft constraints (preferred but flexible) – Conditional constraints (context-dependent) – Hierarchical constraints (priority ordering)
2. Constraint Composition
- Multiple constraints simultaneously
- Constraint conflicts resolution
- Priority-based enforcement
- Constraint inheritance
3. Validation and Feedback
- Immediate validation
- Detailed violation reporting
- Correction suggestions
- Iterative improvement
4. Dynamic Constraints
- Context-aware constraints
- User-specific rules
- Time-based constraints
- Adaptive boundaries
Best Practices: 1. Clarity and Specificity – State constraints explicitly – Provide examples of violations – Clarify edge cases – Use concrete language
2. Prioritization
- Identify critical constraints
- Allow flexibility where possible
- Balance constraints with quality
- Avoid over-constraining
3. Testing
- Test constraint enforcement
- Try boundary cases
- Verify violation detection
- Check false positives
4. Documentation
- Document all constraints
- Explain rationale
- Provide violation examples
- Maintain constraint catalog
Trade-offs: Advantages: – Better control over outputs – Improved safety and compliance – Consistent brand voice – Reduced inappropriate content – Clear expectations – Easier validation
Disadvantages:
- May limit creativity
- Can reduce output quality
- Increases complexity
- Requires careful design
- May need frequent updates
- Potential over-constraint
Production Considerations: 1. Constraint Management – Centralized constraint definitions – Version control for constraints – Easy updates and modifications – Constraint testing framework – Documentation and examples
2. Performance Impact
- Validation overhead
- Retry costs for violations
- Caching validated outputs
- Efficient constraint checking
- Batch validation
3. User Experience
- Clear violation messages
- Suggestion for corrections
- Graceful degradation
- Transparency about constraints
- User constraint customization
4. Monitoring
- Track constraint violations
- Analyze violation patterns
- Measure enforcement effectiveness
- Identify constraint conflicts
- User feedback collection
5. Evolution
- Regular constraint reviews
- Adapt to new requirements
- Learn from violations
- Community feedback
- A/B test constraint changes
File Statistics
- Total Lines: 835
- Classes: 5
- Functions: 1
- Constants: 0
Module Documentation
"""
Pattern 087: Constraint Specification Pattern
Description:
The Constraint Specification pattern explicitly defines boundaries, rules, and
limitations that the LLM must adhere to when generating responses. This pattern
is crucial for controlling LLM behavior, ensuring compliance with requirements,
and preventing undesired outputs. Constraints can be content-based, format-based,
style-based, or domain-specific, and they guide the model toward appropriate
responses while filtering out inappropriate ones.
Constraint specification is essential for:
- Safety and compliance requirements
- Brand voice and style consistency
- Content appropriateness filtering
- Domain-specific requirements
- Length and complexity control
- Factual accuracy boundaries
Components:
1. Constraint Types
- Content constraints (what to include/exclude)
- Format constraints (structure and presentation)
- Style constraints (tone, formality, vocabulary)
- Length constraints (word/character limits)
- Domain constraints (topic boundaries)
- Safety constraints (harmful content prevention)
2. Constraint Expression
- Explicit rules ("must", "must not")
- Positive constraints (requirements)
- Negative constraints (prohibitions)
- Conditional constraints (if-then rules)
- Priority levels (strict vs flexible)
3. Enforcement Strategies
- Pre-generation (prompt engineering)
- Post-generation (validation and filtering)
- Iterative refinement (generate-validate-refine)
- Guardrails (safety layers)
- Fallback handling (when constraints violated)
4. Validation Methods
- Rule-based checking
- Pattern matching
- Content analysis
- Length verification
- Format validation
- Safety scoring
Use Cases:
1. Content Safety
- Prevent harmful content generation
- Filter inappropriate language
- Block sensitive topics
- Ensure age-appropriate content
- Compliance with platform policies
2. Brand Consistency
- Maintain brand voice
- Use approved terminology
- Follow style guidelines
- Consistent tone across content
- Corporate communication standards
3. Domain Expertise
- Stay within knowledge boundaries
- Acknowledge uncertainty
- Avoid medical/legal claims
- Respect professional standards
- Domain-specific terminology
4. Format and Structure
- Length limitations (tweets, abstracts)
- Structural requirements (sections, headings)
- Citation requirements
- Formatting rules (markdown, HTML)
- Template compliance
5. Legal and Compliance
- GDPR compliance (no PII without consent)
- HIPAA compliance (no PHI exposure)
- Copyright respect
- Regulatory requirements
- Terms of service adherence
LangChain Implementation:
LangChain supports constraint specification through:
- System messages with explicit rules
- Constitutional AI principles
- Output validators and filters
- Custom guardrails
- Retry mechanisms with corrections
Key Features:
1. Multi-Level Constraints
- Hard constraints (must be satisfied)
- Soft constraints (preferred but flexible)
- Conditional constraints (context-dependent)
- Hierarchical constraints (priority ordering)
2. Constraint Composition
- Multiple constraints simultaneously
- Constraint conflicts resolution
- Priority-based enforcement
- Constraint inheritance
3. Validation and Feedback
- Immediate validation
- Detailed violation reporting
- Correction suggestions
- Iterative improvement
4. Dynamic Constraints
- Context-aware constraints
- User-specific rules
- Time-based constraints
- Adaptive boundaries
Best Practices:
1. Clarity and Specificity
- State constraints explicitly
- Provide examples of violations
- Clarify edge cases
- Use concrete language
2. Prioritization
- Identify critical constraints
- Allow flexibility where possible
- Balance constraints with quality
- Avoid over-constraining
3. Testing
- Test constraint enforcement
- Try boundary cases
- Verify violation detection
- Check false positives
4. Documentation
- Document all constraints
- Explain rationale
- Provide violation examples
- Maintain constraint catalog
Trade-offs:
Advantages:
- Better control over outputs
- Improved safety and compliance
- Consistent brand voice
- Reduced inappropriate content
- Clear expectations
- Easier validation
Disadvantages:
- May limit creativity
- Can reduce output quality
- Increases complexity
- Requires careful design
- May need frequent updates
- Potential over-constraint
Production Considerations:
1. Constraint Management
- Centralized constraint definitions
- Version control for constraints
- Easy updates and modifications
- Constraint testing framework
- Documentation and examples
2. Performance Impact
- Validation overhead
- Retry costs for violations
- Caching validated outputs
- Efficient constraint checking
- Batch validation
3. User Experience
- Clear violation messages
- Suggestion for corrections
- Graceful degradation
- Transparency about constraints
- User constraint customization
4. Monitoring
- Track constraint violations
- Analyze violation patterns
- Measure enforcement effectiveness
- Identify constraint conflicts
- User feedback collection
5. Evolution
- Regular constraint reviews
- Adapt to new requirements
- Learn from violations
- Community feedback
- A/B test constraint changes
"""
Purpose: This module implements the Constraint Specification pattern, providing a structured approach to agent design and implementation.
Import Statements
Standard Library Imports
import dataclasses.dataclass
import enum.Enum
import langchain_core.output_parsers.StrOutputParser
import langchain_core.prompts.ChatPromptTemplate
import os
import re
import typing.Any
import typing.Callable
import typing.Dict
import typing.List
import typing.Optional
Purpose: Core Python functionality:
– dataclasses.dataclass: Simplified class definitions with @dataclass
– enum.Enum: Enumeration support
– langchain_core.output_parsers.StrOutputParser: Regular expression operations
– langchain_core.prompts.ChatPromptTemplate: Regular expression operations
– os: Environment variable access and system operations
– re: Regular expression operations
– typing.Any: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Callable: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Dict: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.List: Type hints for better code documentation (List, Dict, Any, Optional)
– typing.Optional: Type hints for better code documentation (List, Dict, Any, Optional)
LangChain Imports
from langchain_openai.ChatOpenAI
Purpose: LangChain framework components: – LLM Interface: Wrapper for OpenAI models – Chains: Composable building blocks for complex workflows
Other Imports
from dotenv.load_dotenv
Purpose: Additional dependencies for specialized functionality.
Classes
Class: ConstraintType
Lines 213-220
Inherits from: Enum
Purpose:
Types of constraints
Class: ConstraintSeverity
Lines 223-227
Inherits from: Enum
Purpose:
Severity levels for constraints
Class: Constraint
Lines 231-238
Purpose:
Represents a single constraint
Class: ConstraintConfig
Lines 242-247
Purpose:
Configuration for constraint-based generation
Class: ConstraintSpecificationAgent
Lines 250-604
Purpose:
Agent that enforces constraints on LLM outputs.
This agent demonstrates:
1. Defining multiple types of constraints
2. Enforcing constraints during generation
3. Validating outputs against constraints
4. Handling constraint violations
Methods:
__init__(self, config)
Lines 261-273
Purpose:
Initialize constraint specification agent.
Args:
config: Configuration for constraint handling
Parameters:
– config: Config
add_constraint(self, constraint)
Lines 275-277
Purpose:
Add a constraint to the agent
Parameters:
– constraint: Constraint
clear_constraints(self)
Lines 279-281
Purpose:
Remove all constraints
Parameters:
_build_constraint_instructions(self)
Lines 283-299
Purpose:
Build constraint instructions for prompt
Parameters:
Returns: str
_validate_constraints(self, text)
Lines 301-326
Purpose:
Validate text against all constraints.
Args:
text: Text to validate
Returns:
Validation results
Parameters:
– text: Text
Returns: <ast.Subscript object at 0x000001A06D7F4B90>
generate_with_constraints(self, prompt, task_description)
Lines 328-392
Purpose:
Generate text while enforcing constraints.
Args:
prompt: User prompt
task_description: Description of task
Returns:
Generation result with validation info
Parameters:
– prompt: Prompt template or text
– task_description: Task description
Returns: <ast.Subscript object at 0x000001A06D849590>
generate_with_length_constraint(self, prompt, max_words, min_words)
Lines 394-434
Purpose:
Generate text with length constraints.
Args:
prompt: User prompt
max_words: Maximum word count
min_words: Optional minimum word count
Returns:
Generated text
Parameters:
– prompt: Prompt template or text
– max_words: Max words
– min_words: Min words
Returns: str
generate_with_style_constraint(self, prompt, style)
Lines 436-474
Purpose:
Generate text with style constraints.
Args:
prompt: User prompt
style: Desired style (professional, casual, formal)
Returns:
Generated text
Parameters:
– prompt: Prompt template or text
– style: Style
Returns: str
generate_with_content_constraints(self, prompt, must_include, must_exclude)
Lines 476-526
Purpose:
Generate text with content inclusion/exclusion constraints.
Args:
prompt: User prompt
must_include: Terms that must appear
must_exclude: Terms that must not appear
Returns:
Generated text
Parameters:
– prompt: Prompt template or text
– must_include: Must include
– must_exclude: Must exclude
Returns: str
generate_with_format_constraint(self, prompt, format_type)
Lines 528-566
Purpose:
Generate text with format constraints.
Args:
prompt: User prompt
format_type: Format type (bullet_points, numbered_list, paragraphs)
Returns:
Generated text
Parameters:
– prompt: Prompt template or text
– format_type: Format type
Returns: str
generate_with_safety_constraints(self, prompt)
Lines 568-604
Purpose:
Generate text with safety constraints.
Args:
prompt: User prompt
Returns:
Generated text
Parameters:
– prompt: Prompt template or text
Returns: str
Functions
demonstrate_constraint_specification()
Lines 607-830
Purpose:
Demonstrate constraint specification patterns
Key Concepts Summary
Pattern Overview
The Constraint Specification pattern provides a structured approach to building AI agents with specific capabilities and behaviors. This implementation leverages LangChain’s composable components to create a robust and maintainable solution.
Core Components
- Agent Class: Main implementation of the pattern logic
- Prompt Engineering: Carefully crafted prompts to guide LLM behavior
- Tool Integration: Optional tools for extended functionality
- Memory Management: State handling across interactions
- Output Parsing: Structured response processing
When to Use
✅ Good for: – Scenarios requiring this specific pattern’s strengths – Applications needing structured agent behavior – Systems where explainability is important – Production environments requiring reliability
❌ Not ideal for: – Simple single-prompt tasks – Scenarios requiring different pattern characteristics – Resource-constrained environments (if computationally intensive)
Best Practices Demonstrated
1. Environment Configuration
- ✅ Use
.envfiles for API keys - ✅ Never hardcode credentials
- ✅ Validate environment variables on startup
2. Error Handling
- ✅ Graceful degradation on failures
- ✅ Informative error messages
- ✅ Logging for debugging
3. Prompt Engineering
- ✅ Clear, specific instructions
- ✅ Structured output formats
- ✅ Few-shot examples when beneficial
4. Code Organization
- ✅ Separation of concerns (class-based design)
- ✅ Type hints for clarity
- ✅ Docstrings for documentation
5. Performance Optimization
- ✅ Appropriate temperature settings
- ✅ Token budget management
- ✅ Caching where applicable
LangChain Components Used
- ChatOpenAI: OpenAI model interface
- Chains: Sequential component composition
Why LangChain? – Composable abstractions for LLM applications – Rich ecosystem of integrations – Production-ready patterns – Active community and development
Execution Flow
1. Initialize agent with configuration
↓
2. Load environment and dependencies
↓
3. Prepare prompt with input data
↓
4. Invoke LLM through LangChain
↓
5. Parse and validate response
↓
6. Return formatted result
Key Decision Points: – Model selection (temperature, model type) – Prompt structure (few-shot vs zero-shot) – Error handling strategy – Output format validation
Performance Considerations
Computational Cost
- LLM Calls: Primary cost factor (based on tokens)
- Latency: Depends on model and input size
- Memory: Minimal for most patterns
Optimization Strategies
- Prompt Optimization: Minimize tokens while maintaining clarity
- Caching: Cache repeated queries/responses
- Model Selection: Use smaller models when appropriate
- Batch Processing: Group similar requests
- Streaming: For long responses, stream tokens
Cost Estimates (Approximate)
- GPT-3.5-turbo: ~$0.002 per request
- GPT-4: ~$0.03 per request
- GPT-4-turbo: ~$0.01 per request
Actual costs vary based on input/output token counts
Common Pitfalls to Avoid
1. Prompt Design Issues
❌ Vague or ambiguous instructions
✅ Clear, specific, testable prompts
2. Error Handling
❌ Ignoring API errors or rate limits
✅ Implement retry logic and graceful degradation
3. Token Management
❌ Exceeding model token limits
✅ Truncate inputs, chunk processing
4. Security
❌ Exposing API keys in code
✅ Use environment variables
5. Testing
❌ Only testing happy paths
✅ Test edge cases, failures, malformed inputs
6. Cost Management
❌ Unmonitored API usage
✅ Implement budgets, alerts, and monitoring
Further Improvements
Production Enhancements
- Monitoring: Add logging, metrics, tracing
- Validation: Input/output schema validation
- Rate Limiting: Implement request throttling
- Caching: Redis or in-memory cache for responses
- Async Support: Non-blocking operations for scalability
Feature Extensions
- Multi-Model Support: Switch between providers
- Fallback Models: Graceful degradation strategy
- Custom Tools: Domain-specific function calling
- Advanced Memory: Vector stores for long-term memory
- Evaluation: Automated testing and benchmarking
Code Quality
- Testing: Unit tests, integration tests
- Documentation: API docs, usage examples
- Type Safety: Stricter type hints
- Configuration: Externalized config files
Related Patterns
- Pattern 086
- Pattern 088
Pattern Families: – Reasoning Patterns (001-011) – Multi-Agent Patterns (012-019) – Tool Use Patterns (020-025) – Memory Patterns (026-031) – And many more…
Summary
The Constraint Specification pattern provides a powerful approach to building AI agents with specific capabilities. This implementation demonstrates:
✅ Key Strengths: – Clean, maintainable code structure – LangChain integration for composability – Type hints and documentation – Production-ready patterns
🎯 Best Use Cases: – Applications requiring this pattern’s characteristics – Systems needing structured agent behavior – Production environments requiring reliability
📚 Learning Resources: – LangChain Documentation: https://python.langchain.com/ – Pattern Documentation: See related patterns – OpenAI API Reference: https://platform.openai.com/docs/
File: 087_constraint_specification.py
Total Lines: 835
Pattern Category: AI Agent Design Pattern #087
Generated from actual implementation code
For educational and reference purposes
Leave a Reply