PARS: Personalized Adaptive Recommendation System
Can one recommender work for any small business, and optimize for the user instead of for clicks?
Summary
During my internship at BlueAI I designed and built a recommendation system with a fixed core and a configurable layer, so a new domain needs new settings instead of a new model. I tested it on Amanda, an online fruit and vegetable shop, where recommendations must never break a user's allergies or diet and should also be healthy and sustainable.
Unsafe products are removed before the model sees them. The rest is cheap and broad first, then precise.
Key results
- 4recommendation methods compared side by side: content-based, collaborative filtering, LLM-only and PARS
- 0LLM calls needed when a user asks for recommendations: all LLM work is done offline and cached
- 534products and 32 user profiles in the Amanda test domain
The problem
Most recommendation research assumes a large platform: millions of interactions, lots of computing power, and one goal, engagement. Small businesses have none of that, and in areas like food, health or education the goal is the user’s long-term benefit, not time spent on the site. Two problems follow: systems are locked to one domain, and they are judged only on accuracy. A food shop needs recommendations that never break allergies or a diet, fill nutritional gaps and favor local, low-CO2 products.
What I did
- Built an offline preparation phase that runs once and is cached: cleaning the catalog and user data, rewriting every product description with an LLM so the text embeddings are comparable, turning free-text user notes (for example “I don’t eat red meat”) into extra hard constraints, and building a flavor pairing table for basket suggestions.
- Separated hard constraints from soft preferences. Allergies, diet type and religious rules remove products before retrieval, so no scoring can bring them back. Dislikes only lower a product’s score.
- Implemented three baselines: content-based filtering (TF-IDF plus nutrition and environment scores), user-based collaborative filtering, and an LLM-only recommender with a code-level safety check.
- Designed the PARS pipeline in three stages: retrieval of 50 candidates with two FAISS searches (nutrition vector and text embedding), scoring by taste, nutrition and environment with weights taken from the user’s profile, and reranking for dislikes, flavor pairings and nutritional diversity.
- Added basket building within a budget, with coverage of daily nutrient needs based on the French ANSES reference values, personalized by age, sex, activity and conditions such as pregnancy.
- Built a web interface for blind A/B testing: two methods side by side, 1 to 5 star ratings per item, and live metrics (diversity, novelty, nutritional coverage, constraint respect, latency).
What I learned
- Safety belongs before ranking, not inside it. Removing unsafe items first means no weight setting can recommend something a user is allergic to.
- Use LLMs where they are strong, and cache them. Cleaning descriptions and reading free-text constraints offline gave LLM quality without LLM cost or delay for each user request.
- Accuracy is not the only goal. Nutrition, diversity, novelty and sustainability had to be measured on purpose, otherwise nothing optimizes for them.