Agentic Architecture Pattern: Hybrid Agent

Written by

in


    """
Pattern 06: Hybrid Agent Pattern
Combines reactive and deliberative approaches for balanced performance.
"""

from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI


@dataclass
class Stimulus:
    """Input stimulus."""
    type: str
    data: Any
    urgency: int  # 1-10
    timestamp: datetime = field(default_factory=datetime.now)


@dataclass
class Plan:
    """Deliberated plan."""
    goal: str
    steps: List[str]
    created_at: datetime = field(default_factory=datetime.now)


class HybridAgentPattern:
    """
    Hybrid Agent combining:
    - Reactive layer: Fast responses to urgent stimuli
    - Deliberative layer: Planning for complex tasks
    - Intelligent switching between modes
    """
    
    def __init__(self, name: str = "HybridAgent", model_name: str = "gpt-4"):
        self.name = name
        self.llm = ChatOpenAI(model=model_name, temperature=0.5)
        self.reactive_threshold = 7  # Urgency >= 7 triggers reactive mode
        self.beliefs: Dict[str, Any] = {}
        self.plans: List[Plan] = []
        self.mode_history: List[str] = []
        
    def process(self, stimulus: Stimulus) -> Dict[str, Any]:
        """Process stimulus using hybrid approach."""
        # Decide mode based on urgency
        if stimulus.urgency >= self.reactive_threshold:
            mode = "reactive"
            response = self._react(stimulus)
        else:
            mode = "deliberative"
            response = self._deliberate(stimulus)
        
        self.mode_history.append(mode)
        
        return {
            "stimulus": stimulus.type,
            "mode": mode,
            "urgency": stimulus.urgency,
            "response": response
        }
    
    def _react(self, stimulus: Stimulus) -> str:
        """Reactive response - fast and direct."""
        prompt = ChatPromptTemplate.from_messages([
            ("system", f"You are {self.name} in REACTIVE mode. Respond quickly!"),
            ("human", "URGENT ({urgency}/10): {type} - {data}\nImmediate action:")
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({
            "urgency": stimulus.urgency,
            "type": stimulus.type,
            "data": stimulus.data
        })
        return f"[REACTIVE] {response.content}"
    
    def _deliberate(self, stimulus: Stimulus) -> str:
        """Deliberative response - planned and reasoned."""
        prompt = ChatPromptTemplate.from_messages([
            ("system", f"""You are {self.name} in DELIBERATIVE mode.
            Think carefully and plan your response.
            Current beliefs: {{beliefs}}"""),
            ("human", "Stimulus: {type} ({urgency}/10)\nData: {data}\n\nPlanned response:")
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({
            "urgency": stimulus.urgency,
            "type": stimulus.type,
            "data": stimulus.data,
            "beliefs": str(self.beliefs)
        })
        return f"[DELIBERATIVE] {response.content}"
    
    def update_belief(self, key: str, value: Any):
        """Update agent's beliefs (deliberative layer)."""
        self.beliefs[key] = value
    
    def create_plan(self, goal: str, steps: List[str]):
        """Create a plan (deliberative layer)."""
        plan = Plan(goal=goal, steps=steps)
        self.plans.append(plan)
    
    def run(self, stimuli: List[Stimulus]) -> Dict[str, Any]:
        """
        Process multiple stimuli using hybrid approach.
        
        Args:
            stimuli: List of stimuli to process
            
        Returns:
            Results showing mode switching
        """
        results = []
        
        for stimulus in stimuli:
            result = self.process(stimulus)
            results.append(result)
        
        # Calculate mode usage
        reactive_count = self.mode_history.count("reactive")
        deliberative_count = self.mode_history.count("deliberative")
        
        return {
            "agent": self.name,
            "total_stimuli": len(stimuli),
            "results": results,
            "mode_usage": {
                "reactive": reactive_count,
                "deliberative": deliberative_count
            },
            "reactive_threshold": self.reactive_threshold
        }


# Example usage
if __name__ == "__main__":
    print("\n=== Hybrid Agent Example ===")
    
    agent = HybridAgentPattern(name="HybridBot")
    
    # Set some beliefs for deliberative mode
    agent.update_belief("environment", "office")
    agent.update_belief("time_of_day", "morning")
    
    # Various stimuli with different urgencies
    stimuli = [
        Stimulus(type="meeting_reminder", data="Meeting in 1 hour", urgency=3),
        Stimulus(type="fire_alarm", data="Fire detected on floor 3!", urgency=10),
        Stimulus(type="email", data="New message from colleague", urgency=2),
        Stimulus(type="system_failure", data="Critical service down", urgency=9),
        Stimulus(type="question", data="What's the weather?", urgency=1),
    ]
    
    result = agent.run(stimuli)
    
    print(f"\nAgent: {result['agent']}")
    print(f"Reactive Threshold: {result['reactive_threshold']}/10")
    print(f"\nMode Usage:")
    print(f"  Reactive: {result['mode_usage']['reactive']}")
    print(f"  Deliberative: {result['mode_usage']['deliberative']}")
    print(f"\nProcessing Results:")
    for r in result['results']:
        print(f"\n  {r['stimulus']} (urgency: {r['urgency']}/10)")
        print(f"  Mode: {r['mode']}")
        print(f"  Response: {r['response'][:100]}...")

    

Agentic Architecture Pattern: Hybrid Agent

Pattern 06: 06 Hybrid Agent – Line-by-Line Explanation

Overview

Pattern 06: Hybrid Agent Pattern Combines reactive and deliberative approaches for balanced performance.


Code Structure Analysis

File Information

  • Pattern Number: 06
  • Pattern Name: 06 Hybrid Agent
  • File Path: patterns\core_agent\06_hybrid_agent.py
  • Total Lines: 170

Detailed Code Explanation

Module Docstring

"""
Pattern 06: Hybrid Agent Pattern
Combines reactive and deliberative approaches for balanced performance.
"""

Explanation: This module docstring describes the purpose and key features of the 06 Hybrid Agent pattern.


Imports Section

from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI  # First 20 imports shown

Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional: Type hints for better code documentation – from dataclasses import dataclass, field: Data class decorators for clean data structures – from datetime import datetime: Date and time utilities – from langchain_core.prompts import ChatPromptTemplate: LangChain framework integration – from langchain_openai import ChatOpenAI: LangChain framework integration


Classes

Stimulus (Line 14)

Description: Input stimulus.

Plan (Line 23)

Description: Deliberated plan.

HybridAgentPattern (Line 30)

Description: Hybrid Agent combining: – Reactive layer: Fast responses to urgent stimuli – Deliberative layer: Planning for complex tasks – Intelligent switching between modes

Methods:

__init__ (Line 38)
def __init__(self, name, model_name):
    """No method docstring."""

Purpose: No method docstring.

Parameters: – self: Instance reference – name: Identifier or label – model_name: LLM model to use (e.g., “gpt-4”)

process (Line 46)
def process(self, stimulus):
    """Process stimulus using hybrid approach."""

Purpose: Process stimulus using hybrid approach.

Parameters: – self: Instance reference – stimulus: Parameter for stimulus

_react (Line 65)
def _react(self, stimulus):
    """Reactive response - fast and direct."""

Purpose: Reactive response – fast and direct.

Parameters: – self: Instance reference – stimulus: Parameter for stimulus

_deliberate (Line 80)
def _deliberate(self, stimulus):
    """Deliberative response - planned and reasoned."""

Purpose: Deliberative response – planned and reasoned.

Parameters: – self: Instance reference – stimulus: Parameter for stimulus

update_belief (Line 98)
def update_belief(self, key, value):
    """Update agent's beliefs (deliberative layer)."""

Purpose: Update agent’s beliefs (deliberative layer).

Parameters: – self: Instance reference – key: Parameter for key – value: Parameter for value

create_plan (Line 102)
def create_plan(self, goal, steps):
    """Create a plan (deliberative layer)."""

Purpose: Create a plan (deliberative layer).

Parameters: – self: Instance reference – goal: Parameter for goal – steps: Parameter for steps

run (Line 107)
def run(self, stimuli):
    """Process multiple stimuli using hybrid approach.

Args:
    stimuli: List of stimuli to process

Returns:
    Results showing mode switching"""

Purpose: Process multiple stimuli using hybrid approach.

Args: stimuli: List of stimuli to process

Returns: Results showing mode switching

Parameters: – self: Instance reference – stimuli: Parameter for stimuli


Design Patterns Used

  • Strategy Pattern: Different execution strategies for various scenarios
  • State Pattern: Managing different states in the workflow
  • Chain of Responsibility: Sequential processing through workflow nodes
  • Observer Pattern: Tracking and monitoring pattern execution
  • Factory Pattern: Creating instances with proper configuration

Usage Example

# Initialize the pattern
pattern = Stimulus(name="example", model_name="gpt-4")

# Configure and execute
result = pattern.execute(data={"key": "value"})

# Check results
print(result)

Key Concepts

  • LLM Integration: Uses LangChain/OpenAI for intelligent decision-making
  • Workflow Orchestration: LangGraph manages execution flow through nodes
  • State Management: TypedDict defines workflow state structure
  • Error Handling: Comprehensive error handling and fallback mechanisms
  • Extensibility: Designed for easy customization and extension

Extension Points

This pattern can be extended by: 1. Adding custom workflow nodes 2. Implementing additional validation logic 3. Integrating with external services 4. Customizing LLM prompts and responses 5. Adding monitoring and logging capabilities

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *