Finding J02+J03 de la passe d'audit GenAI, re-verifie firsthand le 2026-09-12 sur origin/main = 162779ec06. Sous-partie (b) confirmee ; la sous-partie (a) du finding original est ecartee en fin de body (voir « Ecarte apres re-verification »).
Le defaut
L'exercice recall@5 demande de mesurer le rappel a 5 de search_qdrant(q, ef=8), mais le helper met le K global (10) dans limit : la requete rend un top-10, pas un top-5. Le K5 = 5 defini dans la cellule d'exercice n'est jamais consomme par le helper. En intersectant un top-10 avec un ground truth top-5, l'eleve mesure |GT5 ∩ top10| / 5, qui vaut 1.0 des que les 5 vrais voisins sont quelque part dans le top-10 — l'exercice peut donc valider un recall@5 de 1.0 quand le vrai recall@5 vaut 0.0.
Second defaut du meme exercice : le TODO demande un « ground truth top-5 ordonne » calcule par la « meme methode numpy que la cellule ground_truth » — or cette cellule reference stocke le ground truth comme un set (l'ordre est detruit) : la methode a recopier ne peut pas produire un top-5 ordonne.
Localisation
MyIA.AI.Notebooks/GenAI/RAG-et-Memoire-Semantique/05b-Stockage-Vectoriel-Serveur.ipynb
- cellule 10 (ground truth) :
ground_truth.append(set(int(i) for i in top_k_sorted)) — ordre perdu ; l'exemple affiche sorted(list(ground_truth[0]))[:5] (tri d'identifiants).
- cellule 12 (helper) :
def search_qdrant(query_vec, ef=None, ...) construit "limit": K avec K = 10 global.
- cellule 19 (exercice) :
K5 = 5 puis # TODO Etudiant : ... mesurer le recall@5 de search_qdrant(q, ef=8).
Sortie de re-verification (origin/main, 2026-09-12)
$ git show origin/main:...05b-Stockage-Vectoriel-Serveur.ipynb | grep -o 'indexing_threshold[^,]*'
indexing_threshold\": 0\n"
$ git show origin/main:...05b | python -c "..." # extraits
cell 12: payload = { "vector": query_vec.tolist(), "limit": K, ... } # K = 10 (global)
cell 19: K5 = 5
# TODO Etudiant : (1) recalculer le ground truth top-5 ordonne ... (2) mesurer le
# recall@5 de search_qdrant(q, ef=8) puis de search_qdrant(q, exact=True),
cell 10: ground_truth.append(set(int(i) for i in top_k_sorted))
K5 apparait une seule fois (definition, jamais consommee) ; search_qdrant(q, ef=8) est bien l'appel demande ; le helper met K (10) dans limit.
Ce qu'un correctif devrait faire (sans l'ecrire)
- Permettre a l'exercice d'interroger avec
limit=5 (le helper prendrait la profondeur en parametre, ou l'exercice construirait son payload) — le recall@5 doit se mesurer contre un top-5 reellement rendu.
- Faire produire a la methode de ground truth un top-5 qui conserve l'ordre (le
set de la cellule 10 est l'idiome du recall@10 non ordonne, pas du top-5 ordonne demande).
Coordination
La PR #15656 (OPEN) retravaille exactement cette zone du notebook : elle ajoute « Exercice 1 — Casser la saturation » et renumerote l'exercice recall@5, mais ne modifie pas le helper (def search_qdrant absent du patch ; "limit": K persiste) — le defaut survit sur la branche de la PR. Le correctif devra atterrir en coordination avec elle, pas en aveugle.
Ecarte apres re-verification (pour eviter le re-dispatch)
La sous-partie (a) du finding — « indexing_threshold: 0 DESACTIVE l'indexation HNSW, or la prose dit "demander l'indexation sans seuil d'attente" » — est invertie : dans la semantique Qdrant de optimizers_config.indexing_threshold (nombre minimal de vecteurs d'un segment pour construire l'index HNSW), la valeur 0 force l'indexation de tous les segments immediatement ; c'est une valeur ELEVEE qui la desactiverait. La prose du notebook est donc correcte, et le benchmark peut legitimement s'interpreter en termes de HNSW/ef. Le recall@10 = 1.000 uniforme des sorties commitees (a tous les ef) s'explique par des requetes triviales (les vecteurs de requete sont des points du corpus eux-memes), pas par une indexation absente. Non-lieu documente.
Reassessed by audit-issue-opener: CONFIRMED pedagogy (mesure d'exercice biaisee : limit=10 pour un recall@5, ground truth non ordonnable)
Finding J02+J03 de la passe d'audit GenAI, re-verifie firsthand le 2026-09-12 sur
origin/main=162779ec06. Sous-partie (b) confirmee ; la sous-partie (a) du finding original est ecartee en fin de body (voir « Ecarte apres re-verification »).Le defaut
L'exercice recall@5 demande de mesurer le rappel a 5 de
search_qdrant(q, ef=8), mais le helper met le K global (10) danslimit: la requete rend un top-10, pas un top-5. LeK5 = 5defini dans la cellule d'exercice n'est jamais consomme par le helper. En intersectant un top-10 avec un ground truth top-5, l'eleve mesure|GT5 ∩ top10| / 5, qui vaut 1.0 des que les 5 vrais voisins sont quelque part dans le top-10 — l'exercice peut donc valider un recall@5 de 1.0 quand le vrai recall@5 vaut 0.0.Second defaut du meme exercice : le TODO demande un « ground truth top-5 ordonne » calcule par la « meme methode numpy que la cellule ground_truth » — or cette cellule reference stocke le ground truth comme un
set(l'ordre est detruit) : la methode a recopier ne peut pas produire un top-5 ordonne.Localisation
MyIA.AI.Notebooks/GenAI/RAG-et-Memoire-Semantique/05b-Stockage-Vectoriel-Serveur.ipynbground_truth.append(set(int(i) for i in top_k_sorted))— ordre perdu ; l'exemple affichesorted(list(ground_truth[0]))[:5](tri d'identifiants).def search_qdrant(query_vec, ef=None, ...)construit"limit": KavecK = 10global.K5 = 5puis# TODO Etudiant : ... mesurer le recall@5 de search_qdrant(q, ef=8).Sortie de re-verification (origin/main, 2026-09-12)
K5apparait une seule fois (definition, jamais consommee) ;search_qdrant(q, ef=8)est bien l'appel demande ; le helper metK(10) danslimit.Ce qu'un correctif devrait faire (sans l'ecrire)
limit=5(le helper prendrait la profondeur en parametre, ou l'exercice construirait son payload) — le recall@5 doit se mesurer contre un top-5 reellement rendu.setde la cellule 10 est l'idiome du recall@10 non ordonne, pas du top-5 ordonne demande).Coordination
La PR #15656 (OPEN) retravaille exactement cette zone du notebook : elle ajoute « Exercice 1 — Casser la saturation » et renumerote l'exercice recall@5, mais ne modifie pas le helper (
def search_qdrantabsent du patch ;"limit": Kpersiste) — le defaut survit sur la branche de la PR. Le correctif devra atterrir en coordination avec elle, pas en aveugle.Ecarte apres re-verification (pour eviter le re-dispatch)
La sous-partie (a) du finding — «
indexing_threshold: 0DESACTIVE l'indexation HNSW, or la prose dit "demander l'indexation sans seuil d'attente" » — est invertie : dans la semantique Qdrant deoptimizers_config.indexing_threshold(nombre minimal de vecteurs d'un segment pour construire l'index HNSW), la valeur 0 force l'indexation de tous les segments immediatement ; c'est une valeur ELEVEE qui la desactiverait. La prose du notebook est donc correcte, et le benchmark peut legitimement s'interpreter en termes de HNSW/ef. Le recall@10 = 1.000 uniforme des sorties commitees (a tous les ef) s'explique par des requetes triviales (les vecteurs de requete sont des points du corpus eux-memes), pas par une indexation absente. Non-lieu documente.Reassessed by audit-issue-opener: CONFIRMED pedagogy (mesure d'exercice biaisee : limit=10 pour un recall@5, ground truth non ordonnable)