Tag: llm

  • Agentic Architecture Pattern: React

    
        """
    Pattern 77: ReAct (Reasoning + Acting) Pattern
    Interleaves reasoning traces with task-specific actions.
    """
    
    from typing import Dict, Any, List, Optional, Callable
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    from pydantic import BaseModel
    from enum import Enum
    
    
    class StepType(str, Enum):
        THOUGHT = "thought"
        ACTION = "action"
        OBSERVATION = "observation"
    
    
    class ReActStep(BaseModel):
        """Represents a step in the ReAct cycle."""
        type: StepType
        content: str
        step_number: int
    
    
    class ReActPattern:
        """
        ReAct Pattern - Reasoning and Acting in an interleaved manner.
        The agent alternates between thinking about what to do and taking actions.
        """
        
        def __init__(self, model_name: str = "gpt-4"):
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.available_actions = self._define_actions()
            self.trace: List[ReActStep] = []
        
        def _define_actions(self) -> Dict[str, Callable]:
            """Define available actions the agent can take."""
            return {
                "search": lambda query: f"Search results for: {query}",
                "calculate": lambda expr: f"Calculation result: {eval(expr)}",
                "lookup": lambda term: f"Definition of {term}: [simulated lookup]",
                "finish": lambda answer: f"Final Answer: {answer}"
            }
        
        def think(self, question: str, context: str = "") -> str:
            """Reasoning step - agent thinks about next action."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", """You are using the ReAct (Reasoning + Acting) pattern.
                
                Think step-by-step about how to answer this question.
                You can use these actions: {actions}
                
                Context so far:
                {context}
                
                Provide your thought process about what to do next."""),
                ("human", "Question: {question}\n\nThought:")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "question": question,
                "actions": ", ".join(self.available_actions.keys()),
                "context": context or "No previous steps"
            })
            
            return response.content
        
        def act(self, thought: str) -> tuple[str, str]:
            """Action step - agent takes an action based on reasoning."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", """Based on this thought, decide which action to take.
                
                Available actions: {actions}
                
                Thought: {thought}
                
                Respond with: Action: [action_name]([argument])
                For example: Action: search(quantum computing)"""),
                ("human", "What action should be taken?")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "thought": thought,
                "actions": ", ".join(self.available_actions.keys())
            })
            
            # Parse action
            action_str = response.content
            action_name = "search"
            action_arg = thought[:30]
            
            if "Action:" in action_str:
                try:
                    action_part = action_str.split("Action:")[1].strip()
                    action_name = action_part.split("(")[0].strip()
                    action_arg = action_part.split("(")[1].split(")")[0].strip()
                except:
                    pass
            
            return action_name, action_arg
        
        def observe(self, action_name: str, action_arg: str) -> str:
            """Observation step - observe the result of the action."""
            if action_name in self.available_actions:
                try:
                    result = self.available_actions[action_name](action_arg)
                    return result
                except Exception as e:
                    return f"Error executing {action_name}: {e}"
            return f"Unknown action: {action_name}"
        
        def run(self, question: str, max_steps: int = 5) -> Dict[str, Any]:
            """
            Execute the ReAct pattern: Think -> Act -> Observe -> Repeat.
            """
            self.trace = []
            context = ""
            final_answer = None
            
            for step_num in range(max_steps):
                # Step 1: Think (Reasoning)
                thought = self.think(question, context)
                self.trace.append(ReActStep(
                    type=StepType.THOUGHT,
                    content=thought,
                    step_number=step_num + 1
                ))
                
                # Step 2: Act
                action_name, action_arg = self.act(thought)
                action_str = f"{action_name}({action_arg})"
                self.trace.append(ReActStep(
                    type=StepType.ACTION,
                    content=action_str,
                    step_number=step_num + 1
                ))
                
                # Check if we're done
                if action_name == "finish":
                    final_answer = action_arg
                    break
                
                # Step 3: Observe
                observation = self.observe(action_name, action_arg)
                self.trace.append(ReActStep(
                    type=StepType.OBSERVATION,
                    content=observation,
                    step_number=step_num + 1
                ))
                
                # Update context
                context += f"\nStep {step_num + 1}:\n  Thought: {thought}\n  Action: {action_str}\n  Observation: {observation}"
            
            return {
                "question": question,
                "trace": self.trace,
                "final_answer": final_answer,
                "total_steps": len(self.trace) // 3
            }
        
        def format_trace(self) -> str:
            """Format the trace for display."""
            output = []
            for step in self.trace:
                prefix = {
                    StepType.THOUGHT: "šŸ’­ Thought",
                    StepType.ACTION: "⚔ Action",
                    StepType.OBSERVATION: "šŸ‘ Observation"
                }[step.type]
                output.append(f"{prefix} {step.step_number}: {step.content}")
            return "\n".join(output)
    
    
    # Example usage
    if __name__ == "__main__":
        agent = ReActPattern()
        
        question = "What is 15% of 240?"
        
        print("=== ReAct Pattern: Reasoning + Acting ===\n")
        print(f"Question: {question}\n")
        
        result = agent.run(question, max_steps=3)
        
        print("=== Execution Trace ===\n")
        print(agent.format_trace())
        
        if result["final_answer"]:
            print(f"\n=== Final Answer ===")
            print(result["final_answer"])
    
        

    Agentic Architecture Pattern: React

    Pattern 77: 77 React – Line-by-Line Explanation

    Overview

    Pattern 77: ReAct (Reasoning + Acting) Pattern Interleaves reasoning traces with task-specific actions.


    Code Structure Analysis

    File Information

    • Pattern Number: 77
    • Pattern Name: 77 React
    • File Path: patterns\execution_control\77_react.py
    • Total Lines: 194

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 77: ReAct (Reasoning + Acting) Pattern
    Interleaves reasoning traces with task-specific actions.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 77 React pattern.


    Imports Section

    from typing import Dict, Any, List, Optional, Callable
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    from pydantic import BaseModel
    from enum import Enum  # First 20 imports shown
    

    Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional, Callable: Type hints for better code documentation – from langchain_core.prompts import ChatPromptTemplate: LangChain framework integration – from langchain_openai import ChatOpenAI: LangChain framework integration – from enum import Enum: Enumeration support for fixed sets of values


    Enumerations

    StepType (Line 13)

    class StepType(Enum):
        THOUGHT
        ACTION
        OBSERVATION
    

    Purpose: No enum docstring.

    Values: – THOUGHT: Represents thought – ACTION: Represents action – OBSERVATION: Represents observation


    Classes

    StepType (Line 13)

    Description: No class docstring.

    ReActStep (Line 19)

    Description: Represents a step in the ReAct cycle.

    ReActPattern (Line 26)

    Description: ReAct Pattern – Reasoning and Acting in an interleaved manner. The agent alternates between thinking about what to do and taking actions.

    Methods:

    __init__ (Line 32)
    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”)

    _define_actions (Line 37)
    def _define_actions(self):
        """Define available actions the agent can take."""
    

    Purpose: Define available actions the agent can take.

    Parameters: – self: Instance reference

    think (Line 46)
    def think(self, question, context):
        """Reasoning step - agent thinks about next action."""
    

    Purpose: Reasoning step – agent thinks about next action.

    Parameters: – self: Instance reference – question: Parameter for question – context: Parameter for context

    act (Line 70)
    def act(self, thought):
        """Action step - agent takes an action based on reasoning."""
    

    Purpose: Action step – agent takes an action based on reasoning.

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

    observe (Line 105)
    def observe(self, action_name, action_arg):
        """Observation step - observe the result of the action."""
    

    Purpose: Observation step – observe the result of the action.

    Parameters: – self: Instance reference – action_name: Parameter for action_name – action_arg: Parameter for action_arg

    run (Line 115)
    def run(self, question, max_steps):
        """Execute the ReAct pattern: Think -> Act -> Observe -> Repeat."""
    

    Purpose: Execute the ReAct pattern: Think -> Act -> Observe -> Repeat.

    Parameters: – self: Instance reference – question: Parameter for question – max_steps: Parameter for max_steps

    format_trace (Line 164)
    def format_trace(self):
        """Format the trace for display."""
    

    Purpose: Format the trace for display.

    Parameters: – self: Instance reference


    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 = StepType(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

  • Agentic Architecture Pattern: Graph Of Thought

    
        """
    Pattern 76: Graph-of-Thought Pattern
    
    Reasoning as a graph structure with nodes (thoughts) and edges (relationships).
    Allows parallel exploration, backtracking, and aggregation of multiple reasoning paths.
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    class ThoughtType(Enum):
        """Type of thought node."""
        HYPOTHESIS = "hypothesis"
        EVIDENCE = "evidence"
        REASONING = "reasoning"
        CONCLUSION = "conclusion"
        QUESTION = "question"
    
    
    @dataclass
    class ThoughtNode:
        """Node in the thought graph."""
        node_id: str
        content: str
        thought_type: ThoughtType
        confidence: float = 0.5  # 0.0 to 1.0
        parent_ids: List[str] = field(default_factory=list)
        child_ids: List[str] = field(default_factory=list)
        metadata: Dict[str, Any] = field(default_factory=dict)
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class ThoughtEdge:
        """Edge connecting thoughts."""
        from_id: str
        to_id: str
        relationship: str  # supports, contradicts, questions, leads_to
        strength: float = 0.5  # 0.0 to 1.0
    
    
    class GraphOfThoughtState(TypedDict):
        """State for graph-of-thought workflow."""
        problem: str
        nodes: List[ThoughtNode]
        edges: List[ThoughtEdge]
        current_node_id: Optional[str]
        explored_ids: Set[str]
        conclusions: List[str]
    
    
    class GraphOfThoughtPattern:
        """
        Graph-of-Thought Pattern - Non-linear reasoning with graph structure.
        
        Thoughts are organized as a graph allowing:
        - Parallel exploration of multiple paths
        - Backtracking when needed
        - Aggregation of insights from different branches
        - Complex relationship modeling
        """
        
        def __init__(self, model_name: str = "gpt-4"):
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.graph = StateGraph(GraphOfThoughtState)
            self._build_graph()
            self.workflow = self.graph.compile()
        
        def _build_graph(self):
            """Build the LangGraph workflow."""
            self.graph.add_node("generate_hypotheses", self._generate_hypotheses)
            self.graph.add_node("explore_path", self._explore_path)
            self.graph.add_node("evaluate_node", self._evaluate_node)
            self.graph.add_node("aggregate_insights", self._aggregate_insights)
            
            self.graph.set_entry_point("generate_hypotheses")
            
            self.graph.add_edge("generate_hypotheses", "explore_path")
            self.graph.add_edge("explore_path", "evaluate_node")
            
            self.graph.add_conditional_edges(
                "evaluate_node",
                self._should_continue_exploration,
                {
                    "explore": "explore_path",
                    "aggregate": "aggregate_insights",
                }
            )
            
            self.graph.add_edge("aggregate_insights", END)
        
        def _generate_hypotheses(self, state: GraphOfThoughtState) -> GraphOfThoughtState:
            """Generate initial hypothesis nodes."""
            print(f"\n   Generating hypotheses for: {state['problem']}")
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Generate 3 diverse hypotheses or approaches to solve this problem. "
                          "Each should explore a different angle. Return one per line."),
                ("human", "{problem}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"problem": state['problem']})
            
            hypotheses = [h.strip() for h in response.content.split('\n') if h.strip()][:3]
            
            nodes = []
            for i, hypothesis in enumerate(hypotheses):
                node = ThoughtNode(
                    node_id=f"hyp_{i}",
                    content=hypothesis,
                    thought_type=ThoughtType.HYPOTHESIS,
                    confidence=0.5
                )
                nodes.append(node)
                print(f"   - Hypothesis {i+1}: {hypothesis[:60]}...")
            
            state["nodes"] = nodes
            state["edges"] = []
            state["explored_ids"] = set()
            state["conclusions"] = []
            
            return state
        
        def _explore_path(self, state: GraphOfThoughtState) -> GraphOfThoughtState:
            """Explore a thought path by expanding a node."""
            # Find unexplored node
            unexplored = [n for n in state["nodes"] 
                         if n.node_id not in state["explored_ids"]]
            
            if not unexplored:
                return state
            
            current_node = unexplored[0]
            state["current_node_id"] = current_node.node_id
            
            print(f"\n   Exploring: {current_node.content[:60]}...")
            
            # Generate reasoning from this node
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Based on this thought, generate 2 follow-up thoughts: "
                          "either supporting evidence, counterarguments, or logical next steps. "
                          "Return one per line."),
                ("human", "{thought}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"thought": current_node.content})
            
            follow_ups = [f.strip() for f in response.content.split('\n') if f.strip()][:2]
            
            for i, follow_up in enumerate(follow_ups):
                child_id = f"{current_node.node_id}_child_{i}"
                child_node = ThoughtNode(
                    node_id=child_id,
                    content=follow_up,
                    thought_type=ThoughtType.REASONING,
                    parent_ids=[current_node.node_id],
                    confidence=0.6
                )
                state["nodes"].append(child_node)
                current_node.child_ids.append(child_id)
                
                # Create edge
                edge = ThoughtEdge(
                    from_id=current_node.node_id,
                    to_id=child_id,
                    relationship="leads_to",
                    strength=0.7
                )
                state["edges"].append(edge)
                
                print(f"   - Follow-up: {follow_up[:50]}...")
            
            state["explored_ids"].add(current_node.node_id)
            
            return state
        
        def _evaluate_node(self, state: GraphOfThoughtState) -> GraphOfThoughtState:
            """Evaluate current node's confidence."""
            current_id = state.get("current_node_id")
            if not current_id:
                return state
            
            current_node = next((n for n in state["nodes"] if n.node_id == current_id), None)
            if not current_node:
                return state
            
            # Simple evaluation based on depth and branching
            depth = len([p for p in current_node.parent_ids])
            children_count = len(current_node.child_ids)
            
            # Update confidence
            current_node.confidence = min(1.0, 0.5 + (children_count * 0.1) + (depth * 0.05))
            
            return state
        
        def _should_continue_exploration(self, state: GraphOfThoughtState) -> str:
            """Decide whether to continue exploring or aggregate."""
            explored = len(state["explored_ids"])
            total = len(state["nodes"])
            
            # Explore at least 5 nodes or until 80% explored
            if explored  0 and explored / total  GraphOfThoughtState:
            """Aggregate insights from the thought graph."""
            print(f"\n   Aggregating insights from {len(state['nodes'])} thoughts...")
            
            # Find leaf nodes (conclusions)
            leaf_nodes = [n for n in state["nodes"] if not n.child_ids]
            
            # Prepare summary of reasoning paths
            paths_summary = []
            for leaf in leaf_nodes[:3]:  # Top 3 paths
                path = self._trace_path(leaf, state["nodes"])
                paths_summary.append(" → ".join([n.content[:40] for n in path]))
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "Given these reasoning paths, synthesize a final conclusion. "
                          "Be comprehensive and consider all perspectives."),
                ("human", "Problem: {problem}\n\nReasoning paths:\n{paths}\n\nProvide final conclusion:")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({
                "problem": state['problem'],
                "paths": "\n".join([f"{i+1}. {p}" for i, p in enumerate(paths_summary)])
            })
            
            state["conclusions"] = [response.content]
            print(f"   - Synthesized conclusion")
            
            return state
        
        def _trace_path(self, node: ThoughtNode, all_nodes: List[ThoughtNode]) -> List[ThoughtNode]:
            """Trace path from root to this node."""
            path = [node]
            current = node
            
            while current.parent_ids:
                parent_id = current.parent_ids[0]
                parent = next((n for n in all_nodes if n.node_id == parent_id), None)
                if not parent:
                    break
                path.insert(0, parent)
                current = parent
            
            return path
        
        def run(self, problem: str) -> Dict[str, Any]:
            """Execute graph-of-thought reasoning."""
            print(f"\n=== Graph-of-Thought Pattern ===")
            
            initial_state: GraphOfThoughtState = {
                "problem": problem,
                "nodes": [],
                "edges": [],
                "current_node_id": None,
                "explored_ids": set(),
                "conclusions": []
            }
            
            final_state = self.workflow.invoke(initial_state)
            
            return {
                "pattern": "GraphOfThought",
                "problem": problem,
                "total_nodes": len(final_state["nodes"]),
                "total_edges": len(final_state["edges"]),
                "explored_nodes": len(final_state["explored_ids"]),
                "conclusions": final_state["conclusions"],
                "graph_structure": {
                    "nodes": len(final_state["nodes"]),
                    "edges": len(final_state["edges"]),
                    "hypotheses": len([n for n in final_state["nodes"] 
                                      if n.thought_type == ThoughtType.HYPOTHESIS])
                }
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Graph-of-Thought Pattern Demo ===\n")
        
        pattern = GraphOfThoughtPattern()
        
        # Complex problem requiring non-linear reasoning
        problem = """
        A company wants to reduce its carbon footprint by 50% in 2 years.
        They have manufacturing plants, offices, and a delivery fleet.
        What strategy should they pursue?
        """
        
        print("Problem:", problem.strip())
        
        result = pattern.run(problem)
        
        print(f"\n=== Results ===")
        print(f"Total thought nodes: {result['total_nodes']}")
        print(f"Explored nodes: {result['explored_nodes']}")
        print(f"Graph edges: {result['total_edges']}")
        print(f"Hypotheses generated: {result['graph_structure']['hypotheses']}")
        
        print(f"\n=== Final Conclusion ===")
        for conclusion in result['conclusions']:
            print(f"{conclusion}")
        
        print("\nāœ“ Graph-of-thought reasoning completed with non-linear exploration!")
    
        

    Agentic Architecture Pattern: Graph Of Thought

    Pattern 76: 76 Graph Of Thought – Line-by-Line Explanation

    Overview

    Pattern 76: Graph-of-Thought Pattern

    Reasoning as a graph structure with nodes (thoughts) and edges (relationships). Allows parallel exploration, backtracking, and aggregation of multiple reasoning paths.


    Code Structure Analysis

    File Information

    • Pattern Number: 76
    • Pattern Name: 76 Graph Of Thought
    • File Path: patterns\execution_control\76_graph_of_thought.py
    • Total Lines: 319

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 76: Graph-of-Thought Pattern
    
    Reasoning as a graph structure with nodes (thoughts) and edges (relationships).
    Allows parallel exploration, backtracking, and aggregation of multiple reasoning paths.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 76 Graph Of Thought 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Enumerations

    ThoughtType (Line 18)

    class ThoughtType(Enum):
        HYPOTHESIS
        EVIDENCE
        REASONING
        CONCLUSION
        QUESTION
    

    Purpose: Type of thought node.

    Values: – HYPOTHESIS: Represents hypothesis – EVIDENCE: Represents evidence – REASONING: Represents reasoning – CONCLUSION: Represents conclusion – QUESTION: Represents question


    Classes

    ThoughtType (Line 18)

    Description: Type of thought node.

    ThoughtNode (Line 28)

    Description: Node in the thought graph.

    ThoughtEdge (Line 41)

    Description: Edge connecting thoughts.

    GraphOfThoughtState (Line 49)

    Description: State for graph-of-thought workflow.

    GraphOfThoughtPattern (Line 59)

    Description: Graph-of-Thought Pattern – Non-linear reasoning with graph structure.

    Thoughts are organized as a graph allowing: – Parallel exploration of multiple paths – Backtracking when needed – Aggregation of insights from different branches – Complex relationship modeling

    Methods:

    __init__ (Line 70)
    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”)

    _build_graph (Line 76)
    def _build_graph(self):
        """Build the LangGraph workflow."""
    

    Purpose: Build the LangGraph workflow.

    Parameters: – self: Instance reference

    _generate_hypotheses (Line 99)
    def _generate_hypotheses(self, state):
        """Generate initial hypothesis nodes."""
    

    Purpose: Generate initial hypothesis nodes.

    Parameters: – self: Instance reference – state: Current workflow state

    _explore_path (Line 132)
    def _explore_path(self, state):
        """Explore a thought path by expanding a node."""
    

    Purpose: Explore a thought path by expanding a node.

    Parameters: – self: Instance reference – state: Current workflow state

    _evaluate_node (Line 186)
    def _evaluate_node(self, state):
        """Evaluate current node's confidence."""
    

    Purpose: Evaluate current node’s confidence.

    Parameters: – self: Instance reference – state: Current workflow state

    _should_continue_exploration (Line 205)
    def _should_continue_exploration(self, state):
        """Decide whether to continue exploring or aggregate."""
    

    Purpose: Decide whether to continue exploring or aggregate.

    Parameters: – self: Instance reference – state: Current workflow state

    _aggregate_insights (Line 215)
    def _aggregate_insights(self, state):
        """Aggregate insights from the thought graph."""
    

    Purpose: Aggregate insights from the thought graph.

    Parameters: – self: Instance reference – state: Current workflow state

    _trace_path (Line 245)
    def _trace_path(self, node, all_nodes):
        """Trace path from root to this node."""
    

    Purpose: Trace path from root to this node.

    Parameters: – self: Instance reference – node: Parameter for node – all_nodes: Parameter for all_nodes

    run (Line 260)
    def run(self, problem):
        """Execute graph-of-thought reasoning."""
    

    Purpose: Execute graph-of-thought reasoning.

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


    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 = ThoughtType(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

  • Agentic Architecture Pattern: Tree Of Thought

    
        """
    Pattern 75: Tree-of-Thought Pattern
    
    Explores multiple reasoning paths in parallel, evaluates them, and
    selects the best solution. Enables deliberate decision making through
    search over thought trees.
    """
    
    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    import uuid
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    @dataclass
    class ThoughtNode:
        """Node in the thought tree."""
        id: str
        content: str
        parent_id: Optional[str]
        children_ids: List[str] = field(default_factory=list)
        score: float = 0.0
        depth: int = 0
        is_terminal: bool = False
        evaluation: Optional[str] = None
    
    
    class TreeOfThoughtPattern:
        """
        Tree-of-Thought Pattern - Explores multiple reasoning branches.
        
        Generates multiple thought paths, evaluates them, and searches
        for the best solution through tree exploration.
        """
        
        def __init__(self, model_name: str = "gpt-4", max_depth: int = 3, branches_per_node: int = 3):
            self.llm = ChatOpenAI(model=model_name, temperature=0.9)
            self.evaluator_llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.max_depth = max_depth
            self.branches_per_node = branches_per_node
            self.nodes: Dict[str, ThoughtNode] = {}
            self.root_id: Optional[str] = None
        
        def generate_thoughts(self, problem: str, parent_thought: Optional[str] = None, depth: int = 0) -> List[str]:
            """Generate multiple thought branches."""
            if depth >= self.max_depth:
                return []
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a creative problem solver. Generate diverse approaches to solve the problem. "
                          "Each approach should be distinct and explore different angles."),
                ("human", f"Problem: {problem}\n"
                         f"{'Current thought: ' + parent_thought if parent_thought else ''}\n\n"
                         f"Generate {self.branches_per_node} different next steps or approaches. "
                         f"Provide them as a numbered list (1. ... 2. ... 3. ...)")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({})
            content = str(response.content)
            
            # Parse thoughts from response
            thoughts = []
            for line in content.split('\n'):
                line = line.strip()
                if line and (line[0].isdigit() or line.startswith('-') or line.startswith('•')):
                    # Remove numbering/bullets
                    thought = line.lstrip('0123456789.-•) ').strip()
                    if thought:
                        thoughts.append(thought)
            
            return thoughts[:self.branches_per_node]
        
        def evaluate_thought(self, problem: str, thought: str) -> float:
            """Evaluate quality of a thought."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are an expert evaluator. Rate how promising this thought/approach is "
                          "for solving the problem. Consider feasibility, creativity, and likelihood of success."),
                ("human", f"Problem: {problem}\n"
                         f"Thought/Approach: {thought}\n\n"
                         f"Rate this approach from 0.0 (terrible) to 10.0 (excellent). "
                         f"Provide only the numeric rating.")
            ])
            
            chain = prompt | self.evaluator_llm
            response = chain.invoke({})
            content = str(response.content).strip()
            
            # Extract numeric rating
            try:
                # Find first number in response
                import re
                match = re.search(r'(\d+\.?\d*)', content)
                if match:
                    score = float(match.group(1))
                    return min(10.0, max(0.0, score))
            except:
                pass
            
            return 5.0  # Default middle score
        
        def build_tree(self, problem: str):
            """Build tree of thoughts."""
            # Create root node
            root_id = str(uuid.uuid4())
            self.root_id = root_id
            
            root_node = ThoughtNode(
                id=root_id,
                content=f"Problem: {problem}",
                parent_id=None,
                depth=0
            )
            self.nodes[root_id] = root_node
            
            # Build tree level by level
            nodes_to_expand = [root_node]
            
            while nodes_to_expand:
                current_node = nodes_to_expand.pop(0)
                
                if current_node.depth >= self.max_depth:
                    current_node.is_terminal = True
                    continue
                
                # Generate child thoughts
                thoughts = self.generate_thoughts(
                    problem,
                    current_node.content if current_node.depth > 0 else None,
                    current_node.depth
                )
                
                for thought in thoughts:
                    # Create child node
                    child_id = str(uuid.uuid4())
                    child_node = ThoughtNode(
                        id=child_id,
                        content=thought,
                        parent_id=current_node.id,
                        depth=current_node.depth + 1
                    )
                    
                    # Evaluate thought
                    score = self.evaluate_thought(problem, thought)
                    child_node.score = score
                    child_node.evaluation = f"Score: {score:.1f}/10.0"
                    
                    self.nodes[child_id] = child_node
                    current_node.children_ids.append(child_id)
                    
                    # Add to expansion queue if not at max depth
                    if child_node.depth  List[ThoughtNode]:
            """Get highest-scoring path from root to leaf."""
            if not self.root_id:
                return []
            
            def find_best_path_recursive(node_id: str) -> tuple[List[ThoughtNode], float]:
                """Recursively find best path."""
                node = self.nodes[node_id]
                
                if not node.children_ids or node.is_terminal:
                    return ([node], node.score)
                
                best_path = [node]
                best_score = node.score
                
                for child_id in node.children_ids:
                    child_path, child_score = find_best_path_recursive(child_id)
                    total_score = node.score + child_score
                    
                    if total_score > best_score:
                        best_score = total_score
                        best_path = [node] + child_path
                
                return (best_path, best_score)
            
            path, _ = find_best_path_recursive(self.root_id)
            return path
        
        def run(self, problem: str) -> Dict[str, Any]:
            """Execute tree-of-thought reasoning."""
            print(f"   Building thought tree (depth={self.max_depth}, branches={self.branches_per_node})...")
            
            # Build tree
            self.build_tree(problem)
            
            # Find best solution path
            best_path = self.get_best_path()
            
            # Analyze tree
            total_nodes = len(self.nodes)
            terminal_nodes = sum(1 for n in self.nodes.values() if n.is_terminal)
            avg_score = sum(n.score for n in self.nodes.values()) / total_nodes if total_nodes > 0 else 0
            
            return {
                "pattern": "TreeOfThought",
                "problem": problem,
                "total_thoughts": total_nodes,
                "terminal_thoughts": terminal_nodes,
                "average_score": avg_score,
                "best_path_length": len(best_path),
                "best_path": [{"depth": n.depth, "thought": n.content, "score": n.score} for n in best_path],
                "best_solution": best_path[-1].content if best_path else None
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Tree-of-Thought Pattern Demo ===\n")
        
        # Create pattern
        pattern = TreeOfThoughtPattern(max_depth=2, branches_per_node=3)
        
        # Solve problem
        print("1. Solving problem with tree-of-thought reasoning...")
        problem = "How can we reduce carbon emissions in urban transportation?"
        
        result = pattern.run(problem)
        
        print(f"\n2. Tree Statistics:")
        print(f"   Total Thoughts Explored: {result['total_thoughts']}")
        print(f"   Terminal Thoughts: {result['terminal_thoughts']}")
        print(f"   Average Score: {result['average_score']:.2f}/10.0")
        
        print(f"\n3. Best Reasoning Path:")
        for step in result['best_path']:
            indent = "   " * step['depth']
            print(f"{indent}└─ [{step['score']:.1f}] {step['thought'][:80]}...")
        
        print(f"\n4. Best Solution:")
        print(f"   {result['best_solution']}")
        
        print("\nāœ“ Tree-of-thought pattern explored multiple reasoning paths!")
    
        

    Agentic Architecture Pattern: Tree Of Thought

    Pattern 75: 75 Tree Of Thought – Line-by-Line Explanation

    Overview

    Pattern 75: Tree-of-Thought Pattern

    Explores multiple reasoning paths in parallel, evaluates them, and selects the best solution. Enables deliberate decision making through search over thought trees.


    Code Structure Analysis

    File Information

    • Pattern Number: 75
    • Pattern Name: 75 Tree Of Thought
    • File Path: patterns\execution_control\75_tree_of_thought.py
    • Total Lines: 239

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 75: Tree-of-Thought Pattern
    
    Explores multiple reasoning paths in parallel, evaluates them, and
    selects the best solution. Enables deliberate decision making through
    search over thought trees.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 75 Tree Of Thought pattern.


    Imports Section

    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    import uuid
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
                import re  # 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

    ThoughtNode (Line 18)

    Description: Node in the thought tree.

    TreeOfThoughtPattern (Line 30)

    Description: Tree-of-Thought Pattern – Explores multiple reasoning branches.

    Generates multiple thought paths, evaluates them, and searches for the best solution through tree exploration.

    Methods:

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

    Purpose: No method docstring.

    Parameters: – self: Instance reference – model_name: LLM model to use (e.g., “gpt-4”) – max_depth: Parameter for max_depth – branches_per_node: Parameter for branches_per_node

    generate_thoughts (Line 46)
    def generate_thoughts(self, problem, parent_thought, depth):
        """Generate multiple thought branches."""
    

    Purpose: Generate multiple thought branches.

    Parameters: – self: Instance reference – problem: Parameter for problem – parent_thought: Parameter for parent_thought – depth: Parameter for depth

    evaluate_thought (Line 76)
    def evaluate_thought(self, problem, thought):
        """Evaluate quality of a thought."""
    

    Purpose: Evaluate quality of a thought.

    Parameters: – self: Instance reference – problem: Parameter for problem – thought: Parameter for thought

    build_tree (Line 104)
    def build_tree(self, problem):
        """Build tree of thoughts."""
    

    Purpose: Build tree of thoughts.

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

    get_best_path (Line 157)
    def get_best_path(self):
        """Get highest-scoring path from root to leaf."""
    

    Purpose: Get highest-scoring path from root to leaf.

    Parameters: – self: Instance reference

    run (Line 185)
    def run(self, problem):
        """Execute tree-of-thought reasoning."""
    

    Purpose: Execute tree-of-thought reasoning.

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


    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 = ThoughtNode(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

  • Agentic Architecture Pattern: Chain Of Thought

    
        """
    Pattern 74: Chain Of Thought
    
    Purpose: Enhanced implementation with full LangChain/LangGraph integration
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    @dataclass
    class ChainOfThoughtConfig:
        """Configuration for Chain Of Thought."""
        model_name: str = "gpt-4"
        temperature: float = 0.7
        max_iterations: int = 10
        enable_logging: bool = True
    
    
    @dataclass
    class ChainOfThoughtState:
        """State information for Chain Of Thought."""
        current_step: int = 0
        data: Dict[str, Any] = field(default_factory=dict)
        results: List[Any] = field(default_factory=list)
        metadata: Dict[str, Any] = field(default_factory=dict)
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class ChainOfThoughtAgent:
        """Agent implementing Chain Of Thought."""
        
        def __init__(self, name: str, config: ChainOfThoughtConfig = None):
            self.name = name
            self.config = config or ChainOfThoughtConfig()
            self.llm = ChatOpenAI(
                model=self.config.model_name,
                temperature=self.config.temperature
            )
            self.state = ChainOfThoughtState()
            self.execution_history: List[Dict[str, Any]] = []
        
        def process(self, input_data: Any) -> Dict[str, Any]:
            """Process input according to Chain Of Thought."""
            self.state.current_step += 1
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}, implementing Chain Of Thought. "
                          f"Provide clear, structured responses."),
                ("human", "Process this input: {input_data}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"input_data": str(input_data)})
            
            result = {
                "agent": self.name,
                "step": self.state.current_step,
                "input": input_data,
                "output": str(response.content),
                "timestamp": datetime.now()
            }
            
            self.execution_history.append(result)
            self.state.results.append(result)
            
            return result
        
        def get_statistics(self) -> Dict[str, Any]:
            """Get agent statistics."""
            return {
                "name": self.name,
                "total_executions": len(self.execution_history),
                "current_step": self.state.current_step,
                "results_count": len(self.state.results)
            }
    
    
    class ChainOfThoughtPattern:
        """
        Chain Of Thought - Enhanced implementation
        
        This pattern provides comprehensive functionality for chain of thought
        with full LangChain/LangGraph integration.
        
        Features:
        - Multi-agent coordination
        - State management
        - Execution tracking
        - LangGraph workflow integration
        """
        
        def __init__(self, config: ChainOfThoughtConfig = None):
            self.config = config or ChainOfThoughtConfig()
            self.agents: Dict[str, ChainOfThoughtAgent] = {}
            self.workflow = self._build_workflow()
            self.execution_log: List[Dict[str, Any]] = []
        
        def _build_workflow(self) -> StateGraph:
            """Build LangGraph workflow for pattern execution."""
            
            class WorkflowState(TypedDict):
                input: str
                processed: str
                output: str
                metadata: Dict[str, Any]
            
            def process_input(state: WorkflowState) -> WorkflowState:
                """Process input node."""
                return {
                    **state,
                    "processed": f"Processed: {state['input']}",
                    "metadata": {"step": "process_input"}
                }
            
            def generate_output(state: WorkflowState) -> WorkflowState:
                """Generate output node."""
                llm = ChatOpenAI(model=self.config.model_name, temperature=self.config.temperature)
                
                prompt = ChatPromptTemplate.from_messages([
                    ("system", "You are implementing Chain Of Thought. Generate comprehensive output."),
                    ("human", "{input}")
                ])
                
                chain = prompt | llm
                response = chain.invoke({"input": state["processed"]})
                
                return {
                    **state,
                    "output": str(response.content),
                    "metadata": {**state.get("metadata", {}), "step": "generate_output"}
                }
            
            # Build workflow graph
            workflow = StateGraph(WorkflowState)
            workflow.add_node("process", process_input)
            workflow.add_node("generate", generate_output)
            workflow.set_entry_point("process")
            workflow.add_edge("process", "generate")
            workflow.add_edge("generate", END)
            
            return workflow.compile()
        
        def register_agent(self, agent: ChainOfThoughtAgent):
            """Register an agent with the pattern."""
            self.agents[agent.name] = agent
            if self.config.enable_logging:
                print(f"Registered agent: {agent.name}")
        
        def execute(self, input_data: Any, agent_name: str = None) -> Dict[str, Any]:
            """Execute the pattern with given input."""
            
            # Use workflow if no specific agent requested
            if agent_name is None:
                result = self.workflow.invoke({
                    "input": str(input_data),
                    "processed": "",
                    "output": "",
                    "metadata": {}
                })
                
                execution_record = {
                    "pattern": "Chain Of Thought",
                    "input": input_data,
                    "output": result.get("output", ""),
                    "metadata": result.get("metadata", {}),
                    "timestamp": datetime.now()
                }
                
                self.execution_log.append(execution_record)
                return execution_record
            
            # Execute with specific agent
            agent = self.agents.get(agent_name)
            if not agent:
                raise ValueError(f"Agent {agent_name} not found")
            
            result = agent.process(input_data)
            self.execution_log.append(result)
            return result
        
        def run(self, input_data: Any) -> Dict[str, Any]:
            """Main execution method."""
            return self.execute(input_data)
        
        def get_statistics(self) -> Dict[str, Any]:
            """Get pattern statistics."""
            return {
                "pattern": "Chain Of Thought",
                "total_executions": len(self.execution_log),
                "registered_agents": len(self.agents),
                "agents": [agent.get_statistics() for agent in self.agents.values()]
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Chain Of Thought Demo ===\n")
        
        # Create configuration
        config = ChainOfThoughtConfig(
            model_name="gpt-4",
            temperature=0.7,
            enable_logging=True
        )
        
        # Create pattern
        pattern = ChainOfThoughtPattern(config)
        
        # Create and register agents
        agent1 = ChainOfThoughtAgent("Agent1", config)
        agent2 = ChainOfThoughtAgent("Agent2", config)
        pattern.register_agent(agent1)
        pattern.register_agent(agent2)
        
        print("\nExecuting pattern workflow...")
        
        # Execute with workflow
        result1 = pattern.run("Demonstrate chain of thought functionality")
        print(f"\nWorkflow Result:")
        print(f"  Output: {result1['output'][:150]}...")
        
        # Execute with specific agents
        result2 = pattern.execute("Specific task for Agent1", agent_name="Agent1")
        print(f"\nAgent1 Result:")
        print(f"  Output: {result2['output'][:150]}...")
        
        result3 = pattern.execute("Specific task for Agent2", agent_name="Agent2")
        print(f"\nAgent2 Result:")
        print(f"  Output: {result3['output'][:150]}...")
        
        # Show statistics
        print("\n=== Statistics ===")
        stats = pattern.get_statistics()
        print(f"Pattern: {stats['pattern']}")
        print(f"Total Executions: {stats['total_executions']}")
        print(f"Registered Agents: {stats['registered_agents']}")
        print(f"\nAgent Statistics:")
        for agent_stats in stats['agents']:
            print(f"  {agent_stats['name']}: {agent_stats['total_executions']} executions")
    
        

    Agentic Architecture Pattern: Chain Of Thought

    Pattern 74: 74 Chain Of Thought – Line-by-Line Explanation

    Overview

    Pattern 74: Chain Of Thought

    Purpose: Enhanced implementation with full LangChain/LangGraph integration


    Code Structure Analysis

    File Information

    • Pattern Number: 74
    • Pattern Name: 74 Chain Of Thought
    • File Path: patterns\execution_control\74_chain_of_thought.py
    • Total Lines: 247

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 74: Chain Of Thought
    
    Purpose: Enhanced implementation with full LangChain/LangGraph integration
    """
    

    Explanation: This module docstring describes the purpose and key features of the 74 Chain Of Thought 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Classes

    ChainOfThoughtConfig (Line 18)

    Description: Configuration for Chain Of Thought.

    ChainOfThoughtState (Line 27)

    Description: State information for Chain Of Thought.

    ChainOfThoughtAgent (Line 36)

    Description: Agent implementing Chain Of Thought.

    Methods:

    __init__ (Line 39)
    def __init__(self, name, config):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – config: Configuration settings

    process (Line 49)
    def process(self, input_data):
        """Process input according to Chain Of Thought."""
    

    Purpose: Process input according to Chain Of Thought.

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

    get_statistics (Line 75)
    def get_statistics(self):
        """Get agent statistics."""
    

    Purpose: Get agent statistics.

    Parameters: – self: Instance reference

    ChainOfThoughtPattern (Line 85)

    Description: Chain Of Thought – Enhanced implementation

    This pattern provides comprehensive functionality for chain of thought with full LangChain/LangGraph integration.

    Features: – Multi-agent coordination – State management – Execution tracking – LangGraph workflow integration

    Methods:

    __init__ (Line 99)
    def __init__(self, config):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – config: Configuration settings

    _build_workflow (Line 105)
    def _build_workflow(self):
        """Build LangGraph workflow for pattern execution."""
    

    Purpose: Build LangGraph workflow for pattern execution.

    Parameters: – self: Instance reference

    register_agent (Line 150)
    def register_agent(self, agent):
        """Register an agent with the pattern."""
    

    Purpose: Register an agent with the pattern.

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

    execute (Line 156)
    def execute(self, input_data, agent_name):
        """Execute the pattern with given input."""
    

    Purpose: Execute the pattern with given input.

    Parameters: – self: Instance reference – input_data: Parameter for input_data – agent_name: Parameter for agent_name

    run (Line 188)
    def run(self, input_data):
        """Main execution method."""
    

    Purpose: Main execution method.

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

    get_statistics (Line 192)
    def get_statistics(self):
        """Get pattern statistics."""
    

    Purpose: Get pattern statistics.

    Parameters: – self: Instance reference

    WorkflowState (Line 108)

    Description: No class docstring.


    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 = ChainOfThoughtConfig(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

  • Agentic Architecture Pattern: Pipeline

    
        """
    Pattern 73: Pipeline Pattern
    
    Data flows through a series of processing stages with transformations
    at each stage. Similar to Unix pipes or data processing pipelines.
    """
    
    from typing import Dict, Any, List, Optional, Callable
    from dataclasses import dataclass, field
    from datetime import datetime
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    @dataclass
    class PipelineStage:
        """Stage in the processing pipeline."""
        name: str
        processor: Callable[[Any], Any]
        description: str = ""
        input_type: Optional[str] = None
        output_type: Optional[str] = None
    
    
    @dataclass
    class PipelineResult:
        """Result from pipeline execution."""
        success: bool
        input_data: Any
        output_data: Optional[Any]
        stages_executed: List[str]
        stage_outputs: Dict[str, Any]
        execution_time: float
        error: Optional[str] = None
    
    
    class PipelineAgent:
        """Agent that acts as a pipeline stage."""
        
        def __init__(self, name: str, role: str, model_name: str = "gpt-4"):
            self.name = name
            self.role = role
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
        
        def transform(self, data: Any) -> Any:
            """Transform input data."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}, a {self.role}. "
                          f"Transform the input data according to your role."),
                ("human", f"Input: {data}\n\nProvide transformed output.")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({})
            return str(response.content)
    
    
    class PipelinePattern:
        """
        Pipeline Pattern - Sequential data transformation chain.
        
        Data flows through stages with each stage transforming the data.
        Stages can be agents, functions, or any callable processor.
        """
        
        def __init__(self):
            self.stages: List[PipelineStage] = []
            self.execution_log: List[PipelineResult] = []
        
        def add_stage(self, stage: PipelineStage):
            """Add stage to pipeline."""
            self.stages.append(stage)
        
        def add_agent_stage(self, agent: PipelineAgent, description: str = ""):
            """Add agent as pipeline stage."""
            stage = PipelineStage(
                name=agent.name,
                processor=agent.transform,
                description=description or f"{agent.role} processing"
            )
            self.stages.append(stage)
        
        def add_function_stage(self, name: str, func: Callable[[Any], Any], description: str = ""):
            """Add function as pipeline stage."""
            stage = PipelineStage(
                name=name,
                processor=func,
                description=description
            )
            self.stages.append(stage)
        
        def execute(self, input_data: Any) -> PipelineResult:
            """Execute data through pipeline."""
            start_time = datetime.now()
            
            stages_executed = []
            stage_outputs = {}
            current_data = input_data
            
            try:
                for stage in self.stages:
                    print(f"   Executing stage: {stage.name}...")
                    
                    # Process data through stage
                    current_data = stage.processor(current_data)
                    
                    # Log execution
                    stages_executed.append(stage.name)
                    stage_outputs[stage.name] = current_data
                
                execution_time = (datetime.now() - start_time).total_seconds()
                
                result = PipelineResult(
                    success=True,
                    input_data=input_data,
                    output_data=current_data,
                    stages_executed=stages_executed,
                    stage_outputs=stage_outputs,
                    execution_time=execution_time
                )
                
            except Exception as e:
                execution_time = (datetime.now() - start_time).total_seconds()
                
                result = PipelineResult(
                    success=False,
                    input_data=input_data,
                    output_data=None,
                    stages_executed=stages_executed,
                    stage_outputs=stage_outputs,
                    execution_time=execution_time,
                    error=str(e)
                )
            
            self.execution_log.append(result)
            return result
        
        def run(self, input_data: Any) -> Dict[str, Any]:
            """Run pipeline and return results."""
            result = self.execute(input_data)
            
            return {
                "pattern": "Pipeline",
                "success": result.success,
                "stages_executed": len(result.stages_executed),
                "total_stages": len(self.stages),
                "execution_time": result.execution_time,
                "output": result.output_data,
                "error": result.error
            }
        
        def get_statistics(self) -> Dict[str, Any]:
            """Get pipeline statistics."""
            if not self.execution_log:
                return {"total_runs": 0}
            
            return {
                "total_runs": len(self.execution_log),
                "successful_runs": sum(1 for r in self.execution_log if r.success),
                "failed_runs": sum(1 for r in self.execution_log if not r.success),
                "avg_execution_time": sum(r.execution_time for r in self.execution_log) / len(self.execution_log),
                "total_stages": len(self.stages)
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Pipeline Pattern Demo ===\n")
        
        # Create pipeline
        pipeline = PipelinePattern()
        
        # Add agent-based stages
        print("1. Building pipeline with agents...")
        extractor = PipelineAgent("Extractor", "data extractor")
        transformer = PipelineAgent("Transformer", "data transformer")
        validator = PipelineAgent("Validator", "data validator")
        
        pipeline.add_agent_stage(extractor, "Extract key information")
        pipeline.add_agent_stage(transformer, "Transform to target format")
        pipeline.add_agent_stage(validator, "Validate output quality")
        
        # Add function-based stage
        def format_output(data: Any) -> str:
            return f"[FORMATTED] {str(data).upper()}"
        
        pipeline.add_function_stage("Formatter", format_output, "Format final output")
        
        # Execute pipeline
        print("\n2. Executing pipeline...")
        input_text = "Process this customer feedback: The product is great but shipping was slow."
        result = pipeline.run(input_text)
        
        print(f"\n3. Pipeline Results:")
        print(f"   Success: {result['success']}")
        print(f"   Stages Executed: {result['stages_executed']}/{result['total_stages']}")
        print(f"   Execution Time: {result['execution_time']:.2f}s")
        
        if result['output']:
            print(f"\n4. Final Output:")
            print(f"   {str(result['output'])[:150]}...")
        
        # Statistics
        stats = pipeline.get_statistics()
        print(f"\n5. Pipeline Statistics:")
        print(f"   Total Runs: {stats['total_runs']}")
        print(f"   Success Rate: {stats['successful_runs']}/{stats['total_runs']}")
        
        print("\nāœ“ Pipeline pattern processed data through transformation stages!")
    
        

    Agentic Architecture Pattern: Pipeline

    Pattern 73: 73 Pipeline – Line-by-Line Explanation

    Overview

    Pattern 73: Pipeline Pattern

    Data flows through a series of processing stages with transformations at each stage. Similar to Unix pipes or data processing pipelines.


    Code Structure Analysis

    File Information

    • Pattern Number: 73
    • Pattern Name: 73 Pipeline
    • File Path: patterns\execution_control\73_pipeline.py
    • Total Lines: 210

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 73: Pipeline Pattern
    
    Data flows through a series of processing stages with transformations
    at each stage. Similar to Unix pipes or data processing pipelines.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 73 Pipeline pattern.


    Imports Section

    from typing import Dict, Any, List, Optional, Callable
    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, Callable: 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

    PipelineStage (Line 16)

    Description: Stage in the processing pipeline.

    PipelineResult (Line 26)

    Description: Result from pipeline execution.

    PipelineAgent (Line 37)

    Description: Agent that acts as a pipeline stage.

    Methods:

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

    Purpose: No method docstring.

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

    transform (Line 45)
    def transform(self, data):
        """Transform input data."""
    

    Purpose: Transform input data.

    Parameters: – self: Instance reference – data: Input data to process

    PipelinePattern (Line 58)

    Description: Pipeline Pattern – Sequential data transformation chain.

    Data flows through stages with each stage transforming the data. Stages can be agents, functions, or any callable processor.

    Methods:

    __init__ (Line 66)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    add_stage (Line 70)
    def add_stage(self, stage):
        """Add stage to pipeline."""
    

    Purpose: Add stage to pipeline.

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

    add_agent_stage (Line 74)
    def add_agent_stage(self, agent, description):
        """Add agent as pipeline stage."""
    

    Purpose: Add agent as pipeline stage.

    Parameters: – self: Instance reference – agent: Parameter for agent – description: Parameter for description

    add_function_stage (Line 83)
    def add_function_stage(self, name, func, description):
        """Add function as pipeline stage."""
    

    Purpose: Add function as pipeline stage.

    Parameters: – self: Instance reference – name: Identifier or label – func: Parameter for func – description: Parameter for description

    execute (Line 92)
    def execute(self, input_data):
        """Execute data through pipeline."""
    

    Purpose: Execute data through pipeline.

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

    run (Line 138)
    def run(self, input_data):
        """Run pipeline and return results."""
    

    Purpose: Run pipeline and return results.

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

    get_statistics (Line 152)
    def get_statistics(self):
        """Get pipeline statistics."""
    

    Purpose: Get pipeline statistics.

    Parameters: – self: Instance reference


    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 = PipelineStage(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

  • Agentic Architecture Pattern: Parallel Agent

    
        """
    Pattern 72: Parallel Agent Pattern
    
    Multiple agents execute tasks concurrently for faster processing.
    Features parallel execution, result aggregation, and synchronization.
    """
    
    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    import asyncio
    import time
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI
    
    
    @dataclass
    class ParallelTask:
        """Task to be executed in parallel."""
        task_id: str
        description: str
        agent_name: Optional[str] = None
        input_data: Any = None
        result: Optional[str] = None
        status: str = "pending"  # pending, running, completed, failed
        start_time: Optional[datetime] = None
        end_time: Optional[datetime] = None
        duration: float = 0
    
    
    @dataclass
    class ParallelExecution:
        """Record of parallel execution."""
        execution_id: str
        tasks: List[ParallelTask]
        total_time: float
        speedup: float  # vs sequential execution
        efficiency: float  # speedup / num_agents
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class ParallelAgent:
        """Agent that can execute tasks concurrently."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.tasks_completed = 0
        
        async def execute_task_async(self, task: ParallelTask) -> str:
            """Execute task asynchronously."""
            task.status = "running"
            task.start_time = datetime.now()
            task.agent_name = self.name
            
            # Simulate work with LLM
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}, executing a task in parallel with other agents."),
                ("human", f"Task: {task.description}\n"
                         f"Input: {task.input_data}\n\n"
                         f"Execute this task (provide brief result).")
            ])
            
            chain = prompt | self.llm
            
            # Simulate some processing time
            await asyncio.sleep(0.1)  # Small delay to simulate work
            
            response = chain.invoke({})
            result = str(response.content)[:200]
            
            task.end_time = datetime.now()
            task.duration = (task.end_time - task.start_time).total_seconds()
            task.result = result
            task.status = "completed"
            self.tasks_completed += 1
            
            return result
    
    
    class ParallelAgentPattern:
        """
        Parallel Agent Pattern - Concurrent task execution.
        
        Multiple agents work simultaneously on different tasks,
        reducing total execution time through parallelism.
        """
        
        def __init__(self):
            self.agents: List[ParallelAgent] = []
            self.execution_history: List[ParallelExecution] = []
        
        def register_agent(self, agent: ParallelAgent):
            """Register agent for parallel execution."""
            self.agents.append(agent)
        
        async def execute_parallel(self, tasks: List[ParallelTask]) -> ParallelExecution:
            """Execute tasks in parallel across available agents."""
            start_time = time.time()
            
            print(f"\n   Executing {len(tasks)} tasks in parallel with {len(self.agents)} agents...")
            
            # Assign tasks to agents (round-robin)
            task_assignments = []
            for i, task in enumerate(tasks):
                agent = self.agents[i % len(self.agents)]
                task_assignments.append(agent.execute_task_async(task))
            
            # Execute all tasks concurrently
            await asyncio.gather(*task_assignments)
            
            total_time = time.time() - start_time
            
            # Calculate metrics
            avg_task_duration = sum(t.duration for t in tasks) / len(tasks)
            sequential_time = sum(t.duration for t in tasks)
            speedup = sequential_time / total_time if total_time > 0 else 1
            efficiency = speedup / len(self.agents) if self.agents else 0
            
            print(f"   āœ“ Completed in {total_time:.2f}s")
            print(f"   Speedup: {speedup:.2f}x (vs sequential: {sequential_time:.2f}s)")
            print(f"   Efficiency: {efficiency:.1%}")
            
            # Record execution
            execution = ParallelExecution(
                execution_id=f"exec_{len(self.execution_history)}",
                tasks=tasks,
                total_time=total_time,
                speedup=speedup,
                efficiency=efficiency
            )
            self.execution_history.append(execution)
            
            return execution
        
        def execute_parallel_sync(self, tasks: List[ParallelTask]) -> ParallelExecution:
            """Synchronous wrapper for parallel execution."""
            return asyncio.run(self.execute_parallel(tasks))
        
        def aggregate_results(self, tasks: List[ParallelTask]) -> Dict[str, Any]:
            """Aggregate results from parallel tasks."""
            completed = [t for t in tasks if t.status == "completed"]
            failed = [t for t in tasks if t.status == "failed"]
            
            results = {
                "total_tasks": len(tasks),
                "completed": len(completed),
                "failed": len(failed),
                "results": {t.task_id: t.result for t in completed},
                "agent_contributions": {}
            }
            
            # Count tasks per agent
            for task in completed:
                if task.agent_name:
                    results["agent_contributions"][task.agent_name] = \
                        results["agent_contributions"].get(task.agent_name, 0) + 1
            
            return results
        
        def run(self, scenario: str) -> Dict[str, Any]:
            """Execute parallel agent pattern."""
            total_executions = len(self.execution_history)
            avg_speedup = (sum(e.speedup for e in self.execution_history) / total_executions 
                          if total_executions > 0 else 0)
            avg_efficiency = (sum(e.efficiency for e in self.execution_history) / total_executions 
                             if total_executions > 0 else 0)
            
            return {
                "pattern": "ParallelAgent",
                "total_agents": len(self.agents),
                "total_executions": total_executions,
                "average_speedup": avg_speedup,
                "average_efficiency": avg_efficiency,
                "scenario": scenario
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Parallel Agent Pattern Demo ===\n")
        
        # Create pattern
        pattern = ParallelAgentPattern()
        
        # Register parallel agents
        print("1. Registering parallel agents...")
        agents = [
            ParallelAgent("Worker1"),
            ParallelAgent("Worker2"),
            ParallelAgent("Worker3"),
            ParallelAgent("Worker4"),
        ]
        
        for agent in agents:
            pattern.register_agent(agent)
        
        print(f"   Registered {len(agents)} agents")
        
        # Create tasks for parallel execution
        print("\n2. Creating tasks...")
        tasks = [
            ParallelTask("t1", "Analyze customer feedback", input_data="feedback_batch_1"),
            ParallelTask("t2", "Process invoice data", input_data="invoices_q4"),
            ParallelTask("t3", "Generate sales report", input_data="sales_data_nov"),
            ParallelTask("t4", "Classify support tickets", input_data="tickets_batch_5"),
            ParallelTask("t5", "Extract document insights", input_data="documents_set_3"),
            ParallelTask("t6", "Summarize meeting notes", input_data="meetings_week_45"),
            ParallelTask("t7", "Validate data quality", input_data="dataset_v2"),
            ParallelTask("t8", "Transform data format", input_data="raw_exports"),
        ]
        
        print(f"   Created {len(tasks)} tasks")
        
        # Execute in parallel
        print("\n3. Executing tasks in parallel...")
        execution = pattern.execute_parallel_sync(tasks)
        
        # Show task assignments
        print("\n4. Task Distribution:")
        for agent in agents:
            agent_tasks = [t for t in tasks if t.agent_name == agent.name]
            print(f"   {agent.name}: {len(agent_tasks)} tasks")
            for task in agent_tasks:
                print(f"      - {task.task_id}: {task.description} ({task.duration:.2f}s)")
        
        # Aggregate results
        print("\n5. Results Aggregation:")
        aggregated = pattern.aggregate_results(tasks)
        print(f"   Total Tasks: {aggregated['total_tasks']}")
        print(f"   Completed: {aggregated['completed']}")
        print(f"   Failed: {aggregated['failed']}")
        
        # Performance metrics
        print("\n6. Performance Metrics:")
        summary = pattern.run("Parallel data processing")
        print(f"   Agents: {summary['total_agents']}")
        print(f"   Average Speedup: {summary['average_speedup']:.2f}x")
        print(f"   Average Efficiency: {summary['average_efficiency']:.1%}")
        
        print("\nāœ“ Parallel agents executed tasks concurrently for faster processing!")
    
        

    Agentic Architecture Pattern: Parallel Agent

    Pattern 72: 72 Parallel Agent – Line-by-Line Explanation

    Overview

    Pattern 72: Parallel Agent Pattern

    Multiple agents execute tasks concurrently for faster processing. Features parallel execution, result aggregation, and synchronization.


    Code Structure Analysis

    File Information

    • Pattern Number: 72
    • Pattern Name: 72 Parallel Agent
    • File Path: patterns\execution_control\72_parallel_agent.py
    • Total Lines: 242

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 72: Parallel Agent Pattern
    
    Multiple agents execute tasks concurrently for faster processing.
    Features parallel execution, result aggregation, and synchronization.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 72 Parallel Agent pattern.


    Imports Section

    from typing import Dict, Any, List, Optional
    from dataclasses import dataclass, field
    from datetime import datetime
    import asyncio
    import time
    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

    ParallelTask (Line 18)

    Description: Task to be executed in parallel.

    ParallelExecution (Line 32)

    Description: Record of parallel execution.

    ParallelAgent (Line 42)

    Description: Agent that can execute tasks concurrently.

    Methods:

    __init__ (Line 45)
    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”)

    ParallelAgentPattern (Line 81)

    Description: Parallel Agent Pattern – Concurrent task execution.

    Multiple agents work simultaneously on different tasks, reducing total execution time through parallelism.

    Methods:

    __init__ (Line 89)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 93)
    def register_agent(self, agent):
        """Register agent for parallel execution."""
    

    Purpose: Register agent for parallel execution.

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

    execute_parallel_sync (Line 136)
    def execute_parallel_sync(self, tasks):
        """Synchronous wrapper for parallel execution."""
    

    Purpose: Synchronous wrapper for parallel execution.

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

    aggregate_results (Line 140)
    def aggregate_results(self, tasks):
        """Aggregate results from parallel tasks."""
    

    Purpose: Aggregate results from parallel tasks.

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

    run (Line 161)
    def run(self, scenario):
        """Execute parallel agent pattern."""
    

    Purpose: Execute parallel agent pattern.

    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 = ParallelTask(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

  • Agentic Architecture Pattern: Sequential Agent

    
        """
    Pattern 71: Sequential Agent Pattern
    
    Agents execute tasks in a strict sequential order, with each agent processing
    the output of the previous agent in a linear chain.
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    @dataclass
    class SequentialTask:
        """Task in sequential execution."""
        task_id: str
        agent_name: str
        input_data: Any
        output_data: Optional[Any] = None
        status: str = "pending"  # pending, running, completed, failed
        start_time: Optional[datetime] = None
        end_time: Optional[datetime] = None
        error: Optional[str] = None
    
    
    class SequentialState(TypedDict):
        """State for sequential execution workflow."""
        tasks: List[SequentialTask]
        current_index: int
        input_data: Any
        final_output: Optional[Any]
        execution_log: List[str]
    
    
    class SequentialAgent:
        """Agent that processes data sequentially."""
        
        def __init__(self, name: str, role: str, model_name: str = "gpt-4"):
            self.name = name
            self.role = role
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
        
        def process(self, input_data: Any) -> Any:
            """Process input and return output."""
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}, a {self.role}. "
                          f"Process the input and provide your output for the next agent."),
                ("human", f"Input: {input_data}\n\nProvide your processed output.")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({})
            return str(response.content)
    
    
    class SequentialAgentPattern:
        """
        Sequential Agent Pattern - Linear execution chain.
        
        Uses LangGraph to manage sequential workflow where each agent
        processes the output of the previous agent in strict order.
        """
        
        def __init__(self):
            self.agents: List[SequentialAgent] = []
            self.execution_history: List[SequentialTask] = []
        
        def add_agent(self, agent: SequentialAgent):
            """Add agent to sequential chain."""
            self.agents.append(agent)
        
        def build_graph(self) -> StateGraph:
            """Build sequential execution graph."""
            workflow = StateGraph(SequentialState)
            
            def execute_next(state: SequentialState) -> SequentialState:
                """Execute next agent in sequence."""
                current_idx = state["current_index"]
                tasks = state["tasks"]
                
                if current_idx >= len(tasks):
                    # All tasks completed
                    if tasks:
                        state["final_output"] = tasks[-1].output_data
                    return state
                
                task = tasks[current_idx]
                task.status = "running"
                task.start_time = datetime.now()
                
                try:
                    # Get agent
                    agent = self.agents[current_idx]
                    
                    # Get input (previous output or initial input)
                    if current_idx == 0:
                        input_data = state["input_data"]
                    else:
                        input_data = tasks[current_idx - 1].output_data
                    
                    # Execute agent
                    output = agent.process(input_data)
                    
                    task.output_data = output
                    task.status = "completed"
                    task.end_time = datetime.now()
                    
                    log_msg = f"Agent {agent.name} completed: {str(output)[:50]}..."
                    state["execution_log"].append(log_msg)
                    
                except Exception as e:
                    task.status = "failed"
                    task.error = str(e)
                    task.end_time = datetime.now()
                    state["execution_log"].append(f"Agent {task.agent_name} failed: {str(e)}")
                
                # Move to next
                state["current_index"] = current_idx + 1
                
                return state
            
            def should_continue(state: SequentialState) -> str:
                """Check if should continue to next agent."""
                if state["current_index"] >= len(state["tasks"]):
                    return "end"
                
                current_task = state["tasks"][state["current_index"]]
                if current_task.status == "failed":
                    return "end"
                
                return "continue"
            
            workflow.add_node("execute", execute_next)
            workflow.set_entry_point("execute")
            
            workflow.add_conditional_edges(
                "execute",
                should_continue,
                {
                    "continue": "execute",
                    "end": END
                }
            )
            
            return workflow.compile()
        
        def run(self, input_data: Any) -> Dict[str, Any]:
            """Execute sequential agent chain."""
            # Create tasks for each agent
            tasks = [
                SequentialTask(
                    task_id=f"task_{i}",
                    agent_name=agent.name,
                    input_data=input_data if i == 0 else None
                )
                for i, agent in enumerate(self.agents)
            ]
            
            initial_state: SequentialState = {
                "tasks": tasks,
                "current_index": 0,
                "input_data": input_data,
                "final_output": None,
                "execution_log": []
            }
            
            # Build and execute graph
            graph = self.build_graph()
            final_state = graph.invoke(initial_state)
            
            # Store history
            self.execution_history.extend(final_state["tasks"])
            
            return {
                "pattern": "Sequential",
                "agents_executed": len([t for t in final_state["tasks"] if t.status == "completed"]),
                "total_agents": len(self.agents),
                "final_output": final_state["final_output"],
                "execution_log": final_state["execution_log"],
                "success": all(t.status == "completed" for t in final_state["tasks"])
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Sequential Agent Pattern Demo ===\n")
        
        # Create pattern
        pattern = SequentialAgentPattern()
        
        # Create agent chain
        print("1. Creating sequential agent chain...")
        researcher = SequentialAgent("Researcher", "research analyst")
        writer = SequentialAgent("Writer", "content writer")
        editor = SequentialAgent("Editor", "editor and proofreader")
        formatter = SequentialAgent("Formatter", "document formatter")
        
        # Add agents in order
        pattern.add_agent(researcher)
        pattern.add_agent(writer)
        pattern.add_agent(editor)
        pattern.add_agent(formatter)
        
        # Execute sequential workflow
        print("\n2. Executing sequential workflow...")
        result = pattern.run("Write a blog post about AI agents")
        
        print(f"\n3. Results:")
        print(f"   Success: {result['success']}")
        print(f"   Agents Executed: {result['agents_executed']}/{result['total_agents']}")
        print(f"\n4. Execution Log:")
        for log in result['execution_log']:
            print(f"   - {log}")
        
        print(f"\n5. Final Output:")
        print(f"   {str(result['final_output'])[:200]}...")
        
        print("\nāœ“ Sequential agent pattern executed tasks in linear order!")
    
        

    Agentic Architecture Pattern: Sequential Agent

    Pattern 71: 71 Sequential Agent – Line-by-Line Explanation

    Overview

    Pattern 71: Sequential Agent Pattern

    Agents execute tasks in a strict sequential order, with each agent processing the output of the previous agent in a linear chain.


    Code Structure Analysis

    File Information

    • Pattern Number: 71
    • Pattern Name: 71 Sequential Agent
    • File Path: patterns\execution_control\71_sequential_agent.py
    • Total Lines: 223

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 71: Sequential Agent Pattern
    
    Agents execute tasks in a strict sequential order, with each agent processing
    the output of the previous agent in a linear chain.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 71 Sequential 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Classes

    SequentialTask (Line 18)

    Description: Task in sequential execution.

    SequentialState (Line 30)

    Description: State for sequential execution workflow.

    SequentialAgent (Line 39)

    Description: Agent that processes data sequentially.

    Methods:

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

    Purpose: No method docstring.

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

    process (Line 47)
    def process(self, input_data):
        """Process input and return output."""
    

    Purpose: Process input and return output.

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

    SequentialAgentPattern (Line 60)

    Description: Sequential Agent Pattern – Linear execution chain.

    Uses LangGraph to manage sequential workflow where each agent processes the output of the previous agent in strict order.

    Methods:

    __init__ (Line 68)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    add_agent (Line 72)
    def add_agent(self, agent):
        """Add agent to sequential chain."""
    

    Purpose: Add agent to sequential chain.

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

    build_graph (Line 76)
    def build_graph(self):
        """Build sequential execution graph."""
    

    Purpose: Build sequential execution graph.

    Parameters: – self: Instance reference

    run (Line 151)
    def run(self, input_data):
        """Execute sequential agent chain."""
    

    Purpose: Execute sequential agent chain.

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


    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 = SequentialTask(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

  • Agentic Architecture Pattern: Rag

    
        """
    Pattern 70: Rag
    
    Purpose: Enhanced implementation with full LangChain/LangGraph integration
    """
    
    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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict
    
    
    @dataclass
    class RagConfig:
        """Configuration for Rag."""
        model_name: str = "gpt-4"
        temperature: float = 0.7
        max_iterations: int = 10
        enable_logging: bool = True
    
    
    @dataclass
    class RagState:
        """State information for Rag."""
        current_step: int = 0
        data: Dict[str, Any] = field(default_factory=dict)
        results: List[Any] = field(default_factory=list)
        metadata: Dict[str, Any] = field(default_factory=dict)
        timestamp: datetime = field(default_factory=datetime.now)
    
    
    class RagAgent:
        """Agent implementing Rag."""
        
        def __init__(self, name: str, config: RagConfig = None):
            self.name = name
            self.config = config or RagConfig()
            self.llm = ChatOpenAI(
                model=self.config.model_name,
                temperature=self.config.temperature
            )
            self.state = RagState()
            self.execution_history: List[Dict[str, Any]] = []
        
        def process(self, input_data: Any) -> Dict[str, Any]:
            """Process input according to Rag."""
            self.state.current_step += 1
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}, implementing Rag. "
                          f"Provide clear, structured responses."),
                ("human", "Process this input: {input_data}")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({"input_data": str(input_data)})
            
            result = {
                "agent": self.name,
                "step": self.state.current_step,
                "input": input_data,
                "output": str(response.content),
                "timestamp": datetime.now()
            }
            
            self.execution_history.append(result)
            self.state.results.append(result)
            
            return result
        
        def get_statistics(self) -> Dict[str, Any]:
            """Get agent statistics."""
            return {
                "name": self.name,
                "total_executions": len(self.execution_history),
                "current_step": self.state.current_step,
                "results_count": len(self.state.results)
            }
    
    
    class RagPattern:
        """
        Rag - Enhanced implementation
        
        This pattern provides comprehensive functionality for rag
        with full LangChain/LangGraph integration.
        
        Features:
        - Multi-agent coordination
        - State management
        - Execution tracking
        - LangGraph workflow integration
        """
        
        def __init__(self, config: RagConfig = None):
            self.config = config or RagConfig()
            self.agents: Dict[str, RagAgent] = {}
            self.workflow = self._build_workflow()
            self.execution_log: List[Dict[str, Any]] = []
        
        def _build_workflow(self) -> StateGraph:
            """Build LangGraph workflow for pattern execution."""
            
            class WorkflowState(TypedDict):
                input: str
                processed: str
                output: str
                metadata: Dict[str, Any]
            
            def process_input(state: WorkflowState) -> WorkflowState:
                """Process input node."""
                return {
                    **state,
                    "processed": f"Processed: {state['input']}",
                    "metadata": {"step": "process_input"}
                }
            
            def generate_output(state: WorkflowState) -> WorkflowState:
                """Generate output node."""
                llm = ChatOpenAI(model=self.config.model_name, temperature=self.config.temperature)
                
                prompt = ChatPromptTemplate.from_messages([
                    ("system", "You are implementing Rag. Generate comprehensive output."),
                    ("human", "{input}")
                ])
                
                chain = prompt | llm
                response = chain.invoke({"input": state["processed"]})
                
                return {
                    **state,
                    "output": str(response.content),
                    "metadata": {**state.get("metadata", {}), "step": "generate_output"}
                }
            
            # Build workflow graph
            workflow = StateGraph(WorkflowState)
            workflow.add_node("process", process_input)
            workflow.add_node("generate", generate_output)
            workflow.set_entry_point("process")
            workflow.add_edge("process", "generate")
            workflow.add_edge("generate", END)
            
            return workflow.compile()
        
        def register_agent(self, agent: RagAgent):
            """Register an agent with the pattern."""
            self.agents[agent.name] = agent
            if self.config.enable_logging:
                print(f"Registered agent: {agent.name}")
        
        def execute(self, input_data: Any, agent_name: str = None) -> Dict[str, Any]:
            """Execute the pattern with given input."""
            
            # Use workflow if no specific agent requested
            if agent_name is None:
                result = self.workflow.invoke({
                    "input": str(input_data),
                    "processed": "",
                    "output": "",
                    "metadata": {}
                })
                
                execution_record = {
                    "pattern": "Rag",
                    "input": input_data,
                    "output": result.get("output", ""),
                    "metadata": result.get("metadata", {}),
                    "timestamp": datetime.now()
                }
                
                self.execution_log.append(execution_record)
                return execution_record
            
            # Execute with specific agent
            agent = self.agents.get(agent_name)
            if not agent:
                raise ValueError(f"Agent {agent_name} not found")
            
            result = agent.process(input_data)
            self.execution_log.append(result)
            return result
        
        def run(self, input_data: Any) -> Dict[str, Any]:
            """Main execution method."""
            return self.execute(input_data)
        
        def get_statistics(self) -> Dict[str, Any]:
            """Get pattern statistics."""
            return {
                "pattern": "Rag",
                "total_executions": len(self.execution_log),
                "registered_agents": len(self.agents),
                "agents": [agent.get_statistics() for agent in self.agents.values()]
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Rag Demo ===\n")
        
        # Create configuration
        config = RagConfig(
            model_name="gpt-4",
            temperature=0.7,
            enable_logging=True
        )
        
        # Create pattern
        pattern = RagPattern(config)
        
        # Create and register agents
        agent1 = RagAgent("Agent1", config)
        agent2 = RagAgent("Agent2", config)
        pattern.register_agent(agent1)
        pattern.register_agent(agent2)
        
        print("\nExecuting pattern workflow...")
        
        # Execute with workflow
        result1 = pattern.run("Demonstrate rag functionality")
        print(f"\nWorkflow Result:")
        print(f"  Output: {result1['output'][:150]}...")
        
        # Execute with specific agents
        result2 = pattern.execute("Specific task for Agent1", agent_name="Agent1")
        print(f"\nAgent1 Result:")
        print(f"  Output: {result2['output'][:150]}...")
        
        result3 = pattern.execute("Specific task for Agent2", agent_name="Agent2")
        print(f"\nAgent2 Result:")
        print(f"  Output: {result3['output'][:150]}...")
        
        # Show statistics
        print("\n=== Statistics ===")
        stats = pattern.get_statistics()
        print(f"Pattern: {stats['pattern']}")
        print(f"Total Executions: {stats['total_executions']}")
        print(f"Registered Agents: {stats['registered_agents']}")
        print(f"\nAgent Statistics:")
        for agent_stats in stats['agents']:
            print(f"  {agent_stats['name']}: {agent_stats['total_executions']} executions")
    
        

    Agentic Architecture Pattern: Rag

    Pattern 70: 70 Rag – Line-by-Line Explanation

    Overview

    Pattern 70: Rag

    Purpose: Enhanced implementation with full LangChain/LangGraph integration


    Code Structure Analysis

    File Information

    • Pattern Number: 70
    • Pattern Name: 70 Rag
    • File Path: patterns\memory_knowledge\70_rag.py
    • Total Lines: 247

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 70: Rag
    
    Purpose: Enhanced implementation with full LangChain/LangGraph integration
    """
    

    Explanation: This module docstring describes the purpose and key features of the 70 Rag 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
    from langgraph.graph import StateGraph, END
    from typing_extensions import TypedDict  # 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 – from langgraph.graph import StateGraph, END: LangGraph for workflow orchestration – from typing_extensions import TypedDict: Type hints for better code documentation


    Classes

    RagConfig (Line 18)

    Description: Configuration for Rag.

    RagState (Line 27)

    Description: State information for Rag.

    RagAgent (Line 36)

    Description: Agent implementing Rag.

    Methods:

    __init__ (Line 39)
    def __init__(self, name, config):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – name: Identifier or label – config: Configuration settings

    process (Line 49)
    def process(self, input_data):
        """Process input according to Rag."""
    

    Purpose: Process input according to Rag.

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

    get_statistics (Line 75)
    def get_statistics(self):
        """Get agent statistics."""
    

    Purpose: Get agent statistics.

    Parameters: – self: Instance reference

    RagPattern (Line 85)

    Description: Rag – Enhanced implementation

    This pattern provides comprehensive functionality for rag with full LangChain/LangGraph integration.

    Features: – Multi-agent coordination – State management – Execution tracking – LangGraph workflow integration

    Methods:

    __init__ (Line 99)
    def __init__(self, config):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference – config: Configuration settings

    _build_workflow (Line 105)
    def _build_workflow(self):
        """Build LangGraph workflow for pattern execution."""
    

    Purpose: Build LangGraph workflow for pattern execution.

    Parameters: – self: Instance reference

    register_agent (Line 150)
    def register_agent(self, agent):
        """Register an agent with the pattern."""
    

    Purpose: Register an agent with the pattern.

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

    execute (Line 156)
    def execute(self, input_data, agent_name):
        """Execute the pattern with given input."""
    

    Purpose: Execute the pattern with given input.

    Parameters: – self: Instance reference – input_data: Parameter for input_data – agent_name: Parameter for agent_name

    run (Line 188)
    def run(self, input_data):
        """Main execution method."""
    

    Purpose: Main execution method.

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

    get_statistics (Line 192)
    def get_statistics(self):
        """Get pattern statistics."""
    

    Purpose: Get pattern statistics.

    Parameters: – self: Instance reference

    WorkflowState (Line 108)

    Description: No class docstring.


    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 = RagConfig(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

  • Agentic Architecture Pattern: Vector Store

    
        """
    Pattern 69: Vector Store Pattern
    
    Agents store and retrieve information using vector embeddings and similarity search.
    Enables semantic search: finding similar content based on meaning, not just keywords.
    """
    
    from typing import Dict, Any, List, Optional, Tuple
    from dataclasses import dataclass, field
    from datetime import datetime
    import numpy as np
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI, OpenAIEmbeddings
    from langchain_community.vectorstores import FAISS
    from langchain_core.documents import Document
    
    
    @dataclass
    class VectorDocument:
        """Document with vector embedding."""
        doc_id: str
        content: str
        metadata: Dict[str, Any] = field(default_factory=dict)
        embedding: Optional[List[float]] = None
        created_at: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class SearchResult:
        """Result from vector similarity search."""
        document: VectorDocument
        similarity_score: float
        rank: int
    
    
    class VectorStore:
        """Vector storage with similarity search."""
        
        def __init__(self, embedding_model: str = "text-embedding-ada-002"):
            self.embeddings = OpenAIEmbeddings(model=embedding_model)
            self.documents: Dict[str, VectorDocument] = {}
            self.vector_store: Optional[FAISS] = None
            self.doc_id_to_index: Dict[str, int] = {}
        
        def add_document(self, doc: VectorDocument):
            """Add document to vector store."""
            self.documents[doc.doc_id] = doc
            
            # Create LangChain document
            lc_doc = Document(
                page_content=doc.content,
                metadata={**doc.metadata, "doc_id": doc.doc_id}
            )
            
            # Add to vector store
            if self.vector_store is None:
                self.vector_store = FAISS.from_documents([lc_doc], self.embeddings)
                self.doc_id_to_index[doc.doc_id] = 0
            else:
                # Add to existing store
                new_store = FAISS.from_documents([lc_doc], self.embeddings)
                self.vector_store.merge_from(new_store)
                self.doc_id_to_index[doc.doc_id] = len(self.doc_id_to_index)
        
        def add_documents_batch(self, docs: List[VectorDocument]):
            """Add multiple documents efficiently."""
            for doc in docs:
                self.documents[doc.doc_id] = doc
            
            # Create LangChain documents
            lc_docs = [
                Document(
                    page_content=doc.content,
                    metadata={**doc.metadata, "doc_id": doc.doc_id}
                )
                for doc in docs
            ]
            
            # Create or merge vector store
            if self.vector_store is None:
                self.vector_store = FAISS.from_documents(lc_docs, self.embeddings)
                for i, doc in enumerate(docs):
                    self.doc_id_to_index[doc.doc_id] = i
            else:
                new_store = FAISS.from_documents(lc_docs, self.embeddings)
                self.vector_store.merge_from(new_store)
                start_idx = len(self.doc_id_to_index)
                for i, doc in enumerate(docs):
                    self.doc_id_to_index[doc.doc_id] = start_idx + i
        
        def similarity_search(self, query: str, k: int = 5) -> List[SearchResult]:
            """Search for similar documents."""
            if self.vector_store is None:
                return []
            
            # Perform similarity search
            results = self.vector_store.similarity_search_with_score(query, k=k)
            
            search_results = []
            for rank, (doc, score) in enumerate(results):
                doc_id = doc.metadata.get("doc_id", "")
                if doc_id in self.documents:
                    search_results.append(SearchResult(
                        document=self.documents[doc_id],
                        similarity_score=1.0 / (1.0 + score),  # Convert distance to similarity
                        rank=rank + 1
                    ))
            
            return search_results
        
        def get_document(self, doc_id: str) -> Optional[VectorDocument]:
            """Get document by ID."""
            return self.documents.get(doc_id)
    
    
    class VectorStoreAgent:
        """Agent with vector store for semantic search."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.7)
            self.vector_store = VectorStore()
            self.search_history: List[Tuple[str, List[SearchResult]]] = []
        
        def store_information(self, doc_id: str, content: str, metadata: Optional[Dict[str, Any]] = None):
            """Store information in vector store."""
            doc = VectorDocument(
                doc_id=doc_id,
                content=content,
                metadata=metadata or {}
            )
            self.vector_store.add_document(doc)
            print(f"   šŸ“¦ {self.name} stored: {doc_id} ({len(content)} chars)")
        
        def store_batch(self, documents: List[Tuple[str, str, Optional[Dict[str, Any]]]]):
            """Store multiple documents at once."""
            docs = [
                VectorDocument(doc_id=doc_id, content=content, metadata=metadata or {})
                for doc_id, content, metadata in documents
            ]
            self.vector_store.add_documents_batch(docs)
            print(f"   šŸ“¦ {self.name} stored {len(docs)} documents in batch")
        
        def search(self, query: str, k: int = 3) -> List[SearchResult]:
            """Search for similar content."""
            results = self.vector_store.similarity_search(query, k=k)
            self.search_history.append((query, results))
            
            print(f"   šŸ” {self.name} searched: '{query}' -> {len(results)} results")
            return results
        
        def answer_with_context(self, question: str, k: int = 3) -> str:
            """Answer question using retrieved context."""
            # Search for relevant documents
            results = self.search(question, k=k)
            
            if not results:
                return f"I don't have information to answer: {question}"
            
            # Build context from search results
            context = "\n\n".join([
                f"[{r.rank}] (similarity: {r.similarity_score:.2f})\n{r.document.content}"
                for r in results
            ])
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name}. Answer questions based on the provided context."),
                ("human", f"Context from my knowledge base:\n{context}\n\n"
                         f"Question: {question}\n\n"
                         f"Answer based on the context above. If the context doesn't contain "
                         f"relevant information, say so. Keep answer concise (2-3 sentences).")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({})
            
            return str(response.content)[:400]
    
    
    class VectorStorePattern:
        """
        Vector Store Pattern - Semantic search with embeddings.
        
        Agents store information as vector embeddings and retrieve similar
        content based on semantic meaning rather than keyword matching.
        """
        
        def __init__(self):
            self.agents: Dict[str, VectorStoreAgent] = {}
        
        def register_agent(self, agent: VectorStoreAgent):
            """Register agent with vector store."""
            self.agents[agent.name] = agent
        
        def run(self, scenario: str) -> Dict[str, Any]:
            """Execute vector store pattern."""
            total_docs = sum(len(agent.vector_store.documents) for agent in self.agents.values())
            total_searches = sum(len(agent.search_history) for agent in self.agents.values())
            
            return {
                "pattern": "VectorStore",
                "scenario": scenario,
                "total_agents": len(self.agents),
                "total_documents": total_docs,
                "total_searches": total_searches
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Vector Store Pattern Demo ===\n")
        
        # Create pattern
        pattern = VectorStorePattern()
        
        # Create agent with vector store
        print("1. Creating agent with vector store...")
        agent = VectorStoreAgent("Librarian")
        pattern.register_agent(agent)
        
        # Store documents
        print("\n2. Storing documents in vector store...")
        
        documents = [
            ("doc1", "Machine learning is a subset of artificial intelligence that enables "
                    "computers to learn from data without explicit programming.",
             {"category": "AI", "difficulty": "beginner"}),
            
            ("doc2", "Neural networks are computing systems inspired by biological neural networks. "
                    "They consist of layers of interconnected nodes that process information.",
             {"category": "AI", "difficulty": "intermediate"}),
            
            ("doc3", "Natural language processing (NLP) is a field of AI that focuses on enabling "
                    "computers to understand, interpret, and generate human language.",
             {"category": "AI", "difficulty": "intermediate"}),
            
            ("doc4", "Deep learning uses neural networks with multiple layers to learn hierarchical "
                    "representations of data, achieving state-of-the-art results in many domains.",
             {"category": "AI", "difficulty": "advanced"}),
            
            ("doc5", "Reinforcement learning is a type of machine learning where agents learn to make "
                    "decisions by interacting with an environment and receiving rewards or penalties.",
             {"category": "AI", "difficulty": "advanced"}),
            
            ("doc6", "Computer vision enables machines to interpret and understand visual information "
                    "from the world, including image recognition and object detection.",
             {"category": "AI", "difficulty": "intermediate"}),
        ]
        
        agent.store_batch(documents)
        
        # Semantic similarity search
        print("\n3. Performing semantic similarity searches...")
        
        queries = [
            "How do computers learn?",
            "What are artificial brains?",
            "Understanding human language with AI",
            "Learning through trial and error"
        ]
        
        for query in queries:
            print(f"\n   Query: '{query}'")
            results = agent.search(query, k=2)
            for result in results:
                print(f"   [{result.rank}] Similarity: {result.similarity_score:.3f}")
                print(f"       {result.document.content[:80]}...")
                print(f"       Category: {result.document.metadata.get('category')}, "
                      f"Difficulty: {result.document.metadata.get('difficulty')}")
        
        # Question answering with context
        print("\n4. Answering questions using retrieved context...")
        
        questions = [
            "What is machine learning?",
            "How do neural networks work?",
            "What's the difference between deep learning and machine learning?",
            "What can computer vision do?"
        ]
        
        for question in questions:
            print(f"\n   Q: {question}")
            answer = agent.answer_with_context(question, k=3)
            print(f"   A: {answer}")
        
        # Statistics
        print("\n5. Vector Store Statistics:")
        summary = pattern.run("AI Knowledge Base")
        print(f"   Total Documents: {summary['total_documents']}")
        print(f"   Total Searches: {summary['total_searches']}")
        
        # Search history analysis
        print("\n6. Search History:")
        for i, (query, results) in enumerate(agent.search_history[:3], 1):
            print(f"   {i}. '{query}' -> {len(results)} results")
            if results:
                best = results[0]
                print(f"      Best match: {best.document.doc_id} (similarity: {best.similarity_score:.3f})")
        
        print("\nāœ“ Vector store pattern enabled semantic search!")
    
        

    Agentic Architecture Pattern: Vector Store

    Pattern 69: 69 Vector Store – Line-by-Line Explanation

    Overview

    Pattern 69: Vector Store Pattern

    Agents store and retrieve information using vector embeddings and similarity search. Enables semantic search: finding similar content based on meaning, not just keywords.


    Code Structure Analysis

    File Information

    • Pattern Number: 69
    • Pattern Name: 69 Vector Store
    • File Path: patterns\memory_knowledge\69_vector_store.py
    • Total Lines: 301

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 69: Vector Store Pattern
    
    Agents store and retrieve information using vector embeddings and similarity search.
    Enables semantic search: finding similar content based on meaning, not just keywords.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 69 Vector Store pattern.


    Imports Section

    from typing import Dict, Any, List, Optional, Tuple
    from dataclasses import dataclass, field
    from datetime import datetime
    import numpy as np
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_openai import ChatOpenAI, OpenAIEmbeddings
    from langchain_community.vectorstores import FAISS
    from langchain_core.documents import Document  # First 20 imports shown
    

    Explanation: The module imports necessary dependencies: – from typing import Dict, Any, List, Optional, Tuple: 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, OpenAIEmbeddings: LangChain framework integration – from langchain_community.vectorstores import FAISS: LangChain framework integration – from langchain_core.documents import Document: LangChain framework integration


    Classes

    VectorDocument (Line 19)

    Description: Document with vector embedding.

    SearchResult (Line 29)

    Description: Result from vector similarity search.

    VectorStore (Line 36)

    Description: Vector storage with similarity search.

    Methods:

    __init__ (Line 39)
    def __init__(self, embedding_model):
        """No method docstring."""
    

    Purpose: No method docstring.

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

    add_document (Line 45)
    def add_document(self, doc):
        """Add document to vector store."""
    

    Purpose: Add document to vector store.

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

    add_documents_batch (Line 65)
    def add_documents_batch(self, docs):
        """Add multiple documents efficiently."""
    

    Purpose: Add multiple documents efficiently.

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

    similarity_search (Line 91)
    def similarity_search(self, query, k):
        """Search for similar documents."""
    

    Purpose: Search for similar documents.

    Parameters: – self: Instance reference – query: Parameter for query – k: Parameter for k

    get_document (Line 111)
    def get_document(self, doc_id):
        """Get document by ID."""
    

    Purpose: Get document by ID.

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

    VectorStoreAgent (Line 116)

    Description: Agent with vector store for semantic search.

    Methods:

    __init__ (Line 119)
    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”)

    store_information (Line 125)
    def store_information(self, doc_id, content, metadata):
        """Store information in vector store."""
    

    Purpose: Store information in vector store.

    Parameters: – self: Instance reference – doc_id: Parameter for doc_id – content: Parameter for content – metadata: Parameter for metadata

    store_batch (Line 135)
    def store_batch(self, documents):
        """Store multiple documents at once."""
    

    Purpose: Store multiple documents at once.

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

    search (Line 144)
    def search(self, query, k):
        """Search for similar content."""
    

    Purpose: Search for similar content.

    Parameters: – self: Instance reference – query: Parameter for query – k: Parameter for k

    answer_with_context (Line 152)
    def answer_with_context(self, question, k):
        """Answer question using retrieved context."""
    

    Purpose: Answer question using retrieved context.

    Parameters: – self: Instance reference – question: Parameter for question – k: Parameter for k

    VectorStorePattern (Line 180)

    Description: Vector Store Pattern – Semantic search with embeddings.

    Agents store information as vector embeddings and retrieve similar content based on semantic meaning rather than keyword matching.

    Methods:

    __init__ (Line 188)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 191)
    def register_agent(self, agent):
        """Register agent with vector store."""
    

    Purpose: Register agent with vector store.

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

    run (Line 195)
    def run(self, scenario):
        """Execute vector store pattern."""
    

    Purpose: Execute vector store pattern.

    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 = VectorDocument(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

  • Agentic Architecture Pattern: Graph Based Knowledge

    
        """
    Pattern 68: Graph-Based Knowledge Pattern
    
    Agents store knowledge as a graph with nodes (entities) and edges (relationships).
    Enables path finding, traversal, and graph-based reasoning.
    """
    
    from typing import Dict, Any, List, Optional, Set, Tuple
    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 NodeType(Enum):
        """Type of knowledge graph node."""
        ENTITY = "entity"
        CONCEPT = "concept"
        EVENT = "event"
        ATTRIBUTE = "attribute"
    
    
    @dataclass
    class GraphNode:
        """Node in knowledge graph."""
        node_id: str
        node_type: NodeType
        label: str
        properties: Dict[str, Any] = field(default_factory=dict)
        created_at: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class GraphEdge:
        """Edge in knowledge graph."""
        edge_id: str
        source_id: str
        target_id: str
        relationship: str
        weight: float = 1.0
        properties: Dict[str, Any] = field(default_factory=dict)
        created_at: datetime = field(default_factory=datetime.now)
    
    
    @dataclass
    class GraphPath:
        """Path through knowledge graph."""
        nodes: List[str]
        edges: List[str]
        total_weight: float
        path_length: int
    
    
    class KnowledgeGraph:
        """Graph-based knowledge storage with traversal."""
        
        def __init__(self):
            self.nodes: Dict[str, GraphNode] = {}
            self.edges: Dict[str, GraphEdge] = {}
            self.adjacency: Dict[str, Set[str]] = {}  # node_id -> {edge_ids}
        
        def add_node(self, node: GraphNode):
            """Add node to graph."""
            self.nodes[node.node_id] = node
            if node.node_id not in self.adjacency:
                self.adjacency[node.node_id] = set()
        
        def add_edge(self, edge: GraphEdge):
            """Add edge to graph."""
            self.edges[edge.edge_id] = edge
            
            # Update adjacency
            if edge.source_id not in self.adjacency:
                self.adjacency[edge.source_id] = set()
            self.adjacency[edge.source_id].add(edge.edge_id)
        
        def get_neighbors(self, node_id: str) -> List[Tuple[GraphNode, GraphEdge]]:
            """Get neighboring nodes and connecting edges."""
            neighbors = []
            
            if node_id not in self.adjacency:
                return neighbors
            
            for edge_id in self.adjacency[node_id]:
                edge = self.edges.get(edge_id)
                if edge:
                    target_node = self.nodes.get(edge.target_id)
                    if target_node:
                        neighbors.append((target_node, edge))
            
            return neighbors
        
        def find_path(self, start_id: str, end_id: str, 
                      max_depth: int = 5) -> Optional[GraphPath]:
            """Find path between two nodes using BFS."""
            if start_id not in self.nodes or end_id not in self.nodes:
                return None
            
            # BFS
            queue = [(start_id, [start_id], [], 0.0)]
            visited = {start_id}
            
            while queue:
                current_id, path_nodes, path_edges, total_weight = queue.pop(0)
                
                if current_id == end_id:
                    return GraphPath(
                        nodes=path_nodes,
                        edges=path_edges,
                        total_weight=total_weight,
                        path_length=len(path_nodes) - 1
                    )
                
                if len(path_nodes) >= max_depth:
                    continue
                
                # Explore neighbors
                for neighbor, edge in self.get_neighbors(current_id):
                    if neighbor.node_id not in visited:
                        visited.add(neighbor.node_id)
                        queue.append((
                            neighbor.node_id,
                            path_nodes + [neighbor.node_id],
                            path_edges + [edge.edge_id],
                            total_weight + edge.weight
                        ))
            
            return None
        
        def find_nodes_by_type(self, node_type: NodeType) -> List[GraphNode]:
            """Find all nodes of a specific type."""
            return [node for node in self.nodes.values() 
                    if node.node_type == node_type]
        
        def find_related(self, node_id: str, relationship: str) -> List[GraphNode]:
            """Find nodes related by specific relationship."""
            related = []
            
            if node_id not in self.adjacency:
                return related
            
            for edge_id in self.adjacency[node_id]:
                edge = self.edges.get(edge_id)
                if edge and edge.relationship == relationship:
                    target = self.nodes.get(edge.target_id)
                    if target:
                        related.append(target)
            
            return related
        
        def get_subgraph(self, node_id: str, depth: int = 2) -> Tuple[Set[str], Set[str]]:
            """Get subgraph around a node."""
            nodes = {node_id}
            edges = set()
            
            queue = [(node_id, 0)]
            visited = {node_id}
            
            while queue:
                current_id, current_depth = queue.pop(0)
                
                if current_depth >= depth:
                    continue
                
                for neighbor, edge in self.get_neighbors(current_id):
                    edges.add(edge.edge_id)
                    if neighbor.node_id not in visited:
                        visited.add(neighbor.node_id)
                        nodes.add(neighbor.node_id)
                        queue.append((neighbor.node_id, current_depth + 1))
            
            return nodes, edges
    
    
    class GraphKnowledgeAgent:
        """Agent with graph-based knowledge representation."""
        
        def __init__(self, name: str, model_name: str = "gpt-4"):
            self.name = name
            self.llm = ChatOpenAI(model=model_name, temperature=0.3)
            self.graph = KnowledgeGraph()
        
        def learn_entity(self, entity_id: str, label: str, 
                         properties: Optional[Dict[str, Any]] = None):
            """Learn about an entity."""
            node = GraphNode(
                node_id=entity_id,
                node_type=NodeType.ENTITY,
                label=label,
                properties=properties or {}
            )
            self.graph.add_node(node)
            print(f"   šŸ”· {self.name} learned entity: {label}")
        
        def learn_relationship(self, source_id: str, target_id: str, 
                              relationship: str, weight: float = 1.0):
            """Learn a relationship between entities."""
            edge_id = f"{source_id}_{relationship}_{target_id}"
            edge = GraphEdge(
                edge_id=edge_id,
                source_id=source_id,
                target_id=target_id,
                relationship=relationship,
                weight=weight
            )
            self.graph.add_edge(edge)
            print(f"   šŸ”— {self.name} learned: {source_id} --{relationship}-> {target_id}")
        
        def query_relationship(self, entity_id: str, relationship: str) -> str:
            """Query relationships from an entity."""
            related = self.graph.find_related(entity_id, relationship)
            
            if not related:
                return f"No {relationship} relationships found for {entity_id}."
            
            entity = self.graph.nodes.get(entity_id)
            entity_label = entity.label if entity else entity_id
            
            related_labels = [node.label for node in related]
            
            prompt = ChatPromptTemplate.from_messages([
                ("system", f"You are {self.name} with graph-based knowledge."),
                ("human", f"Entity: {entity_label}\n"
                         f"Relationship: {relationship}\n"
                         f"Related entities: {', '.join(related_labels)}\n\n"
                         f"Provide a natural language summary of this relationship. (1-2 sentences)")
            ])
            
            chain = prompt | self.llm
            response = chain.invoke({})
            
            return str(response.content)[:200]
        
        def find_connection(self, entity1_id: str, entity2_id: str) -> str:
            """Find how two entities are connected."""
            path = self.graph.find_path(entity1_id, entity2_id)
            
            if not path:
                return f"No connection found between {entity1_id} and {entity2_id}."
            
            # Build path description
            path_desc = []
            for i in range(len(path.nodes) - 1):
                node1 = self.graph.nodes.get(path.nodes[i])
                node2 = self.graph.nodes.get(path.nodes[i + 1])
                edge = self.graph.edges.get(path.edges[i])
                
                if node1 and node2 and edge:
                    path_desc.append(f"{node1.label} --{edge.relationship}-> {node2.label}")
            
            return f"Path: {' → '.join(path_desc)} (length: {path.path_length}, weight: {path.total_weight:.1f})"
    
    
    class GraphBasedKnowledgePattern:
        """
        Graph-Based Knowledge Pattern - Knowledge as graph structures.
        
        Agents represent knowledge as nodes and edges, enabling graph
        traversal, path finding, and relationship-based reasoning.
        """
        
        def __init__(self):
            self.agents: Dict[str, GraphKnowledgeAgent] = {}
        
        def register_agent(self, agent: GraphKnowledgeAgent):
            """Register agent with graph knowledge."""
            self.agents[agent.name] = agent
        
        def run(self, domain: str) -> Dict[str, Any]:
            """Execute graph knowledge pattern."""
            total_nodes = sum(len(agent.graph.nodes) for agent in self.agents.values())
            total_edges = sum(len(agent.graph.edges) for agent in self.agents.values())
            
            return {
                "pattern": "GraphBasedKnowledge",
                "domain": domain,
                "total_agents": len(self.agents),
                "total_nodes": total_nodes,
                "total_edges": total_edges
            }
    
    
    # Example usage
    if __name__ == "__main__":
        print("=== Graph-Based Knowledge Pattern Demo ===\n")
        
        # Create pattern
        pattern = GraphBasedKnowledgePattern()
        
        # Create agent with graph knowledge
        print("1. Creating agent with graph knowledge...")
        agent = GraphKnowledgeAgent("Scholar")
        pattern.register_agent(agent)
        
        # Build knowledge graph about a company
        print("\n2. Building knowledge graph...")
        
        # Entities
        agent.learn_entity("company", "TechCorp", {"type": "company", "founded": 2010})
        agent.learn_entity("ceo", "Alice Johnson", {"role": "CEO"})
        agent.learn_entity("cto", "Bob Smith", {"role": "CTO"})
        agent.learn_entity("product1", "CloudApp", {"category": "SaaS"})
        agent.learn_entity("product2", "DataPlatform", {"category": "Analytics"})
        agent.learn_entity("customer1", "Acme Corp", {"type": "enterprise"})
        agent.learn_entity("tech1", "Python", {"type": "language"})
        agent.learn_entity("tech2", "Kubernetes", {"type": "platform"})
        
        # Relationships
        print("\n3. Adding relationships...")
        agent.learn_relationship("ceo", "company", "leads", 1.0)
        agent.learn_relationship("cto", "company", "works_for", 1.0)
        agent.learn_relationship("cto", "ceo", "reports_to", 1.0)
        agent.learn_relationship("company", "product1", "develops", 1.0)
        agent.learn_relationship("company", "product2", "develops", 1.0)
        agent.learn_relationship("customer1", "product1", "uses", 1.0)
        agent.learn_relationship("product1", "tech1", "built_with", 1.0)
        agent.learn_relationship("product2", "tech1", "built_with", 1.0)
        agent.learn_relationship("product2", "tech2", "deployed_on", 1.0)
        
        # Query relationships
        print("\n4. Querying relationships...")
        summary = agent.query_relationship("company", "develops")
        print(f"   {summary}")
        
        summary = agent.query_relationship("product1", "built_with")
        print(f"   {summary}")
        
        # Find connections
        print("\n5. Finding connections between entities...")
        connections = [
            ("customer1", "tech1"),
            ("cto", "customer1"),
            ("tech2", "ceo")
        ]
        
        for entity1, entity2 in connections:
            print(f"\n   Connection: {entity1}  {entity2}")
            result = agent.find_connection(entity1, entity2)
            print(f"   {result}")
        
        # Explore subgraph
        print("\n6. Exploring subgraph around 'company'...")
        nodes, edges = agent.graph.get_subgraph("company", depth=2)
        print(f"   Nodes in subgraph: {len(nodes)}")
        print(f"   Edges in subgraph: {len(edges)}")
        
        node_labels = [agent.graph.nodes[nid].label for nid in nodes if nid in agent.graph.nodes]
        print(f"   Entities: {', '.join(node_labels)}")
        
        # Find by type
        print("\n7. Finding entities by type...")
        entities = agent.graph.find_nodes_by_type(NodeType.ENTITY)
        print(f"   Total entities: {len(entities)}")
        for entity in entities[:5]:
            print(f"   - {entity.label} ({entity.properties.get('type', 'N/A')})")
        
        # Statistics
        print("\n8. Graph Statistics:")
        summary = pattern.run("Company Knowledge")
        print(f"   Total Nodes: {summary['total_nodes']}")
        print(f"   Total Edges: {summary['total_edges']}")
        print(f"   Avg connections per node: {summary['total_edges'] / max(1, summary['total_nodes']):.1f}")
        
        # Analyze graph structure
        print("\n9. Graph Structure Analysis:")
        node_degrees = {}
        for node_id in agent.graph.nodes:
            degree = len(agent.graph.adjacency.get(node_id, set()))
            node_degrees[node_id] = degree
        
        if node_degrees:
            max_degree = max(node_degrees.values())
            central_nodes = [nid for nid, deg in node_degrees.items() if deg == max_degree]
            print(f"   Max node degree: {max_degree}")
            print(f"   Most connected: {[agent.graph.nodes[nid].label for nid in central_nodes]}")
        
        print("\nāœ“ Graph-based knowledge pattern enabled relationship reasoning!")
    
        

    Agentic Architecture Pattern: Graph Based Knowledge

    Pattern 68: 68 Graph Based Knowledge – Line-by-Line Explanation

    Overview

    Pattern 68: Graph-Based Knowledge Pattern

    Agents store knowledge as a graph with nodes (entities) and edges (relationships). Enables path finding, traversal, and graph-based reasoning.


    Code Structure Analysis

    File Information

    • Pattern Number: 68
    • Pattern Name: 68 Graph Based Knowledge
    • File Path: patterns\memory_knowledge\68_graph_based_knowledge.py
    • Total Lines: 379

    Detailed Code Explanation

    Module Docstring

    """
    Pattern 68: Graph-Based Knowledge Pattern
    
    Agents store knowledge as a graph with nodes (entities) and edges (relationships).
    Enables path finding, traversal, and graph-based reasoning.
    """
    

    Explanation: This module docstring describes the purpose and key features of the 68 Graph Based Knowledge pattern.


    Imports Section

    from typing import Dict, Any, List, Optional, Set, Tuple
    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, Tuple: 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

    NodeType (Line 16)

    class NodeType(Enum):
        ENTITY
        CONCEPT
        EVENT
        ATTRIBUTE
    

    Purpose: Type of knowledge graph node.

    Values: – ENTITY: Represents entity – CONCEPT: Represents concept – EVENT: Represents event – ATTRIBUTE: Represents attribute


    Classes

    NodeType (Line 16)

    Description: Type of knowledge graph node.

    GraphNode (Line 25)

    Description: Node in knowledge graph.

    GraphEdge (Line 35)

    Description: Edge in knowledge graph.

    GraphPath (Line 47)

    Description: Path through knowledge graph.

    KnowledgeGraph (Line 55)

    Description: Graph-based knowledge storage with traversal.

    Methods:

    __init__ (Line 58)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    add_node (Line 63)
    def add_node(self, node):
        """Add node to graph."""
    

    Purpose: Add node to graph.

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

    add_edge (Line 69)
    def add_edge(self, edge):
        """Add edge to graph."""
    

    Purpose: Add edge to graph.

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

    get_neighbors (Line 78)
    def get_neighbors(self, node_id):
        """Get neighboring nodes and connecting edges."""
    

    Purpose: Get neighboring nodes and connecting edges.

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

    find_path (Line 94)
    def find_path(self, start_id, end_id, max_depth):
        """Find path between two nodes using BFS."""
    

    Purpose: Find path between two nodes using BFS.

    Parameters: – self: Instance reference – start_id: Parameter for start_id – end_id: Parameter for end_id – max_depth: Parameter for max_depth

    find_nodes_by_type (Line 131)
    def find_nodes_by_type(self, node_type):
        """Find all nodes of a specific type."""
    

    Purpose: Find all nodes of a specific type.

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

    find_related (Line 136)
    def find_related(self, node_id, relationship):
        """Find nodes related by specific relationship."""
    

    Purpose: Find nodes related by specific relationship.

    Parameters: – self: Instance reference – node_id: Parameter for node_id – relationship: Parameter for relationship

    get_subgraph (Line 152)
    def get_subgraph(self, node_id, depth):
        """Get subgraph around a node."""
    

    Purpose: Get subgraph around a node.

    Parameters: – self: Instance reference – node_id: Parameter for node_id – depth: Parameter for depth

    GraphKnowledgeAgent (Line 176)

    Description: Agent with graph-based knowledge representation.

    Methods:

    __init__ (Line 179)
    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”)

    learn_entity (Line 184)
    def learn_entity(self, entity_id, label, properties):
        """Learn about an entity."""
    

    Purpose: Learn about an entity.

    Parameters: – self: Instance reference – entity_id: Parameter for entity_id – label: Parameter for label – properties: Parameter for properties

    learn_relationship (Line 196)
    def learn_relationship(self, source_id, target_id, relationship, weight):
        """Learn a relationship between entities."""
    

    Purpose: Learn a relationship between entities.

    Parameters: – self: Instance reference – source_id: Parameter for source_id – target_id: Parameter for target_id – relationship: Parameter for relationship – weight: Parameter for weight

    query_relationship (Line 210)
    def query_relationship(self, entity_id, relationship):
        """Query relationships from an entity."""
    

    Purpose: Query relationships from an entity.

    Parameters: – self: Instance reference – entity_id: Parameter for entity_id – relationship: Parameter for relationship

    find_connection (Line 235)
    def find_connection(self, entity1_id, entity2_id):
        """Find how two entities are connected."""
    

    Purpose: Find how two entities are connected.

    Parameters: – self: Instance reference – entity1_id: Parameter for entity1_id – entity2_id: Parameter for entity2_id

    GraphBasedKnowledgePattern (Line 255)

    Description: Graph-Based Knowledge Pattern – Knowledge as graph structures.

    Agents represent knowledge as nodes and edges, enabling graph traversal, path finding, and relationship-based reasoning.

    Methods:

    __init__ (Line 263)
    def __init__(self):
        """No method docstring."""
    

    Purpose: No method docstring.

    Parameters: – self: Instance reference

    register_agent (Line 266)
    def register_agent(self, agent):
        """Register agent with graph knowledge."""
    

    Purpose: Register agent with graph knowledge.

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

    run (Line 270)
    def run(self, domain):
        """Execute graph knowledge pattern."""
    

    Purpose: Execute graph knowledge pattern.

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


    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 = NodeType(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