Ressource technique · RUMBA.EX

Sélection d'articles et d'exercices avec RAG, modèle pondéré et formules mathématiques

Modèle pondéré de sélection d'articles et d'exercices de Rumba avec RAG, pgvector, formules mathématiques, profils latents et recommandation pédagogique explicable.

Cadre général de la recommandation dans Rumba

Cette note présente le modèle de sélection utilisé par Rumba pour recommander des articles et des exercices dans un cadre pédagogique compatible avec un pipeline RAG. L’objectif n’est pas seulement de produire un classement. Il s’agit de construire une recommandation explicable, pondérée, auditabile et suffisamment robuste pour articuler profils latents, contenus pédagogiques et récupération de contexte. Le système repose sur un diagnostic en deux temps, une estimation probabiliste des profils, puis une agrégation avec une matrice de similarité contenu profil.

Cette architecture cherche à concilier précision de la recommandation, lisibilité des règles de calcul et intégration à un environnement plus large mobilisant des embeddings et pgvector. Le point important est que la recommandation ne dépend pas d’une simple heuristique opaque. Elle repose sur des formules interprétables et des étapes distinctes que l’on peut contrôler.

Variables du modèle et logique de sélection

On note l’ensemble des profils latents, l’ensemble des contenus pédagogiques et le sous-ensemble des items posés lors du diagnostic. Chaque item observé produit un score d’erreur, et chaque item diagnostique porte une distribution de poids sur les profils. La matrice de similarité relie ensuite chaque profil à chaque article ou exercice. Le cœur du problème consiste à estimer un vecteur de confiance sur les profils, puis à transformer cette estimation en un score de pertinence pour chaque contenu.

Ce cadre est utile parce qu’il sépare clairement trois niveaux. D’abord l’observation des réponses. Ensuite l’inférence sur les profils. Enfin la sélection des contenus. Cette séparation améliore la lisibilité scientifique du système et facilite les ajustements méthodologiques.

Étape 1, agrégation pondérée des erreurs

Le premier calcul consiste à agréger les erreurs observées en les pondérant selon leur lien avec les profils. Chaque profil reçoit ainsi un score brut qui reflète l’intensité des signaux accumulés pendant le diagnostic.

Sp = j ∈ 𝒬 Wj,p · rj

Cette étape est décisive, car elle transforme un ensemble de réponses localisées en une estimation plus globale du positionnement de l’utilisateur. La pondération évite de traiter toutes les erreurs comme équivalentes. Certaines réponses ont davantage de valeur diagnostique que d’autres.

Étape 2, transformation en degrés de confiance

Les scores bruts sont ensuite transformés en degrés de confiance à l’aide d’une softmax inversée. Ce choix permet de convertir une logique d’erreur en distribution probabiliste sur les profils, tout en maintenant une température réglable.

cp = exp( − Sp / τ ) q ∈ 𝒫 exp( − Sq / τ )

Le paramètre de température régule la dispersion des croyances. Une température faible produit une distribution plus concentrée. Une température plus élevée laisse davantage de place à l’incertitude. Cette propriété est utile pour calibrer le comportement du système selon le niveau de prudence recherché.

Étape 3, score de pertinence pour chaque article ou exercice

Une fois la confiance profilée obtenue, la recommandation agrège cette distribution avec la matrice de similarité entre profils et contenus. Chaque article ou exercice reçoit alors un score final de pertinence.

Re = p ∈ 𝒫 cp · Mp,e

Ce mécanisme fait le lien entre diagnostic et sélection. Il permet de faire émerger des contenus cohérents avec les besoins estimés de l’utilisateur. Dans une version complète du système, la matrice peut être issue d’embeddings vectoriels calculés en amont et récupérés via pgvector.

Diversité, autorité et re-ranking éditorial

Le tri par pertinence seule ne suffit pas. Une recommandation utile doit aussi éviter la redondance, ouvrir plusieurs domaines d’apprentissage et tenir compte de signaux d’autorité. Pour cette raison, Rumba ajoute un score final intégrant diversité et qualité éditoriale.

Fe = α · Re − β · De + γ · Ae

La pénalisation de redondance évite de proposer plusieurs contenus trop proches. Le terme d’autorité permet d’intégrer des critères comme la fraîcheur, la qualité ou la couverture pédagogique. Le système conserve ainsi une logique fine de personnalisation sans tomber dans la répétition automatique.

Diagnostic en deux temps et efficacité pédagogique

Le diagnostic utilisé par Rumba ne cherche pas à poser un grand nombre de questions indistinctes. Il procède par étapes. Une première phase fait émerger des profils candidats. Une seconde phase affine ensuite l’estimation sur les profils les plus plausibles. Cette stratégie réduit la variance des estimations tout en limitant le nombre d’items à afficher.

Ce choix est important dans un cadre pédagogique et conversationnel. Il améliore la fluidité de l’expérience utilisateur et rend l’intégration dans un pipeline RAG plus crédible. Le système gagne en réactivité sans renoncer à la qualité de l’inférence.

Implémentation minimale du noyau de sélection

Le premier bloc ci-dessous illustre le cœur du système. On y retrouve la softmax inversée, l’agrégation pondérée des erreurs et le calcul de pertinence sur les contenus.

selection_core.py

selection_core.pyextrait technique
from __future__ import annotations
import math
from typing import Dict

Profile = str
ItemId  = str

def softmax_inverse(scores: Dict[Profile, float], tau: float = 0.35) -> Dict[Profile, float]:
    """Renvoie c_p = softmax(-S_p/tau)."""
    vals = {p: -s / max(tau, 1e-9) for p, s in scores.items()}
    m = max(vals.values()) if vals else 0.0
    exps = {p: math.exp(v - m) for p, v in vals.items()}
    Z = sum(exps.values()) or 1.0
    return {p: exps[p] / Z for p in scores}

def aggregate_profile_scores(weight_matrix: Dict[ItemId, Dict[Profile, float]],
                             observed_errors: Dict[ItemId, float]) -> Dict[Profile, float]:
    """S_p = sum_j W_{j,p} r_j (W normalisé en L1 par item)."""
    S: Dict[Profile, float] = {}
    for j, rj in observed_errors.items():
        row = weight_matrix.get(j, {})
        Z = sum(row.values()) or 1.0
        for p, w in row.items():
            S[p] = S.get(p, 0.0) + (w / Z) * float(rj)
    return S

def relevance(M: Dict[Profile, Dict[ItemId, float]], conf: Dict[Profile, float]) -> Dict[ItemId, float]:
    """R_e = sum_p c_p M_{p,e}."""
    R: Dict[ItemId, float] = {}
    for p, row in M.items():
        cp = conf.get(p, 0.0)
        if cp == 0.0:
            continue
        for e, sim in row.items():
            R[e] = R.get(e, 0.0) + cp * float(sim)
    return R

Exemple minimal pour tester la chaîne complète

Le second bloc fournit un jeu de données simple. Il permet de vérifier le fonctionnement complet de la chaîne, depuis les erreurs observées jusqu’au calcul de la pertinence finale.

demo_selection.py

demo_selection.pyextrait technique
M = {
  "profil_A": {"e1": 0.9, "e2": 0.2, "e3": 0.1},
  "profil_B": {"e1": 0.1, "e2": 0.8, "e3": 0.6}
}
meta = {
  "e1": {"domain": "Lecture", "title": "Article 1"},
  "e2": {"domain": "Grammaire", "title": "Article 2"},
  "e3": {"domain": "Lecture", "title": "Article 3"}
}
W = {
  "q1": {"profil_A": 0.8, "profil_B": 0.2},
  "q2": {"profil_A": 0.3, "profil_B": 0.7}
}
r = {"q1": 0.2, "q2": 0.7}

S = aggregate_profile_scores(W, r)
c = softmax_inverse(S, tau=0.4)
R = relevance(M, c)

print("S:", S)
print("c:", c)
print("R:", R)

Articulation avec pgvector et un pipeline RAG

Dans un système complet, la matrice de similarité peut être dérivée d’embeddings stockés dans pgvector. Les similarités sont alors calculées à partir de distances vectorielles ou de mesures cosinus, puis matérialisées dans une logique de recherche KNN. Le pipeline ne remplace pas cette recherche vectorielle. Il la contraint et l’oriente grâce à la distribution de profils obtenue pendant le diagnostic.

Cette articulation présente un intérêt majeur pour les systèmes RAG. Le modèle de langage reçoit un contexte non seulement proche sur le plan sémantique, mais aussi pondéré par une logique pédagogique explicable. La récupération devient ainsi plus utile, plus ciblée et mieux alignée avec les besoins estimés de l’utilisateur.

Conclusion

Le modèle de sélection de Rumba combine un diagnostic pondéré, une transformation probabiliste des profils, une agrégation de pertinence et un re-ranking intégrant diversité et autorité. Cette chaîne rend la recommandation plus stable, plus explicable et plus compatible avec un environnement RAG fondé sur des embeddings et pgvector.

L’intérêt du modèle tient précisément à cette articulation entre formules mathématiques, logique pédagogique et infrastructure vectorielle. Il ne s’agit pas simplement de classer des contenus. Il s’agit de construire une recommandation mesurable, interprétable et capable d’alimenter un LLM avec des contextes pertinents, variés et auditables.