Factory Pattern

The Factory pattern is essential for LLM applications that need to create different types of objects based on runtime conditions, such as selecting AI models, creating specialized tools, or instantiating different processing pipelines.

Why Factory Pattern for LLM?

LLM applications often require:

  • Dynamic object creation: Choose specific implementations based on runtime conditions

  • Decoupled instantiation: Separate object creation from object usage

  • Configuration-driven creation: Create objects based on user preferences or system settings

  • Easy extensibility: Add new implementations without modifying existing code

Key LLM Use Cases

1. AI Model Factory

Creating different AI models based on requirements:

from abc import ABC, abstractmethod
from enum import Enum

class ModelType(Enum):
    FAST = "fast"
    BALANCED = "balanced" 
    ADVANCED = "advanced"
    SPECIALIZED = "specialized"

class AIModel(ABC):
    @abstractmethod
    def generate(self, prompt, **kwargs):
        pass
    
    @abstractmethod
    def get_model_info(self):
        pass

class FastModel(AIModel):
    def __init__(self):
        self.model_name = "gpt-3.5-turbo"
        self.max_tokens = 1000
        self.cost_per_token = 0.002
    
    def generate(self, prompt, **kwargs):
        # Fast, lightweight model for simple queries
        return f"Fast response to: {prompt}"
    
    def get_model_info(self):
        return {
            "name": self.model_name,
            "speed": "high",
            "cost": "low",
            "quality": "good"
        }

class BalancedModel(AIModel):
    def __init__(self):
        self.model_name = "gpt-4"
        self.max_tokens = 2000
        self.cost_per_token = 0.03
    
    def generate(self, prompt, **kwargs):
        # Balanced model for general use
        return f"Balanced response to: {prompt}"
    
    def get_model_info(self):
        return {
            "name": self.model_name,
            "speed": "medium",
            "cost": "medium", 
            "quality": "high"
        }

class AdvancedModel(AIModel):
    def __init__(self):
        self.model_name = "gpt-4-turbo"
        self.max_tokens = 4000
        self.cost_per_token = 0.06
    
    def generate(self, prompt, **kwargs):
        # Most capable model for complex tasks
        return f"Advanced response to: {prompt}"
    
    def get_model_info(self):
        return {
            "name": self.model_name,
            "speed": "low",
            "cost": "high",
            "quality": "excellent"
        }

class SpecializedModel(AIModel):
    def __init__(self, domain):
        self.domain = domain
        self.model_name = f"specialized-{domain}-model"
        self.max_tokens = 2000
    
    def generate(self, prompt, **kwargs):
        return f"Specialized {self.domain} response to: {prompt}"
    
    def get_model_info(self):
        return {
            "name": self.model_name,
            "domain": self.domain,
            "quality": "domain-optimized"
        }

class AIModelFactory:
    @staticmethod
    def create_model(model_type: ModelType, **kwargs):
        """Factory method to create AI models based on type"""
        if model_type == ModelType.FAST:
            return FastModel()
        elif model_type == ModelType.BALANCED:
            return BalancedModel()
        elif model_type == ModelType.ADVANCED:
            return AdvancedModel()
        elif model_type == ModelType.SPECIALIZED:
            domain = kwargs.get('domain', 'general')
            return SpecializedModel(domain)
        else:
            raise ValueError(f"Unknown model type: {model_type}")
    
    @staticmethod
    def create_model_by_requirements(requirements):
        """Create model based on specific requirements"""
        if requirements.get('speed_priority', False):
            return AIModelFactory.create_model(ModelType.FAST)
        elif requirements.get('cost_sensitive', False):
            return AIModelFactory.create_model(ModelType.FAST)
        elif requirements.get('quality_priority', False):
            return AIModelFactory.create_model(ModelType.ADVANCED)
        elif requirements.get('domain'):
            return AIModelFactory.create_model(
                ModelType.SPECIALIZED, 
                domain=requirements['domain']
            )
        else:
            return AIModelFactory.create_model(ModelType.BALANCED)

# Usage examples
def handle_user_query(query, user_preferences):
    # Create appropriate model based on user preferences
    model = AIModelFactory.create_model_by_requirements(user_preferences)
    response = model.generate(query)
    return response, model.get_model_info()

# Different usage scenarios
urgent_response = handle_user_query(
    "Quick math question", 
    {"speed_priority": True}
)

research_response = handle_user_query(
    "Complex analysis needed",
    {"quality_priority": True}
)

medical_response = handle_user_query(
    "Medical consultation",
    {"domain": "medical"}
)

Benefits:

  • Dynamic model selection based on requirements

  • Easy addition of new models

  • Centralized model creation logic

  • Requirement-based intelligent selection

2. Tool Factory for AI Agents

Creating different tools for AI agents based on needs:

Benefits:

  • Dynamic tool creation based on agent requirements

  • Easy registration of new tools

  • Type-specific tool sets

  • Centralized tool management

3. Prompt Template Factory

Creating different prompt templates based on task types:

Benefits:

  • Automatic template selection based on task

  • Consistent prompt formatting

  • Easy template registration and extension

  • Parameter validation and requirements

4. Evaluation Metric Factory

Creating different evaluation metrics based on task type:

Benefits:

  • Task-appropriate metric selection

  • Consistent evaluation interfaces

  • Easy metric registration and extension

  • Comprehensive evaluation capabilities

Implementation Advantages

1. Flexibility

  • Runtime object creation based on conditions

  • Easy switching between different implementations

  • Configuration-driven object instantiation

  • Dynamic behavior modification

2. Extensibility

  • Easy addition of new types without modifying existing code

  • Registration mechanism for new implementations

  • Plugin-like architecture

  • Modular component addition

3. Maintainability

  • Centralized creation logic

  • Clear separation of concerns

  • Consistent object interfaces

  • Simplified testing and debugging

4. Scalability

  • Support for numerous object types

  • Efficient object creation and management

  • Resource optimization through appropriate selection

  • Performance tuning through type-specific implementations

Real-World Impact

The Factory pattern in LLM applications provides:

  • Dynamic Adaptation: Create appropriate objects based on runtime requirements

  • System Flexibility: Easy switching between different implementations and configurations

  • Development Efficiency: Reduced boilerplate code and simplified object management

  • Quality Assurance: Consistent object creation patterns and validation


๐Ÿ”— Interactive Implementation

๐Ÿ““ Factory Pattern Notebookarrow-up-right Open In Colabarrow-up-right - Multi-provider AI client system with intelligent selection, failover, and cost optimization.

This pattern is fundamental for production LLM systems where you need to create different types of objects dynamically based on user requirements, system conditions, or configuration settings while maintaining clean, maintainable code.

Last updated