
Optimiser la recherche de vecteurs : pourquoi devriez-vous aplatir les données structurées
des données structurées dans un système RAG, les ingénieurs intègrent souvent par défaut du JSON brut dans une base de données vectorielle. La réalité, cependant, est que cette approche intuitive conduit à des performances extrêmement médiocres. Les intégrations modernes sont basées sur l’architecture BERT, qui est essentiellement la partie codeur d’un Transformateuret sont formés sur un énorme ensemble de données textuelles dans le but principal de capturer la signification sémantique. Les modèles d’intégration modernes peuvent fournir des performances de récupération incroyables, mais ils sont formés sur un large ensemble de textes non structurés en mettant l’accent sur la signification sémantique. Par conséquent, même si l’intégration de JSON peut sembler une solution intuitivement simple et élégante, l’utilisation d’un modèle d’intégration générique pour les objets JSON démontrerait des résultats loin des performances optimales.
Plongée profonde
Tokenisation
La première étape est la tokenisation, qui prend le texte et le divise en jetons, qui constituent généralement une partie générique du mot. Les modèles d’intégration modernes utilisent des algorithmes de tokenisation Byte-Pair Encoding (BPE) ou WordPièce. Ces algorithmes sont optimisés pour le langage naturel, divisant les mots en sous-composants communs. Lorsqu’un tokenizer rencontre du JSON brut, il a du mal à gérer la fréquence élevée des caractères non alphanumériques. Par exemple, "usd": 10, n’est pas considéré comme une paire clé-valeur ; au lieu de cela, il est fragmenté :
- Les citations (
"), côlon (:), et une virgule (,) - Jetons
usdet10
Cela crée un faible rapport signal/bruit. En langage naturel, presque tous les mots contribuent au « signal » sémantique. En JSON (et dans d’autres formats structurés), un pourcentage important de jetons est « gaspillé » dans une syntaxe structurelle qui ne contient aucune valeur sémantique.
Calcul de l’attention
Le pouvoir fondamental de Transformateurs réside dans le mécanisme de l’attention. Cela permet au modèle de pondérer l’importance des jetons les uns par rapport aux autres.
Dans la phrase The price is 10 US dollars or 9 eurosl’attention peut facilement lier la valeur 10 à la notion price car ces relations sont bien représentées dans les données de pré-entraînement du modèle et le modèle a vu ce modèle linguistique des millions de fois. Par contre, dans le JSON brut :
"price": {
"usd": 10,
"eur": 9,
}
le modèle rencontre une syntaxe structurelle pour laquelle il n’a pas été principalement optimisé pour « lire ». Sans le connecteur linguistique, le vecteur résultant ne parviendra pas à capturer la véritable intention des données, car les relations entre la clé et la valeur sont obscurcies par le format lui-même.
Mise en commun moyenne
La dernière étape de la génération d’une représentation intégrée unique du document est Mean Pooling. Mathématiquement, l’intégration finale (E) est le centre de gravité de tous les vecteurs de jetons (e1, e2, e3) dans le document :

C’est là que les jetons JSON deviennent un handicap mathématique. Si 25 % des jetons du document sont des marqueurs structurels (accolades, guillemets, deux-points), le vecteur final est fortement influencé par le « sens » de la ponctuation. En conséquence, le vecteur est effectivement « éloigné » de son véritable centre sémantique dans l’espace vectoriel par ces jetons de bruit. Lorsqu’un utilisateur soumet une requête en langage naturel, la distance entre le vecteur de requête « propre » et le vecteur JSON « bruyant » augmente, ce qui nuit directement aux métriques de récupération.
Aplatissez-le
Alors maintenant que nous connaissons les limitations de JSON, nous devons trouver comment les résoudre. L’approche générale et la plus simple consiste à aplatir le JSON et à le convertir en langage naturel.
Considérons l’objet produit typique :
{
"skuId": "123",
"description": "This is a test product used for demonstration purposes",
"quantity": 5,
"price": {
"usd": 10,
"eur": 9,
},
"availableDiscounts": ["1", "2", "3"],
"giftCardAvailable": "true",
"category": "demo product"
...
}
Il s’agit d’un objet simple avec quelques attributs comme la description, etc. Appliquons-lui la tokenisation et voyons à quoi il ressemble :

Maintenant, convertissons-le en texte pour faciliter le travail des intégrations. Pour ce faire, nous pouvons définir un modèle et y substituer les valeurs JSON. Par exemple, ce modèle pourrait être utilisé pour décrire le produit :
Product with SKU {skuId} belongs to the category "{category}"
Description: {description}
It has a quantity of {quantity} available
The price is {price.usd} US dollars or {price.eur} euros
Available discount ids include {availableDiscounts as comma-separated list}
Gift cards are {giftCardAvailable ? "available" : "not available"} for this product
Le résultat final ressemblera donc à :
Product with SKU 123 belongs to the category "demo product"
Description: This is a test product used for demonstration purposes
It has a quantity of 5 available
The price is 10 US dollars or 9 euros
Available discount ids include 1, 2, and 3
Gift cards are available for this product
Et appliquez-lui un tokenizer :

Non seulement il contient désormais 14 % de jetons en moins, mais il s’agit également d’une forme beaucoup plus claire avec la signification sémantique et le contexte requis.
Mesurons les résultats
Remarque : Le code complet et reproductible de cette expérience est disponible dans le Bloc-notes Google Colab
Essayons maintenant de mesurer les performances de récupération pour les deux options. Nous allons nous concentrer sur les métriques de récupération standard telles que Recall@k, Precision@k et MRR pour rester simple, et utiliserons un modèle d’intégration générique (tout-MiniLM-L6-v2) et le Amazon ESCI ensemble de données avec 5 000 requêtes aléatoires et 3 809 produits associés.
Le tout-MiniLM-L6-v2 est un choix populaire, qui est petit (22,7 millions de paramètres) mais fournit des résultats rapides et précis, ce qui en fait un bon choix pour cette expérience.
Pour l’ensemble de données, la version de Amazon ESCI est utilisé, spécifiquement milistu/amazon-esci-data (), qui est disponible sur Hugging Face et contient une collection de produits Amazon et de données de requêtes de recherche.
La fonction d’aplatissement utilisée pour la conversion de texte est :
def flatten_product(product):
return (
f"Product {product['product_title']} from brand {product['product_brand']}"
f" and product id {product['product_id']}"
f" and description {product['product_description']}"
)
Voici un exemple de données JSON brutes :
{
"product_id": "B07NKPWJMG",
"title": "RoWood 3D Puzzles for Adults, Wooden Mechanical Gear Kits for Teens Kids Age 14+",
"description": "<p> <strong>Specifications</strong><br /> Model Number: Rowood Treasure box LK502<br /> Average build time: 5 hours<br /> Total Pieces: 123<br /> Model weight: 0.69 kg<br /> Box weight: 0.74 KG<br /> Assembled size: 100*124*85 mm<br /> Box size: 320*235*39 mm<br /> Certificates: EN71,-1,-2,-3,ASTMF963<br /> Recommended Age Range: 14+<br /> <br /> <strong>Contents</strong><br /> Plywood sheets<br /> Metal Spring<br /> Illustrated instructions<br /> Accessories<br /> <br /> <strong>MADE FOR ASSEMBLY</strong><br /> -Follow the instructions provided in the booklet and assembly 3d puzzle with some exciting and engaging fun. Fell the pride of self creation getting this exquisite wooden work like a pro.<br /> <strong>GLORIFY YOUR LIVING SPACE</strong><br /> -Revive the enigmatic charm and cheer your parties and get-togethers with an experience that is unique and interesting .<br /> <br />",
"brand": "RoWood",
"color": "Treasure Box"
}
Pour la recherche vectorielle, deux FAISS des index sont créés : un pour le texte aplati et un pour le texte au format JSON. Les deux index sont plats, ce qui signifie qu’ils compareront les distances pour chacune des entrées existantes au lieu d’utiliser un Voisin le plus proche approximatif (ANN) indice. Ceci est important pour garantir que les métriques de récupération ne sont pas affectées par l’ANN.
D = 384
index_json = faiss.IndexFlatIP(D)
index_flatten = faiss.IndexFlatIP(D)
Pour réduire l’ensemble de données, un nombre aléatoire de 5 000 requêtes a été sélectionné et tous les produits correspondants ont été intégrés et ajoutés aux index. En conséquence, les métriques collectées sont les suivantes :

all-MiniLM-L6-v2 modèle d’intégration sur l’ensemble de données Amazon ESCI. L’approche aplatie donne systématiquement des scores plus élevés pour toutes les mesures de récupération clés (Precision@10, Recall@10 et MRR). Image de l’auteurEt le changement de performances de la version aplatie est :

L’analyse confirme que l’intégration de données structurées brutes dans un espace vectoriel générique est une approche sous-optimale et que l’ajout d’une simple étape de prétraitement consistant à aplatir les données structurées apporte systématiquement une amélioration significative des métriques de récupération (en augmentant le rappel@k et la précision@k d’environ 20 %). Le principal point à retenir pour les ingénieurs qui construisent des systèmes RAG est qu’une préparation efficace des données est extrêmement importante pour atteindre des performances optimales du système de récupération sémantique/RAG.
Références
[1] Code de test complet https://colab.research.google.com/drive/1dTgt6xwmA6CeIKE38lf2cZVahaJNbQB1?usp=sharing
[2] Modèle https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
[3] Ensemble de données Amazon ESCI. Version spécifique utilisée : https://huggingface.co/datasets/milistu/amazon-esci-data
L’ensemble de données original disponible sur https://www.amazon.science/code-and-datasets/shopping-queries-dataset-a-large-scale-esci-benchmark-for-improving-product-search
[4] FAISS https://ai.meta.com/tools/faiss/



