Créer un pipeline de données non structurées pour RAG
Cet article décrit comment créer un pipeline de données non structurées pour les applications d'IA générative. Les pipelines non structurés sont particulièrement utiles pour les applications de génération augmentée par la récupération (RAG).
Découvrez comment convertir un contenu non structuré, tel que des fichiers texte et des PDF, en un index vectoriel que les agents d'IA ou d'autres récupérateurs peuvent interroger. Vous apprendrez également comment expérimenter et affiner votre pipeline pour optimiser le découpage, l'indexation et l'analyse des données, ce qui vous permettra de dépanner et d'expérimenter le pipeline pour obtenir de meilleurs résultats.
Notebook de pipeline de données non structurées
Le Notebook suivant vous montre comment implémenter les informations de cet article pour créer un pipeline de données non structurées.
pipeline de données non structurées Databricks
Composants clés du pipeline de données
La base de toute application RAG avec des données non structurées est le pipeline de données. Ce pipeline est responsable de la conservation et de la préparation des données non structurées dans un format que l'application RAG peut utiliser efficacement.
Bien que ce pipeline de données puisse devenir complexe en fonction du cas d'utilisation, voici les composants clés à prendre en compte lors de la première création de votre application RAG :
-
Composition et ingestion du corpus: sélectionnez les bonnes sources de données et le bon contenu en fonction du cas d'utilisation spécifique.
-
Prétraitement des données: Transformez les données brutes en un format propre et cohérent, adapté à l'intégration et à la récupération.
- Analyse: extrayez les informations pertinentes des données brutes à l’aide de techniques d’analyse appropriées.
- Enrichissement: enrichissez des données avec des métadonnées supplémentaires et supprimez le bruit.
- Extraction de métadonnées: extrayez des métadonnées utiles pour implémenter une récupération de données plus rapide et plus efficace.
- Deduplication: Analysez les documents pour identifier et éliminer les documents dupliqués ou quasi dupliqués.
- Filtrage: Éliminez les documents non pertinents ou indésirables de la collection.
-
Découpage en blocs: Décomposez les données analysées en blocs plus petits et gérables pour une récupération efficace.
-
Intégration: Convertissez les données textuelles fragmentées en une représentation vectorielle numérique qui capture leur signification sémantique.
-
Indexation et stockage: créez des index vectoriels efficaces pour des performances de recherche optimisées.
Composition et ingestion du corpus
Votre application RAG ne peut pas récupérer les informations requises pour répondre à une requête utilisateur sans le corpus de données approprié. Les données appropriées dépendent entièrement des exigences et des objectifs spécifiques de votre application, ce qui rend crucial de consacrer du temps à la compréhension des nuances des données disponibles. Pour plus d'informations, voir cycle de vie du développement d'Agent.
Par exemple, lors de la création d'un bot d'assistance client, vous pourriez envisager d'inclure les éléments suivants :
- Documents de base de connaissances
- Questions fréquemment posées (FAQ)
- Manuels et spécifications de produits
- Guides de dépannage
Impliquez des experts du domaine et des parties prenantes dès le début de tout projet afin d'aider à identifier et à organiser le contenu pertinent qui pourrait améliorer la qualité et la couverture de votre corpus de données. Ils peuvent fournir des insights sur les types de requêtes que les utilisateurs sont susceptibles de soumettre et aider à prioriser les informations les plus critiques à inclure.
Databricks vous recommande d'ingérer les données de manière évolutive et incrémentielle. Databricks propose diverses méthodes pour l'ingestion des données, notamment des connecteurs entièrement managés pour les applications SaaS et des intégrations d'API. En tant que bonne pratique, les données sources brutes doivent être ingérées et stockées dans une table cible. Cette approche assure la préservation, la traçabilité et l'audit des données. Consultez les connecteurs standard dans Lakeflow Connect.
Prétraitement des données
Une fois les données importées, il est essentiel de nettoyer et de formater les données brutes dans un format cohérent adapté à l'intégration et à la récupération.
Analyse
Après avoir identifié les sources de données appropriées pour votre application de récupération, l'étape suivante consiste à extraire les informations requises des données brutes. Ce processus, connu sous le nom d'analyse syntaxique (parsing), implique de transformer les données non structurées en un format que l'application RAG peut utiliser efficacement.
Les techniques et outils d'analyse spécifiques que vous utilisez dépendent du type de données avec lequel vous travaillez. Par exemple :
- Documents texte (PDF, documents Word) : les bibliothèques prêtes à l’emploi comme unstructured et PyPDF2 peuvent gérer divers formats de fichiers et offrir des options pour personnaliser le processus d’analyse.
- Documents HTML : les bibliothèques d'analyse HTML telles que BeautifulSoup et lxml peuvent être utilisées pour extraire le contenu pertinent des pages web. Ces bibliothèques peuvent aider à parcourir la structure HTML, à sélectionner des éléments spécifiques et à extraire le texte ou les attributs souhaités.
- Images et documents numérisés : Des techniques de reconnaissance optique de caractères (OCR) sont généralement nécessaires pour extraire le texte des images. Les bibliothèques OCR populaires incluent des bibliothèques open source telles que Tesseract ou des versions SaaS comme Amazon Textract, Azure AI Vision OCR et Google Cloud Vision API.
Meilleures pratiques pour l'analyse des données
L’analyse garantit que les données sont propres, structurées et prêtes pour la génération d’embeddings et la recherche IA. Lors de l'analyse de vos données, tenez compte des bonnes pratiques suivantes :
- Nettoyage des données : prétraitez le texte extrait pour supprimer les informations non pertinentes ou bruyantes, telles que les en-têtes, les pieds de page ou les caractères spéciaux. Réduisez la quantité d'informations inutiles ou mal formées que votre chaîne RAG doit traiter.
- Gestion des erreurs et des exceptions : Mettez en œuvre des mécanismes de gestion des erreurs et de journalisation pour identifier et résoudre tout problème rencontré pendant le processus d'analyse. Cela vous aide à identifier et à résoudre rapidement les problèmes. Cela indique souvent des problèmes en amont liés à la qualité des données source.
- Personnalisation de la logique d'analyse : En fonction de la structure et du format de vos données, vous devrez peut-être personnaliser la logique d'analyse pour extraire les informations les plus pertinentes. Bien que cela puisse nécessiter un effort supplémentaire en amont, investissez le temps nécessaire pour ce faire, si besoin est, car cela prévient souvent de nombreux problèmes de qualité en aval.
- Évaluation de la qualité de l'analyse : évaluez régulièrement la qualité des données analysées en examinant manuellement un échantillon de la sortie. Cela peut vous aider à identifier tout problème ou toute zone d'amélioration dans le processus d'analyse.
Enrichissement
Enrichissez des données avec des métadonnées supplémentaires et supprimez le bruit. Bien que l’enrichissement soit facultatif, il peut considérablement améliorer les performances globales de votre application.
Extraction de métadonnées
La génération et l'extraction de métadonnées qui capturent des informations essentielles sur le contenu, le contexte et la structure du document peuvent améliorer considérablement la qualité de la récupération et les performances d'une application RAG. Les métadonnées fournissent des signaux supplémentaires qui améliorent la pertinence, permettent un filtrage avancé et prennent en charge les exigences de recherche spécifiques à un domaine.
Bien que des bibliothèques telles que LangChain et LlamaIndex fournissent des analyseurs intégrés capables d'extraire automatiquement les métadonnées standard associées, il est souvent utile de compléter cela par des métadonnées personnalisées adaptées à votre cas d'utilisation spécifique. Cette approche garantit que les informations critiques spécifiques au domaine sont capturées, ce qui améliore la récupération et la génération en aval. Vous pouvez également utiliser de grands modèles de langage (LLM) pour automatiser l'amélioration des métadonnées.
Les types de métadonnées incluent :
- Métadonnées au niveau du document : nom du fichier, URL, information sur l'auteur, Timestamp de création et de modification, coordonnées GPS et gestion des versions du document.
- Métadonnées basées sur le contenu : mots-clés extraits, résumés, sujets, entités nommées et balises spécifiques au domaine (noms de produits et catégories comme PII ou HIPAA).
- Métadonnées structurelles : en-têtes de section, table des matières, numéros de page et limites de contenu sémantique (chapitres ou sous-sections).
- Métadonnées contextuelles : système source, date d'ingestion, niveau de sensibilité des données, langue d'origine ou instructions transnationales.
Le stockage des métadonnées à côté des documents fragmentés ou de leurs embeddings correspondants est essentiel pour des performances optimales. Cela permettra également d'affiner les informations récupérées et d'améliorer la précision et l'évolutivité de votre application. De plus, l'intégration des métadonnées dans les pipelines de recherche hybride, ce qui signifie combiner la recherche par similarité vectorielle avec le filtrage par mots-clés, peut améliorer la pertinence, en particulier dans le cas de grands datasets ou de scénarios de critères de recherche spécifiques.
Déduplication
Selon vos sources, vous pouvez vous retrouver avec des documents en double ou des quasi-doublons. Par exemple, si vous extrayez des données d'un ou plusieurs lecteurs partagés, plusieurs copies du même document pourraient exister à plusieurs emplacements. Certaines de ces copies peuvent présenter de subtiles modifications. De même, votre base de connaissances peut contenir des copies de votre documentation produit ou des brouillons de billets de blog. Si ces doublons persistent dans votre corpus, vous risquez de vous retrouver avec des blocs très redondants dans votre index final, ce qui peut réduire les performances de votre application.
Vous pouvez éliminer certains doublons en utilisant uniquement les métadonnées. Par exemple, si un élément a le même titre et la même date de création, mais plusieurs entrées provenant de sources ou d'emplacements différents, vous pouvez les filtrer en fonction des métadonnées.
Cependant, cela peut ne pas être suffisant. Pour aider à identifier et à éliminer les doublons basés sur le contenu des documents, vous pouvez utiliser une technique connue sous le nom de hachage sensible à la localité. Plus précisément, une technique appelée MinHash fonctionne bien ici, et une implémentation Spark est déjà disponible dans Spark ML. Cela fonctionne en créant un hachage pour le document basé sur les mots qu'il contient et peut ensuite identifier efficacement les doublons ou les quasi-doublons en se joignant à ces hachages. À un niveau très élevé, il s'agit d'un processus en quatre étapes :
- Créez un vecteur de caractéristiques pour chaque document. Si nécessaire, envisagez d'appliquer des techniques telles que la suppression des mots vides, la racinisation et la lemmisation pour améliorer les résultats, puis de tokeniser en n-grammes.
- Ajustez un modèle MinHash et hachez les vecteurs en utilisant MinHash pour la distance de Jaccard.
- Exécuter une jointure de similarité en utilisant ces hachages pour produire un jeu de résultats pour chaque document en double ou quasi-identique.
- Filtrez les doublons que vous ne souhaitez pas conserver.
Une étape de déduplication de base peut sélectionner arbitrairement les documents à conserver (comme le premier dans les résultats de chaque doublon ou un choix aléatoire parmi les doublons). Une amélioration potentielle consisterait à sélectionner la « meilleure » version du doublon en utilisant d’autres logiques (telles que la mise à jour la plus récente, l’état de publication ou la source la plus fiable). Notez également que vous devrez peut-être expérimenter avec l’étape de featurization et le nombre de tables de hachage utilisées dans le modèle MinHash afin d'améliorer les résultats de correspondance.
Pour plus d'informations, consultez la documentation Spark sur le hachage sensible à la localité.
Filtrage
Certains des documents que vous ingérez dans votre corpus peuvent ne pas être utiles pour votre agent, soit parce qu'ils sont hors de propos pour son objectif, trop anciens ou peu fiables, soit parce qu'ils contiennent un contenu problématique tel qu'un langage nuisible. Cependant, d'autres documents peuvent contenir des informations sensibles que vous ne souhaitez pas exposer par l'intermédiaire de votre agent.
Par conséquent, envisagez d'inclure une étape dans votre pipeline pour filtrer ces documents en utilisant des métadonnées, par exemple en appliquant un classificateur de toxicité au document afin de produire une prédiction que vous pouvez utiliser comme filtre. Un autre exemple serait d'appliquer un algorithme de détection des informations personnelles identifiables (PII) aux documents pour les filtrer.
Enfin, toutes les sources de documents que vous alimentez dans votre agent sont des vecteurs d'attaque potentiels pour les mauvais acteurs afin de lancer des attaques par empoisonnement des données. Vous pouvez également envisager d'ajouter des mécanismes de détection et de filtrage pour aider à les identifier et à les éliminer.
Segmentation

Après avoir analysé les données brutes dans un format plus structuré, supprimé les doublons et filtré les informations indésirables, l’étape suivante consiste à les diviser en unités plus petites et gérables appelées segments. Le découpage de documents volumineux en segments plus petits et sémantiquement concentrés garantit que les données récupérées s’inscrivent dans le contexte du LLM tout en minimisant l’inclusion d’informations distrayantes ou non pertinentes. Les choix faits en matière de segmentation affecteront directement les données récupérées fournies par le LLM, ce qui en fait l’une des premières couches d’optimisation dans une application RAG.
Lorsque vous segmentez vos données, tenez compte des facteurs suivants :
- Stratégie de segmentation : La méthode que vous utilisez pour diviser le texte original en segments. Cela peut impliquer des techniques de base telles que le fractionnement par phrases, paragraphes, nombre spécifique de caractères/jetons, et des stratégies de fractionnement plus avancées spécifiques aux documents.
- Taille des fragments : Les fragments plus petits peuvent se concentrer sur des détails spécifiques mais perdre certaines informations contextuelles environnantes. Les plus grands morceaux peuvent capturer plus de contexte, mais peuvent inclure des informations non pertinentes ou être coûteux en calcul.
- Chevauchement entre les segments : pour s'assurer que les informations importantes ne sont pas perdues lors de la division des données en segments, envisagez d'inclure un certain chevauchement entre les segments adjacents. Le chevauchement peut assurer la continuité et la préservation du contexte entre les segments et améliorer les résultats de récupération.
- Cohérence sémantique : lorsque cela est possible, visez à créer des morceaux sémantiquement cohérents qui contiennent des informations connexes mais peuvent être autonomes en tant qu'unité de texte significative. Ceci peut être réalisé en considérant la structure des données d'origine, tels que les paragraphes, les sections ou les limites thématiques.
- **Métadonnées :** Les métadonnées pertinentes, telles que le nom du document source, le titre de la section ou les noms de produits, peuvent améliorer la récupération. Ces informations supplémentaires peuvent aider à faire correspondre les queries de récupération aux segments.
Stratégies de segmentation des données
Trouver la bonne méthode de découpage est à la fois itératif et dépendant du contexte. Il n'existe pas d'approche universelle. La taille et la méthode optimales des blocs dépendent du cas d'utilisation spécifique et de la nature des données traitées. De manière générale, les stratégies de découpage en fragments peuvent être considérées comme les suivantes :
- **Découpage en blocs de taille fixe :** fractionnez le texte en blocs d’une taille prédéterminée, comme un nombre fixe de caractères ou de jetons (par exemple, LangChain CharacterTextSplitter). Bien que le fractionnement par un nombre arbitraire de caractères/jetons soit rapide et facile à configurer, il ne produira généralement pas de blocs sémantiquement cohérents et uniformes. Cette approche fonctionne rarement pour les applications de niveau production.
- Fragmentation basée sur les paragraphes : Utilisez les limites naturelles des paragraphes dans le texte pour définir des fragments. Cette méthode peut aider à préserver la cohérence sémantique des blocs, car les paragraphes contiennent souvent des informations connexes (par exemple, LangChain RecursiveCharacterTextSplitter).
- Segmentation spécifique au format : des formats tels que Markdown ou HTML ont une structure intrinsèque qui peut définir les limites des segments (par exemple, les en-têtes markdown). Des outils comme le MarkdownHeaderTextSplitter de LangChain ou les répartiteurs HTML basés sur les en-têtes/sectionspeuvent être utilisés à cette fin.
- **Découpage sémantique** : Des techniques telles que la modélisation de sujets peuvent être appliquées pour identifier des sections sémantiquement cohérentes dans le texte. Ces approches analysent le contenu ou la structure de chaque document pour déterminer les limites de fragments les plus appropriées en fonction des changements de sujet. Bien que plus complexe que les approches de base, le découpage sémantique peut aider à créer des fragments qui sont plus alignés avec les divisions sémantiques naturelles dans le texte (voir LangChain SemanticChunker, par exemple).
Exemple : Découpage en segments de taille fixe

Exemple de découpage à taille fixe utilisant RecursiveCharacterTextSplitter de LangChain avec chunk_size=100 et chunk_overlap=20. ChunkViz offre un moyen interactif de visualiser comment différentes tailles de segments et valeurs de chevauchement de segments avec les diviseurs de caractères de Langchain affectent les segments résultants.
Intégration

Après avoir segmenté vos données, l'étape suivante consiste à convertir les segments de texte en une représentation vectorielle à l'aide d'un modèle d'intégration. Un modèle d'intégration convertit chaque segment de texte en une représentation vectorielle qui capture sa signification sémantique. En représentant les segments sous forme de vecteurs denses, les intégrations permettent une récupération rapide et précise des segments les plus pertinents en fonction de leur similarité sémantique à une query de récupération. La query de récupération sera transformée au moment de la query en utilisant le même modèle d'intégration que celui utilisé pour intégrer les fragments dans le pipeline de données.
Lorsque vous sélectionnez un modèle d'intégration, tenez compte des facteurs suivants :
-
Choix du modèle : Chaque modèle d'intégration présente des nuances, et les benchmarks disponibles peuvent ne pas capturer les caractéristiques spécifiques de vos données. Il est crucial de sélectionner un modèle qui a été entraîné sur des données similaires. Il peut également être utile d'explorer tous les modèles d'intégration disponibles qui sont conçus pour des tâches spécifiques. Expérimentez avec différents modèles d'intégration prêts à l'emploi, même ceux qui pourraient être moins bien classés sur les classements standards comme MTEB. Quelques exemples à considérer :
-
Max. de jetons : connaissez la limite maximale de jetons pour le modèle d'intégration choisi. Si vous transmettez des segments qui dépassent cette limite, ils seront tronqués, ce qui risque d'entraîner la perte d'informations importantes. Par exemple, bge-large-en-v1.5 a une limite maximale de jetons de 512.
-
Taille du modèle : Les modèles d'intégration plus grands offrent généralement de meilleures performances, mais nécessitent davantage de ressources de calcul. Selon votre cas d'utilisation spécifique et les ressources disponibles, vous devrez équilibrer performances et efficacité.
-
**Affinement** : si votre application RAG utilise un langage spécifique au domaine (tel que des acronymes ou une terminologie d'entreprise interne), envisagez d'affiner le modèle d'incorporation sur des données spécifiques au domaine. Cela peut aider le modèle à mieux saisir les nuances et la terminologie de votre domaine particulier et peut souvent conduire à une amélioration des performances de récupération.
Indexation et stockage
La prochaine étape du pipeline consiste à créer des index sur les incorporations et les métadonnées générées lors des étapes précédentes. Cette étape consiste à organiser des incorporations vectorielles à haute dimension dans des structures de données efficaces qui permettent des recherches de similarité rapides et précises.
Lorsque vous déployez des endpoints et des index AI Search, AI Search garantit des recherches rapides et efficaces pour vos queries. Vous n'avez pas à vous soucier de tester et de choisir les meilleures techniques d'indexation.
Pour les pipelines RAG de production, Databricks recommande la recherche IA. Les fragments et les métadonnées sont stockés dans une table Delta qui prend en charge un index de recherche IA, lequel utilise des incorporations gérées par Databricks et sert des queries de similarité à faible latence. Le stockage des métadonnées avec les intégrations dans la même table Delta permet un filtrage efficace lors de la récupération.