learn.chetana.fr

La recherche hybride : pgvector + FTS + trigram + RRF

15 min de lectureAvancé

Le problĂšme : « BOUL. INOX 50MM x100 » → quel produit ?

Une ligne de commande arrive salie : abrĂ©viations, fautes, rĂ©fĂ©rences partielles. Le retrouver dans un catalogue de dizaines de milliers de variants est un problĂšme de recherche, pas de classification. Aucune technique seule ne suffit — le projet en fusionne quatre, toutes dans PostgreSQL :

SourceOutil PGAttrape
SKU exactILIKE + heuristique « ça ressemble à une réf »les références précises
Full-textcolonne générée TSVECTOR + websearch_to_tsquery('french'), score ts_rank_cdles mots exacts, pluriels/conjugaisons
Trigramextension pg_trgm, similarity() + index GINles fautes de frappe (« boulon »≈« bulon »)
Vecteurpgvector : search_vec <=> :emb (cosine), index HNSWle sens (« vis » ≈ « boulon »)

Les embeddings : Cohere embed-multilingual (1024 dim), une colonne vector(1024) par variant, avec le bon input_type (search_document Ă  l'indexation, search_query Ă  la requĂȘte — l'asymĂ©trie compte).

La fusion : Reciprocal Rank Fusion

Comment combiner quatre listes aux scores incomparables (un ts_rank_cd et un cosinus ne se comparent pas) ? RRF ne regarde que les rangs :

score(candidat) = ÎŁ sur chaque source :  1 / (60 + rang_dans_la_source)

Un candidat bien classĂ© dans plusieurs sources monte — robuste, sans normalisation de scores, sans rĂ©glage. C'est la mĂȘme fusion que tu as croisĂ©e au cours ML (recherche d'entreprise) — ici en pur SQL applicatif.

AprÚs le retrieval : scoring métier et deep match

Les candidats passent ensuite un scoring 5 dimensions (id, marque, texte, catĂ©gorie, spĂ©cifications) pondĂ©rĂ©, avec deux rĂšgles dures : le golden match (rĂ©fĂ©rence exacte → score 1, on ne discute pas) et le brand veto (mauvaise marque explicite → Ă©liminĂ©). Si le meilleur score reste sous le seuil, le deep match s'enclenche : un petit LLM (Haiku) réécrit la requĂȘte en ~3 variantes → nouveaux candidats → re-rank Cohere (cross-encoder) → dĂ©cision. Le LLM n'intervient qu'en dernier recours : la voie rapide est du pur PostgreSQL Ă  quelques millisecondes.

đŸ§© Quiz1/4

Pourquoi fusionner par rangs (RRF) plutĂŽt que par scores ?

🃏 Flashcards1/4