-
Notifications
You must be signed in to change notification settings - Fork 1
4.1 Preferences Module
preferences.py is a module designed to pick up on a user's preferences, for example, likes or dislikes for example. The goal is to allow for a more customized approach to conversations between the user and LLM, allowing for it to feel less "robotic" and have a more natural flow while chatting. This should also allow the app to pick up on other things relevant to the user in other ways, helping it make suggestions, decisions and use of memories or other tools.
This file implements a PreferenceExtractor system that can analyze text and identify what users like, dislike, love, or hate. It's designed to work with your chatbot's memory system to build user profiles.
The file uses several key libraries:
- spacy: For advanced natural language processing (optional fallback if not available)
- re: For regex pattern matching
- dataclasses: For clean data structures
- enum: For defining constants
- typing: For type hints, list, dict, optional
- logging: For logging
Tracks how a preference was found:
- REGEX_PATTERN: Found using regex patterns
- SPACY_ENTITY: Found using spaCy's entity recognition
- SPACY_DEPENDENCY: Found using spaCy's dependency parsing
- SENTIMENT_ANALYSIS: Found using sentiment analysis
Defines the strength of preferences:
LIKES, DISLIKES, LOVES, HATES, NEUTRAL
This is a dataclass that stores each extracted preference:
@dataclass
class PreferenceResult:
user_id: str # Who said it
preference_type: str # likes/dislikes/loves/hates
preference_category: str # food/games/activities/etc
preference_value: str # the actual thing (e.g., "pizza")
confidence: float # how sure we are (0.0-1.0)
extraction_method: str # how we found it
context: str # surrounding text
original_input: str # full original text
notes: Optional[str] = None # extra info@dataclassThis is where the magic happens! Let's break down its key methods:
init()
- Tries to load spaCy models (large first, then small, then fallback)
- Sets up regex patterns and spaCy matchers
- Defines categories (food, games, colors, etc.)
- Sets confidence thresholds
This is the method you'd call to extract preferences from text.
What it does:
- Handles compound sentences (splits on "but")
- Runs multiple extraction methods
- Filters by confidence
- Validates and deduplicates results
- Applies sentiment hierarchy
Pattern matching is a simple (and possibly obvious) method for targeting words that would identify a potential preference.
This uses regex patterns like:
-
"i love [something]"→ confidence 0.85, type:LOVES -
"i don't like [something]"→ confidence 0.8, type:DISLIKES -
"my favorite [something] is [item]"→ confidence 0.9, type:LOVES
NLP (Natural Language Processing) and NER (Named Entity Recognition) are AI tools that can help a user parse input text to identify possible preferences and objects that align with the identified preference. This uses spaCy's linguistic analysis to find preferences in more complex sentences.
Splits text like "I like pizza and pasta" into separate preferences for "pizza" and "pasta".
Filters out noise like:
- Too short/long text
- Just sentiment words (
"love","hate") - Mostly stop words (
"the","and","but")
Tries to classify preferences into categories like "food", "games", "activities", etc. It will need to be updated periodically to add more categories as they become relevant, likely after reviewing chat logs and other collected data from usage.
Here's an example flow when you call extract_preferences("I love pizza but hate mushrooms"):
-
Split compound sentence:
"I love pizza"+"I hate mushrooms" - Run regex patterns on each part
- Run spaCy analysis (if available)
-
Parse objects: Extract
"pizza"and"mushrooms" -
Validate: Check if
"pizza"and"mushrooms"are valid preferences -
Categorize: Classify both as
"food" -
Create results: Two
PreferenceResultobjects - Return: List of validated, high-confidence preferences
- Hybrid approach: Uses both simple regex AND advanced NLP
- Confidence scoring: Knows how sure it is about each preference
- Graceful degradation: Works even if spaCy isn't installed
- Extensible: Easy to add new patterns or categories
- Validation: Filters out noise and invalid results
This module is built with simple yet robust, production-ready code that handles edge cases and provides multiple fallback options. It may require periodic updates for other cases and exceptions if ever needed, but it covers most of the bases of finding user preferences within the nuances of the use of the English language around grammatical rules and syntax.
The PreferenceExtractor uses a sophisticated confidence scoring system to ensure only high-quality preferences are extracted and stored.
-
Explicit favorites:
0.9- "My favorite food is pizza" -
Strong emotions (love/hate):
0.85- "I love pizza" / "I hate mushrooms" -
Clear dislikes:
0.8- "I don't like olives" -
Moderate preferences:
0.75- "I like pasta" / "I enjoy cooking"
-
Default minimum threshold:
0.6filters out uncertain extractions - Higher confidence = more reliable for building user profiles
- Prevents noise from ambiguous statements like "pizza is okay" (would score ~0.4)
- Intensity words: "really love" gets higher confidence than just "love"
- Explicit patterns: "My favorite X is Y" gets maximum confidence
- Clear negation: "don't like" is more confident than implied dislike
"I absolutely love chocolate" → 0.85 (LOVES)
"My favorite game is Minecraft" → 0.9 (LOVES)
"I don't really like horror movies" → 0.8 (DISLIKES)
"Pizza is pretty good" → 0.4 (filtered out - below threshold)The system uses a hybrid approach that gracefully handles different installation scenarios:
-
First attempt: Load
en_core_web_lg(large model, best accuracy) -
Fallback: Load
en_core_web_sm(small model, good performance) - Final fallback: Regex-only mode (no spaCy required)
- Regex patterns still work - covers 80% of common preference expressions
- Performance impact: Minimal - regex is actually faster
- Accuracy trade-off: May miss complex grammatical structures
- No dependency issues - works on any Python installation
- Advanced parsing: Handles complex sentence structures
- Entity recognition: Better at identifying compound nouns ("chocolate ice cream")
- Dependency parsing: Understands relationships between words
- Contextual understanding: Can handle more nuanced expressions
# Regex-only mode:
"I love pizza" ✅ (0.85 confidence)
"Pizza is my favorite food" ✅ (0.9 confidence)
# spaCy enhancement:
"The pizza I had yesterday was amazing" ✅ (spaCy catches this)
"I'm not a fan of spicy food" ✅ (spaCy understands negation better)- Production servers: spaCy recommended for best accuracy
- Lightweight deployments: Regex-only is sufficient for basic needs
- Development/testing: Either works fine
- Adding new preference categories.
- Integrating this module with the updated MemoryManager module.
- Integrating this module (and the MemoryManager module) into the main functioning of the app.