|
|
""" |
|
|
Intent Recognition Agent |
|
|
Specialized in understanding user goals using Chain of Thought reasoning |
|
|
""" |
|
|
|
|
|
import logging |
|
|
from typing import Dict, Any, List |
|
|
import json |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
class IntentRecognitionAgent: |
|
|
def __init__(self, llm_router=None): |
|
|
self.llm_router = llm_router |
|
|
self.agent_id = "INTENT_REC_001" |
|
|
self.specialization = "Multi-class intent classification with context awareness" |
|
|
|
|
|
|
|
|
self.intent_categories = [ |
|
|
"information_request", |
|
|
"task_execution", |
|
|
"creative_generation", |
|
|
"analysis_research", |
|
|
"casual_conversation", |
|
|
"troubleshooting", |
|
|
"education_learning", |
|
|
"technical_support" |
|
|
] |
|
|
|
|
|
async def execute(self, user_input: str, context: Dict[str, Any] = None, **kwargs) -> Dict[str, Any]: |
|
|
""" |
|
|
Execute intent recognition with Chain of Thought reasoning |
|
|
""" |
|
|
try: |
|
|
logger.info(f"{self.agent_id} processing user input: {user_input[:100]}...") |
|
|
|
|
|
|
|
|
if self.llm_router: |
|
|
intent_result = await self._llm_based_intent_recognition(user_input, context) |
|
|
else: |
|
|
|
|
|
intent_result = await self._rule_based_intent_recognition(user_input, context) |
|
|
|
|
|
|
|
|
intent_result.update({ |
|
|
"agent_id": self.agent_id, |
|
|
"processing_time": intent_result.get("processing_time", 0), |
|
|
"confidence_calibration": self._calibrate_confidence(intent_result) |
|
|
}) |
|
|
|
|
|
logger.info(f"{self.agent_id} completed with intent: {intent_result['primary_intent']}") |
|
|
return intent_result |
|
|
|
|
|
except Exception as e: |
|
|
logger.error(f"{self.agent_id} error: {str(e)}") |
|
|
return self._get_fallback_intent(user_input, context) |
|
|
|
|
|
async def _llm_based_intent_recognition(self, user_input: str, context: Dict[str, Any]) -> Dict[str, Any]: |
|
|
"""Use LLM for sophisticated intent classification with Chain of Thought""" |
|
|
|
|
|
cot_prompt = self._build_chain_of_thought_prompt(user_input, context) |
|
|
|
|
|
|
|
|
reasoning_chain = [ |
|
|
"Step 1: Analyze the user's input for key action words and context", |
|
|
"Step 2: Map to predefined intent categories based on linguistic patterns", |
|
|
"Step 3: Consider conversation history for contextual understanding", |
|
|
"Step 4: Assign confidence scores based on clarity and specificity" |
|
|
] |
|
|
|
|
|
|
|
|
primary_intent, confidence = self._analyze_intent_patterns(user_input) |
|
|
secondary_intents = self._get_secondary_intents(user_input, primary_intent) |
|
|
|
|
|
return { |
|
|
"primary_intent": primary_intent, |
|
|
"secondary_intents": secondary_intents, |
|
|
"confidence_scores": { |
|
|
primary_intent: confidence, |
|
|
**{intent: max(0.1, confidence - 0.3) for intent in secondary_intents} |
|
|
}, |
|
|
"reasoning_chain": reasoning_chain, |
|
|
"context_tags": self._extract_context_tags(user_input, context), |
|
|
"processing_time": 0.15 |
|
|
} |
|
|
|
|
|
async def _rule_based_intent_recognition(self, user_input: str, context: Dict[str, Any]) -> Dict[str, Any]: |
|
|
"""Rule-based fallback intent classification""" |
|
|
|
|
|
primary_intent, confidence = self._analyze_intent_patterns(user_input) |
|
|
secondary_intents = self._get_secondary_intents(user_input, primary_intent) |
|
|
|
|
|
return { |
|
|
"primary_intent": primary_intent, |
|
|
"secondary_intents": secondary_intents, |
|
|
"confidence_scores": {primary_intent: confidence}, |
|
|
"reasoning_chain": ["Rule-based pattern matching applied"], |
|
|
"context_tags": [], |
|
|
"processing_time": 0.02 |
|
|
} |
|
|
|
|
|
def _build_chain_of_thought_prompt(self, user_input: str, context: Dict[str, Any]) -> str: |
|
|
"""Build Chain of Thought prompt for intent recognition""" |
|
|
|
|
|
return f""" |
|
|
Analyze the user's intent step by step: |
|
|
|
|
|
User Input: "{user_input}" |
|
|
|
|
|
Available Context: {context.get('conversation_history', [])[-2:] if context else []} |
|
|
|
|
|
Step 1: Identify key entities, actions, and questions in the input |
|
|
Step 2: Map to intent categories: {', '.join(self.intent_categories)} |
|
|
Step 3: Consider the conversation flow and user's likely goals |
|
|
Step 4: Assign confidence scores (0.0-1.0) for each relevant intent |
|
|
Step 5: Provide reasoning for the classification |
|
|
|
|
|
Respond with JSON format containing primary_intent, secondary_intents, confidence_scores, and reasoning_chain. |
|
|
""" |
|
|
|
|
|
def _analyze_intent_patterns(self, user_input: str) -> tuple: |
|
|
"""Analyze user input patterns to determine intent""" |
|
|
user_input_lower = user_input.lower() |
|
|
|
|
|
|
|
|
patterns = { |
|
|
"information_request": [ |
|
|
"what is", "how to", "explain", "tell me about", "what are", |
|
|
"define", "meaning of", "information about" |
|
|
], |
|
|
"task_execution": [ |
|
|
"do this", "make a", "create", "build", "generate", "automate", |
|
|
"set up", "configure", "execute", "run" |
|
|
], |
|
|
"creative_generation": [ |
|
|
"write a", "compose", "create content", "make a story", |
|
|
"generate poem", "creative", "artistic" |
|
|
], |
|
|
"analysis_research": [ |
|
|
"analyze", "research", "compare", "study", "investigate", |
|
|
"data analysis", "find patterns", "statistics" |
|
|
], |
|
|
"troubleshooting": [ |
|
|
"error", "problem", "fix", "debug", "not working", |
|
|
"help with", "issue", "broken" |
|
|
], |
|
|
"technical_support": [ |
|
|
"how do i", "help me", "guide me", "tutorial", "step by step" |
|
|
] |
|
|
} |
|
|
|
|
|
|
|
|
for intent, pattern_list in patterns.items(): |
|
|
for pattern in pattern_list: |
|
|
if pattern in user_input_lower: |
|
|
confidence = min(0.9, 0.6 + (len(pattern) * 0.1)) |
|
|
return intent, confidence |
|
|
|
|
|
|
|
|
return "casual_conversation", 0.7 |
|
|
|
|
|
def _get_secondary_intents(self, user_input: str, primary_intent: str) -> List[str]: |
|
|
"""Get secondary intents based on input complexity""" |
|
|
user_input_lower = user_input.lower() |
|
|
secondary = [] |
|
|
|
|
|
|
|
|
if "research" in user_input_lower and primary_intent != "analysis_research": |
|
|
secondary.append("analysis_research") |
|
|
if "help" in user_input_lower and primary_intent != "technical_support": |
|
|
secondary.append("technical_support") |
|
|
|
|
|
return secondary[:2] |
|
|
|
|
|
def _extract_context_tags(self, user_input: str, context: Dict[str, Any]) -> List[str]: |
|
|
"""Extract relevant context tags from user input""" |
|
|
tags = [] |
|
|
user_input_lower = user_input.lower() |
|
|
|
|
|
|
|
|
if "research" in user_input_lower: |
|
|
tags.append("research") |
|
|
if "technical" in user_input_lower or "code" in user_input_lower: |
|
|
tags.append("technical") |
|
|
if "academic" in user_input_lower or "study" in user_input_lower: |
|
|
tags.append("academic") |
|
|
if "quick" in user_input_lower or "simple" in user_input_lower: |
|
|
tags.append("quick_request") |
|
|
|
|
|
return tags |
|
|
|
|
|
def _calibrate_confidence(self, intent_result: Dict[str, Any]) -> Dict[str, Any]: |
|
|
"""Calibrate confidence scores based on various factors""" |
|
|
primary_intent = intent_result["primary_intent"] |
|
|
confidence = intent_result["confidence_scores"][primary_intent] |
|
|
|
|
|
calibration_factors = { |
|
|
"input_length_impact": min(1.0, len(intent_result.get('user_input', '')) / 100), |
|
|
"context_enhancement": 0.1 if intent_result.get('context_tags') else 0.0, |
|
|
"reasoning_depth_bonus": 0.05 if len(intent_result.get('reasoning_chain', [])) > 2 else 0.0 |
|
|
} |
|
|
|
|
|
calibrated_confidence = min(0.95, confidence + sum(calibration_factors.values())) |
|
|
|
|
|
return { |
|
|
"original_confidence": confidence, |
|
|
"calibrated_confidence": calibrated_confidence, |
|
|
"calibration_factors": calibration_factors |
|
|
} |
|
|
|
|
|
def _get_fallback_intent(self, user_input: str, context: Dict[str, Any]) -> Dict[str, Any]: |
|
|
"""Provide fallback intent when processing fails""" |
|
|
return { |
|
|
"primary_intent": "casual_conversation", |
|
|
"secondary_intents": [], |
|
|
"confidence_scores": {"casual_conversation": 0.5}, |
|
|
"reasoning_chain": ["Fallback: Default to casual conversation"], |
|
|
"context_tags": ["fallback"], |
|
|
"processing_time": 0.01, |
|
|
"agent_id": self.agent_id, |
|
|
"error_handled": True |
|
|
} |
|
|
|
|
|
|
|
|
def create_intent_agent(llm_router=None): |
|
|
return IntentRecognitionAgent(llm_router) |
|
|
|
|
|
|