ADR-0012 — Intent-Aware Sorting Strategy¶
Context¶
Natural language queries in tmdbGPT Phase 1 often contain implicit sorting preferences that standard popularity-based sorting doesn't capture effectively. Users express temporal, quality, and contextual sorting intents through keywords that require intelligent interpretation:
- Temporal Intent: "Latest movies by A24", "First films by Steven Spielberg"
- Quality Intent: "Best rated horror movies", "Worst Adam Sandler movies"
- Contextual Intent: List queries benefit from popularity sorting, while specific intents need specialized parameters
The challenge was developing a systematic approach to detect user sorting preferences from natural language and translate them into appropriate TMDB API sort_by parameters while maintaining backward compatibility with existing query processing.
Decision¶
Implement Intent-Aware Sorting Strategy using keyword-based pattern matching with hierarchical intent detection and automatic parameter injection into execution steps.
Core Strategy: - Analyze user queries for temporal, quality, and popularity sorting keywords - Apply hierarchical intent detection (temporal > quality > popularity default) - Inject appropriate TMDB API sort parameters into execution steps - Override existing sort parameters when user intent is detected - Maintain comprehensive keyword coverage for robust natural language handling
Technical Implementation:
class IntentAwareSorting:
# Intent keyword mapping with comprehensive coverage
TEMPORAL_RECENT_KEYWORDS = ["latest", "recent", "newest", "new", "current", "most recent"]
TEMPORAL_CHRONOLOGICAL_KEYWORDS = ["first", "earliest", "debut", "initial", "original", "chronological"]
QUALITY_HIGH_KEYWORDS = ["highest rated", "best rated", "top rated", "highly rated", "best reviewed", "greatest"]
QUALITY_LOW_KEYWORDS = ["worst", "bad", "terrible", "lowest rated", "poorly rated", "awful", "horrible"]
@classmethod
def determine_sort_strategy(cls, query: str, question_type: str = None) -> Optional[Dict[str, str]]:
query_lower = query.lower()
# Hierarchical intent detection (temporal > quality > popularity)
temporal_sort = cls._check_temporal_intent(query_lower)
if temporal_sort:
return temporal_sort
quality_sort = cls._check_quality_intent(query_lower)
if quality_sort:
return quality_sort
# Default popularity for list queries
if question_type == "list":
return {"sort_by": "popularity.desc"}
return None
@classmethod
def _check_temporal_intent(cls, query_lower: str) -> Optional[Dict[str, str]]:
# Recent/latest intent - newest first
if any(keyword in query_lower for keyword in cls.TEMPORAL_RECENT_KEYWORDS):
return {"sort_by": "release_date.desc"}
# Chronological/first intent - oldest first
if any(keyword in query_lower for keyword in cls.TEMPORAL_CHRONOLOGICAL_KEYWORDS):
return {"sort_by": "release_date.asc"}
return None
@classmethod
def _check_quality_intent(cls, query_lower: str) -> Optional[Dict[str, str]]:
# High quality intent - best rated first with minimum vote threshold
if any(keyword in query_lower for keyword in cls.QUALITY_HIGH_KEYWORDS):
return {
"sort_by": "vote_average.desc",
"vote_count.gte": "50" # Meaningful ratings threshold
}
# Low quality intent - worst rated first with lower vote threshold
if any(keyword in query_lower for keyword in cls.QUALITY_LOW_KEYWORDS):
return {
"sort_by": "vote_average.asc",
"vote_count.gte": "10" # Bad movies get fewer votes
}
return None
Pipeline Integration:
# Main pipeline integration (app.py)
question_type = state.extraction_result.get("question_type")
for step in execution_steps:
step = IntentAwareSorting.apply_sort_to_step_parameters(step, state.input, question_type)
# Company/network query integration (plan_utils.py)
company_step = IntentAwareSorting.apply_sort_to_step_parameters(company_step, state.input, question_type)
Consequences¶
Positive¶
- Semantic Query Alignment: "Latest movies by A24" correctly uses
release_date.descinstead of generic popularity sorting - Quality-Aware Results: "Best rated horror movies" applies
vote_average.descwith minimum vote thresholds for meaningful results - Temporal Functionality: Timeline queries like "First movies by Steven Spielberg" get chronological ordering (
release_date.asc) - Backward Compatibility: Existing queries without specific intent continue using popularity-based sorting
- Hierarchical Priority: Temporal intent overrides quality intent, which overrides popularity default
- Comprehensive Coverage: Extensive keyword mapping handles natural language variations
Negative¶
- Keyword-Based Limitations: Relies on predefined keyword matching rather than semantic understanding
- Override Behavior: Always overrides existing
sort_byparameters when user intent detected - Maintenance Overhead: Keyword lists require updates for new user intent patterns
- Debug Output: Produces console debug output during intent analysis
Performance Impact¶
- Minimal Processing Overhead: Simple keyword matching with O(n) complexity over keyword lists
- API Efficiency: Quality queries include vote count thresholds to filter out unreliable ratings
- Result Relevance: Intent-specific sorting improves result relevance for temporal and quality queries
Compliance¶
This strategy follows established software engineering practices: - Single Responsibility: Clear separation between intent detection and parameter injection - Open-Closed Principle: Easily extensible for new intent types without modifying existing code - Dependency Injection: Applied as a pipeline stage without tight coupling to other components - Defensive Programming: Handles missing parameters gracefully with sensible defaults
Related Decisions¶
- Complements ADR-0011 Temporal Sorting and Constraint Interaction Pattern by providing the intent detection mechanism
- Builds on existing TMDB API parameter mapping strategies established in financial constraint ADRs
- Integrates with the pipeline architecture without disrupting existing constraint validation or filtering logic
- Establishes foundation for future semantic intent understanding beyond keyword-based detection
Validation Results¶
Temporal Intent Queries:
✅ "Latest movies by A24" → sort_by: release_date.desc
✅ "Recent Christopher Nolan films" → sort_by: release_date.desc
✅ "First movies by Steven Spielberg" → sort_by: release_date.asc + timeline query processing
✅ "Earliest Quentin Tarantino films" → sort_by: release_date.asc
Quality Intent Queries:
✅ "Best rated horror movies" → sort_by: vote_average.desc + vote_count.gte: 50
✅ "Highest rated dramas from 2023" → sort_by: vote_average.desc + quality thresholds
✅ "Worst Adam Sandler movies" → sort_by: vote_average.asc + vote_count.gte: 10
✅ "Terrible comedy movies" → sort_by: vote_average.asc + quality thresholds
List Query Defaults:
✅ "Movies by Marvel Studios" → sort_by: popularity.desc (no specific intent)
✅ "HBO shows" → sort_by: popularity.desc (list query default)
✅ "Action movies from 2023" → sort_by: popularity.desc (discovery queries)
Intent Hierarchy Validation:
✅ "Latest best rated movies" → sort_by: release_date.desc (temporal overrides quality)
✅ "First highly rated films by Nolan" → sort_by: release_date.asc (temporal precedence)
✅ "Recent terrible horror movies" → sort_by: release_date.desc (temporal over quality)
Integration Testing: - Pipeline Integration: Successfully applied to all execution steps without disrupting existing functionality - Company/Network Queries: Proper integration with symbol-free query routing - Timeline Query Coordination: Seamless interaction with constraint validation bypass logic - Regression Prevention: All existing queries maintain expected behavior when no specific intent detected
Performance Metrics: - Intent Detection Speed: <1ms for keyword analysis across all intent categories - Parameter Injection: Zero measurable overhead during step parameter modification - Result Quality: Improved relevance for temporal and quality-based queries without degrading other query types