Spaces:
Build error
Build error
Refactor chat interface for improved user experience - Updated the chat interface to enhance user interaction by refining the layout and adding new features. This update aims to provide a more intuitive and engaging experience for users while utilizing the music discovery functionalities.
481a1d6 | # LLM Fallback System Design Document | |
| **Date**: January 2025 | |
| **Author**: BeatDebate Team | |
| **Status**: Design Phase | |
| **Review Status**: Pending | |
| --- | |
| ## 1. Problem Statement | |
| **Objective**: Implement a graceful fallback mechanism for music queries that fall outside BeatDebate's predefined intent categories, ensuring users always receive music recommendations even when queries exceed the specialized 4-agent system's scope. | |
| **Current State**: BeatDebate's 4-agent system excels at handling specific intent categories (By Artist, Artist Similarity, Discovery, Genre/Mood, Contextual, Hybrid, Follow-ups). However, when users submit queries outside these categories or when the backend fails to return recommendations, users may receive error messages or no response. | |
| **Value Proposition**: | |
| - **100% Query Coverage**: Every user query gets a music recommendation response | |
| - **Graceful Degradation**: Maintain service quality even for edge cases | |
| - **Transparent Experience**: Users understand when fallback is used | |
| - **System Robustness**: Handle backend failures and unknown intents seamlessly | |
| - **User Retention**: Prevent abandonment due to failed queries | |
| --- | |
| ## 2. Goals & Non-Goals | |
| ### ✅ In Scope | |
| - **Fallback Trigger Detection**: Identify when to use LLM fallback (unknown intent or failed recommendations) | |
| - **Gemini Flash 2.0 Integration**: Leverage existing LLM infrastructure for fallback recommendations | |
| - **Response Format Consistency**: Maintain same UI format with clear fallback disclaimer | |
| - **Error Handling**: Graceful handling of both unknown intents and system failures | |
| - **User Transparency**: Clear indication when fallback system is active | |
| - **Chat History Integration**: Include conversation context in fallback requests | |
| - **Track Info Display**: Format fallback responses for Last.fm/Spotify/YouTube links | |
| ### ❌ Out of Scope (v1) | |
| - **Complex Fallback Logic**: Advanced multi-agent fallback (single LLM call only) | |
| - **Fallback Analytics**: Detailed tracking of fallback usage patterns | |
| - **Fallback Caching**: Caching of fallback responses | |
| - **Custom Fallback Models**: Using different LLMs for different query types | |
| - **Fallback Training**: Fine-tuning models for music recommendations | |
| --- | |
| ## 3. Architecture Overview | |
| ``` | |
| User Query | |
| ↓ | |
| ┌─────────────────────────┐ | |
| │ Chat Interface │ | |
| │ (Frontend) │ | |
| └────────────┬────────────┘ | |
| │ | |
| ▼ | |
| ┌─────────────────────────┐ | |
| │ Backend API │ | |
| │ /recommendations │ | |
| └────────────┬────────────┘ | |
| │ | |
| Success? ─────────── No ────┐ | |
| │ │ | |
| Yes │ | |
| │ ▼ | |
| ▼ ┌─────────────────────────┐ | |
| ┌─────────────────────────┐ │ LLM Fallback │ | |
| │ 4-Agent System │ │ (Gemini Flash 2.0) │ | |
| │ Response │ │ │ | |
| └─────────────────────────┘ └────────────┬────────────┘ | |
| │ │ | |
| │ ▼ | |
| │ ┌─────────────────────────┐ | |
| │ │ Fallback Response │ | |
| │ │ Formatter │ | |
| │ └────────────┬────────────┘ | |
| │ │ | |
| ▼ ▼ | |
| ┌─────────────────────────────────────────────────────┐ | |
| │ Chat Interface Response │ | |
| │ (Same Format + Disclaimer) │ | |
| └─────────────────────────────────────────────────────┘ | |
| ``` | |
| --- | |
| ## 4. Technical Design | |
| ### 4.1 Fallback Trigger Detection | |
| #### 4.1.1 Backend Response Analysis | |
| ```python | |
| class FallbackTrigger(Enum): | |
| UNKNOWN_INTENT = "unknown_intent" # Backend returns unknown intent | |
| NO_RECOMMENDATIONS = "no_recommendations" # Backend returns empty results | |
| API_ERROR = "api_error" # Backend returns error status | |
| TIMEOUT = "timeout" # Backend request timeout | |
| ``` | |
| #### 4.1.2 Trigger Detection Logic | |
| ```python | |
| async def _should_use_fallback(self, response: Optional[Dict]) -> Tuple[bool, FallbackTrigger]: | |
| """ | |
| Determine if fallback should be used based on backend response. | |
| Returns: | |
| Tuple of (should_fallback, trigger_reason) | |
| """ | |
| if response is None: | |
| return True, FallbackTrigger.API_ERROR | |
| if response.get("intent") == "unknown" or response.get("intent") == "unsupported": | |
| return True, FallbackTrigger.UNKNOWN_INTENT | |
| recommendations = response.get("recommendations", []) | |
| if not recommendations or len(recommendations) == 0: | |
| return True, FallbackTrigger.NO_RECOMMENDATIONS | |
| return False, None | |
| ``` | |
| ### 4.2 LLM Fallback Service | |
| #### 4.2.1 Fallback Request Structure | |
| ```python | |
| @dataclass | |
| class FallbackRequest: | |
| query: str | |
| session_id: str | |
| chat_context: Optional[Dict] = None | |
| trigger_reason: FallbackTrigger = None | |
| max_recommendations: int = 10 | |
| ``` | |
| #### 4.2.2 Gemini Integration | |
| ```python | |
| class LLMFallbackService: | |
| """Service for handling LLM-based music recommendations when 4-agent system fails.""" | |
| def __init__(self, gemini_client): | |
| self.gemini_client = gemini_client | |
| self.logger = logging.getLogger(__name__) | |
| async def get_fallback_recommendations( | |
| self, | |
| request: FallbackRequest | |
| ) -> Dict[str, Any]: | |
| """ | |
| Get music recommendations from Gemini Flash 2.0 as fallback. | |
| Args: | |
| request: Fallback request with query and context | |
| Returns: | |
| Formatted response matching regular recommendation format | |
| """ | |
| prompt = self._build_fallback_prompt(request) | |
| try: | |
| response = await self.gemini_client.generate_content_async(prompt) | |
| parsed_response = self._parse_gemini_response(response) | |
| return { | |
| "recommendations": parsed_response["tracks"], | |
| "explanation": parsed_response["explanation"], | |
| "fallback_used": True, | |
| "fallback_reason": request.trigger_reason.value, | |
| "confidence": 0.7 # Default fallback confidence | |
| } | |
| except Exception as e: | |
| self.logger.error(f"Fallback service failed: {e}") | |
| return self._create_emergency_response(request.query) | |
| ``` | |
| #### 4.2.3 Fallback Prompt Engineering | |
| ```python | |
| def _build_fallback_prompt(self, request: FallbackRequest) -> str: | |
| """Build optimized prompt for music recommendations.""" | |
| context_info = "" | |
| if request.chat_context: | |
| previous_queries = request.chat_context.get("previous_queries", []) | |
| if previous_queries: | |
| context_info = f"\nConversation context: {', '.join(previous_queries[-2:])}" | |
| prompt = f""" | |
| You are a music recommendation assistant. The user asked: "{request.query}"{context_info} | |
| Provide exactly {request.max_recommendations} music track recommendations in this JSON format: | |
| {{ | |
| "tracks": [ | |
| {{ | |
| "title": "Track Name", | |
| "artist": "Artist Name", | |
| "confidence": 0.85, | |
| "reason": "Brief explanation why this fits the request" | |
| }} | |
| ], | |
| "explanation": "Overall explanation of the recommendation approach" | |
| }} | |
| Guidelines: | |
| - Focus on diverse, high-quality music recommendations | |
| - Include mix of popular and lesser-known tracks when appropriate | |
| - Ensure artist and title are accurate and searchable | |
| - Provide confidence scores between 0.6-0.9 | |
| - Keep reasons concise but meaningful | |
| - Consider the conversation context if provided | |
| Respond ONLY with valid JSON. | |
| """ | |
| return prompt | |
| ``` | |
| ### 4.3 Chat Interface Integration | |
| #### 4.3.1 Modified Process Flow | |
| ```python | |
| async def process_message( | |
| self, | |
| message: str, | |
| history: List[Tuple[str, str]] | |
| ) -> Tuple[str, List[Tuple[str, str]], str]: | |
| """Enhanced process_message with fallback support.""" | |
| if not message.strip(): | |
| return "", history, "" | |
| logger.info(f"Processing message: {message}") | |
| try: | |
| # Primary: Get recommendations from 4-agent system | |
| recommendations_response = await self._get_recommendations(message) | |
| # Check if fallback is needed | |
| should_fallback, trigger_reason = await self._should_use_fallback( | |
| recommendations_response | |
| ) | |
| if should_fallback: | |
| logger.info(f"Using LLM fallback due to: {trigger_reason.value}") | |
| recommendations_response = await self._get_fallback_recommendations( | |
| message, trigger_reason | |
| ) | |
| if recommendations_response: | |
| # Format response with fallback indicator | |
| formatted_response = self.response_formatter.format_recommendations( | |
| recommendations_response | |
| ) | |
| # Add to history and create player HTML | |
| history.append((message, formatted_response)) | |
| self._update_conversation_history(message, formatted_response, recommendations_response) | |
| lastfm_player_html = self._create_lastfm_player_html( | |
| recommendations_response.get("recommendations", []) | |
| ) | |
| return "", history, lastfm_player_html | |
| else: | |
| # Emergency fallback | |
| error_response = self._create_emergency_response(message) | |
| history.append((message, error_response)) | |
| return "", history, "" | |
| except Exception as e: | |
| logger.error(f"Error processing message: {e}") | |
| error_response = f"An error occurred: {str(e)}" | |
| history.append((message, error_response)) | |
| return "", history, "" | |
| ``` | |
| #### 4.3.2 Fallback Response Formatting | |
| ```python | |
| async def _get_fallback_recommendations( | |
| self, | |
| query: str, | |
| trigger_reason: FallbackTrigger | |
| ) -> Dict[str, Any]: | |
| """Get fallback recommendations from LLM service.""" | |
| fallback_request = FallbackRequest( | |
| query=query, | |
| session_id=self.session_id, | |
| chat_context=self._get_chat_context(), | |
| trigger_reason=trigger_reason, | |
| max_recommendations=10 | |
| ) | |
| fallback_response = await self.fallback_service.get_fallback_recommendations( | |
| fallback_request | |
| ) | |
| # Add fallback disclaimer to response | |
| if fallback_response and fallback_response.get("fallback_used"): | |
| # Insert disclaimer at the beginning of explanation | |
| original_explanation = fallback_response.get("explanation", "") | |
| fallback_explanation = ( | |
| f"**⚠️ DEFAULTING TO REGULAR LLM** - This query is outside our " | |
| f"specialized 4-agent system's scope.\n\n{original_explanation}" | |
| ) | |
| fallback_response["explanation"] = fallback_explanation | |
| return fallback_response | |
| ``` | |
| ### 4.4 Response Formatter Updates | |
| #### 4.4.1 Fallback Indicator Styling | |
| ```python | |
| class ResponseFormatter: | |
| def format_recommendations(self, response: Dict[str, Any]) -> str: | |
| """Enhanced formatter with fallback indication.""" | |
| if response.get("fallback_used"): | |
| disclaimer = self._create_fallback_disclaimer( | |
| response.get("fallback_reason", "unknown") | |
| ) | |
| formatted_response = f"{disclaimer}\n\n{self._format_tracks(response)}" | |
| else: | |
| formatted_response = self._format_tracks(response) | |
| return formatted_response | |
| def _create_fallback_disclaimer(self, reason: str) -> str: | |
| """Create styled fallback disclaimer.""" | |
| return ( | |
| "🔄 **DEFAULTING TO REGULAR LLM**\n" | |
| "*This query is outside our specialized 4-agent system's scope. " | |
| "Using general AI assistance for recommendations.*\n" | |
| "---" | |
| ) | |
| ``` | |
| --- | |
| ## 5. Implementation Plan | |
| ### 5.1 Phase 1: Core Fallback Infrastructure (Week 1) | |
| 1. **LLMFallbackService Implementation** | |
| - Create `src/services/llm_fallback_service.py` | |
| - Implement Gemini Flash 2.0 integration | |
| - Add fallback prompt engineering | |
| - Create fallback response parsing | |
| 2. **Trigger Detection Logic** | |
| - Enhance `chat_interface.py` with fallback detection | |
| - Add `FallbackTrigger` enum and detection methods | |
| - Update `_get_recommendations` method | |
| 3. **Basic Testing** | |
| - Unit tests for `LLMFallbackService` | |
| - Unit tests for trigger detection | |
| - Mock Gemini responses for testing | |
| ### 5.2 Phase 2: UI Integration (Week 1) | |
| 1. **Response Formatter Updates** | |
| - Add fallback disclaimer formatting | |
| - Ensure consistent track display format | |
| - Maintain Last.fm/Spotify/YouTube links | |
| 2. **Chat Interface Updates** | |
| - Integrate fallback service into message processing | |
| - Update conversation history handling | |
| - Add fallback logging and monitoring | |
| 3. **Integration Testing** | |
| - End-to-end testing with mock failures | |
| - Test various fallback scenarios | |
| - Verify UI consistency | |
| ### 5.3 Phase 3: Testing & Refinement (Week 1-2) | |
| 1. **Comprehensive Testing** | |
| - Test unknown intent queries | |
| - Test backend failure scenarios | |
| - Test conversation context preservation | |
| - Performance testing | |
| 2. **Prompt Optimization** | |
| - Refine Gemini prompts for better music recommendations | |
| - Test edge cases and unusual queries | |
| - Optimize response quality | |
| 3. **Documentation & Monitoring** | |
| - Update API documentation | |
| - Add monitoring for fallback usage | |
| - Create troubleshooting guides | |
| --- | |
| ## 6. Risk Analysis & Mitigation | |
| ### 6.1 Technical Risks | |
| **Risk**: Gemini API failures causing total system failure | |
| **Mitigation**: | |
| - Implement emergency response for double-failures | |
| - Add retry logic with exponential backoff | |
| - Create static fallback recommendations for critical failures | |
| **Risk**: Fallback response quality significantly lower than 4-agent system | |
| **Mitigation**: | |
| - Extensive prompt engineering and testing | |
| - Clear user expectations through disclaimer | |
| - Monitor user feedback and iterate | |
| **Risk**: Response time degradation due to additional LLM call | |
| **Mitigation**: | |
| - Implement async processing | |
| - Set reasonable timeout limits | |
| - Consider caching common fallback responses | |
| ### 6.2 User Experience Risks | |
| **Risk**: Users might prefer fallback over main system | |
| **Mitigation**: | |
| - Clear messaging about specialized system capabilities | |
| - Ensure 4-agent system provides superior recommendations for in-scope queries | |
| - Monitor usage patterns | |
| **Risk**: Fallback disclaimer might reduce trust | |
| **Mitigation**: | |
| - Frame as "additional coverage" rather than "failure" | |
| - Emphasize transparency as a feature | |
| - Provide clear indication of when main system is active | |
| --- | |
| ## 7. Success Metrics | |
| ### 7.1 Functional Metrics | |
| - **Query Coverage**: 100% of queries receive some form of recommendation | |
| - **Fallback Accuracy**: Fallback triggers correctly identify edge cases | |
| - **Response Consistency**: Fallback responses maintain UI format standards | |
| - **Error Reduction**: Significant decrease in failed query responses | |
| ### 7.2 Quality Metrics | |
| - **Response Time**: Fallback responses within 5-10 seconds | |
| - **Recommendation Quality**: User feedback on fallback recommendations | |
| - **Context Preservation**: Chat context maintained across fallback usage | |
| - **System Robustness**: Graceful handling of all failure scenarios | |
| --- | |
| ## 8. Future Enhancements | |
| ### 8.1 Advanced Fallback Logic | |
| - Multi-step fallback with different LLMs | |
| - Specialized fallback agents for different query types | |
| - Hybrid fallback combining multiple data sources | |
| ### 8.2 Fallback Analytics | |
| - Detailed tracking of fallback usage patterns | |
| - A/B testing of different fallback approaches | |
| - User preference learning for fallback scenarios | |
| ### 8.3 Proactive Fallback | |
| - Confidence-based fallback triggering | |
| - Parallel execution of main system and fallback | |
| - Smart routing based on query analysis | |
| --- | |
| ## 9. Conclusion | |
| The LLM Fallback System design provides a robust safety net for BeatDebate, ensuring every user query receives a meaningful response while maintaining transparency about system capabilities. This approach balances user experience with technical robustness, creating a more reliable and trustworthy music recommendation system. | |
| The phased implementation approach allows for iterative refinement while minimizing risk to the existing 4-agent system. The clear architectural separation ensures the fallback mechanism can be enhanced independently without affecting core functionality. | |
| --- | |
| **Document Version**: 1.0 | |
| **Created**: January 2025 | |
| **Status**: Design Phase | |
| **Next Phase**: Implementation Planning |