AACsearch
Relevance Studio

Personnalisation

Profils utilisateur, segments, reranking de session et recommandations dans Relevance Studio. Comment personalize=true + sessionId câblent le boost de profil au classement, et bonnes pratiques sur les PII.

Le domaine Personnalisation de Relevance Studio transforme les signaux d'utilisateurs anonymes et connectés en ajustements de classement. Il est bâti sur quatre couches, chacune optionnelle et activable indépendamment par index :

  1. Profils utilisateur — vecteurs de features par utilisateur, dérivés de l'historique d'achats et de clics.
  2. Segments — cohortes larges (p. ex. "acheteurs fréquents", "chasseurs de promos") qui groupent les profils pour des boosts ajustables par l'éditeur.
  3. Reranking de session — réordonnancement court, en session, basé sur les dernières requêtes et clics.
  4. Recommandations — blocs produits liés, aussi achetés, souvent vus ensemble, alimentés par le même store de profils.

Quand activer la personnalisation

Activez la personnalisation quand les trois conditions sont réunies :

  • Votre recherche a un vrai concept d'utilisateur récurrent (connecté ou ID anonyme stable).
  • Vous avez au moins ~10k événements de clic par index et par semaine — en dessous, le signal est trop bruité.
  • Les curations éditeur ne suffisent pas à différencier la même requête pour différents utilisateurs.

En cas de doute, commencez par le reranking de session seul — il ne demande aucun historique et se dégrade en no-op pour les nouveaux visiteurs.

Toute requête de recherche publique peut opter en envoyant deux champs supplémentaires :

  • personalize: true dans le body — active la couche pour cette requête.
  • sessionId: "<id-stable>" — un UUID ou cookie hashé qui rattache la requête au profil (ou, pour les anonymes, à leur session).

Le serveur résout ces champs dans le chemin de lecture, avant l'appel multi_search de Typesense, et combine en AND une expression de boost de profil au classement existant. Le flow correspond aux cinq gates d'une recherche normale — auth, rate limit, tenant filter, scoped filter, multi_search — avec une étape supplémentaire entre rate-limit et tenant-filter : applyPersonalization.

IDs stables et PII

Le sessionId DOIT être opaque pour AACsearch. Ne pas envoyer d'emails bruts, de numéros de téléphone ou d'IDs CRM. Le motif recommandé :

sessionId = sha256(your_internal_user_id + BETTER_AUTH_SECRET_FRAGMENT).slice(0, 32)

L'historique côté serveur derrière chaque profil est plafonné à 100 entrées par session. Les clics et vues plus anciens sont éliminés FIFO. C'est intentionnel : profil compact, rapide à charger sur le hot path, et facile à expirer pour les demandes RGPD de droit à l'oubli (un seul DELETE /personalization/profile/<sessionId> le purge).

Exemple : curl

curl -X POST https://api.aacsearch.com/api/search/public/multi \
  -H "Authorization: Bearer ss_search_pub_XXXXXX" \
  -H "Content-Type: application/json" \
  -d '{
    "searches": [
      {
        "collection": "products",
        "q": "running shoes",
        "query_by": "title,brand,description",
        "personalize": true,
        "sessionId": "9f3c1b2e8a7d4f6c0b1a2d3e4f5a6b7c"
      }
    ]
  }'

La forme de la réponse ne change pas. Si personalize=true ne peut s'appliquer — profil vide, personnalisation désactivée sur l'index, ou entitlement Scale manquant — la requête retombe proprement sur le classement standard et un flag personalization_applied: false est inclus dans les métadonnées.

Exemple : SDK TypeScript / client oRPC

import { client } from "@repo/api/client";

const res = await client.search.public.multi.call({
  searches: [
    {
      collection: "products",
      q: "running shoes",
      query_by: "title,brand,description",
      personalize: true,
      sessionId: visitorSessionId, // sha256(uid + secret).slice(0, 32)
    },
  ],
});

Pour l'usage navigateur, préférez le flow scoped search token décrit dans Architecture → Chemin de lecture — les champs personalize et sessionId y transitent inchangés.

Câbler le boost de profil au classement

Dans Studio → Pertinence → Personnalisation, un admin choisit comment les features de profil influencent le classement. Trois modes :

ModeEffet sur le classementQuand utiliser
offNo-op (par défaut sur les nouveaux index).Établir des baselines.
boostAjoute un boost _personalization_score au ranker existant.Déploiement prudent, les curations restent dominantes.
rerankRe-trie les top-K du ranker de base par le score de personnalisation.Index à fort trafic et bonne couverture de profils.

Le poids du boost est un nombre 0–10. Démarrez à 1.0, observez le CTR dans le panneau Feedback de clics pendant une semaine, puis montez par pas de 0.5. Au-dessus de 5.0, le boost domine typiquement les curations — n'y allez que si un A/B le valide.

Segments

Un segment est un filtre sauvegardé sur l'espace des profils. Les segments sont définis dans Studio et évalués côté serveur sur chaque requête personnalisée. Exemples livrés :

  • frequent_buyers — profils avec ≥ 3 achats sur 30 jours.
  • cart_abandoners — profils avec ≥ 1 add_to_cart et 0 purchase sur 7 jours.
  • discount_hunters — profils dont les produits cliqués avaient discount_pct > 0 dans ≥ 50% des clics récents.

Chaque segment a son propre poids de boost. Un utilisateur dans deux segments reçoit le max des deux (pas la somme) — la maths reste prévisible en cas de chevauchement.

Recommandations

Le même store de profils alimente les endpoints de recommandation. Ils sont exposés comme procedures oRPC propres et ne demandent pas personalize=true sur l'appel search :

  • recommendations.related — basé contenu : similaire au productId d'entrée.
  • recommendations.alsoBought — collaboratif : depuis le graphe clic-et-achat.
  • recommendations.frequentlyViewedTogether — co-vue dans la session.

Voir la section dédiée Recommandations pour le schéma complet requête/réponse.

Bonnes pratiques sur les PII

  1. Ne jamais envoyer d'email / téléphone / customer ID brut dans sessionId. Hashez d'abord avec un secret côté serveur.
  2. Traitez sessionId comme un token, pas un identifiant. Il doit tourner à la déconnexion.
  3. Plafonnez l'historique à 100 entrées. C'est le défaut côté serveur et la seule configuration supportée — documenté ici pour que les clients raisonnent sur la rétention.
  4. Câblez un hook delete RGPD. Quand un utilisateur invoque le droit à l'oubli, appelez la procedure personalization.profile.delete avec son sessionId stable. Le wipe est synchrone et idempotent.
  5. Ne personnalisez pas les sessions admin en inspection. Les requêtes d'inspection Studio doivent passer personalize=false pour que l'explicateur de classement voie le classement non biaisé.

Lié

On this page