De « nous avons des vecteurs » à « cela évolue réellement et ne nous met pas en faillite ».
👦 Neveu : Mon oncle, la phase 2 est terminée. Je comprends la tokenisation, les intégrations, la similarité cosinus. Mais deux choses me dérangent. Premièrement : où vivent réellement ces vecteurs, physiquement ? Deuxièmement : lorsque nous en avons 5 millions, comment la recherche peut-elle rester rapide sans vérifier chacun d'entre eux ? C'est comme de la magie en ce moment.
👨🦳 Oncle : Bien, parce que ce n'est pas de la magie, et si vous le traitez comme de la magie, vous prendrez de mauvaises décisions plus tard. Quel index utiliser, combien de mémoire vous aurez besoin, pourquoi votre recherche est soudainement devenue plus lente après l'ajout d'un million de vecteurs, pourquoi votre facture d'intégration est bien plus élevée qu'elle ne devrait l'être - rien de tout cela n'a de sens tant que vous ne comprenez pas ce qui se passe réellement en dessous. Prenons cela dans l'ordre : d'abord où vivent les choses, puis comment la recherche reste rapide, puis - la partie ignorée par presque tous les didacticiels - comment arrêter de dépenser de l'argent en faisant tout cela.
Phase 2 : Intégrations et recherche sémantique ✅ ↓ AUJOURD'HUI ← NOUS SOMMES ICI │ ├─ Partie 1 : Où les intégrations sont réellement enregistrées (conception de schéma) ├─ Partie 2 : Pourquoi vous ne pouvez pas simplement « tout vérifier » (le mur de force brute) ├─ Partie 3 : FIV — L'approche de quartier ├─ Partie 4 : HNSW — L'approche routière ├─ Partie 5 : Quantification du produit — Compression des vecteurs ├─ Partie 6 : Métriques de distance — Ce que « similaire » signifie réellement ├─ Partie 7 : Indexation des métadonnées — L'autre moitié que tout le monde oublie ├─ Partie 8 : L'assembler dans pgvector ├─ Partie 9 : Choisir honnêtement une base de données vectorielles └─ Partie 10 : Économie des jetons — Arrêtez de payer deux fois pour la même chose ↓ Un système qui survit au trafic réel et à une vraie facture👨🦳 Tonton : Avant de parler d'indexation, réglons les bases. Un vecteur en soi est inutile. Ce que vous stockez réellement est une ligne : le vecteur, ainsi que tout ce dont vous avez besoin pour l'utiliser plus tard, le retrouver et éviter de le payer deux fois.
Tableau:document_chunks
| Colonne | But |
|---|---|
identifiant | Identifiant unique |
chunk_text | Le texte original — conservé comme assurance pour une réintégration ultérieure avec un nouveau modèle |
intégration | vecteur(1536) |
modèle_d'intégration | par ex.'texte-incorporation-3-petit'— différents modèles produisent des espaces vectoriels incompatibles |
content_hash | SHA-256 dechunk_text- utilisé pour la déduplication, plus d'informations à ce sujet dans la partie 10 |
métadonnées | jsonb—{ département, doc_type, uploaded_by, source_file } |
créé_à | Horodatage |
👦 Neveu : Pourquoi les métadonnées sont-elles distinctesjsonbcolonne au lieu de juste... plus de colonnes ?
👨🦳 Tonton : Parce que les métadonnées changent de forme en fonction du document. Un élément de politique RH pourrait avoir{ département : "RH", doc_type : "politique" }. Un morceau de ticket de support pourrait avoir{ customer_id : 4521, priorité : "élevée" }. Si vous essayiez de créer une colonne rigide pour chaque champ possible dans chaque type de document, vous redessineriez votre tableau chaque semaine.jsonbvous donne cette flexibilité - et c'est la partie qui manque aux gens - vous pouvez toujours indexer dans unjsonbcolonne, ce que nous ferons correctement dans la partie 7.
CRÉER UNE EXTENSION SI N'EXISTE PAS vecteur ; CREATE TABLE document_chunks ( id BIGSERIAL PRIMARY KEY, chunk_text TEXT NOT NULL, incorporation de VECTOR(1536) NOT NULL, embedding_model VARCHAR(50) NOT NULL, content_hash VARCHAR(64) NOT NULL, métadonnées JSONB DEFAULT '{}',created_at TIMESTAMP DEFAULT now() );👦 Neveu :content_hashencore une fois – c'est la même idée SHA-256 issue de la déduplation des fichiers de la phase 1, n'est-ce pas ?
👨🦳 Oncle : Même idée, un niveau plus profond. Dans la phase 1, nous avons haché l'intégralité du fichier pour éviter de stocker deux fois le même fichier. Ici, nous hachons chaque morceau individuel, pour éviter d'incorporer le même morceau deux fois, car deux fichiers complètement différents peuvent contenir exactement le même paragraphe : une clause juridique standard partagée, une clause de non-responsabilité répétée, un paragraphe d'introduction standard de l'entreprise copié dans cinquante documents. Gardez cette pensée. Cela devient de l'argent réel dans la partie 10.
👨🦳 Oncle : Maintenant, la question de la vitesse de recherche. Supposons que vous disposiez de 5 millions de vecteurs de blocs, chacun ayant 1 536 dimensions. Un utilisateur pose une question, vous l'intégrez dans un vecteur de requête. Quelle est la manière la plus stupide possible de trouver les morceaux les plus similaires ?
👦 Neveu : comparez le vecteur de requête avec chacun des 5 millions de vecteurs, calculez la similarité pour chacun, triez, prenez le top 5.
👨🦳 Oncle : Exactement, cela s'appelle un index plat ou une recherche exhaustive. Voyons ce que cela coûte réellement, en chiffres réels, sans de vagues gestes de la main.
5 000 000 de vecteurs × 1 536 dimensions chacun Pour CHAQUE requête : Comparez avec 5 000 000 de vecteurs Chaque comparaison : 1 536 multiplications + ajouts (similitude cosinus) Nombre total d'opérations par requête : 5 000 000 × 1 536 ≈ 7,68 MILLIARDS d'opérations Sur une machine typique : ~ 20 à 30 secondes par requête👦 Neveu : 30 secondes ?! Personne n’attend 30 secondes pour une réponse du chatbot.
👨🦳 Oncle : C'est exactement pourquoi la force brute ne fonctionne qu'à petite échelle – quelques milliers de vecteurs, peut-être. Au-delà de cela, vous avez besoin d'une stratégie fondamentalement différente : ne pas tout vérifier, vérifier uniquement les candidats potentiels. Ce compromis porte un nom : la recherche du voisin le plus proche, ou ANN.
👦 Neveu : « Approximativement » ? Donc cela pourrait donner une mauvaise réponse ?
👨🦳 Oncle : Cela pourrait vous donner le 4ème match le plus proche au lieu du 1er réel, de temps en temps. Cet échange en vaut presque toujours la peine, car l’alternative consiste à vérifier exactement les 5 millions de vecteurs, à chaque requête, pour toujours. Vous échangez un tout petit peu de précision contr...
[Courte citation de 8% de l'article original]