youtube-summarizer/backend/services/perspective_agents.py

526 lines
21 KiB
Python

"""Multi-perspective analysis agents for YouTube video analysis."""
import asyncio
import json
import logging
from typing import Dict, List, Optional, Any
from datetime import datetime
from ..core.exceptions import ServiceError
from .deepseek_service import DeepSeekService
logger = logging.getLogger(__name__)
class BaseAnalysisAgent:
"""Base class for analysis agents."""
def __init__(self, agent_id: str, name: str, ai_service: Optional[DeepSeekService] = None):
"""Initialize the base analysis agent.
Args:
agent_id: Unique identifier for the agent
name: Human-readable name for the agent
ai_service: DeepSeek AI service instance
"""
self.agent_id = agent_id
self.name = name
self.ai_service = ai_service or DeepSeekService()
self.capabilities = self._get_capabilities()
def _get_capabilities(self) -> List[str]:
"""Get agent capabilities. Override in subclasses."""
return []
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
"""Execute agent analysis. Override in subclasses."""
raise NotImplementedError("Subclasses must implement execute method")
def get_capabilities(self) -> List[str]:
"""Get list of agent capabilities."""
return self.capabilities
class TechnicalAnalysisAgent(BaseAnalysisAgent):
"""Technical Analysis Agent for analyzing technical concepts and implementation details."""
def __init__(self, ai_service: Optional[DeepSeekService] = None):
"""Initialize the Technical Analysis Agent.
Args:
ai_service: DeepSeek AI service instance
"""
super().__init__(
agent_id="technical_analyst",
name="Technical Analysis Agent",
ai_service=ai_service
)
def _get_capabilities(self) -> List[str]:
"""Get technical analysis capabilities."""
return [
"technical_analysis",
"architecture_review",
"code_quality_assessment",
"performance_analysis",
"security_evaluation",
"scalability_assessment",
"technology_evaluation",
"implementation_guidance"
]
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
"""Execute technical analysis of video content."""
try:
start_time = datetime.now()
# Extract content from state
transcript = state.get("transcript", "")
video_id = state.get("video_id", "")
video_title = state.get("video_title", "")
if not transcript:
raise ServiceError("No transcript provided for technical analysis")
# Create technical analysis prompt
prompt = f"""
As a Technical Analyst, analyze this video content focusing on:
**Technical Concepts**: Identify and explain technical topics, technologies, frameworks, tools
**Architecture & Design**: Evaluate architectural patterns, design decisions, system design
**Implementation Details**: Analyze code examples, best practices, implementation strategies
**Performance & Scalability**: Assess performance implications and scalability considerations
**Security Aspects**: Identify security-related topics and considerations
Video: {video_title}
Transcript: {transcript[:4000]}...
Provide analysis in this JSON format:
{{
"summary": "Technical summary of the video content",
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
"focus_areas": ["area1", "area2", "area3"],
"recommendations": ["rec1", "rec2", "rec3"],
"confidence_score": 0.85,
"technical_concepts": ["concept1", "concept2", "concept3"],
"implementation_notes": "Key implementation considerations"
}}
"""
# Generate technical analysis
response = await self.ai_service.generate_response(
prompt,
temperature=0.3,
max_tokens=1500
)
# Parse JSON response
try:
analysis_data = json.loads(response)
except json.JSONDecodeError:
# Fallback parsing if JSON is malformed
analysis_data = {
"summary": response[:500] + "..." if len(response) > 500 else response,
"key_insights": ["Technical analysis completed"],
"focus_areas": ["Technical implementation"],
"recommendations": ["Review technical details"],
"confidence_score": 0.7,
"technical_concepts": ["General technical content"],
"implementation_notes": "Analysis completed"
}
# Calculate processing time
processing_time = (datetime.now() - start_time).total_seconds()
# Build result
result = {
"status": "success",
"analysis_results": {
"technical": {
"agent_type": "technical",
"agent_id": self.agent_id,
"summary": analysis_data.get("summary", ""),
"key_insights": analysis_data.get("key_insights", []),
"focus_areas": analysis_data.get("focus_areas", []),
"recommendations": analysis_data.get("recommendations", []),
"confidence_score": analysis_data.get("confidence_score", 0.8),
"technical_concepts": analysis_data.get("technical_concepts", []),
"implementation_notes": analysis_data.get("implementation_notes", ""),
"processing_time_seconds": processing_time
}
}
}
logger.info(f"Technical analysis completed for video {video_id} in {processing_time:.2f}s")
return result
except Exception as e:
logger.error(f"Error in technical analysis: {e}")
return {
"status": "error",
"error": str(e),
"agent_id": self.agent_id
}
class BusinessAnalysisAgent(BaseAnalysisAgent):
"""Business Analysis Agent for analyzing business value and strategic implications."""
def __init__(self, ai_service: Optional[DeepSeekService] = None):
"""Initialize the Business Analysis Agent.
Args:
ai_service: DeepSeek AI service instance
"""
super().__init__(
agent_id="business_analyst",
name="Business Analysis Agent",
ai_service=ai_service
)
def _get_capabilities(self) -> List[str]:
"""Get business analysis capabilities."""
return [
"business_value_assessment",
"market_analysis",
"roi_evaluation",
"strategic_planning",
"competitive_analysis",
"cost_benefit_analysis",
"business_case_development",
"stakeholder_analysis"
]
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
"""Execute business analysis of video content."""
try:
start_time = datetime.now()
# Extract content from state
transcript = state.get("transcript", "")
video_id = state.get("video_id", "")
video_title = state.get("video_title", "")
if not transcript:
raise ServiceError("No transcript provided for business analysis")
# Create business analysis prompt
prompt = f"""
As a Business Analyst, analyze this video content focusing on:
**Business Value**: Identify business opportunities, value propositions, market potential
**Strategic Implications**: Evaluate strategic impact, competitive advantages, market positioning
**ROI & Metrics**: Assess return on investment, key performance indicators, success metrics
**Market Analysis**: Analyze target markets, customer segments, market trends
**Risk Assessment**: Identify business risks, challenges, mitigation strategies
Video: {video_title}
Transcript: {transcript[:4000]}...
Provide analysis in this JSON format:
{{
"summary": "Business summary of the video content",
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
"focus_areas": ["area1", "area2", "area3"],
"recommendations": ["rec1", "rec2", "rec3"],
"confidence_score": 0.85,
"business_opportunities": ["opp1", "opp2", "opp3"],
"strategic_notes": "Key strategic considerations"
}}
"""
# Generate business analysis
response = await self.ai_service.generate_response(
prompt,
temperature=0.4,
max_tokens=1500
)
# Parse JSON response
try:
analysis_data = json.loads(response)
except json.JSONDecodeError:
# Fallback parsing if JSON is malformed
analysis_data = {
"summary": response[:500] + "..." if len(response) > 500 else response,
"key_insights": ["Business analysis completed"],
"focus_areas": ["Business strategy"],
"recommendations": ["Review business implications"],
"confidence_score": 0.7,
"business_opportunities": ["General business value"],
"strategic_notes": "Analysis completed"
}
# Calculate processing time
processing_time = (datetime.now() - start_time).total_seconds()
# Build result
result = {
"status": "success",
"analysis_results": {
"business": {
"agent_type": "business",
"agent_id": self.agent_id,
"summary": analysis_data.get("summary", ""),
"key_insights": analysis_data.get("key_insights", []),
"focus_areas": analysis_data.get("focus_areas", []),
"recommendations": analysis_data.get("recommendations", []),
"confidence_score": analysis_data.get("confidence_score", 0.8),
"business_opportunities": analysis_data.get("business_opportunities", []),
"strategic_notes": analysis_data.get("strategic_notes", ""),
"processing_time_seconds": processing_time
}
}
}
logger.info(f"Business analysis completed for video {video_id} in {processing_time:.2f}s")
return result
except Exception as e:
logger.error(f"Error in business analysis: {e}")
return {
"status": "error",
"error": str(e),
"agent_id": self.agent_id
}
class UserExperienceAgent(BaseAnalysisAgent):
"""User Experience Agent for analyzing usability and user-centric aspects."""
def __init__(self, ai_service: Optional[DeepSeekService] = None):
"""Initialize the User Experience Agent.
Args:
ai_service: DeepSeek AI service instance
"""
super().__init__(
agent_id="ux_analyst",
name="User Experience Agent",
ai_service=ai_service
)
def _get_capabilities(self) -> List[str]:
"""Get user experience analysis capabilities."""
return [
"user_experience_evaluation",
"usability_assessment",
"accessibility_analysis",
"user_journey_mapping",
"interaction_design_review",
"user_research_insights",
"conversion_optimization",
"user_feedback_analysis"
]
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
"""Execute user experience analysis of video content."""
try:
start_time = datetime.now()
# Extract content from state
transcript = state.get("transcript", "")
video_id = state.get("video_id", "")
video_title = state.get("video_title", "")
if not transcript:
raise ServiceError("No transcript provided for UX analysis")
# Create UX analysis prompt
prompt = f"""
As a User Experience Analyst, analyze this video content focusing on:
**User Experience**: Evaluate user-centric design, usability principles, user satisfaction
**Accessibility**: Assess accessibility considerations, inclusive design, universal access
**User Journey**: Analyze user workflows, interaction patterns, user pain points
**Interface Design**: Evaluate UI/UX design principles, visual design, interaction design
**User Research**: Identify user needs, behaviors, preferences, feedback
Video: {video_title}
Transcript: {transcript[:4000]}...
Provide analysis in this JSON format:
{{
"summary": "UX summary of the video content",
"key_insights": ["insight1", "insight2", "insight3", "insight4", "insight5"],
"focus_areas": ["area1", "area2", "area3"],
"recommendations": ["rec1", "rec2", "rec3"],
"confidence_score": 0.85,
"usability_factors": ["factor1", "factor2", "factor3"],
"accessibility_notes": "Key accessibility considerations"
}}
"""
# Generate UX analysis
response = await self.ai_service.generate_response(
prompt,
temperature=0.4,
max_tokens=1500
)
# Parse JSON response
try:
analysis_data = json.loads(response)
except json.JSONDecodeError:
# Fallback parsing if JSON is malformed
analysis_data = {
"summary": response[:500] + "..." if len(response) > 500 else response,
"key_insights": ["UX analysis completed"],
"focus_areas": ["User experience"],
"recommendations": ["Review user-centric design"],
"confidence_score": 0.7,
"usability_factors": ["General usability"],
"accessibility_notes": "Analysis completed"
}
# Calculate processing time
processing_time = (datetime.now() - start_time).total_seconds()
# Build result
result = {
"status": "success",
"analysis_results": {
"user_experience": {
"agent_type": "user_experience",
"agent_id": self.agent_id,
"summary": analysis_data.get("summary", ""),
"key_insights": analysis_data.get("key_insights", []),
"focus_areas": analysis_data.get("focus_areas", []),
"recommendations": analysis_data.get("recommendations", []),
"confidence_score": analysis_data.get("confidence_score", 0.8),
"usability_factors": analysis_data.get("usability_factors", []),
"accessibility_notes": analysis_data.get("accessibility_notes", ""),
"processing_time_seconds": processing_time
}
}
}
logger.info(f"UX analysis completed for video {video_id} in {processing_time:.2f}s")
return result
except Exception as e:
logger.error(f"Error in UX analysis: {e}")
return {
"status": "error",
"error": str(e),
"agent_id": self.agent_id
}
class SynthesisAgent(BaseAnalysisAgent):
"""Synthesis Agent for combining multiple perspective analyses into unified insights."""
def __init__(self, ai_service: Optional[DeepSeekService] = None):
"""Initialize the Synthesis Agent.
Args:
ai_service: DeepSeek AI service instance
"""
super().__init__(
agent_id="synthesis_agent",
name="Synthesis Agent",
ai_service=ai_service
)
def _get_capabilities(self) -> List[str]:
"""Get synthesis capabilities."""
return [
"multi_perspective_synthesis",
"insight_integration",
"cross_domain_analysis",
"pattern_identification",
"recommendation_consolidation",
"holistic_evaluation",
"strategic_synthesis",
"unified_reporting"
]
async def execute(self, state: Dict[str, Any]) -> Dict[str, Any]:
"""Execute synthesis of multiple perspective analyses."""
try:
start_time = datetime.now()
# Extract content from state
analysis_results = state.get("analysis_results", {})
transcript = state.get("transcript", "")
video_id = state.get("video_id", "")
video_title = state.get("video_title", "")
if not analysis_results:
raise ServiceError("No analysis results provided for synthesis")
# Create synthesis prompt
prompt = f"""
As a Synthesis Agent, combine these multiple perspective analyses into unified insights:
Video: {video_title}
Analysis Results:
{json.dumps(analysis_results, indent=2)}
Provide synthesis in this JSON format:
{{
"summary": "Unified summary combining all perspectives",
"unified_insights": ["insight1", "insight2", "insight3", "insight4", "insight5", "insight6", "insight7", "insight8"],
"cross_cutting_themes": ["theme1", "theme2", "theme3"],
"recommendations": ["rec1", "rec2", "rec3", "rec4", "rec5"],
"confidence_score": 0.85,
"perspective_alignment": "How well the different perspectives align",
"key_takeaways": ["takeaway1", "takeaway2", "takeaway3"]
}}
"""
# Generate synthesis
response = await self.ai_service.generate_response(
prompt,
temperature=0.3,
max_tokens=2000
)
# Parse JSON response
try:
analysis_data = json.loads(response)
except json.JSONDecodeError:
# Fallback parsing if JSON is malformed
analysis_data = {
"summary": response[:500] + "..." if len(response) > 500 else response,
"unified_insights": ["Synthesis analysis completed"],
"cross_cutting_themes": ["General themes"],
"recommendations": ["Review combined analysis"],
"confidence_score": 0.7,
"perspective_alignment": "Analysis completed",
"key_takeaways": ["Combined insights available"]
}
# Calculate processing time
processing_time = (datetime.now() - start_time).total_seconds()
# Build result
result = {
"status": "success",
"analysis_results": {
"synthesis": {
"agent_type": "synthesis",
"agent_id": self.agent_id,
"summary": analysis_data.get("summary", ""),
"unified_insights": analysis_data.get("unified_insights", []),
"cross_cutting_themes": analysis_data.get("cross_cutting_themes", []),
"recommendations": analysis_data.get("recommendations", []),
"confidence_score": analysis_data.get("confidence_score", 0.8),
"perspective_alignment": analysis_data.get("perspective_alignment", ""),
"key_takeaways": analysis_data.get("key_takeaways", []),
"processing_time_seconds": processing_time
}
}
}
logger.info(f"Synthesis completed for video {video_id} in {processing_time:.2f}s")
return result
except Exception as e:
logger.error(f"Error in synthesis: {e}")
return {
"status": "error",
"error": str(e),
"agent_id": self.agent_id
}