{"id":546,"date":"2026-10-09T11:08:29","date_gmt":"2026-10-09T09:08:29","guid":{"rendered":"https:\/\/www.ranksignal.fr\/blog\/?p=546"},"modified":"2026-10-14T17:37:38","modified_gmt":"2026-10-14T15:37:38","slug":"qu-est-ce-qu-une-recherche-vectorielle","status":"publish","type":"post","link":"https:\/\/www.ranksignal.fr\/blog\/rag\/qu-est-ce-qu-une-recherche-vectorielle\/","title":{"rendered":"Recherche vectorielle : trouver des voisins, pas des mots"},"content":{"rendered":"<p><\/p>\n<p>Un agent dispose de plusieurs outils : un calculateur branch\u00e9 sur Wolfram Alpha, un d\u00e9clencheur Zapier, un envoi de message Slack. Un utilisateur lui \u00e9crit \u00ab Solve this equation: 2x + 3 = 7 \u00bb. Le nom d&rsquo;aucun outil n&rsquo;appara\u00eet dans la phrase, et la description du calculateur parle de \u00ab compute expressions \u00bb, pas d&rsquo;\u00ab equation \u00bb. Pourtant, il faut bien choisir. L&rsquo;agent y parvient en cherchant ce qui est <em>proche<\/em>, jamais ce qui est <em>identique<\/em> : voil\u00e0 ce qu&rsquo;on appelle une recherche vectorielle, et tu vas la suivre pas \u00e0 pas, du nombre jusqu&rsquo;\u00e0 l&rsquo;index.<\/p>\n<p><strong>Sommaire<\/strong><\/p>\n<ul>\n<li><a href=\"#l-essentiel-en-30-secondes\">L&rsquo;essentiel en 30 secondes<\/a><\/li>\n<li><a href=\"#chercher-une-position-plutot-qu-un-mot\">Chercher une position plut\u00f4t qu&rsquo;un mot<\/a><\/li>\n<li><a href=\"#proche-se-calcule-du-produit-scalaire-au-cosinus\">\u00ab Proche \u00bb se calcule : du produit scalaire au cosinus<\/a><\/li>\n<li><a href=\"#une-requete-de-bout-en-bout-choisir-un-outil\">Une requ\u00eate de bout en bout : choisir un outil<\/a><\/li>\n<li><a href=\"#un-index-entre-la-question-et-les-voisins\">Un index entre la question et les voisins<\/a><\/li>\n<li><a href=\"#ou-ranger-les-vecteurs-et-a-quel-prix\">O\u00f9 ranger les vecteurs, et \u00e0 quel prix<\/a><\/li>\n<li><a href=\"#plus-qu-une-recherche-de-passages\">Plus qu&rsquo;une recherche de passages<\/a><\/li>\n<li><a href=\"#trois-choses-qu-elle-ne-sait-pas-faire\">Trois choses qu&rsquo;elle ne sait pas faire<\/a><\/li>\n<\/ul>\n<h2 id=\"l-essentiel-en-30-secondes\">L&rsquo;essentiel en 30 secondes<\/h2>\n<ul>\n<li>Une recherche vectorielle <strong>compare des positions, pas des mots<\/strong> : la requ\u00eate et chaque texte deviennent des vecteurs, et l&rsquo;on garde les plus proches.<\/li>\n<li>Un vecteur est <strong>une liste de nombres de longueur fixe<\/strong>, produite par un mod\u00e8le d&rsquo;<a href=\"\/blog\/rag\/que-sont-les-embeddings\/\" title=\"embedding\">embedding<\/a>, le m\u00eame pour la requ\u00eate et pour les textes.<\/li>\n<li>La proximit\u00e9 se mesure surtout par <strong>le cosinus de l&rsquo;angle<\/strong>, parce que le produit scalaire brut favorise les vecteurs longs.<\/li>\n<li>Un <strong>index<\/strong> range les vecteurs pour trouver vite les voisins, au prix d&rsquo;une r\u00e9ponse parfois seulement approch\u00e9e.<\/li>\n<li>Elle sert \u00e0 retrouver des passages, mais aussi \u00e0 choisir un outil ou une route ; elle <strong>ne sait ni compter ni agr\u00e9ger<\/strong>.<\/li>\n<\/ul>\n<h2 id=\"chercher-une-position-plutot-qu-un-mot\">Chercher une position plut\u00f4t qu&rsquo;un mot<\/h2>\n<p>Avant de chercher, il faut savoir ce qu&rsquo;on cherche. Un vecteur n&rsquo;a rien de myst\u00e9rieux : c&rsquo;est <strong>une liste ordonn\u00e9e de nombres<\/strong>, chaque position d\u00e9signant une valeur. On peut le dessiner comme une fl\u00e8che partie de l&rsquo;origine, dont la longueur (la norme) et la direction portent l&rsquo;information. Multiplier par 2 double sa longueur ; multiplier par un nombre n\u00e9gatif retourne la fl\u00e8che.<\/p>\n<p>Reste \u00e0 transformer un texte en fl\u00e8che. C&rsquo;est le m\u00e9tier d&rsquo;un mod\u00e8le d&#8217;embedding : il avale un texte de longueur quelconque, ou une image, et rend un vecteur de <strong>longueur toujours identique<\/strong> qui garde le sens de l&rsquo;entr\u00e9e. Tous les contenus se retrouvent alors dans un m\u00eame espace, o\u00f9 l&rsquo;on compare des distances avec de simples math\u00e9matiques. Le nombre de cases du vecteur, sa dimension, fixe la quantit\u00e9 d&rsquo;information qu&rsquo;il peut porter, au prix d&rsquo;un calcul de plus en plus co\u00fbteux.<\/p>\n<blockquote>\n<p><strong>\ud83d\udca1 Intuition<\/strong> Imagine chaque texte comme une \u00e9pingle plant\u00e9e sur une carte g\u00e9ante, avec des centaines de dimensions au lieu de deux. Poser une question, c&rsquo;est planter une nouvelle \u00e9pingle et regarder quelles \u00e9pingles se trouvent tout autour.<\/p>\n<\/blockquote>\n<p>La <strong>recherche vectorielle<\/strong> tient alors en deux gestes : convertir la requ\u00eate en vecteur, puis retrouver les vecteurs les plus proches du sien. La r\u00e8gle d&rsquo;or est d&rsquo;utiliser <strong>le m\u00eame mod\u00e8le que pour les textes<\/strong>, sans jamais en changer en cours de route : un autre mod\u00e8le placerait les \u00e9pingles ailleurs, et il faudrait recalculer tout l&rsquo;index.<\/p>\n<h2 id=\"proche-se-calcule-du-produit-scalaire-au-cosinus\">\u00ab Proche \u00bb se calcule : du produit scalaire au cosinus<\/h2>\n<p>Dire que deux vecteurs sont proches suppose une r\u00e8gle de mesure. La plus directe est le produit scalaire : on multiplie les cases deux \u00e0 deux, puis on additionne.<\/p>\n<p><p class=\"ql-center-displayed-equation\" style=\"line-height: 64px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-154a418b757bed95cb3d06c2394831fd_l3.png\" height=\"64\" width=\"474\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#91; &#97;&#92;&#99;&#100;&#111;&#116;&#32;&#98;&#61;&#92;&#115;&#117;&#109;&#95;&#123;&#105;&#61;&#49;&#125;&#94;&#123;&#78;&#125;&#97;&#95;&#105;&#32;&#98;&#95;&#105;&#61;&#97;&#95;&#49;&#98;&#95;&#49;&#43;&#97;&#95;&#50;&#98;&#95;&#50;&#43;&#92;&#100;&#111;&#116;&#115;&#43;&#97;&#95;&#110;&#98;&#95;&#110;&#44;&#92;&#113;&#113;&#117;&#97;&#100;&#32;&#124;&#97;&#124;&#61;&#92;&#115;&#113;&#114;&#116;&#123;&#92;&#115;&#117;&#109;&#95;&#123;&#105;&#61;&#49;&#125;&#94;&#123;&#78;&#125;&#97;&#95;&#105;&#94;&#50;&#125;&#46;&#92;&#93;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p><\/p>\n<p>Ici <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-f91083f3035e5168a6f0b3e6335d6858_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#97;&#95;&#105;\" title=\"Rendered by QuickLaTeX.com\" height=\"11\" width=\"14\" style=\"vertical-align: -3px;\"\/> et <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-bafc6a170096e9ce8f24ef610ca89f3a_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#98;&#95;&#105;\" title=\"Rendered by QuickLaTeX.com\" height=\"15\" width=\"13\" style=\"vertical-align: -3px;\"\/> sont les cases des deux vecteurs, <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-5793832f979c2268e3694c246d53b1bb_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#78;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"16\" style=\"vertical-align: 0px;\"\/> leur dimension, et <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-1bccd92ab192dbd351addd3306cf1567_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#124;&#97;&#124;\" title=\"Rendered by QuickLaTeX.com\" height=\"19\" width=\"15\" style=\"vertical-align: -5px;\"\/> la norme de <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-5c53d6ebabdbcfa4e107550ea60b1b19_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#97;\" title=\"Rendered by QuickLaTeX.com\" height=\"8\" width=\"9\" style=\"vertical-align: 0px;\"\/>, c&rsquo;est-\u00e0-dire sa longueur. Le r\u00e9sultat est grand quand les deux vecteurs ont de grandes valeurs dans les m\u00eames dimensions, et nul quand ils sont orthogonaux, donc sans rapport.<\/p>\n<p>Le produit scalaire a pourtant trois d\u00e9fauts. <strong>Il favorise les vecteurs longs<\/strong>, il avantage les vecteurs aux valeurs \u00e9lev\u00e9es (en g\u00e9n\u00e9ral ceux des mots tr\u00e8s fr\u00e9quents, donc peu utiles), et sa valeur n&rsquo;est pas born\u00e9e : impossible de dire si un score est \u00ab bon \u00bb sans point de comparaison.<\/p>\n<p>Le rem\u00e8de consiste \u00e0 normaliser, c&rsquo;est-\u00e0-dire \u00e0 diviser par les normes. On obtient le cosinus de l&rsquo;angle entre les deux vecteurs :<\/p>\n<p><p class=\"ql-center-displayed-equation\" style=\"line-height: 60px;\"><span class=\"ql-right-eqno\"> &nbsp; <\/span><span class=\"ql-left-eqno\"> &nbsp; <\/span><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-5972a9f2f26bea16bd9786feb1effc7b_l3.png\" height=\"60\" width=\"295\" class=\"ql-img-displayed-equation quicklatex-auto-format\" alt=\"&#92;&#91; &#92;&#99;&#111;&#115;&#92;&#116;&#104;&#101;&#116;&#97;&#61;&#92;&#102;&#114;&#97;&#99;&#123;&#97;&#92;&#99;&#100;&#111;&#116;&#32;&#98;&#125;&#123;&#124;&#97;&#124;&#92;&#44;&#124;&#98;&#124;&#125;&#61;&#92;&#102;&#114;&#97;&#99;&#123;&#92;&#115;&#117;&#109;&#95;&#123;&#105;&#61;&#49;&#125;&#94;&#123;&#78;&#125;&#97;&#95;&#105;&#98;&#95;&#105;&#125;&#123;&#92;&#115;&#113;&#114;&#116;&#123;&#92;&#115;&#117;&#109;&#95;&#123;&#105;&#61;&#49;&#125;&#94;&#123;&#78;&#125;&#97;&#95;&#105;&#94;&#50;&#125;&#92;&#44;&#92;&#115;&#113;&#114;&#116;&#123;&#92;&#115;&#117;&#109;&#95;&#123;&#105;&#61;&#49;&#125;&#94;&#123;&#78;&#125;&#98;&#95;&#105;&#94;&#50;&#125;&#125;&#46;&#92;&#93;\" title=\"Rendered by QuickLaTeX.com\"\/><\/p><\/p>\n<p>Au num\u00e9rateur, le produit scalaire de tout \u00e0 l&rsquo;heure ; au d\u00e9nominateur, le produit des deux longueurs. Une fois ces longueurs divis\u00e9es, il ne reste que la direction.<\/p>\n<p>Le r\u00e9sultat reste compris entre \u22121 et 1 : \u22121 pour des vecteurs oppos\u00e9s, 0 pour des vecteurs orthogonaux, 1 pour des vecteurs parfaitement semblables. Comme <strong>la longueur n&rsquo;influence pas le r\u00e9sultat<\/strong>, \u00e9tirer un vecteur ne change rien au score. Le calcul est rapide, il fonctionne en grande dimension, et il r\u00e9agit moins \u00e0 la fr\u00e9quence des mots, donc il supporte mieux les valeurs aberrantes.<\/p>\n<p>Le cosinus n&rsquo;est pas le seul choix. La distance euclidienne en est un autre, o\u00f9 une petite distance signale des vecteurs proches. Pour des textes, on retient plut\u00f4t l&rsquo;angle que l&rsquo;intensit\u00e9 brute, ce qui convient bien aux agents conversationnels.<\/p>\n<h2 id=\"une-requete-de-bout-en-bout-choisir-un-outil\">Une requ\u00eate de bout en bout : choisir un outil<\/h2>\n<p>Revenons \u00e0 notre agent. Les vecteurs de son catalogue d&rsquo;outils se calculent une seule fois, puis restent pr\u00eats \u00e0 \u00eatre retrouv\u00e9s. \u00c0 l&rsquo;arriv\u00e9e d&rsquo;une requ\u00eate, on la code avec le m\u00eame mod\u00e8le, on interroge la base, et l&rsquo;outil le plus proche sort.<\/p>\n<pre><code>def select_tool(query: str, top_k: int = 1) -&gt; list:\n   &quot;&quot;&quot;\n   Select the most relevant tool(s) based on the user's query using\n   vector-based retrieval.\n\n   Args:\n       query (str): The user's input query.\n       top_k (int): Number of top tools to retrieve.\n\n   Returns:\n       list: List of selected tool functions.\n   &quot;&quot;&quot;\n   query_embedding = embeddings.embed_text(query).astype('float32')\n   faiss.normalize_L2(query_embedding.reshape(1, -1))\n   D, I = index.search(query_embedding.reshape(1, -1), top_k)\n   selected_tools = [index_to_tool[idx] for idx in I[0] if idx in index_to_tool]\n   return selected_tools\n<\/code><\/pre>\n<p>Lis la fonction ligne \u00e0 ligne. <code>embeddings<\/code>, <code>index<\/code> et <code>index_to_tool<\/code> sont pr\u00e9par\u00e9s en amont : le mod\u00e8le d&#8217;embedding, l&rsquo;index qui contient les vecteurs des outils, et un dictionnaire qui relie la position d&rsquo;un vecteur \u00e0 l&rsquo;outil correspondant. La premi\u00e8re ligne utile encode la requ\u00eate, la deuxi\u00e8me normalise le vecteur.<\/p>\n<p>Vient ensuite le c\u0153ur : <code>index.search(\u2026, top_k)<\/code> renvoie deux tableaux, que le code nomme <code>D<\/code> et <code>I<\/code>. Seul <code>I<\/code> sert ici, parce qu&rsquo;il donne <strong>les positions des voisins retrouv\u00e9s<\/strong> ; <code>top_k<\/code> fixe leur nombre, ici un seul par d\u00e9faut. La derni\u00e8re ligne traduit ces positions en noms d&rsquo;outils.<\/p>\n<p>Pour \u00ab Solve this equation: 2x + 3 = 7 \u00bb, on attend que l&rsquo;outil de calcul remonte, sans qu&rsquo;un seul mot de la requ\u00eate ne co\u00efncide avec sa description. Une fois l&rsquo;outil choisi, un mod\u00e8le de langage d\u00e9duit ses param\u00e8tres \u00e0 partir de la requ\u00eate, puis l&rsquo;outil est appel\u00e9.<\/p>\n<h2 id=\"un-index-entre-la-question-et-les-voisins\">Un index entre la question et les voisins<\/h2>\n<p>Dans la fonction pr\u00e9c\u00e9dente, <code>index.search<\/code> fait tout le travail. Qu&rsquo;y a-t-il derri\u00e8re ? Un index vectoriel, <strong>une structure de donn\u00e9es qui organise les vecteurs<\/strong> pour en retrouver vite les plus proches. Il n&rsquo;est pas strictement indispensable, mais il est vivement recommand\u00e9.<\/p>\n<p>Prenons un autre exemple, dans une base de graphe. Chaque fragment de texte y devient un n\u0153ud portant deux propri\u00e9t\u00e9s : son texte et son embedding. L&rsquo;index est b\u00e2ti sur la seconde.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6adef4738dcf0&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6adef4738dcf0\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"2250\" height=\"1350\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk.png\" alt=\"Trois n\u0153uds de type fragment, chacun avec un num\u00e9ro, un texte et un embedding, et un index vectoriel nomm\u00e9 \u00ab pdf \u00bb construit sur la propri\u00e9t\u00e9 embedding\" class=\"wp-image-543\" srcset=\"https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk.png 2250w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk-300x180.png 300w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk-1024x614.png 1024w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk-768x461.png 768w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk-1536x922.png 1536w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch02_modele_chunk-2048x1229.png 2048w\" sizes=\"auto, (max-width: 2250px) 100vw, 2250px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Regarde le bandeau du bas : l&rsquo;index ne porte pas sur le texte, mais sur la propri\u00e9t\u00e9 qui contient le vecteur. C&rsquo;est elle qui sera compar\u00e9e \u00e0 la requ\u00eate.<\/figcaption><\/figure>\n\n\n<pre><code>driver.execute_query(&quot;&quot;&quot;CREATE VECTOR INDEX pdf IF NOT EXISTS\nFOR (c:Chunk)\nON c.embedding&quot;&quot;&quot;)\n<\/code><\/pre>\n<p>La commande cr\u00e9e, s&rsquo;il n&rsquo;existe pas d\u00e9j\u00e0, un index nomm\u00e9 <code>pdf<\/code> sur les embeddings de tous les n\u0153uds de type fragment. Il doit tenir compte du nombre de dimensions des vecteurs, ici 1536, puisque c&rsquo;est ce que produit le mod\u00e8le choisi ; il compare par similarit\u00e9 cosinus. Si tu changes un jour de mod\u00e8le et que la dimension change, il faudra recr\u00e9er l&rsquo;index.<\/p>\n<p>Pour l&rsquo;interroger, on transforme la question en embedding avec le m\u00eame mod\u00e8le, puis on appelle l&rsquo;index :<\/p>\n<pre><code>CALL db.index.vector.queryNodes('pdf', 2, &#36;question_embedding) YIELD node\nAS hits, score\nRETURN hits.text AS text, score, hits.index AS index\n<\/code><\/pre>\n<p><code>queryNodes<\/code> re\u00e7oit trois choses : le nom de l&rsquo;index, le nombre de voisins voulus (ici 2) et le vecteur de la question. Il rend chaque n\u0153ud trouv\u00e9 avec son score de similarit\u00e9, dont la requ\u00eate extrait le texte et la position.<\/p>\n<p>Une question reste en suspens : l&rsquo;index trouve-t-il le voisin <em>exact<\/em> ? Pas toujours. Beaucoup d&rsquo;index pratiquent la <strong>recherche du plus proche voisin approch\u00e9e<\/strong> : ils renvoient un voisin tr\u00e8s proche, sans garantir que ce soit le tout premier, en \u00e9change de la vitesse. L&rsquo;indexation Flat, elle, reste exacte mais bien plus lente ; HNSW accepte de perdre un peu de pr\u00e9cision pour gagner beaucoup de temps.<\/p>\n<blockquote>\n<p><strong>\ud83d\udccc \u00c0 retenir<\/strong> Un index promet des voisins tr\u00e8s proches, rapidement. Il ne promet pas le plus proche \u00e0 coup s\u00fbr : c&rsquo;est le prix de la vitesse.<\/p>\n<\/blockquote>\n<h2 id=\"ou-ranger-les-vecteurs-et-a-quel-prix\">O\u00f9 ranger les vecteurs, et \u00e0 quel prix<\/h2>\n<p>Une base de donn\u00e9es vectorielle est une base sp\u00e9cialis\u00e9e pour stocker, indexer et chercher efficacement des vecteurs de grande dimension. Il en existe des dizaines, et il n&rsquo;y en a probablement pas de meilleure dans l&rsquo;absolu : il y en a une qui convient \u00e0 ton projet. Les crit\u00e8res qui d\u00e9partagent :<\/p>\n<table>\n<thead>\n<tr>\n<th>Crit\u00e8re<\/th>\n<th>Ce qu&rsquo;il tranche<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Libre ou propri\u00e9taire<\/td>\n<td>Transparence et personnalisation contre support d\u00e9di\u00e9 ; la licence peut \u00eatre incompatible avec ton produit<\/td>\n<\/tr>\n<tr>\n<td>Langages et maturit\u00e9<\/td>\n<td>Compatibilit\u00e9 avec ta pile technique ; stabilit\u00e9 et suivi en production<\/td>\n<\/tr>\n<tr>\n<td>Performance<\/td>\n<td>Vitesse d&rsquo;insertion (le rythme d&rsquo;ajout des vecteurs) et vitesse de requ\u00eate (le temps de r\u00e9ponse)<\/td>\n<\/tr>\n<tr>\n<td>Int\u00e9gration<\/td>\n<td>Toutes les bases n&rsquo;acceptent pas un reranker ou une recherche hybride<\/td>\n<\/tr>\n<tr>\n<td>Co\u00fbt<\/td>\n<td>Cloud parfois tr\u00e8s cher, maintenance et support compris<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Le choix d\u00e9pend aussi du trafic \u00e0 servir. Deux profils s&rsquo;opposent : <strong>les remplissages \u00e0 haut d\u00e9bit<\/strong> (indexer des millions de documents, mettre \u00e0 jour un catalogue) et les consultations \u00e0 faible latence (requ\u00eates d&rsquo;utilisateurs, o\u00f9 chaque milliseconde compte). Si tu dois faire les deux et que le trafic justifie le co\u00fbt, il vaut mieux b\u00e2tir un syst\u00e8me distinct pour chacun.<\/p>\n<p>Reste la taille du vecteur lui-m\u00eame. Une piste consiste \u00e0 entra\u00eener l&rsquo;encodeur pour que l&rsquo;information essentielle se concentre dans les premi\u00e8res cases du vecteur, la perte d&rsquo;entra\u00eenement tenant compte de la qualit\u00e9 \u00e0 plusieurs dimensions. R\u00e9sultat : on <strong>coupe la fin du vecteur<\/strong> sans trop perdre en performance, et la base stocke des vecteurs plus petits.<\/p>\n<h2 id=\"plus-qu-une-recherche-de-passages\">Plus qu&rsquo;une recherche de passages<\/h2>\n<p>Retrouver des passages de texte est l&#8217;emploi le plus connu. Ce n&rsquo;est pas le seul, car chercher du \u00ab proche \u00bb sert partout o\u00f9 l&rsquo;on h\u00e9site entre plusieurs options.<\/p>\n<p><strong>Aiguiller une question.<\/strong> Un routeur s\u00e9mantique garde une liste de requ\u00eates d&rsquo;exemple, chacune associ\u00e9e \u00e0 sa route. Ces exemples sont convertis en vecteurs et rang\u00e9s dans une base ; \u00e0 l&rsquo;arriv\u00e9e d&rsquo;une requ\u00eate, on cherche l&rsquo;exemple le plus semblable et l&rsquo;on prend sa route. Imagine une entreprise avec trois domaines, banque, assurance et finance : pour des raisons de r\u00e9glementation et de vie priv\u00e9e, le chatbot ne doit pas fouiller les dossiers d&rsquo;un autre service, et chercher partout serait lent et brouillon.<\/p>\n<p><strong>Ouvrir la porte d&rsquo;un graphe.<\/strong> Pour une question centr\u00e9e sur une entit\u00e9 (\u00ab What are the healing properties of chamomile ? \u00bb), une recherche vectorielle rep\u00e8re d&rsquo;abord les entit\u00e9s du graphe qui ont un rapport de sens avec elle. Ces entit\u00e9s deviennent des points d&rsquo;entr\u00e9e pour r\u00e9cup\u00e9rer leurs voisines directes, leurs relations, des r\u00e9sum\u00e9s de communaut\u00e9 et des fragments de texte.<\/p>\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6adef4738e342&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6adef4738e342\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"823\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-scaled.png\" alt=\"Une question d\u00e9clenche une recherche vectorielle, qui alimente en parall\u00e8le trois sources (entit\u00e9s connect\u00e9es, relations connect\u00e9es, fragments de texte), puis une \u00e9tape de classement et de filtrage produit la r\u00e9ponse finale\" class=\"wp-image-544\" srcset=\"https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-scaled.png 2560w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-300x96.png 300w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-1024x329.png 1024w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-768x247.png 768w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-1536x494.png 1536w, https:\/\/www.ranksignal.fr\/wp-content\/uploads\/2026\/10\/b1_ch07_recherche_locale-2048x658.png 2048w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Suis le sch\u00e9ma de gauche \u00e0 droite : la recherche vectorielle n&rsquo;est que la premi\u00e8re case. Tout le reste de la cha\u00eene travaille \u00e0 partir des points d&rsquo;entr\u00e9e qu&rsquo;elle a d\u00e9sign\u00e9s, avant qu&rsquo;on classe, filtre et limite le r\u00e9sultat pour qu&rsquo;il tienne dans la fen\u00eatre de contexte du mod\u00e8le.<\/figcaption><\/figure>\n\n\n<p>Ces m\u00eames vecteurs, rang\u00e9s dans une base, alimentent aussi les m\u00e9moires d&rsquo;agents, la recherche et les syst\u00e8mes de recommandation.<\/p>\n<h2 id=\"trois-choses-qu-elle-ne-sait-pas-faire\">Trois choses qu&rsquo;elle ne sait pas faire<\/h2>\n<p><strong>Compter, trier, agr\u00e9ger.<\/strong> Prends la question \u00ab List the top three highest-rated movies directed by Steven Spielberg and their average score \u00bb. Aucune recherche par similarit\u00e9 ne peut y r\u00e9pondre : il faut une requ\u00eate pr\u00e9cise.<\/p>\n<pre><code>MATCH (:Reviewer)-[r:REVIEWED]-&gt;(m:Movie)&lt;-[:DIRECTED]-(:Director {name:\n'Steven Spielberg'})\nRETURN m.title, AVG(r.score) AS avg_rating\nORDER BY avg_rating DESC\nLIMIT 3\n<\/code><\/pre>\n<p>Cette requ\u00eate ne cherche pas les n\u0153uds les plus similaires : elle calcule une moyenne par film, trie et garde trois r\u00e9sultats. Voil\u00e0 un travail d&rsquo;agr\u00e9gation, pour lequel une recherche de voisins n&rsquo;est pas con\u00e7ue.<\/p>\n<blockquote>\n<p><strong>\u26a0\ufe0f Pi\u00e8ge<\/strong> Une recherche vectorielle r\u00e9pond toujours par \u00ab les plus proches \u00bb, m\u00eame quand la question demande autre chose que de la proximit\u00e9. Un r\u00e9sultat qui a l&rsquo;air plausible ne prouve donc pas que la bonne m\u00e9thode a \u00e9t\u00e9 employ\u00e9e.<\/p>\n<\/blockquote>\n<p><strong>D\u00e9cider seule combien de r\u00e9sultats garder.<\/strong> Apr\u00e8s une recherche vectorielle, on renvoie les <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-3422b6bb5c160593658b7c39425d9880_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#107;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"9\" style=\"vertical-align: 0px;\"\/> meilleurs, une coupure arbitraire fix\u00e9e \u00e0 l&rsquo;avance, qui peut faire perdre une information pertinente. Augmenter <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.ranksignal.fr\/wp-content\/ql-cache\/quicklatex.com-3422b6bb5c160593658b7c39425d9880_l3.png\" class=\"ql-img-inline-formula quicklatex-auto-format\" alt=\"&#107;\" title=\"Rendered by QuickLaTeX.com\" height=\"12\" width=\"9\" style=\"vertical-align: 0px;\"\/> est la parade la plus simple, mais on ne peut pas tout renvoyer : les r\u00e9sultats ne tiendraient pas dans la longueur de contexte du mod\u00e8le, et celui-ci peinerait \u00e0 manier une telle masse d&rsquo;information.<\/p>\n<p><strong>Rattraper des textes mal d\u00e9crits.<\/strong> La recherche ne vaut que ce que valent les textes qu&rsquo;elle compare. Pour des outils, on donne \u00e0 chacun un nom concis et descriptif (<code>calculate_sum<\/code> plut\u00f4t que <code>process_numbers<\/code>) et un r\u00e9sum\u00e9 d&rsquo;une phrase sur sa finalit\u00e9 propre. M\u00eame ainsi, quand le catalogue grandit, le chevauchement des descriptions devient souvent <strong>une source d&rsquo;erreurs de s\u00e9lection<\/strong>.<\/p>\n<p>Retiens donc l&rsquo;image de d\u00e9part : une recherche vectorielle plante ta question sur une carte et lit ce qui l&rsquo;entoure. Elle excelle quand la r\u00e9ponse est une affaire de voisinage, et se trompe d&rsquo;outil quand la r\u00e9ponse demande de compter.<\/p>","protected":false},"excerpt":{"rendered":"<p>Une recherche vectorielle compare des positions dans un espace, pas des mots. Vecteurs, cosinus, index et limites, avec un agent qui choisit son outil.<\/p>\n","protected":false},"author":1,"featured_media":545,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-546","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rag"],"_links":{"self":[{"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/posts\/546","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/comments?post=546"}],"version-history":[{"count":3,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/posts\/546\/revisions"}],"predecessor-version":[{"id":809,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/posts\/546\/revisions\/809"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/media\/545"}],"wp:attachment":[{"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/media?parent=546"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/categories?post=546"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ranksignal.fr\/blog\/wp-json\/wp\/v2\/tags?post=546"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}