Accueil / Articles

Recherche sémantique avec ChromaDB et des embeddings pour une plateforme multi-agents

Passer d’une plateforme multi-agents d’entreprise à une recherche sémantique réelle : segmentation tenant compte des mots, distance cosinus dans ChromaDB, couches de test et la prochaine étape de RetrievalAgent.

Éditeur : REACTAPP.TOP10 min de lecture2308 mots

Sources: Building Real Semantic Retrieval for an Enterprise Multi-Agent AI Platform

Un nouveau jalon a été atteint dans le projet Enterprise Multi-Agent AI Platform : son pipeline de récupération effectue désormais une véritable recherche sémantique, en utilisant des embeddings stockés dans ChromaDB. L’architecture est passée de la préparation des documents à un processus de récupération fonctionnel, qui consiste d’abord à exécuter SourceDocument, puis DocumentChunker, ensuite EmbeddingService, suivi d’OpenAI Embeddings, puis ChromaDB, puis la recherche sémantique, et enfin RetrievedDocument.

C’est un changement significatif de phase. La plateforme ne se contente plus de préparer des documents et de générer des embeddings ; elle peut maintenant stocker des connaissances d’entreprise vectorisées, les rechercher par leur sens, classer les fragments pertinents et restituer des résultats structurés. Sa mise en place a également mis en évidence quelques problèmes liés à la qualité de la récupération qui devaient être résolus avant que le pipeline ne puisse être intégré au RetrievalAgent.

Le pipeline prend forme

L’architecture de récupération est organisée comme suit :

Enterprise Documents
        │
        ▼
   SourceDocument
        │
        ▼
 DocumentChunker
        │
        ▼
  DocumentChunk[]
        │
        ▼
 EmbeddingService
        │
        ▼
 OpenAI Embeddings
        │
        ▼
     ChromaDB
        │
        ▼
 Semantic Search
        │
        ▼
RetrievedDocument[]
        │
        ▼
  RetrievalAgent

Chaque couche a une seule responsabilité, et c’est intentionnel. L’objectif n’a jamais été de disposer d’une seule fonction RAG massive qui chargerait les fichiers, diviserait le texte, créerait des embeddings, gérerait la base de données vectorielle, effectuerait des recherches et produirait une réponse. Le système est plutôt assemblé à partir de frontières architecturales claires.

Étape 1 : documents sources

Tout commence avec les connaissances de l’entreprise. Avec le temps, ce contenu peut provenir de fichiers PDF, DOCX et TXT, de rapports financiers, de politiques internes, de documentation technique, de matériel de recherche et de bases de connaissances d’entreprise. Le modèle SourceDocument donne à ce matériel une forme standard avant qu’il ne pénètre dans le pipeline. Conceptuellement, cela se présente comme suit :

SourceDocument
 ├── document_id
 ├── content
 ├── source
 └── metadata

Le principe essentiel ici est la traçabilité. Tout ce qui sera récupéré ultérieurement doit rester lié à sa source d’origine.

Étape 2 : segmentation

Les documents volumineux ne devraient généralement pas être intégrés en un seul bloc. Le DocumentChunker transforme chaque SourceDocument en parties plus petites prêtes à être récupérées :

SourceDocument
      │
      ▼
DocumentChunker
      │
      ├── Chunk 0
      ├── Chunk 1
      ├── Chunk 2
      └── Chunk N

Chaque morceau conserve son chunk_id, document_id, content, source, chunk_index ainsi que ses métadonnées. La recherche sémantique peut donc fonctionner sur de petites unités d’information sans perdre le lien avec le document original.

Améliorer la qualité des morceaux

L’exécution du véritable pipeline de récupération a révélé un problème. La segmentation basée sur les caractères peut couper du texte en prose à des endroits inadaptés, parfois même au milieu d’un mot. Une frontière peut théoriquement donner naissance à un morceau qui se termine de la manière suivante :

...important financial risks for

suivi d’un bloc qui commence comme ceci :

the upcoming quarter...

ou, dans les cas les plus graves, une séparation au milieu d’un mot. De tels fragments sont techniquement valides, mais la qualité de récupération dépend de bien plus que des structures de données valides. Les limites déterminent la qualité sémantique de tout ce qui est intégré.

La stratégie de segmentation a donc été modifiée pour privilégier les limites des mots dans le texte narratif normal, tout en conservant une solution de secours basée sur les limites des caractères pour les textes ne contenant pas d’espaces blancs utiles. Le segmentateur dispose désormais de deux modes de fonctionnement :

Normal prose
    ↓
Prefer word-aware boundaries
Text without whitespace
    ↓
Fallback to character boundaries

C’est un petit détail d’implémentation qui recèle une grande leçon architecturale : réussir les tests ne signifie pas que la qualité de la récupération est bonne, et les données réelles révèlent des problèmes que les tests unitaires isolés ne peuvent pas toujours mettre en évidence.

Étape 3 : embeddings

Lorsque les fragments sont prêts, le EmbeddingService convertit leur texte en vecteurs numériques.

DocumentChunk
      │
      ▼
EmbeddingService
      │
      ▼
Embedding Model
      │
      ▼
Vector Representation

Le service prend en charge des embeddings de texte unique pour les requêtes et des embeddings par lots pour les fragments de documents. Un test d’intégration local réalisé précédemment a confirmé une dimension vectorielle de 1 536. Ce chiffre importe moins que le fait que l’implémentation des embeddings reste derrière une frontière de service, de sorte que l’agent de récupération n’a jamais besoin de savoir comment les vecteurs sont générés.

Étape 4 : Stockage vectoriel ChromaDB

La couche suivante est le stockage persistant des vecteurs. Chaque fragment peut désormais être stocké avec son vecteur et ses métadonnées. Conceptuellement :

DocumentChunk
      +
Embedding
      +
Metadata
      │
      ▼
   ChromaDB
      │
      ▼
Persistent Vector Collection

Un enregistrement vectoriel peut conserver des informations telles que :

Vector Record
 ├── chunk_id
 ├── embedding
 ├── content
 ├── document_id
 ├── source
 ├── chunk_index
 └── metadata

Un vecteur nu n’est d’aucune utilité pour le reste de l’application. La plateforme a besoin du contenu réel et doit savoir d’où provient ce contenu.

Étape 5 : recherche sémantique

Avec des fragments intégrés stockés dans ChromaDB, le système peut effectuer une recherche sémantique. Le chemin de la requête est le suivant :

User Query
     │
     ▼
EmbeddingService
     │
     ▼
Query Embedding
     │
     ▼
   ChromaDB
     │
     ▼
Similarity Search
     │
     ▼
Top-K Relevant Chunks
     │
     ▼
RetrievedDocument[]

La récupération des données est passée de la recherche de documents contenant exactement ces mots à celle de segments dont le sens correspond le mieux à la requête. C’est l’une des capacités fondamentales de RAG.

Une correction de la métrique de similarité

Des tests réels ont mis en évidence un deuxième problème. Les bases de données vectorielles prennent en charge différentes métriques de distance ou de similarité, et si la collection utilise une métrique tandis que l’application interprète la distance retournée comme étant une autre, le score de pertinence devient trompeur. Pour ce pipeline, la collection ChromaDB a été explicitement configurée pour utiliser la distance cosinus, permettant ainsi à la couche de récupération d’interpréter systématiquement les résultats en termes de similarité basée sur le cosinus.

Query Embedding
      │
      ▼
ChromaDB
      │
      ▼
Cosine Distance
      │
      ▼
Similarity Score
      │
      ▼
Ranked Results

La récupération sémantique ne consiste pas seulement à restituer des documents. Elle vise également à comprendre leur degré de pertinence.

Résultats réels de récupération

Après le découpage en blocs et les corrections de similarité, le pipeline a été testé avec une requête réelle sur les risques financiers. Les résultats classés présentaient des scores de similarité d’environ 0,6181, 0,5520 et 0,4198, et le contexte récupéré comprenait les informations pertinentes sur les risques de liquidité et la volatilité du marché. Le pipeline a donc suivi ce parcours jusqu’au bout :

Question
   ↓
Query Embedding
   ↓
ChromaDB
   ↓
Semantic Similarity
   ↓
Relevant Chunks
   ↓
Financial Risk Context

À ce moment-là, l’infrastructure de récupération a cessé d’être une simple tâche de configuration pour commencer à démontrer une véritable récupération de connaissances sémantiques.

Pourquoi les vrais tests de récupération sont importants

Les tests unitaires simulés restent extrêmement utiles. Ils assurent rapidité, déterminisme, sécurité dans les processus d’intégration continue, aucun coût lié à des API externes, des scénarios d’échec contrôlés et l’isolation de la logique applicative. Cependant, ils ne peuvent pas répondre à toutes les questions. Un test simulé peut confirmer que la structure fonctionne correctement :

EmbeddingService
      ↓
Expected Vector

Cependant, cela ne peut pas montrer pleinement que la chaîne suivante produit un bon comportement de récupération :

Real Document
      ↓
Real Chunking
      ↓
Real Embedding
      ↓
Real Vector Database
      ↓
Real Semantic Query
      ↓
Useful Context

Ainsi, la stratégie de test sépare plusieurs niveaux de validation.

Stratégie de test

La plateforme évolue vers trois niveaux complémentaires de test.

Les tests unitaires sont rapides et déterministes et font partie du pipeline CI normal :

Application Logic
      ↓
Mock External Dependencies
      ↓
Controlled Results
      ↓
Assertions

Les tests d’intégration valident l’infrastructure réelle et peuvent être exécutés séparément de la suite CI rapide :

Application
      ↓
Real Embedding Provider
      ↓
Real ChromaDB
      ↓
End-to-End Retrieval

Les tests de performance et de résilience deviennent nécessaires à mesure que la plateforme mûrit :

Realistic Workload
      ↓
Concurrent Requests
      ↓
Latency
Throughput
Rate Limits
Failures
Cost
Scalability

Un système d’IA prêt pour la production a besoin des trois éléments. Simuler les services externes dans les tests unitaires ne remplace pas les tests d’intégration, et les tests d’intégration ne remplacent pas les tests de performance. Chaque couche répond à une question d’ingénierie différente.

CI toujours opérationnel

Après les améliorations apportées à la récupération des données, le lot de tests rapide reste fonctionnel : 17 tests réussissent et 2 tests d’intégration sont désactivés. C’est important car le pipeline RAG devient de plus en plus sophistiqué sans pour autant compromettre la validation fiable du CI. Le cycle de développement se poursuit comme suit :

Code Change
     ↓
Fast Unit Tests
     ↓
Commit
     ↓
Push
     ↓
GitHub Actions
     ↓
CI Validation
     ↓
Keep Green

Les tests sur des services réels restent disponibles en tant qu’exécution distincte.

Connexion de RAG à la plateforme multi-agent

L’infrastructure de récupération n’existe pas de manière isolée. Elle est conçue pour devenir la couche de connaissances du système multi-agent plus vaste, et l’architecture globale évolue dans cette direction :

User
                          │
                          ▼
                    Supervisor Agent
                          │
                          ▼
                     Planning Agent
                          │
                          ▼
                    Execution Plan
                          │
                          ▼
                     Agent Registry
                          │
             ┌────────────┼────────────┐
             ▼            ▼            ▼
      RetrievalAgent ResearchAgent AnalysisAgent
             │
             ▼
      RetrievalService
             │
             ▼
      EmbeddingService
             │
             ▼
          ChromaDB
             │
             ▼
      Semantic Search
             │
             ▼
      Relevant Context
             │
             ▼
       Downstream Agents

C’est ici que le RAG et l’orchestration multi-agents commencent à se fusionner.

Réserver une simplicité à l’agent de récupération

Un objectif clé est de faire en sorte que le RetrievalAgent reste concentré sur sa propre tâche. Il n’a pas besoin de connaître les algorithmes de segmentation, l’implémentation des embeddings, les dimensions vectorielles, les mécanismes internes de ChromaDB, les calculs de similarité ou la configuration du stockage. Au lieu de cela :

RetrievalAgent
      ↓
RetrievalService
      ↓
VectorStoreService
      ↓
EmbeddingService + ChromaDB

L’agent demande des connaissances pertinentes, et l’infrastructure de récupération décide de la manière dont ces connaissances sont trouvées. Cette séparation permet à l’implémentation sous-jacente d’évoluer sans avoir à réécrire l’agent.

Prochain objectif : remplacer la récupération temporaire

La prochaine étape est claire. L’agent de récupération doit encore être connecté directement à l’infrastructure de récupération réelle. Actuellement, c’est organisé comme suit :

BEFORE
RetrievalAgent
      ↓
Temporary Local Documents

Et l’objectif est le suivant :

NEXT
RetrievalAgent
      ↓
RetrievalService
      ↓
VectorStoreService
      ↓
EmbeddingService
      ↓
ChromaDB
      ↓
Semantic Search
      ↓
Enterprise Knowledge

Après cette intégration, l’agent cesse de retourner des résultats temporaires codés en dur et tire les connaissances de la véritable collection indexée de documents.

De l’infrastructure à l’exécution multi-agent

Cette intégration marque une autre transition. La majeure partie du travail mené jusqu’à présent a porté sur la construction de l’infrastructure de récupération. Une fois que RetrievalAgent utilise le véritable pipeline sémantique, l’architecture peut prendre en charge des workflows tels que celui-ci :

User Request
      ↓
Supervisor
      ↓
Planning Agent
      ↓
Execution Plan
      ↓
Retrieval Agent
      ↓
Enterprise Knowledge
      ↓
Analysis Agent
      ↓
Report Agent
      ↓
Quality Review
      ↓
Final Response

RAG devient alors une fonctionnalité au sein d’un système d’exécution multi-agents plus large, et n’est plus une fonction de récupération indépendante.

La voie à suivre

Le plan de développement de la récupération évolue des composants fondamentaux vers des capacités orientées vers la production :

Document Contracts               ✅
        ↓
Chunking                         ✅
        ↓
Embeddings                       ✅
        ↓
ChromaDB Vector Storage          ✅
        ↓
Semantic Search                  ✅
        ↓
RetrievalAgent Integration       ← NEXT
        ↓
Reranking
        ↓
Caching & Cost Controls
        ↓
Observability & Metrics
        ↓
Multi-Tenant Isolation
        ↓
Production Hardening

Les étapes ultérieures gagnent en importance à mesure que la plateforme passe d’une architecture fonctionnelle à une opération d’entreprise.

Une plateforme RAG en production a besoin de plus que simplement du retraitement des données

Obtenir des extraits pertinents à partir de ChromaDB constitue une étape importante, mais ce n’est pas la fin de l’architecture. Une plateforme de retraitement en production doit finalement gérer :

  • Le réclassement, car la similarité vectorielle initiale ne garantit pas toujours le meilleur ordre.
  • Le cache, car les embeddings et recherches répétées augmentent la latence et les coûts.
  • L’observabilité, afin de pouvoir mesurer la latence de retraitement, la latence des embeddings, le nombre de documents, les scores, les échecs et les coûts.
  • L’évolution des modèles et de l’espace vectoriel, car le changement de modèles d’embeddings peut nécessiter des index versionnés et un ré-embedding contrôlé.
  • Gestion des limites de débit, car les fournisseurs externes d’IA imposent des contraintes opérationnelles non déterministes.
  • Isolation multi-locataires, car les données d’entreprise ne peuvent pas partager des limites de récupération non restreintes.
  • Contrats de schéma, ce qui signifie des interfaces stables entre les couches d’ingestion, d’intégration, de stockage, de récupération et d’agent.
  • Tests de performance dans des conditions de concurrence et de volume de données réalistes.
  • Ces éléments doivent figurer dans le plan de développement, mais ils devraient être ajoutés progressivement selon des limites claires et non mélangés dans une seule implémentation massive dès le début.

    Le principe d’ingénierie

    La leçon la plus importante de cette étape : concevoir d’abord l’abstraction, vérifier le comportement à l’aide de données réelles, puis renforcer les caractéristiques de production au fur et à mesure que l’architecture évolue. Cette progression a été délibérée :

    Data Contract
         ↓
    Chunking
         ↓
    Unit Testing
         ↓
    Embeddings
         ↓
    Mocked Provider Testing
         ↓
    Real Integration Validation
         ↓
    Vector Storage
         ↓
    Semantic Retrieval
         ↓
    Retrieval Quality Improvements
         ↓
    Agent Integration
    

    Chaque étape met en évidence une catégorie différente de problèmes, c’est précisément pourquoi l’architecture incrémentale s’avère efficace.

    Des documents à l’exécution multi-agents

    La vision d’ensemble commence à se préciser :

    Enterprise Knowledge
            ↓
    Document Processing
            ↓
    Chunking
            ↓
    Embeddings
            ↓
    Vector Storage
            ↓
    Semantic Retrieval
            ↓
    Retrieval Agent
            ↓
    Multi-Agent Orchestration
            ↓
    Analysis + Research + Reporting
            ↓
    Quality Review
            ↓
    Grounded Enterprise Response
    

    RAG n’est pas toute la plateforme. C’est l’infrastructure de connaissances qui permet aux agents spécialisés de travailler dans un contexte d’entreprise concret.

    Jalon actuel

    Ce qui existe aujourd’hui : des modèles de documents uniformes, un découpage des textes en segments simples ou tenant compte des frontières des mots, un service d’embedding accompagné de tests unitaires simulés ainsi que d’un test de validation réel, un stockage persistant dans ChromaDB avec une similarité cosinus définie explicitement, une recherche sémantique qui affiche des résultats classés, ainsi qu’un ensemble rapide de 17 tests réussis. Le prochain jalon consiste à relier RetrievalAgent au véritable pipeline de récupération sémantique, ce qui marquera le moment où le système cesse d’être simplement un sous-système RAG pour commencer à exécuter des tâches multi-agents utilisant RAG.

    L’IA d’entreprise ne signifie pas simplement brancher un LLM à une base de données vectorielle pour proclamer la victoire. Les différentes couches nécessitent des contrats, les contrats exigent des tests, les intégrations requièrent une validation réelle, et le système doit disposer d’espace pour évoluer. Le processus a évolué, passant de documents, de fragments, d’embeddings et de vecteurs à des documents, des fragments, des embeddings, ChromaDB, une recherche sémantique ainsi qu’un contexte d’entreprise pertinent. Ce qui vient ensuite, c’est que ce contexte soit acheminé vers le RetrievalAgent puis vers une exécution multi-agentes. Le cycle de travail reste inchangé : concevoir, tester, mesurer, améliorer, intégrer et échelonner.