"""
Pattern 33: Matrix Organization Pattern
Agents report to both functional managers and project managers simultaneously.
Dual reporting structure balances functional expertise with project needs.
"""
from typing import Dict, Any, List, Optional, Set
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 ManagerType(Enum):
FUNCTIONAL = "functional"
PROJECT = "project"
@dataclass
class MatrixAgent:
"""Agent with dual reporting structure."""
name: str
functional_area: str # e.g., Engineering, Design, Marketing
functional_manager: Optional[str] = None
projects: List[str] = field(default_factory=list)
project_managers: List[str] = field(default_factory=list)
tasks: List[Dict[str, Any]] = field(default_factory=list)
@dataclass
class Manager:
"""Manager in matrix organization."""
name: str
manager_type: ManagerType
area: str # Functional area or Project name
direct_reports: Set[str] = field(default_factory=set)
@dataclass
class ConflictResolution:
"""Conflict between functional and project priorities."""
agent_name: str
functional_priority: str
project_priority: str
resolution: Optional[str] = None
timestamp: datetime = field(default_factory=datetime.now)
class MatrixOrganizationPattern:
"""
Matrix Organization Pattern - Dual reporting structure.
Features:
- Functional managers (expertise areas)
- Project managers (initiatives)
- Agents report to both
- Priority conflict resolution
- Resource balancing
"""
def __init__(self, model_name: str = "gpt-4"):
self.llm = ChatOpenAI(model=model_name, temperature=0.7)
self.agents: Dict[str, MatrixAgent] = {}
self.functional_managers: Dict[str, Manager] = {}
self.project_managers: Dict[str, Manager] = {}
self.conflicts: List[ConflictResolution] = []
def add_functional_manager(self, name: str, area: str):
"""Add a functional manager."""
manager = Manager(name, ManagerType.FUNCTIONAL, area)
self.functional_managers[name] = manager
print(f"✓ Added functional manager: {name} ({area})")
def add_project_manager(self, name: str, project: str):
"""Add a project manager."""
manager = Manager(name, ManagerType.PROJECT, project)
self.project_managers[name] = manager
print(f"✓ Added project manager: {name} (Project: {project})")
def add_agent(self, agent: MatrixAgent):
"""Add an agent with functional assignment."""
self.agents[agent.name] = agent
# Assign to functional manager
for fm_name, fm in self.functional_managers.items():
if fm.area == agent.functional_area:
agent.functional_manager = fm_name
fm.direct_reports.add(agent.name)
break
print(f"✓ Added agent: {agent.name} ({agent.functional_area}) → "
f"Functional Manager: {agent.functional_manager}")
def assign_to_project(self, agent_name: str, project_name: str,
project_manager_name: str):
"""Assign agent to a project with project manager."""
if agent_name in self.agents and project_manager_name in self.project_managers:
agent = self.agents[agent_name]
pm = self.project_managers[project_manager_name]
agent.projects.append(project_name)
agent.project_managers.append(project_manager_name)
pm.direct_reports.add(agent_name)
print(f"✓ {agent_name} assigned to project '{project_name}' → PM: {project_manager_name}")
def assign_task(self, agent_name: str, task: str, source_manager: str,
manager_type: ManagerType) -> Dict[str, Any]:
"""Assign task from either functional or project manager."""
if agent_name not in self.agents:
return {"success": False, "error": "Agent not found"}
agent = self.agents[agent_name]
task_info = {
"task": task,
"source_manager": source_manager,
"manager_type": manager_type.value,
"assigned_at": datetime.now()
}
agent.tasks.append(task_info)
return {"success": True, "agent": agent_name, "task": task}
def resolve_priority_conflict(self, agent_name: str, functional_task: str,
project_task: str) -> ConflictResolution:
"""Resolve conflict between functional and project priorities."""
if agent_name not in self.agents:
return None
agent = self.agents[agent_name]
conflict = ConflictResolution(
agent_name=agent_name,
functional_priority=functional_task,
project_priority=project_task
)
# Use LLM to resolve conflict
prompt = ChatPromptTemplate.from_messages([
("system", f"You are resolving a priority conflict for {agent_name}, "
f"who works in {agent.functional_area}. "
f"They report to both a functional manager and project managers. "
f"Provide a balanced resolution that considers both priorities."),
("human", f"Functional Manager Priority: {functional_task}\n"
f"Project Manager Priority: {project_task}\n\n"
f"Resolution:")
])
chain = prompt | self.llm
response = chain.invoke({})
conflict.resolution = response.content.strip()
self.conflicts.append(conflict)
return conflict
def get_agent_workload(self, agent_name: str) -> Dict[str, Any]:
"""Get agent's workload across all dimensions."""
if agent_name not in self.agents:
return {}
agent = self.agents[agent_name]
return {
"agent": agent_name,
"functional_area": agent.functional_area,
"functional_manager": agent.functional_manager,
"active_projects": len(agent.projects),
"project_managers": agent.project_managers,
"total_tasks": len(agent.tasks),
"tasks_by_manager_type": {
"functional": sum(1 for t in agent.tasks if t["manager_type"] == "functional"),
"project": sum(1 for t in agent.tasks if t["manager_type"] == "project")
}
}
def get_manager_team(self, manager_name: str) -> Dict[str, Any]:
"""Get team reporting to a manager."""
if manager_name in self.functional_managers:
manager = self.functional_managers[manager_name]
elif manager_name in self.project_managers:
manager = self.project_managers[manager_name]
else:
return {}
return {
"manager": manager_name,
"type": manager.manager_type.value,
"area": manager.area,
"direct_reports": list(manager.direct_reports)
}
def run(self, scenario: str) -> Dict[str, Any]:
"""Execute matrix organization scenario."""
return {
"pattern": "Matrix Organization",
"scenario": scenario,
"agents": len(self.agents),
"functional_managers": len(self.functional_managers),
"project_managers": len(self.project_managers),
"conflicts_resolved": len(self.conflicts)
}
# Example usage
if __name__ == "__main__":
print("=== Matrix Organization Pattern Demo ===\n")
org = MatrixOrganizationPattern()
# Add functional managers
print("--- Functional Managers ---")
org.add_functional_manager("Sarah", "Engineering")
org.add_functional_manager("Mike", "Design")
org.add_functional_manager("Lisa", "Data Science")
# Add project managers
print("\n--- Project Managers ---")
org.add_project_manager("Tom", "Mobile App Launch")
org.add_project_manager("Jane", "AI Integration")
# Add agents
print("\n--- Agents (Dual Reporting) ---")
agents = [
MatrixAgent("Alice", "Engineering"),
MatrixAgent("Bob", "Design"),
MatrixAgent("Carol", "Data Science"),
MatrixAgent("David", "Engineering")
]
for agent in agents:
org.add_agent(agent)
# Assign agents to projects
print("\n--- Project Assignments ---")
org.assign_to_project("Alice", "Mobile App Launch", "Tom")
org.assign_to_project("Bob", "Mobile App Launch", "Tom")
org.assign_to_project("Carol", "AI Integration", "Jane")
org.assign_to_project("David", "AI Integration", "Jane")
# Assign tasks from both types of managers
print("\n--- Task Assignments ---")
org.assign_task("Alice", "Code review for team", "Sarah", ManagerType.FUNCTIONAL)
org.assign_task("Alice", "Build login feature", "Tom", ManagerType.PROJECT)
org.assign_task("Carol", "Train ML model", "Jane", ManagerType.PROJECT)
org.assign_task("Carol", "Mentor junior analysts", "Lisa", ManagerType.FUNCTIONAL)
# Resolve priority conflict
print("\n--- Priority Conflict Resolution ---")
conflict = org.resolve_priority_conflict(
"Alice",
"Lead technical training session (Functional Manager)",
"Complete critical app release (Project Manager)"
)
print(f"Agent: {conflict.agent_name}")
print(f"Functional: {conflict.functional_priority}")
print(f"Project: {conflict.project_priority}")
print(f"Resolution: {conflict.resolution}")
# Show agent workload
print("\n--- Agent Workload ---")
for agent_name in ["Alice", "Carol"]:
workload = org.get_agent_workload(agent_name)
print(f"\n{agent_name}:")
print(f" Functional Area: {workload['functional_area']}")
print(f" Functional Manager: {workload['functional_manager']}")
print(f" Active Projects: {workload['active_projects']}")
print(f" Project Managers: {', '.join(workload['project_managers'])}")
print(f" Total Tasks: {workload['total_tasks']}")
print(f" Tasks by Type: Functional={workload['tasks_by_manager_type']['functional']}, "
f"Project={workload['tasks_by_manager_type']['project']}")
# Show manager teams
print("\n--- Manager Teams ---")
for manager_name in ["Sarah", "Tom"]:
team = org.get_manager_team(manager_name)
print(f"\n{manager_name} ({team['type']} - {team['area']}):")
print(f" Reports: {', '.join(team['direct_reports'])}")
print("\n--- Summary ---")
result = org.run("Dual reporting structure demo")
print(f"Pattern: {result['pattern']}")
print(f"Total Agents: {result['agents']}")
print(f"Functional Managers: {result['functional_managers']}")
print(f"Project Managers: {result['project_managers']}")
print(f"Conflicts Resolved: {result['conflicts_resolved']}")
Agentic Architecture Pattern: Matrix Organization
Pattern 33: 33 Matrix Organization – Line-by-Line Explanation
Overview
Pattern 33: Matrix Organization Pattern
Agents report to both functional managers and project managers simultaneously. Dual reporting structure balances functional expertise with project needs.
Code Structure Analysis
File Information
- Pattern Number: 33
- Pattern Name: 33 Matrix Organization
- File Path:
patterns\organizational\33_matrix_organization.py - Total Lines: 286
Detailed Code Explanation
Module Docstring
"""
Pattern 33: Matrix Organization Pattern
Agents report to both functional managers and project managers simultaneously.
Dual reporting structure balances functional expertise with project needs.
"""
Explanation: This module docstring describes the purpose and key features of the 33 Matrix Organization pattern.
Imports Section
from typing import Dict, Any, List, Optional, Set
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, Set: 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
ManagerType (Line 16)
class ManagerType(Enum):
FUNCTIONAL
PROJECT
Purpose: No enum docstring.
Values:
– FUNCTIONAL: Represents functional
– PROJECT: Represents project
Classes
ManagerType (Line 16)
Description: No class docstring.
MatrixAgent (Line 22)
Description: Agent with dual reporting structure.
Manager (Line 33)
Description: Manager in matrix organization.
ConflictResolution (Line 42)
Description: Conflict between functional and project priorities.
MatrixOrganizationPattern (Line 51)
Description: Matrix Organization Pattern – Dual reporting structure.
Features: – Functional managers (expertise areas) – Project managers (initiatives) – Agents report to both – Priority conflict resolution – Resource balancing
Methods:
__init__ (Line 63)
def __init__(self, model_name):
"""No method docstring."""
Purpose: No method docstring.
Parameters:
– self: Instance reference
– model_name: LLM model to use (e.g., “gpt-4”)
add_functional_manager (Line 70)
def add_functional_manager(self, name, area):
"""Add a functional manager."""
Purpose: Add a functional manager.
Parameters:
– self: Instance reference
– name: Identifier or label
– area: Parameter for area
add_project_manager (Line 76)
def add_project_manager(self, name, project):
"""Add a project manager."""
Purpose: Add a project manager.
Parameters:
– self: Instance reference
– name: Identifier or label
– project: Parameter for project
add_agent (Line 82)
def add_agent(self, agent):
"""Add an agent with functional assignment."""
Purpose: Add an agent with functional assignment.
Parameters:
– self: Instance reference
– agent: Parameter for agent
assign_to_project (Line 96)
def assign_to_project(self, agent_name, project_name, project_manager_name):
"""Assign agent to a project with project manager."""
Purpose: Assign agent to a project with project manager.
Parameters:
– self: Instance reference
– agent_name: Parameter for agent_name
– project_name: Parameter for project_name
– project_manager_name: Parameter for project_manager_name
assign_task (Line 109)
def assign_task(self, agent_name, task, source_manager, manager_type):
"""Assign task from either functional or project manager."""
Purpose: Assign task from either functional or project manager.
Parameters:
– self: Instance reference
– agent_name: Parameter for agent_name
– task: Parameter for task
– source_manager: Parameter for source_manager
– manager_type: Parameter for manager_type
resolve_priority_conflict (Line 126)
def resolve_priority_conflict(self, agent_name, functional_task, project_task):
"""Resolve conflict between functional and project priorities."""
Purpose: Resolve conflict between functional and project priorities.
Parameters:
– self: Instance reference
– agent_name: Parameter for agent_name
– functional_task: Parameter for functional_task
– project_task: Parameter for project_task
get_agent_workload (Line 157)
def get_agent_workload(self, agent_name):
"""Get agent's workload across all dimensions."""
Purpose: Get agent’s workload across all dimensions.
Parameters:
– self: Instance reference
– agent_name: Parameter for agent_name
get_manager_team (Line 176)
def get_manager_team(self, manager_name):
"""Get team reporting to a manager."""
Purpose: Get team reporting to a manager.
Parameters:
– self: Instance reference
– manager_name: Parameter for manager_name
run (Line 192)
def run(self, scenario):
"""Execute matrix organization scenario."""
Purpose: Execute matrix organization scenario.
Parameters:
– self: Instance reference
– scenario: Parameter for scenario
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 = ManagerType(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