Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
There are two timescales of user intent and treating them as one is a recurring bug. Long-term user modeling captures stable taste — someone who's bought hiking gear for years is probably still into hiking gear. Session-based modeling captures what the user wants right now, in this visit — they might be shopping for a gift, in a completely different category than their usual taste. A model that only uses long-term profiles will keep recommending hiking gear to someone actively browsing baby products for a friend's shower. A model that only uses the current session ignores years of signal and treats every new visitor as a stranger with no history. Real systems blend both: a long-term embedding anchors general taste, and a session-based signal (often a simple sequence model) re-weights or overrides it for the current visit's evident intent.
The demo represents a user as a long-term taste vector (averaged over history) and re-scores candidates by blending it with a session-only signal (a simple recency-weighted average of just this session's clicks), then shows how the blended recommendation shifts based on session behavior alone.
import numpy as np
rng = np.random.default_rng(4)
CATEGORIES = ["hiking", "baby", "electronics", "books", "kitchen"]
item_vecs = {c: rng.normal(size=3) for c in CATEGORIES} # toy embeddings
# Long-term profile: years of hiking purchases.
long_term_history = ["hiking"] * 8 + ["books"] * 2
long_term_vec = np.mean([item_vecs[c] for c in long_term_history], axis=0)
# This session: browsing baby products for a friend's shower.
session_clicks = ["baby", "baby", "baby"]
session_vec = np.mean([item_vecs[c] for c in session_clicks], axis=0)
def score(candidate_vec, user_vec):
# cosine similarity
return np.dot(candidate_vec, user_vec) / (np.linalg.norm(candidate_vec) * np.linalg.norm(user_vec) + 1e-9)
def blended_vec(alpha):
# alpha=0 -> pure long-term, alpha=1 -> pure session
return (1 - alpha) * long_term_vec + alpha * session_vec
for alpha in (0.0, 0.5, 0.9):
uvec = blended_vec(alpha)
ranked = sorted(CATEGORIES, key=lambda c: score(item_vecs[c], uvec), reverse=True)
print(f"alpha={alpha:.1f} (session weight) top-3 categories: {ranked[:3]}")python3 main.py