> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # Recherche et indexation **Ajouté dans :** `@mastra/core@1.1.0` La recherche permet aux agents de trouver du contenu pertinent dans les fichiers indexés du workspace. Lorsqu'un agent doit répondre à une question ou trouver une information, il peut effectuer une recherche dans le contenu indexé au lieu de lire chaque fichier. ## Fonctionnement La recherche dans un workspace comporte deux phases : l'indexation et l'interrogation. ### Indexation Le contenu doit être indexé avant de pouvoir faire l'objet d'une recherche. Lorsque vous indexez un document : - le contenu est tokenisé (divisé en termes interrogeables) ; - pour BM25, les fréquences des termes et les statistiques du document sont calculées ; - pour la recherche vectorielle, le contenu est converti en embedding à l'aide de votre fonction d'embedding, puis stocké dans le magasin vectoriel. Chaque document indexé contient : - **id** : un identifiant unique (généralement le chemin du fichier) ; - **content** : le contenu textuel ; - **metadata** : des données clé-valeur facultatives stockées avec le document. ### Interrogation Lorsque vous effectuez une recherche : 1. La requête est traitée avec la même tokenisation ou le même embedding que lors de l'indexation. 2. Un score est attribué aux documents en fonction de leur pertinence par rapport à la requête. 3. Les résultats sont classés par score et renvoyés avec le contenu correspondant. Les workspaces prennent en charge trois modes de recherche : la recherche BM25 par mots-clés, la recherche sémantique vectorielle et la recherche hybride, qui combine les deux précédentes. ## Recherche BM25 par mots-clés BM25 attribue un score aux documents en fonction de la fréquence des termes et de la longueur du document. Ce mode est particulièrement adapté aux correspondances exactes et à la terminologie spécifique. ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, }) ``` Pour personnaliser les paramètres BM25 (`k1` correspond à la saturation de la fréquence des termes et `b` à la normalisation de la longueur du document) : ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: { k1: 1.5, b: 0.75, }, }) ``` ## Recherche vectorielle La recherche vectorielle utilise des embeddings pour trouver du contenu sémantiquement similaire. Elle nécessite un magasin vectoriel et une fonction d'embedding. ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embed } from 'ai' import { openai } from '@ai-sdk/openai' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: async (text: string) => { const { embedding } = await embed({ model: openai.embedding('text-embedding-3-small'), value: text, }) return embedding }, }) ``` ### Embedding par lots La fonction d'embedding ci-dessus traite un seul texte à la fois. Indexer un workspace contenant des centaines de fichiers appelle le fournisseur des centaines de fois, ce qui est lent et coûteux. Lorsque le fournisseur prend en charge le traitement par lots (par exemple, avec `embedMany` d'OpenAI), transmettez une fonction d'embedding qui reçoit un tableau de textes et renvoie plusieurs embeddings en un seul appel. Pour activer cette fonctionnalité, définissez une propriété `batch: true` sur la fonction. Mastra vérifie la présence de cette propriété lors de l'exécution et utilise alors le traitement par lots. L'exemple suivant remplace la fonction d'embedding traitant un seul texte par une version par lots. Cette fonction reçoit un tableau et renvoie un tableau d'embeddings dans le même ordre. Elle possède également deux propriétés supplémentaires : - `batch: true` : indique que la fonction peut traiter des lots. Sans cette propriété, Mastra l'appelle avec un seul texte à la fois. - `maxBatchSize` : taille maximale du tableau que le fournisseur accepte en un seul appel. Mastra divise les requêtes plus volumineuses en lots de cette taille et les envoie en parallèle. Définissez cette valeur sur la limite documentée par votre fournisseur (par exemple, 2048 pour OpenAI, 96 pour Cohere ou 128 pour Voyage). Omettez-la pour envoyer tous les textes en attente dans une seule requête. ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embedMany } from 'ai' import { openai } from '@ai-sdk/openai' const model = openai.embedding('text-embedding-3-small') const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: Object.assign( async (texts: string[]) => { const { embeddings } = await embedMany({ model, values: texts }) return embeddings }, { batch: true as const, maxBatchSize: 2048 }, ), }) ``` `Object.assign` ajoute les propriétés `batch` et `maxBatchSize` à la fonction d'embedding. Mastra les lit comme des métadonnées et ne les transmet jamais au fournisseur. Les fonctions d'embedding qui traitent un seul texte continuent de fonctionner. La signature de fonction `(text: string) => Promise` reste inchangée, de sorte que le code existant continue de s'exécuter sans modification. ## Recherche hybride Configurez à la fois BM25 et la recherche vectorielle pour activer le mode hybride, qui associe la correspondance par mots-clés à la compréhension sémantique. ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, vectorStore: pineconeVector, embedder: embedderFn, }) ``` ## Nom d'index personnalisé Par défaut, le nom de l'index de recherche est dérivé de l'identifiant du workspace. Pour définir un nom personnalisé, utilisez `searchIndexName` : ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, searchIndexName: 'my_workspace_vectors', }) ``` Le nom de l'index doit être un identifiant SQL valide : il doit commencer par une lettre ou un trait de soulignement, contenir uniquement des lettres, des chiffres ou des traits de soulignement et ne pas dépasser 63 caractères. ## Indexer du contenu ### Indexation manuelle Utilisez `workspace.index()` pour ajouter du contenu à l'index de recherche par programmation. Les chemins de fichiers deviennent les identifiants des documents. Vous pouvez également transmettre des métadonnées pour chaque document. ```typescript // Basic indexing await workspace.index('/docs/guide.md', 'Content of the guide...') // Index with metadata for filtering or context await workspace.index('/docs/api.md', apiDocContent, { metadata: { category: 'api', version: '2.0', }, }) ``` L'indexation manuelle est utile lorsque : - vous indexez du contenu qui ne provient pas de fichiers (par exemple, des enregistrements de base de données ou des réponses d'API) ; - vous souhaitez prétraiter ou découper le contenu avant de l'indexer ; - vous devez ajouter des métadonnées personnalisées aux documents. ### Indexation automatique Configurez `autoIndexPaths` pour indexer automatiquement les fichiers lors de l'initialisation du workspace. Chaque entrée peut être un chemin de répertoire (indexé récursivement) ou un motif glob pour une indexation sélective. ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs', 'support/faq'], }) await workspace.init() ``` Lorsque `init()` est appelé, tous les fichiers correspondants sont lus et indexés pour la recherche. Le chemin du fichier devient l'identifiant du document. Les motifs glob permettent d'indexer des types de fichiers précis : ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs/**/*.md', 'support/**/*.txt'], }) ``` ## Effectuer une recherche Utilisez `workspace.search()` pour trouver du contenu pertinent. Les résultats sont classés par score de pertinence. ```typescript const results = await workspace.search('password reset') for (const result of results) { console.log(`${result.id}: ${result.score}`) console.log(result.content) } ``` ### Options de recherche Vous pouvez personnaliser le comportement de la recherche à l'aide d'options : ```typescript const results = await workspace.search('authentication flow', { topK: 10, mode: 'hybrid', minScore: 0.5, vectorWeight: 0.5, }) ``` | Option | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `topK` | Nombre maximal de résultats à renvoyer. Valeur par défaut : 5. | | `mode` | Mode de recherche : `'bm25'`, `'vector'` ou `'hybrid'`. Utilise par défaut le meilleur mode disponible selon la configuration. | | `minScore` | Exclut les résultats dont le score est inférieur à ce seuil (0 à 1). | | `vectorWeight` | En mode hybride, pondération des scores vectoriels par rapport à BM25. 0 = uniquement BM25, 1 = uniquement la recherche vectorielle, 0,5 = pondération égale. | ### Résultats de recherche Chaque résultat contient : ```typescript interface SearchResult { id: string // Document ID (typically file path) content: string // The matching content score: number // Relevance score (0-1) lineRange?: { // Lines where the match was found start: number end: number } metadata?: Record // Metadata stored with the document scoreDetails?: { // Score breakdown (hybrid mode only) vector?: number bm25?: number } } ``` **Comprendre les scores :** - Les scores sont compris entre 0 et 1, où 1 correspond à une concordance parfaite. - Les scores BM25 sont normalisés par rapport à la meilleure concordance de l'ensemble de résultats. - Les scores vectoriels représentent la similarité cosinus entre les embeddings de la requête et ceux du document. - En mode hybride, les scores sont combinés à l'aide du paramètre `vectorWeight`. ### Quand utiliser chaque mode | Mode | Idéal pour | Exemples de requêtes | | -------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- | | `bm25` | Termes exacts, requêtes techniques, code | « hook useState », « erreur 404 », « config.yaml » | | `vector` | Requêtes conceptuelles, langage naturel | « comment gérer l'authentification des utilisateurs », « bonnes pratiques de gestion des erreurs » | | `hybrid` | Recherche générale, types de requêtes inconnus | La plupart des cas d'usage des agents | ## Outils des agents Lorsque vous configurez la recherche sur un workspace, les agents reçoivent des outils pour rechercher et indexer du contenu. Consultez la [référence de la classe Workspace](https://mastra.zisheng.pro/fr/reference/workspace/workspace-class) pour plus de détails. ## Ressources associées - [Présentation de Workspace](https://mastra.zisheng.pro/fr/docs/workspace/overview) - [Présentation de RAG](https://mastra.zisheng.pro/fr/guides/rag/overview) - [Référence de la classe Workspace](https://mastra.zisheng.pro/fr/reference/workspace/workspace-class)