"""
Pattern 08: Goal-Oriented Agent Pattern
Agent that explicitly pursues and manages goals.
"""
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
class GoalStatus(Enum):
"""Status of a goal."""
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
FAILED = "failed"
ABANDONED = "abandoned"
@dataclass
class Goal:
"""A goal the agent pursues."""
id: str
description: str
priority: int # 1-10
status: GoalStatus = GoalStatus.PENDING
sub_goals: List[str] = field(default_factory=list)
progress: float = 0.0 # 0.0 to 1.0
created_at: datetime = field(default_factory=datetime.now)
deadline: Optional[datetime] = None
class GoalOrientedAgentPattern:
"""
Goal-Oriented Agent that:
- Maintains explicit goals
- Prioritizes goals
- Decomposes goals into sub-goals
- Tracks progress
- Adapts when goals fail
"""
def __init__(self, name: str = "GoalAgent", model_name: str = "gpt-4"):
self.name = name
self.llm = ChatOpenAI(model=model_name, temperature=0.6)
self.goals: Dict[str, Goal] = {}
self.goal_counter = 0
def add_goal(self, description: str, priority: int = 5, deadline: Optional[datetime] = None) -> str:
"""Add a new goal."""
goal_id = f"goal_{self.goal_counter}"
self.goal_counter += 1
goal = Goal(
id=goal_id,
description=description,
priority=priority,
deadline=deadline
)
self.goals[goal_id] = goal
print(f"🎯 New goal: {description} (priority: {priority})")
return goal_id
def decompose_goal(self, goal_id: str) -> List[str]:
"""Decompose a goal into sub-goals."""
goal = self.goals[goal_id]
prompt = ChatPromptTemplate.from_messages([
("system", f"You are {self.name}. Decompose goals into achievable sub-goals."),
("human", "Goal: {goal}\n\nBreak this down into 3-5 concrete sub-goals:")
])
chain = prompt | self.llm
response = chain.invoke({"goal": goal.description})
# Parse sub-goals (simplified)
sub_goals_text = str(response.content)
sub_goals = [line.strip() for line in sub_goals_text.split("\n") if line.strip() and any(c.isdigit() for c in line)]
# Create sub-goal IDs
sub_goal_ids = []
for sub_goal_desc in sub_goals[:5]: # Limit to 5
sub_id = self.add_goal(sub_goal_desc, priority=goal.priority - 1)
sub_goal_ids.append(sub_id)
goal.sub_goals = sub_goal_ids
print(f"📋 Decomposed into {len(sub_goal_ids)} sub-goals")
return sub_goal_ids
def select_next_goal(self) -> Optional[Goal]:
"""Select the next goal to work on."""
active_goals = [g for g in self.goals.values()
if g.status in [GoalStatus.PENDING, GoalStatus.IN_PROGRESS]]
if not active_goals:
return None
# Sort by priority, then by deadline
active_goals.sort(key=lambda g: (
-g.priority, # Higher priority first
g.deadline if g.deadline else datetime.max # Earlier deadline first
))
return active_goals[0]
def work_on_goal(self, goal_id: str) -> Dict[str, Any]:
"""Work on achieving a goal."""
goal = self.goals[goal_id]
goal.status = GoalStatus.IN_PROGRESS
prompt = ChatPromptTemplate.from_messages([
("system", f"You are {self.name} working on a goal."),
("human", """Goal: {goal}
Priority: {priority}
Current progress: {progress:.0%}
What actions should I take to make progress on this goal?""")
])
chain = prompt | self.llm
response = chain.invoke({
"goal": goal.description,
"priority": goal.priority,
"progress": goal.progress
})
actions = str(response.content)
# Simulate progress
goal.progress = min(1.0, goal.progress + 0.3)
if goal.progress >= 1.0:
goal.status = GoalStatus.COMPLETED
print(f"✅ Goal completed: {goal.description}")
return {
"goal_id": goal_id,
"actions": actions,
"progress": goal.progress,
"status": goal.status.value
}
def run(self, initial_goals: List[Dict[str, Any]], cycles: int = 3) -> Dict[str, Any]:
"""
Run goal-oriented agent.
Args:
initial_goals: List of dicts with 'description' and 'priority'
cycles: Number of work cycles
Returns:
Results of goal pursuit
"""
# Add initial goals
for goal_spec in initial_goals:
goal_id = self.add_goal(
goal_spec['description'],
goal_spec.get('priority', 5)
)
# Optionally decompose complex goals
if goal_spec.get('decompose', False):
self.decompose_goal(goal_id)
# Work on goals
results = []
for cycle in range(cycles):
print(f"\n--- Cycle {cycle + 1}/{cycles} ---")
goal = self.select_next_goal()
if not goal:
print("No active goals remaining")
break
result = self.work_on_goal(goal.id)
results.append(result)
# Summary
completed = sum(1 for g in self.goals.values() if g.status == GoalStatus.COMPLETED)
in_progress = sum(1 for g in self.goals.values() if g.status == GoalStatus.IN_PROGRESS)
return {
"agent": self.name,
"total_goals": len(self.goals),
"completed": completed,
"in_progress": in_progress,
"cycles_executed": len(results),
"work_results": results
}
# Example usage
if __name__ == "__main__":
print("\n=== Goal-Oriented Agent Example ===")
agent = GoalOrientedAgentPattern(name="GoalBot")
initial_goals = [
{"description": "Learn a new programming language", "priority": 8, "decompose": True},
{"description": "Improve physical fitness", "priority": 6},
{"description": "Complete project documentation", "priority": 7}
]
result = agent.run(initial_goals, cycles=4)
print("\n=== Results ===")
print(f"Agent: {result['agent']}")
print(f"Total goals created: {result['total_goals']}")
print(f"Completed: {result['completed']}")
print(f"In progress: {result['in_progress']}")
print(f"Cycles executed: {result['cycles_executed']}")
print("\nWork done:")
for i, work in enumerate(result['work_results'], 1):
print(f"\n Cycle {i}: {work['goal_id']}")
print(f" Progress: {work['progress']:.0%}")
print(f" Status: {work['status']}")
Agentic Architecture Pattern: Goal Oriented Agent
Pattern 08: 08 Goal Oriented Agent – Line-by-Line Explanation
Overview
Pattern 08: Goal-Oriented Agent Pattern Agent that explicitly pursues and manages goals.
Code Structure Analysis
File Information
- Pattern Number: 08
- Pattern Name: 08 Goal Oriented Agent
- File Path:
patterns\core_agent\08_goal_oriented_agent.py - Total Lines: 220
Detailed Code Explanation
Module Docstring
"""
Pattern 08: Goal-Oriented Agent Pattern
Agent that explicitly pursues and manages goals.
"""
Explanation: This module docstring describes the purpose and key features of the 08 Goal Oriented Agent pattern.
Imports Section
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
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 enum import Enum: Enumeration support for fixed sets of values
– from langchain_core.prompts import ChatPromptTemplate: LangChain framework integration
– from langchain_openai import ChatOpenAI: LangChain framework integration
Enumerations
GoalStatus (Line 14)
class GoalStatus(Enum):
PENDING
IN_PROGRESS
COMPLETED
FAILED
ABANDONED
Purpose: Status of a goal.
Values:
– PENDING: Initial state, not yet processed
– IN_PROGRESS: Represents in progress
– COMPLETED: Successfully finished
– FAILED: Execution failed
– ABANDONED: Represents abandoned
Classes
GoalStatus (Line 14)
Description: Status of a goal.
Goal (Line 24)
Description: A goal the agent pursues.
GoalOrientedAgentPattern (Line 36)
Description: Goal-Oriented Agent that: – Maintains explicit goals – Prioritizes goals – Decomposes goals into sub-goals – Tracks progress – Adapts when goals fail
Methods:
__init__ (Line 46)
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”)
add_goal (Line 52)
def add_goal(self, description, priority, deadline):
"""Add a new goal."""
Purpose: Add a new goal.
Parameters:
– self: Instance reference
– description: Parameter for description
– priority: Parameter for priority
– deadline: Parameter for deadline
decompose_goal (Line 68)
def decompose_goal(self, goal_id):
"""Decompose a goal into sub-goals."""
Purpose: Decompose a goal into sub-goals.
Parameters:
– self: Instance reference
– goal_id: Parameter for goal_id
select_next_goal (Line 95)
def select_next_goal(self):
"""Select the next goal to work on."""
Purpose: Select the next goal to work on.
Parameters:
– self: Instance reference
work_on_goal (Line 111)
def work_on_goal(self, goal_id):
"""Work on achieving a goal."""
Purpose: Work on achieving a goal.
Parameters:
– self: Instance reference
– goal_id: Parameter for goal_id
run (Line 148)
def run(self, initial_goals, cycles):
"""Run goal-oriented agent.
Args:
initial_goals: List of dicts with 'description' and 'priority'
cycles: Number of work cycles
Returns:
Results of goal pursuit"""
Purpose: Run goal-oriented agent.
Args: initial_goals: List of dicts with ‘description’ and ‘priority’ cycles: Number of work cycles
Returns: Results of goal pursuit
Parameters:
– self: Instance reference
– initial_goals: Parameter for initial_goals
– cycles: Parameter for cycles
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 = GoalStatus(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
Leave a Reply