initial state: muzick music player + recommendation engine
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Recommendation & Vibe Specification
|
||||
|
||||
This document defines the logic for the "Vibe" engine, moving from simple similarity to a continuous, evolving listening experience.
|
||||
|
||||
## 1. The "Vibe" Concept
|
||||
The "Vibe" is an infinite, stateful listening session. Unlike a static playlist, it is a **Rolling Window** that evolves based on user interaction.
|
||||
|
||||
## 2. Scoring Logic
|
||||
|
||||
When generating a sequence, every candidate track is assigned a score.
|
||||
|
||||
$$Score = (W_{genre} \cdot S_{genre}) + (W_{artist} \cdot S_{artist}) + (W_{random} \cdot R)$$
|
||||
|
||||
### **Scoring Components**
|
||||
* **$S_{genre}$ (Genre Match):**
|
||||
* Uses hierarchical weights (e.g., `Deep House` (1.0) $\rightarrow$ `House` (0.8) $\rightarrow$ `Electronic` (0.5)).
|
||||
* Calculated as the highest weight match between candidate and "Center Track."
|
||||
* **$S_{artist}$ (Artist Similarity):**
|
||||
* A binary or weighted score based on whether the artist is in the user's "Liked" list or frequent listening history.
|
||||
* **$R$ (Randomness/Exploration):**
|
||||
* A jitter factor to ensure the queue doesn't feel repetitive.
|
||||
|
||||
## 3. The Rolling Window Algorithm
|
||||
|
||||
The backend does not return a fixed list. It returns a **Sequence Chunk**.
|
||||
|
||||
### **Step-by-Step Generation**
|
||||
1. **Identify the Center:** Find the `last_successfully_played_track_id`.
|
||||
2. **Candidate Selection:**
|
||||
* **Local Pool (80%):** Tracks from the user's library similar to the center track.
|
||||
* **Probation Pool (20%):** Tracks from the `recommendation_batch` that have `probation=1`.
|
||||
3. **Constraint Application (Batch Rules):**
|
||||
* **Diversity Check:** No more than 1 track from the same artist per chunk.
|
||||
* **Genre Cap:** No more than 2 tracks from the same genre per chunk.
|
||||
4. **Chunking:** Return a sequence of $N$ tracks (e.g., 20).
|
||||
|
||||
## 4. The "Vibe" Session Lifecycle
|
||||
|
||||
A "Vibe" is represented by a `recommendation_batch` record.
|
||||
|
||||
| State | Description |
|
||||
| :--- | :--- |
|
||||
| **ACTIVE** | The user is currently listening. The stream is being generated. |
|
||||
| **RESOLVED** | The session has ended naturally or timed out. |
|
||||
| **FAILED** | The session was interrupted by a critical error or manual reset. |
|
||||
|
||||
### **Transition Logic**
|
||||
* **Start:** User clicks "Start Vibe" $\rightarrow$ Create `ACTIVE` batch.
|
||||
* **Progress:** User listens $\rightarrow$ Update `last_interaction_at` in the batch.
|
||||
* **Termination:**
|
||||
* **Natural:** User exits the app $\rightarrow$ Session marked `RESOLVED` after 24h.
|
||||
* **Manual:** User ends session $\rightarrow$ Mark `RESOLVED` immediately.
|
||||
* **Timeout:** No interaction for 24h $\rightarrow$ Mark `RESOLVED`.
|
||||
|
||||
## 5. Success/Failure Feedback Loop
|
||||
|
||||
The engine learns from the `feedback` table:
|
||||
* **`action = 'promoted'`:** (High Score) Increase weight of this genre/artist in future seeds.
|
||||
* **`action = 'disliked'`:** (Negative Signal) Decrease weight of this genre/artist.
|
||||
* **`action = 'skipped'`:** (Transient Negative) Do not adjust long-term weights, but avoid this specific track in the current session window.
|
||||
Reference in New Issue
Block a user