Agentic Architecture Pattern: Commonsense Reasoning

Written by

in


    """
Pattern 205: Commonsense Reasoning Pattern

Applies everyday knowledge and intuitive understanding to reason about
situations. Handles implicit knowledge that humans take for granted.
"""

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


class KnowledgeType(Enum):
    """Types of commonsense knowledge."""
    PHYSICAL = "physical"  # Gravity, objects fall
    SOCIAL = "social"  # People have feelings
    TEMPORAL = "temporal"  # Time flows forward
    SPATIAL = "spatial"  # Objects have location
    CAUSAL = "causal"  # Actions have consequences
    FUNCTIONAL = "functional"  # Objects have purposes


@dataclass
class CommonsenseKnowledge:
    """Piece of commonsense knowledge."""
    statement: str
    knowledge_type: KnowledgeType
    confidence: float = 0.9
    source: str = "general"


@dataclass
class ReasoningQuery:
    """Query requiring commonsense reasoning."""
    question: str
    context: Dict[str, Any]
    requires_knowledge: List[KnowledgeType] = field(default_factory=list)


@dataclass
class CommonsenseAnswer:
    """Answer based on commonsense reasoning."""
    query: str
    answer: str
    reasoning: str
    knowledge_used: List[CommonsenseKnowledge]
    confidence: float


class CommonsenseKnowledgeBase:
    """Storage for commonsense knowledge."""
    
    def __init__(self):
        self.knowledge: List[CommonsenseKnowledge] = []
        self._populate_basic_knowledge()
    
    def _populate_basic_knowledge(self):
        """Populate with basic commonsense knowledge."""
        basic_knowledge = [
            CommonsenseKnowledge("Objects fall down due to gravity", KnowledgeType.PHYSICAL),
            CommonsenseKnowledge("People need food and water to survive", KnowledgeType.PHYSICAL),
            CommonsenseKnowledge("Time moves forward, not backward", KnowledgeType.TEMPORAL),
            CommonsenseKnowledge("People feel pain when hurt", KnowledgeType.SOCIAL),
            CommonsenseKnowledge("Tools are used to accomplish tasks", KnowledgeType.FUNCTIONAL),
            CommonsenseKnowledge("Actions have consequences", KnowledgeType.CAUSAL),
        ]
        self.knowledge.extend(basic_knowledge)
    
    def get_relevant_knowledge(self, knowledge_types: List[KnowledgeType]) -> List[CommonsenseKnowledge]:
        """Get knowledge relevant to types."""
        if not knowledge_types:
            return self.knowledge
        return [k for k in self.knowledge if k.knowledge_type in knowledge_types]
    
    def add_knowledge(self, knowledge: CommonsenseKnowledge):
        """Add new commonsense knowledge."""
        self.knowledge.append(knowledge)


class CommonsenseReasoningAgent:
    """Agent that applies commonsense reasoning."""
    
    def __init__(self, name: str, model_name: str = "gpt-4"):
        self.name = name
        self.llm = ChatOpenAI(model=model_name, temperature=0.5)
        self.knowledge_base = CommonsenseKnowledgeBase()
        self.answers: List[CommonsenseAnswer] = []
    
    def reason(self, query: ReasoningQuery) -> CommonsenseAnswer:
        """Apply commonsense reasoning to query."""
        print(f"\n  {self.name}: Reasoning about: {query.question[:60]}...")
        
        # Get relevant knowledge
        relevant_knowledge = self.knowledge_base.get_relevant_knowledge(
            query.requires_knowledge
        )
        
        knowledge_text = "\n".join([
            f"- {k.statement} ({k.knowledge_type.value})"
            for k in relevant_knowledge
        ])
        
        prompt = ChatPromptTemplate.from_messages([
            ("system", "You are applying commonsense reasoning. Use everyday knowledge "
                      "that people typically understand intuitively."),
            ("human", """Question: {question}

Context: {context}

Relevant Commonsense Knowledge:
{knowledge}

Provide:
1. A direct answer
2. Step-by-step reasoning showing commonsense logic
3. Confidence level (0.0-1.0)

Format:
ANSWER: 
REASONING: 
CONFIDENCE: """)
        ])
        
        chain = prompt | self.llm
        response = chain.invoke({
            "question": query.question,
            "context": str(query.context),
            "knowledge": knowledge_text
        })
        
        # Parse response
        answer_text = ""
        reasoning_text = ""
        confidence = 0.8
        
        for line in response.content.split("\n"):
            if line.startswith("ANSWER:"):
                answer_text = line.replace("ANSWER:", "").strip()
            elif line.startswith("REASONING:"):
                reasoning_text = line.replace("REASONING:", "").strip()
            elif line.startswith("CONFIDENCE:"):
                try:
                    confidence = float(line.replace("CONFIDENCE:", "").strip())
                except:
                    confidence = 0.8
        
        if not answer_text:
            answer_text = response.content[:200]
        if not reasoning_text:
            reasoning_text = "Applied commonsense reasoning"
        
        answer = CommonsenseAnswer(
            query=query.question,
            answer=answer_text,
            reasoning=reasoning_text,
            knowledge_used=relevant_knowledge,
            confidence=confidence
        )
        
        self.answers.append(answer)
        print(f"  Answer: {answer_text[:80]}...")
        print(f"  Confidence: {confidence}")
        
        return answer


class CommonsenseReasoningPattern:
    """
    Commonsense Reasoning Pattern - Apply everyday knowledge.
    
    Uses intuitive, everyday knowledge to reason about situations
    that require implicit understanding.
    """
    
    def __init__(self):
        self.agents: Dict[str, CommonsenseReasoningAgent] = {}
    
    def register_agent(self, agent: CommonsenseReasoningAgent):
        """Register commonsense reasoning agent."""
        self.agents[agent.name] = agent
    
    def run(self, queries: List[ReasoningQuery]) -> Dict[str, Any]:
        """Execute commonsense reasoning on queries."""
        print("=== Commonsense Reasoning Pattern ===\n")
        
        for agent in self.agents.values():
            print(f"{agent.name}: Processing {len(queries)} queries...")
            for query in queries:
                agent.reason(query)
        
        return {
            "pattern": "CommonsenseReasoning",
            "agents": len(self.agents),
            "queries_processed": len(queries),
            "total_answers": sum(len(a.answers) for a in self.agents.values())
        }


# Example usage
if __name__ == "__main__":
    print("=== Commonsense Reasoning Pattern Demo ===\n")
    
    # Create pattern and agent
    pattern = CommonsenseReasoningPattern()
    agent = CommonsenseReasoningAgent("CommonSenseBot")
    pattern.register_agent(agent)
    
    # Queries requiring commonsense
    print("1. Creating queries requiring commonsense reasoning...\n")
    queries = [
        ReasoningQuery(
            question="If I drop a glass on a hard floor, what will likely happen?",
            context={"object": "glass", "surface": "hard floor", "action": "drop"},
            requires_knowledge=[KnowledgeType.PHYSICAL, KnowledgeType.CAUSAL]
        ),
        ReasoningQuery(
            question="If someone hasn't eaten all day, what should I offer them?",
            context={"person": "hungry", "time_without_food": "all day"},
            requires_knowledge=[KnowledgeType.PHYSICAL, KnowledgeType.SOCIAL]
        ),
        ReasoningQuery(
            question="Why would someone use an umbrella on a rainy day?",
            context={"weather": "rainy", "object": "umbrella"},
            requires_knowledge=[KnowledgeType.FUNCTIONAL, KnowledgeType.PHYSICAL]
        ),
        ReasoningQuery(
            question="If I'm late for an important meeting, how should I communicate?",
            context={"situation": "late", "event": "important meeting"},
            requires_knowledge=[KnowledgeType.SOCIAL, KnowledgeType.TEMPORAL]
        ),
    ]
    
    # Run reasoning
    summary = pattern.run(queries)
    
    print(f"\n2. Summary:")
    print(f"   Queries processed: {summary['queries_processed']}")
    print(f"   Total answers: {summary['total_answers']}")
    
    print(f"\n3. Answers with Reasoning:")
    for i, answer in enumerate(agent.answers, 1):
        print(f"\n   Query {i}: {answer.query[:50]}...")
        print(f"   Answer: {answer.answer}")
        print(f"   Reasoning: {answer.reasoning[:100]}...")
        print(f"   Knowledge types used: {len(answer.knowledge_used)}")
    
    print("\nāœ“ Commonsense reasoning applied everyday knowledge!")

    

Agentic Architecture Pattern: Commonsense Reasoning

Pattern 205: 205 Commonsense Reasoning Pattern – Line-by-Line Explanation

Overview

Pattern 205: Commonsense Reasoning Pattern

Applies everyday knowledge and intuitive understanding to reason about situations. Handles implicit knowledge that humans take for granted.


Code Structure Analysis

File Information

  • Pattern Number: 205
  • Pattern Name: 205 Commonsense Reasoning Pattern
  • File Path: patterns\advanced_reasoning\205_commonsense_reasoning_pattern.py
  • Total Lines: 251

Detailed Code Explanation

Module Docstring

"""
Pattern 205: Commonsense Reasoning Pattern

Applies everyday knowledge and intuitive understanding to reason about
situations. Handles implicit knowledge that humans take for granted.
"""

Explanation: This module docstring describes the purpose and key features of the 205 Commonsense Reasoning Pattern pattern.


Imports Section

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

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


Enumerations

KnowledgeType (Line 16)

class KnowledgeType(Enum):
    PHYSICAL
    SOCIAL
    TEMPORAL
    SPATIAL
    CAUSAL
    FUNCTIONAL

Purpose: Types of commonsense knowledge.

Values: – PHYSICAL: Represents physical – SOCIAL: Represents social – TEMPORAL: Represents temporal – SPATIAL: Represents spatial – CAUSAL: Represents causal – FUNCTIONAL: Represents functional


Classes

KnowledgeType (Line 16)

Description: Types of commonsense knowledge.

CommonsenseKnowledge (Line 27)

Description: Piece of commonsense knowledge.

ReasoningQuery (Line 36)

Description: Query requiring commonsense reasoning.

CommonsenseAnswer (Line 44)

Description: Answer based on commonsense reasoning.

CommonsenseKnowledgeBase (Line 53)

Description: Storage for commonsense knowledge.

Methods:

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

Purpose: No method docstring.

Parameters: – self: Instance reference

_populate_basic_knowledge (Line 60)
def _populate_basic_knowledge(self):
    """Populate with basic commonsense knowledge."""

Purpose: Populate with basic commonsense knowledge.

Parameters: – self: Instance reference

get_relevant_knowledge (Line 72)
def get_relevant_knowledge(self, knowledge_types):
    """Get knowledge relevant to types."""

Purpose: Get knowledge relevant to types.

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

add_knowledge (Line 78)
def add_knowledge(self, knowledge):
    """Add new commonsense knowledge."""

Purpose: Add new commonsense knowledge.

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

CommonsenseReasoningAgent (Line 83)

Description: Agent that applies commonsense reasoning.

Methods:

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

reason (Line 92)
def reason(self, query):
    """Apply commonsense reasoning to query."""

Purpose: Apply commonsense reasoning to query.

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

CommonsenseReasoningPattern (Line 170)

Description: Commonsense Reasoning Pattern – Apply everyday knowledge.

Uses intuitive, everyday knowledge to reason about situations that require implicit understanding.

Methods:

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

Purpose: No method docstring.

Parameters: – self: Instance reference

register_agent (Line 181)
def register_agent(self, agent):
    """Register commonsense reasoning agent."""

Purpose: Register commonsense reasoning agent.

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

run (Line 185)
def run(self, queries):
    """Execute commonsense reasoning on queries."""

Purpose: Execute commonsense reasoning on queries.

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


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 = KnowledgeType(name="example", model_name="gpt-4")

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

# Check results
print(result)

Key Concepts

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

Extension Points

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

Comments

Leave a Reply

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