Agentic Design Pattern: Domain Expert

Written by

in


    """
Pattern 133: Domain Expert Agent

Description:
    The Domain Expert Agent pattern creates specialized agents with deep expertise
    in specific domains or fields. Unlike general-purpose agents, domain experts
    possess comprehensive knowledge, terminology, methodologies, and best practices
    specific to their area of specialization. They can provide expert-level advice,
    perform domain-specific reasoning, and apply specialized knowledge effectively.
    
    Domain expertise goes beyond simple knowledge retrieval - it includes understanding
    domain-specific workflows, recognizing patterns, applying heuristics, knowing
    what questions to ask, and understanding the nuances and edge cases within the
    domain. Expert agents can explain complex concepts using domain terminology,
    evaluate solutions using domain-specific criteria, and provide guidance that
    reflects years of accumulated expertise.
    
    This pattern is essential for applications requiring specialized knowledge such
    as medical diagnosis assistants, legal advisors, financial analysts, scientific
    research assistants, engineering consultants, and other professional AI systems.

Key Components:
    1. Domain Knowledge Base: Comprehensive domain-specific information
    2. Terminology Handler: Domain-specific vocabulary and jargon
    3. Best Practices Repository: Field-standard methodologies
    4. Case History: Examples and precedents from the domain
    5. Reasoning Engine: Domain-specific logic and heuristics
    6. Validation System: Domain-appropriate quality checks
    7. Reference System: Citations and sources

Domain Characteristics:
    1. Depth: Comprehensive coverage of specialized area
    2. Terminology: Field-specific vocabulary
    3. Methodology: Domain-standard approaches
    4. Context: Understanding of domain landscape
    5. Precedents: Historical cases and examples
    6. Standards: Industry regulations and best practices
    7. Boundaries: Knowing limits of expertise

Expert Behaviors:
    1. Ask clarifying questions
    2. Identify missing information
    3. Consider edge cases
    4. Reference standards and regulations
    5. Explain reasoning process
    6. Acknowledge uncertainty
    7. Provide multiple perspectives
    8. Use appropriate terminology

Use Cases:
    - Medical diagnosis assistants
    - Legal research and advisory
    - Financial analysis and planning
    - Engineering design consultation
    - Scientific research assistance
    - Tax preparation and planning
    - Architectural design
    - Software architecture advisory

Advantages:
    - Expert-level guidance
    - Domain-appropriate reasoning
    - Specialized knowledge application
    - Professional terminology usage
    - Best practice adherence
    - Quality assurance
    - Credible advice

Challenges:
    - Knowledge maintenance and updates
    - Handling edge cases
    - Avoiding overconfidence
    - Managing liability concerns
    - Balancing depth vs. accessibility
    - Keeping current with field changes
    - Regulatory compliance

LangChain Implementation:
    This implementation uses LangChain for:
    - Domain knowledge integration
    - Expert reasoning chains
    - Specialized RAG with domain documents
    - Domain-specific validation
    
Production Considerations:
    - Regularly update domain knowledge
    - Version control expert systems
    - Track expert vs. actual outcomes
    - Implement human expert review
    - Include disclaimers appropriately
    - Maintain audit trails
    - Ensure regulatory compliance
    - Support expert override mechanisms
"""

import os
from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from dotenv import load_dotenv

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI

load_dotenv()


class ExpertiseLevel(Enum):
    """Level of expertise."""
    NOVICE = "novice"
    INTERMEDIATE = "intermediate"
    ADVANCED = "advanced"
    EXPERT = "expert"
    MASTER = "master"


class ConfidenceLevel(Enum):
    """Confidence in response."""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    VERY_HIGH = "very_high"


@dataclass
class DomainKnowledge:
    """
    Domain-specific knowledge item.
    
    Attributes:
        topic: Knowledge area
        content: Information content
        source: Where knowledge came from
        reliability: How reliable (0-1)
        last_updated: When last verified
        tags: Categorization tags
    """
    topic: str
    content: str
    source: str = "expert_knowledge"
    reliability: float = 0.9
    last_updated: datetime = field(default_factory=datetime.now)
    tags: List[str] = field(default_factory=list)


@dataclass
class ExpertResponse:
    """
    Expert agent response.
    
    Attributes:
        answer: Main response
        confidence: Confidence level
        reasoning: Explanation of reasoning
        references: Supporting sources
        caveats: Important limitations or warnings
        follow_up_questions: Suggested clarifications
        alternatives: Alternative approaches
    """
    answer: str
    confidence: ConfidenceLevel
    reasoning: str = ""
    references: List[str] = field(default_factory=list)
    caveats: List[str] = field(default_factory=list)
    follow_up_questions: List[str] = field(default_factory=list)
    alternatives: List[str] = field(default_factory=list)


@dataclass
class DomainExpertise:
    """
    Definition of domain expertise.
    
    Attributes:
        domain_name: Name of domain
        description: Domain description
        expertise_areas: Specific areas of expertise
        methodologies: Standard approaches
        key_concepts: Important domain concepts
        terminology: Domain-specific vocabulary
        standards: Relevant standards and regulations
        common_issues: Frequently encountered problems
        best_practices: Field best practices
    """
    domain_name: str
    description: str
    expertise_areas: List[str] = field(default_factory=list)
    methodologies: List[str] = field(default_factory=list)
    key_concepts: Dict[str, str] = field(default_factory=dict)
    terminology: Dict[str, str] = field(default_factory=dict)
    standards: List[str] = field(default_factory=list)
    common_issues: List[str] = field(default_factory=list)
    best_practices: List[str] = field(default_factory=list)


class DomainExpertAgent:
    """
    Agent with specialized domain expertise.
    
    This agent provides expert-level guidance in a specific domain,
    using specialized knowledge, terminology, and reasoning.
    """
    
    def __init__(
        self,
        expertise: DomainExpertise,
        expertise_level: ExpertiseLevel = ExpertiseLevel.EXPERT,
        temperature: float = 0.3
    ):
        """
        Initialize domain expert agent.
        
        Args:
            expertise: Domain expertise definition
            expertise_level: Level of expertise
            temperature: LLM temperature (lower for more consistent expert advice)
        """
        self.expertise = expertise
        self.expertise_level = expertise_level
        self.llm = ChatOpenAI(temperature=temperature, model="gpt-3.5-turbo")
        self.knowledge_base: List[DomainKnowledge] = []
        self.consultation_history: List[Dict[str, Any]] = []
    
    def _build_expert_context(self) -> str:
        """Build expert context for prompts."""
        context_parts = [
            f"You are a {self.expertise_level.value}-level expert in {self.expertise.domain_name}.",
            f"Domain: {self.expertise.description}",
        ]
        
        if self.expertise.expertise_areas:
            areas = ", ".join(self.expertise.expertise_areas)
            context_parts.append(f"Areas of expertise: {areas}")
        
        if self.expertise.methodologies:
            methods = ", ".join(self.expertise.methodologies)
            context_parts.append(f"Standard methodologies: {methods}")
        
        if self.expertise.standards:
            standards = ", ".join(self.expertise.standards)
            context_parts.append(f"Relevant standards: {standards}")
        
        if self.expertise.best_practices:
            practices = "\n".join([f"  - {p}" for p in self.expertise.best_practices])
            context_parts.append(f"Best practices:\n{practices}")
        
        if self.expertise.key_concepts:
            concepts = "\n".join([f"  - {k}: {v}" for k, v in self.expertise.key_concepts.items()])
            context_parts.append(f"Key concepts:\n{concepts}")
        
        return "\n".join(context_parts)
    
    def add_knowledge(self, knowledge: DomainKnowledge):
        """Add domain knowledge to expert's knowledge base."""
        self.knowledge_base.append(knowledge)
    
    def consult(
        self,
        question: str,
        context: Optional[str] = None,
        require_reasoning: bool = True
    ) -> ExpertResponse:
        """
        Provide expert consultation.
        
        Args:
            question: Question or problem
            context: Additional context
            require_reasoning: Include reasoning explanation
            
        Returns:
            Expert response
        """
        expert_context = self._build_expert_context()
        
        # Build prompt
        prompt_template = (
            "{expert_context}\n\n"
            "Provide expert guidance on the following:\n\n"
            "Question: {question}\n\n"
        )
        
        if context:
            prompt_template += "Additional Context: {context}\n\n"
        
        prompt_template += (
            "Provide a comprehensive expert response including:\n"
            "1. Direct answer\n"
            "2. Expert reasoning and analysis\n"
            "3. Relevant considerations and caveats\n"
            "4. Best practices to follow\n"
            "5. Potential alternatives or approaches\n\n"
            "Use appropriate domain terminology and cite relevant standards when applicable."
        )
        
        prompt = ChatPromptTemplate.from_template(prompt_template)
        chain = prompt | self.llm | StrOutputParser()
        
        input_data = {
            "expert_context": expert_context,
            "question": question
        }
        
        if context:
            input_data["context"] = context
        
        response_text = chain.invoke(input_data)
        
        # Assess confidence based on question clarity and domain coverage
        confidence = self._assess_confidence(question)
        
        # Parse response components
        answer, reasoning, caveats = self._parse_response(response_text)
        
        # Store consultation
        self.consultation_history.append({
            "question": question,
            "answer": answer,
            "timestamp": datetime.now(),
            "confidence": confidence.value
        })
        
        return ExpertResponse(
            answer=answer,
            confidence=confidence,
            reasoning=reasoning,
            caveats=caveats
        )
    
    def _assess_confidence(self, question: str) -> ConfidenceLevel:
        """
        Assess confidence level in response.
        
        Args:
            question: The question asked
            
        Returns:
            Confidence level
        """
        # Check if question relates to core expertise
        question_lower = question.lower()
        
        # Count matches with expertise areas
        expertise_matches = sum(
            1 for area in self.expertise.expertise_areas
            if area.lower() in question_lower
        )
        
        # Terminology matches
        terminology_matches = sum(
            1 for term in self.expertise.terminology.keys()
            if term.lower() in question_lower
        )
        
        total_matches = expertise_matches + terminology_matches
        
        if total_matches >= 3:
            return ConfidenceLevel.VERY_HIGH
        elif total_matches >= 2:
            return ConfidenceLevel.HIGH
        elif total_matches >= 1:
            return ConfidenceLevel.MEDIUM
        else:
            return ConfidenceLevel.LOW
    
    def _parse_response(self, response_text: str) -> Tuple[str, str, List[str]]:
        """Parse response into components."""
        # Simple parsing - in production, use more sophisticated extraction
        lines = response_text.split('\n')
        
        answer_lines = []
        reasoning_lines = []
        caveat_lines = []
        
        current_section = "answer"
        
        for line in lines:
            line_lower = line.lower()
            
            if "reasoning" in line_lower or "analysis" in line_lower:
                current_section = "reasoning"
            elif "caveat" in line_lower or "consideration" in line_lower or "warning" in line_lower:
                current_section = "caveats"
            elif line.strip():
                if current_section == "answer":
                    answer_lines.append(line)
                elif current_section == "reasoning":
                    reasoning_lines.append(line)
                elif current_section == "caveats":
                    caveat_lines.append(line)
        
        answer = "\n".join(answer_lines) if answer_lines else response_text
        reasoning = "\n".join(reasoning_lines)
        caveats = [line.strip('- ').strip() for line in caveat_lines if line.strip()]
        
        return answer, reasoning, caveats
    
    def explain_concept(self, concept: str, audience_level: str = "intermediate") -> str:
        """
        Explain a domain concept.
        
        Args:
            concept: Concept to explain
            audience_level: Target audience (novice/intermediate/advanced)
            
        Returns:
            Explanation
        """
        expert_context = self._build_expert_context()
        
        # Check if concept is in terminology
        concept_definition = self.expertise.terminology.get(concept, "")
        
        prompt = ChatPromptTemplate.from_template(
            "{expert_context}\n\n"
            "Explain the concept of '{concept}' for a {audience_level} audience.\n"
            "{definition_context}\n"
            "Provide:\n"
            "1. Clear definition\n"
            "2. Key characteristics\n"
            "3. Practical examples\n"
            "4. Common misconceptions\n"
            "5. Related concepts\n\n"
            "Use appropriate technical depth for the audience level."
        )
        
        chain = prompt | self.llm | StrOutputParser()
        
        definition_context = f"Domain definition: {concept_definition}" if concept_definition else ""
        
        explanation = chain.invoke({
            "expert_context": expert_context,
            "concept": concept,
            "audience_level": audience_level,
            "definition_context": definition_context
        })
        
        return explanation
    
    def identify_issues(self, scenario: str) -> List[str]:
        """
        Identify potential issues in a scenario.
        
        Args:
            scenario: Description of situation
            
        Returns:
            List of identified issues
        """
        expert_context = self._build_expert_context()
        
        # Include common issues from domain
        common_issues = "\n".join([f"- {issue}" for issue in self.expertise.common_issues])
        
        prompt = ChatPromptTemplate.from_template(
            "{expert_context}\n\n"
            "Common issues in this domain:\n"
            "{common_issues}\n\n"
            "Scenario:\n"
            "{scenario}\n\n"
            "As an expert, identify potential issues, problems, or concerns in this scenario.\n"
            "List each issue on a separate line starting with '- '."
        )
        
        chain = prompt | self.llm | StrOutputParser()
        
        response = chain.invoke({
            "expert_context": expert_context,
            "common_issues": common_issues,
            "scenario": scenario
        })
        
        # Parse issues
        issues = [
            line.strip('- ').strip()
            for line in response.split('\n')
            if line.strip().startswith('-')
        ]
        
        return issues
    
    def recommend_approach(self, problem: str) -> Dict[str, Any]:
        """
        Recommend approach for solving a problem.
        
        Args:
            problem: Problem description
            
        Returns:
            Recommended approach with rationale
        """
        expert_context = self._build_expert_context()
        
        methodologies = ", ".join(self.expertise.methodologies)
        practices = "\n".join([f"- {p}" for p in self.expertise.best_practices])
        
        prompt = ChatPromptTemplate.from_template(
            "{expert_context}\n\n"
            "Available methodologies: {methodologies}\n\n"
            "Best practices:\n"
            "{practices}\n\n"
            "Problem:\n"
            "{problem}\n\n"
            "Recommend the best approach to solve this problem. Include:\n"
            "APPROACH: [recommended approach]\n"
            "METHODOLOGY: [which methodology to use]\n"
            "STEPS: [key steps]\n"
            "RATIONALE: [why this approach]\n"
            "ALTERNATIVES: [other options]"
        )
        
        chain = prompt | self.llm | StrOutputParser()
        
        response = chain.invoke({
            "expert_context": expert_context,
            "methodologies": methodologies,
            "practices": practices,
            "problem": problem
        })
        
        # Parse recommendation
        return {
            "raw_response": response,
            "problem": problem,
            "timestamp": datetime.now()
        }
    
    def get_expertise_summary(self) -> Dict[str, Any]:
        """Get summary of expert capabilities."""
        return {
            "domain": self.expertise.domain_name,
            "description": self.expertise.description,
            "expertise_level": self.expertise_level.value,
            "areas_of_expertise": self.expertise.expertise_areas,
            "methodologies": self.expertise.methodologies,
            "standards": self.expertise.standards,
            "total_consultations": len(self.consultation_history),
            "knowledge_base_size": len(self.knowledge_base)
        }


def demonstrate_domain_expert():
    """Demonstrate domain expert agent pattern."""
    
    print("=" * 80)
    print("DOMAIN EXPERT AGENT PATTERN DEMONSTRATION")
    print("=" * 80)
    
    # Example 1: Software Architecture Expert
    print("\n" + "=" * 80)
    print("Example 1: Software Architecture Expert")
    print("=" * 80)
    
    software_expertise = DomainExpertise(
        domain_name="Software Architecture",
        description="Design and structure of software systems",
        expertise_areas=[
            "Microservices",
            "System Design",
            "Scalability",
            "Design Patterns",
            "API Design"
        ],
        methodologies=[
            "Domain-Driven Design",
            "Clean Architecture",
            "Event-Driven Architecture",
            "Hexagonal Architecture"
        ],
        key_concepts={
            "Separation of Concerns": "Dividing system into distinct features with minimal overlap",
            "SOLID Principles": "Five design principles for maintainable software",
            "Scalability": "Ability to handle growth in workload"
        },
        terminology={
            "Microservice": "Small, independent service focused on single business capability",
            "API Gateway": "Single entry point for all client requests",
            "Circuit Breaker": "Pattern preventing cascading failures"
        },
        standards=[
            "REST API Design",
            "OpenAPI Specification",
            "12-Factor App"
        ],
        common_issues=[
            "Tight coupling between components",
            "Lack of scalability planning",
            "Poor API design",
            "Missing error handling",
            "Inadequate monitoring"
        ],
        best_practices=[
            "Design for failure",
            "Implement proper logging and monitoring",
            "Use asynchronous communication where appropriate",
            "Maintain clear API contracts",
            "Document architectural decisions"
        ]
    )
    
    architect = DomainExpertAgent(
        expertise=software_expertise,
        expertise_level=ExpertiseLevel.EXPERT
    )
    
    print(f"\nExpert Domain: {software_expertise.domain_name}")
    print(f"Expertise Level: {architect.expertise_level.value}")
    print(f"Areas: {', '.join(software_expertise.expertise_areas[:3])}...")
    
    # Example 2: Expert consultation
    print("\n" + "=" * 80)
    print("Example 2: Expert Consultation")
    print("=" * 80)
    
    question = "I'm building an e-commerce platform. Should I use microservices or a monolith?"
    
    print(f"\nQuestion: {question}")
    print("\nExpert Response:")
    print("-" * 60)
    
    response = architect.consult(question)
    print(response.answer)
    print(f"\nConfidence: {response.confidence.value}")
    
    if response.caveats:
        print(f"\nCaveats:")
        for caveat in response.caveats:
            print(f"  - {caveat}")
    
    # Example 3: Concept explanation
    print("\n" + "=" * 80)
    print("Example 3: Explaining Domain Concepts")
    print("=" * 80)
    
    concept = "Microservice"
    audience = "intermediate"
    
    print(f"\nExplaining '{concept}' for {audience} audience:")
    print("-" * 60)
    
    explanation = architect.explain_concept(concept, audience_level=audience)
    print(explanation)
    
    # Example 4: Issue identification
    print("\n" + "=" * 80)
    print("Example 4: Identifying Issues in Scenario")
    print("=" * 80)
    
    scenario = """
    We have a system where the web frontend directly calls the database.
    All services share the same database. We deploy everything together as one unit.
    When traffic increases, the entire system slows down.
    """
    
    print("\nScenario:")
    print(scenario)
    print("\nIdentified Issues:")
    
    issues = architect.identify_issues(scenario)
    for i, issue in enumerate(issues, 1):
        print(f"{i}. {issue}")
    
    # Example 5: Approach recommendation
    print("\n" + "=" * 80)
    print("Example 5: Recommending Approach")
    print("=" * 80)
    
    problem = "Need to scale our notification system that currently sends 10k emails/day but will need to handle 1M/day"
    
    print(f"\nProblem: {problem}")
    print("\nRecommended Approach:")
    print("-" * 60)
    
    recommendation = architect.recommend_approach(problem)
    print(recommendation["raw_response"])
    
    # Example 6: Medical Domain Expert
    print("\n" + "=" * 80)
    print("Example 6: Medical Domain Expert")
    print("=" * 80)
    
    medical_expertise = DomainExpertise(
        domain_name="General Medicine",
        description="Medical diagnosis and treatment",
        expertise_areas=[
            "Symptom Analysis",
            "Differential Diagnosis",
            "Treatment Planning",
            "Patient Care"
        ],
        methodologies=[
            "Evidence-Based Medicine",
            "Clinical Decision Making",
            "Patient-Centered Care"
        ],
        terminology={
            "Differential Diagnosis": "Process of distinguishing between similar conditions",
            "Prognosis": "Predicted course of a disease",
            "Contraindication": "Condition that makes treatment inadvisable"
        },
        standards=[
            "HIPAA Compliance",
            "Clinical Practice Guidelines",
            "Medical Ethics"
        ],
        best_practices=[
            "Always consider patient history",
            "Rule out serious conditions first",
            "Consider drug interactions",
            "Obtain informed consent",
            "Document thoroughly"
        ]
    )
    
    doctor = DomainExpertAgent(
        expertise=medical_expertise,
        expertise_level=ExpertiseLevel.EXPERT,
        temperature=0.2  # Very low for medical advice
    )
    
    print(f"\nExpert Domain: {medical_expertise.domain_name}")
    print(f"Standards: {', '.join(medical_expertise.standards)}")
    
    # Medical consultation
    medical_question = "What should I consider when a patient presents with chest pain?"
    
    print(f"\nMedical Question: {medical_question}")
    print("\nDISCLAIMER: This is a demonstration. Not real medical advice.")
    print("-" * 60)
    
    medical_response = doctor.consult(medical_question)
    print(medical_response.answer[:500] + "...")  # Truncate for demo
    print(f"\nConfidence: {medical_response.confidence.value}")
    
    # Example 7: Financial Expert
    print("\n" + "=" * 80)
    print("Example 7: Financial Planning Expert")
    print("=" * 80)
    
    financial_expertise = DomainExpertise(
        domain_name="Financial Planning",
        description="Personal and business financial planning",
        expertise_areas=[
            "Investment Strategy",
            "Retirement Planning",
            "Tax Planning",
            "Risk Management"
        ],
        methodologies=[
            "Modern Portfolio Theory",
            "Asset Allocation",
            "Risk Assessment"
        ],
        standards=[
            "SEC Regulations",
            "Fiduciary Duty",
            "CFP Standards"
        ],
        best_practices=[
            "Diversify investments",
            "Consider tax implications",
            "Match risk to time horizon",
            "Rebalance regularly",
            "Have emergency fund"
        ]
    )
    
    financial_advisor = DomainExpertAgent(
        expertise=financial_expertise,
        expertise_level=ExpertiseLevel.EXPERT
    )
    
    financial_question = "I'm 30 years old and want to start investing for retirement. Where should I start?"
    
    print(f"\nQuestion: {financial_question}")
    print("\nExpert Guidance:")
    print("-" * 60)
    
    financial_response = financial_advisor.consult(financial_question)
    print(financial_response.answer)
    
    # Example 8: Expertise summary
    print("\n" + "=" * 80)
    print("Example 8: Expert Capabilities Summary")
    print("=" * 80)
    
    summary = architect.get_expertise_summary()
    
    print("\nEXPERT PROFILE:")
    print("=" * 60)
    print(f"Domain: {summary['domain']}")
    print(f"Expertise Level: {summary['expertise_level']}")
    print(f"\nAreas of Expertise:")
    for area in summary['areas_of_expertise']:
        print(f"  • {area}")
    print(f"\nMethodologies:")
    for method in summary['methodologies']:
        print(f"  • {method}")
    print(f"\nTotal Consultations: {summary['total_consultations']}")
    
    # Summary
    print("\n" + "=" * 80)
    print("SUMMARY: Domain Expert Agent Pattern")
    print("=" * 80)
    
    summary_text = """
    The Domain Expert Agent pattern demonstrated:
    
    1. EXPERTISE DEFINITION (Example 1):
       - Comprehensive domain specification
       - Areas of expertise
       - Standard methodologies
       - Key concepts and terminology
       - Relevant standards and regulations
       - Common issues and challenges
       - Best practices
    
    2. EXPERT CONSULTATION (Example 2):
       - Professional guidance
       - Domain-appropriate reasoning
       - Confidence assessment
       - Caveat identification
       - Best practice application
    
    3. CONCEPT EXPLANATION (Example 3):
       - Audience-appropriate depth
       - Domain terminology
       - Practical examples
       - Clear definitions
       - Related concepts
    
    4. ISSUE IDENTIFICATION (Example 4):
       - Expert problem recognition
       - Domain-specific concerns
       - Pattern matching
       - Risk assessment
       - Comprehensive analysis
    
    5. APPROACH RECOMMENDATION (Example 5):
       - Methodology selection
       - Step-by-step guidance
       - Rationale explanation
       - Alternative considerations
       - Best practice integration
    
    6. DOMAIN SPECIALIZATION (Examples 6-7):
       - Medical expertise
       - Financial planning
       - Different domain requirements
       - Standards compliance
       - Professional ethics
    
    7. MULTI-DOMAIN CAPABILITY (Examples 1, 6, 7):
       - Software architecture
       - Medical diagnosis
       - Financial planning
       - Domain-specific reasoning
       - Appropriate terminology
    
    8. TRANSPARENCY (Example 8):
       - Expertise summary
       - Capability disclosure
       - Consultation tracking
       - Knowledge base size
       - Performance metrics
    
    KEY BENEFITS:
    ✓ Expert-level guidance
    ✓ Domain-appropriate reasoning
    ✓ Specialized knowledge application
    ✓ Professional terminology
    ✓ Best practice adherence
    ✓ Quality assurance
    ✓ Credible advice
    ✓ Comprehensive coverage
    
    USE CASES:
    • Medical diagnosis assistance
    • Legal research and advisory
    • Financial analysis and planning
    • Engineering consultation
    • Scientific research support
    • Tax preparation
    • Architectural design
    • Software architecture advisory
    
    EXPERT BEHAVIORS:
    → Ask clarifying questions
    → Identify missing information
    → Consider edge cases
    → Reference standards
    → Explain reasoning
    → Acknowledge uncertainty
    → Provide multiple perspectives
    → Use appropriate terminology
    
    DOMAIN CHARACTERISTICS:
    • Depth: Comprehensive specialized coverage
    • Terminology: Field-specific vocabulary
    • Methodology: Standard approaches
    • Context: Domain landscape understanding
    • Precedents: Historical cases
    • Standards: Industry regulations
    • Boundaries: Expertise limits
    
    BEST PRACTICES:
    1. Regularly update domain knowledge
    2. Version control expert systems
    3. Track predictions vs. outcomes
    4. Include human expert review
    5. Add appropriate disclaimers
    6. Maintain audit trails
    7. Ensure regulatory compliance
    8. Support expert override
    
    TRADE-OFFS:
    • Depth vs. breadth
    • Accuracy vs. accessibility
    • Confidence vs. caution
    • Automation vs. human oversight
    
    PRODUCTION CONSIDERATIONS:
    → Regular knowledge base updates
    → Version control of expertise
    → Track expert vs. actual outcomes
    → Human expert review loops
    → Appropriate disclaimers
    → Complete audit trails
    → Regulatory compliance checks
    → Expert override mechanisms
    → Liability management
    → Certification where applicable
    
    This pattern enables agents to provide professional-grade expertise in
    specialized domains, delivering value that requires deep knowledge and
    experience while maintaining appropriate boundaries and transparency.
    """
    
    print(summary_text)


if __name__ == "__main__":
    demonstrate_domain_expert()

    

Agentic Design Pattern: Domain Expert

Pattern 133: Domain Expert – Line-by-Line Explanation

Overview

This document provides a detailed line-by-line explanation of the Domain Expert pattern implementation.


Pattern Description

Pattern 133: Domain Expert Agent

Description: The Domain Expert Agent pattern creates specialized agents with deep expertise in specific domains or fields. Unlike general-purpose agents, domain experts possess comprehensive knowledge, terminology, methodologies, and best practices specific to their area of specialization. They can provide expert-level advice, perform domain-specific reasoning, and apply specialized knowledge effectively.

Domain expertise goes beyond simple knowledge retrieval - it includes understanding
domain-specific workflows, recognizing patterns, applying heuristics, knowing
what questions to ask, and understanding the nuances and edge cases within the
domain. Expert agents can explain complex concepts using domain terminology,
evaluate solutions using domain-specific criteria, and provide guidance that
reflects years of accumulated expertise.

This pattern is essential for applications requiring specialized knowledge such
as medical diagnosis assistants, legal advisors, financial analysts, scientific
research assistants, engineering consultants, and other professional AI systems.

Key Components: 1. Domain Knowledge Base: Comprehensive domain-specific information 2. Terminology Handler: Domain-specific vocabulary and jargon 3. Best Practices Repository: Field-standard methodologies 4. Case History: Examples and precedents from the domain 5. Reasoning Engine: Domain-specific logic and heuristics 6. Validation System: Domain-appropriate quality checks 7. Reference System: Citations and sources

Domain Characteristics: 1. Depth: Comprehensive coverage of specialized area 2. Terminology: Field-specific vocabulary 3. Methodology: Domain-standard approaches 4. Context: Understanding of domain landscape 5. Precedents: Historical cases and examples 6. Standards: Industry regulations and best practices 7. Boundaries: Knowing limits of expertise

Expert Behaviors: 1. Ask clarifying questions 2. Identify missing information 3. Consider edge cases 4. Reference standards and regulations 5. Explain reasoning process 6. Acknowledge uncertainty 7. Provide multiple perspectives 8. Use appropriate terminology

Use Cases: – Medical diagnosis assistants – Legal research and advisory – Financial analysis and planning – Engineering design consultation – Scientific research assistance – Tax preparation and planning – Architectural design – Software architecture advisory

Advantages: – Expert-level guidance – Domain-appropriate reasoning – Specialized knowledge application – Professional terminology usage – Best practice adherence – Quality assurance – Credible advice

Challenges: – Knowledge maintenance and updates – Handling edge cases – Avoiding overconfidence – Managing liability concerns – Balancing depth vs. accessibility – Keeping current with field changes – Regulatory compliance

LangChain Implementation: This implementation uses LangChain for: – Domain knowledge integration – Expert reasoning chains – Specialized RAG with domain documents – Domain-specific validation

Production Considerations: – Regularly update domain knowledge – Version control expert systems – Track expert vs. actual outcomes – Implement human expert review – Include disclaimers appropriately – Maintain audit trails – Ensure regulatory compliance – Support expert override mechanisms


File Statistics

  • Total Lines: 946
  • Classes: 6
  • Functions: 1
  • Constants: 0

Module Documentation

"""
Pattern 133: Domain Expert Agent

Description:
    The Domain Expert Agent pattern creates specialized agents with deep expertise
    in specific domains or fields. Unlike general-purpose agents, domain experts
    possess comprehensive knowledge, terminology, methodologies, and best practices
    specific to their area of specialization. They can provide expert-level advice,
    perform domain-specific reasoning, and apply specialized knowledge effectively.

    Domain expertise goes beyond simple knowledge retrieval - it includes understanding
    domain-specific workflows, recognizing patterns, applying heuristics, knowing
    what questions to ask, and understanding the nuances and edge cases within the
    domain. Expert agents can explain complex concepts using domain terminology,
    evaluate solutions using domain-specific criteria, and provide guidance that
    reflects years of accumulated expertise.

    This pattern is essential for applications requiring specialized knowledge such
    as medical diagnosis assistants, legal advisors, financial analysts, scientific
    research assistants, engineering consultants, and other professional AI systems.

Key Components:
    1. Domain Knowledge Base: Comprehensive domain-specific information
    2. Terminology Handler: Domain-specific vocabulary and jargon
    3. Best Practices Repository: Field-standard methodologies
    4. Case History: Examples and precedents from the domain
    5. Reasoning Engine: Domain-specific logic and heuristics
    6. Validation System: Domain-appropriate quality checks
    7. Reference System: Citations and sources

Domain Characteristics:
    1. Depth: Comprehensive coverage of specialized area
    2. Terminology: Field-specific vocabulary
    3. Methodology: Domain-standard approaches
    4. Context: Understanding of domain landscape
    5. Precedents: Historical cases and examples
    6. Standards: Industry regulations and best practices
    7. Boundaries: Knowing limits of expertise

Expert Behaviors:
    1. Ask clarifying questions
    2. Identify missing information
    3. Consider edge cases
    4. Reference standards and regulations
    5. Explain reasoning process
    6. Acknowledge uncertainty
    7. Provide multiple perspectives
    8. Use appropriate terminology

Use Cases:
    - Medical diagnosis assistants
    - Legal research and advisory
    - Financial analysis and planning
    - Engineering design consultation
    - Scientific research assistance
    - Tax preparation and planning
    - Architectural design
    - Software architecture advisory

Advantages:
    - Expert-level guidance
    - Domain-appropriate reasoning
    - Specialized knowledge application
    - Professional terminology usage
    - Best practice adherence
    - Quality assurance
    - Credible advice

Challenges:
    - Knowledge maintenance and updates
    - Handling edge cases
    - Avoiding overconfidence
    - Managing liability concerns
    - Balancing depth vs. accessibility
    - Keeping current with field changes
    - Regulatory compliance

LangChain Implementation:
    This implementation uses LangChain for:
    - Domain knowledge integration
    - Expert reasoning chains
    - Specialized RAG with domain documents
    - Domain-specific validation

Production Considerations:
    - Regularly update domain knowledge
    - Version control expert systems
    - Track expert vs. actual outcomes
    - Implement human expert review
    - Include disclaimers appropriately
    - Maintain audit trails
    - Ensure regulatory compliance
    - Support expert override mechanisms
"""

Purpose: This module implements the Domain Expert pattern, providing a structured approach to agent design and implementation.


Import Statements

Standard Library Imports

import dataclasses.dataclass
import dataclasses.field
import datetime.datetime
import enum.Enum
import langchain_core.output_parsers.StrOutputParser
import langchain_core.prompts.ChatPromptTemplate
import os
import typing.Any
import typing.Dict
import typing.List
import typing.Optional
import typing.Tuple

Purpose: Core Python functionality: – dataclasses.dataclass: Simplified class definitions with @dataclass – dataclasses.field: Simplified class definitions with @dataclass – datetime.datetime: Date and time handling – enum.Enum: Enumeration support – langchain_core.output_parsers.StrOutputParser: Regular expression operations – langchain_core.prompts.ChatPromptTemplate: Regular expression operations – os: Environment variable access and system operations – typing.Any: Type hints for better code documentation (List, Dict, Any, Optional) – typing.Dict: Type hints for better code documentation (List, Dict, Any, Optional) – typing.List: Type hints for better code documentation (List, Dict, Any, Optional) – typing.Optional: Type hints for better code documentation (List, Dict, Any, Optional) – typing.Tuple: Type hints for better code documentation (List, Dict, Any, Optional)

LangChain Imports

from langchain_openai.ChatOpenAI

Purpose: LangChain framework components: – LLM Interface: Wrapper for OpenAI models – Chains: Composable building blocks for complex workflows

Other Imports

from dotenv.load_dotenv

Purpose: Additional dependencies for specialized functionality.


Classes

Class: ExpertiseLevel

Lines 110-116

Inherits from: Enum

Purpose:

Level of expertise.

Class: ConfidenceLevel

Lines 119-124

Inherits from: Enum

Purpose:

Confidence in response.

Class: DomainKnowledge

Lines 128-145

Purpose:

Domain-specific knowledge item.

Attributes:
    topic: Knowledge area
    content: Information content
    source: Where knowledge came from
    reliability: How reliable (0-1)
    last_updated: When last verified
    tags: Categorization tags

Class: ExpertResponse

Lines 149-168

Purpose:

Expert agent response.

Attributes:
    answer: Main response
    confidence: Confidence level
    reasoning: Explanation of reasoning
    references: Supporting sources
    caveats: Important limitations or warnings
    follow_up_questions: Suggested clarifications
    alternatives: Alternative approaches

Class: DomainExpertise

Lines 172-195

Purpose:

Definition of domain expertise.

Attributes:
    domain_name: Name of domain
    description: Domain description
    expertise_areas: Specific areas of expertise
    methodologies: Standard approaches
    key_concepts: Important domain concepts
    terminology: Domain-specific vocabulary
    standards: Relevant standards and regulations
    common_issues: Frequently encountered problems
    best_practices: Field best practices

Class: DomainExpertAgent

Lines 198-541

Purpose:

Agent with specialized domain expertise.

This agent provides expert-level guidance in a specific domain,
using specialized knowledge, terminology, and reasoning.

Methods:

__init__(self, expertise, expertise_level, temperature)

Lines 206-224

Purpose:

Initialize domain expert agent.

Args:
    expertise: Domain expertise definition
    expertise_level: Level of expertise
    temperature: LLM temperature (lower for more consistent expert advice)

Parameters: – expertise: Expertise – expertise_level: Expertise level – temperature: Sampling temperature (0-1)

_build_expert_context(self)

Lines 226-253

Purpose:

Build expert context for prompts.

Parameters:

Returns: str

add_knowledge(self, knowledge)

Lines 255-257

Purpose:

Add domain knowledge to expert's knowledge base.

Parameters: – knowledge: Knowledge

consult(self, question, context, require_reasoning)

Lines 259-330

Purpose:

Provide expert consultation.

Args:
    question: Question or problem
    context: Additional context
    require_reasoning: Include reasoning explanation

Returns:
    Expert response

Parameters: – question: Question to answer – context: Context – require_reasoning: Require reasoning

Returns: ExpertResponse

_assess_confidence(self, question)

Lines 332-366

Purpose:

Assess confidence level in response.

Args:
    question: The question asked

Returns:
    Confidence level

Parameters: – question: Question to answer

Returns: ConfidenceLevel

_parse_response(self, response_text)

Lines 368-398

Purpose:

Parse response into components.

Parameters: – response_text: Response text

Returns: <ast.Subscript object at 0x000001A06D63D090>

explain_concept(self, concept, audience_level)

Lines 400-440

Purpose:

Explain a domain concept.

Args:
    concept: Concept to explain
    audience_level: Target audience (novice/intermediate/advanced)

Returns:
    Explanation

Parameters: – concept: Concept – audience_level: Audience level

Returns: str

identify_issues(self, scenario)

Lines 442-482

Purpose:

Identify potential issues in a scenario.

Args:
    scenario: Description of situation

Returns:
    List of identified issues

Parameters: – scenario: Scenario

Returns: <ast.Subscript object at 0x000001A06D77E010>

recommend_approach(self, problem)

Lines 484-528

Purpose:

Recommend approach for solving a problem.

Args:
    problem: Problem description

Returns:
    Recommended approach with rationale

Parameters: – problem: Problem

Returns: <ast.Subscript object at 0x000001A06D7504D0>

get_expertise_summary(self)

Lines 530-541

Purpose:

Get summary of expert capabilities.

Parameters:

Returns: <ast.Subscript object at 0x000001A06D168B90>


Functions

demonstrate_domain_expert()

Lines 544-941

Purpose:

Demonstrate domain expert agent pattern.

Key Concepts Summary

Pattern Overview

The Domain Expert pattern provides a structured approach to building AI agents with specific capabilities and behaviors. This implementation leverages LangChain’s composable components to create a robust and maintainable solution.

Core Components

  1. Agent Class: Main implementation of the pattern logic
  2. Prompt Engineering: Carefully crafted prompts to guide LLM behavior
  3. Tool Integration: Optional tools for extended functionality
  4. Memory Management: State handling across interactions
  5. Output Parsing: Structured response processing

When to Use

✅ Good for: – Scenarios requiring this specific pattern’s strengths – Applications needing structured agent behavior – Systems where explainability is important – Production environments requiring reliability

❌ Not ideal for: – Simple single-prompt tasks – Scenarios requiring different pattern characteristics – Resource-constrained environments (if computationally intensive)


Best Practices Demonstrated

1. Environment Configuration

  • ✅ Use .env files for API keys
  • ✅ Never hardcode credentials
  • ✅ Validate environment variables on startup

2. Error Handling

  • ✅ Graceful degradation on failures
  • ✅ Informative error messages
  • ✅ Logging for debugging

3. Prompt Engineering

  • ✅ Clear, specific instructions
  • ✅ Structured output formats
  • ✅ Few-shot examples when beneficial

4. Code Organization

  • ✅ Separation of concerns (class-based design)
  • ✅ Type hints for clarity
  • ✅ Docstrings for documentation

5. Performance Optimization

  • ✅ Appropriate temperature settings
  • ✅ Token budget management
  • ✅ Caching where applicable

LangChain Components Used

  • ChatOpenAI: OpenAI model interface
  • Chains: Sequential component composition

Why LangChain? – Composable abstractions for LLM applications – Rich ecosystem of integrations – Production-ready patterns – Active community and development


Execution Flow

1. Initialize agent with configuration
   ↓
2. Load environment and dependencies
   ↓
3. Prepare prompt with input data
   ↓
4. Invoke LLM through LangChain
   ↓
5. Parse and validate response
   ↓
6. Return formatted result

Key Decision Points: – Model selection (temperature, model type) – Prompt structure (few-shot vs zero-shot) – Error handling strategy – Output format validation


Performance Considerations

Computational Cost

  • LLM Calls: Primary cost factor (based on tokens)
  • Latency: Depends on model and input size
  • Memory: Minimal for most patterns

Optimization Strategies

  1. Prompt Optimization: Minimize tokens while maintaining clarity
  2. Caching: Cache repeated queries/responses
  3. Model Selection: Use smaller models when appropriate
  4. Batch Processing: Group similar requests
  5. Streaming: For long responses, stream tokens

Cost Estimates (Approximate)

  • GPT-3.5-turbo: ~$0.002 per request
  • GPT-4: ~$0.03 per request
  • GPT-4-turbo: ~$0.01 per request

Actual costs vary based on input/output token counts


Common Pitfalls to Avoid

1. Prompt Design Issues

❌ Vague or ambiguous instructions
✅ Clear, specific, testable prompts

2. Error Handling

❌ Ignoring API errors or rate limits
✅ Implement retry logic and graceful degradation

3. Token Management

❌ Exceeding model token limits
✅ Truncate inputs, chunk processing

4. Security

❌ Exposing API keys in code
✅ Use environment variables

5. Testing

❌ Only testing happy paths
✅ Test edge cases, failures, malformed inputs

6. Cost Management

❌ Unmonitored API usage
✅ Implement budgets, alerts, and monitoring


Further Improvements

Production Enhancements

  1. Monitoring: Add logging, metrics, tracing
  2. Validation: Input/output schema validation
  3. Rate Limiting: Implement request throttling
  4. Caching: Redis or in-memory cache for responses
  5. Async Support: Non-blocking operations for scalability

Feature Extensions

  1. Multi-Model Support: Switch between providers
  2. Fallback Models: Graceful degradation strategy
  3. Custom Tools: Domain-specific function calling
  4. Advanced Memory: Vector stores for long-term memory
  5. Evaluation: Automated testing and benchmarking

Code Quality

  1. Testing: Unit tests, integration tests
  2. Documentation: API docs, usage examples
  3. Type Safety: Stricter type hints
  4. Configuration: Externalized config files

Related Patterns

  • Pattern 132
  • Pattern 134

Pattern Families: – Reasoning Patterns (001-011) – Multi-Agent Patterns (012-019) – Tool Use Patterns (020-025) – Memory Patterns (026-031) – And many more…


Summary

The Domain Expert pattern provides a powerful approach to building AI agents with specific capabilities. This implementation demonstrates:

✅ Key Strengths: – Clean, maintainable code structure – LangChain integration for composability – Type hints and documentation – Production-ready patterns

🎯 Best Use Cases: – Applications requiring this pattern’s characteristics – Systems needing structured agent behavior – Production environments requiring reliability

📚 Learning Resources: – LangChain Documentation: https://python.langchain.com/ – Pattern Documentation: See related patterns – OpenAI API Reference: https://platform.openai.com/docs/


File: 133_domain_expert.py
Total Lines: 946
Pattern Category: AI Agent Design Pattern #133


Generated from actual implementation code
For educational and reference purposes

Comments

Leave a Reply

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