Créer un assistant de recherche documentaire avec RAG
Dans ce guide, vous créerez un assistant de recherche IA capable d’analyser des articles universitaires et de répondre à des questions précises sur leur contenu avec la génération augmentée par récupération, ou RAG.
Vous utiliserez comme exemple l’article Transformer original « Attention Is All You Need ». Vous utiliserez une base de données libSQL locale.
PrérequisLien direct vers Prérequis
- Node.js
v22.13.0ou version ultérieure est installé - Une clé API d’un fournisseur de modèles pris en charge
- Un projet Mastra existant (suivez le guide d’installation pour configurer un nouveau projet)
Fonctionnement de RAGLien direct vers Fonctionnement de RAG
Voyons comment fonctionne RAG et comment implémenter chaque composant.
Stockage/index de connaissancesLien direct vers Stockage/index de connaissances
- Conversion du texte en représentations vectorielles
- Création de représentations numériques du contenu
- Implémentation : vous utiliserez
text-embedding-3-smalld’OpenAI pour créer des embeddings et les stocker dans LibSQLVector
RécupérateurLien direct vers Récupérateur
- Recherche de contenu pertinent avec la recherche par similarité
- Mise en correspondance des embeddings de requête avec les vecteurs stockés
- Implémentation : vous utiliserez LibSQLVector pour effectuer des recherches de similarité sur les embeddings stockés
GénérateurLien direct vers Générateur
- Traitement du contenu récupéré avec un LLM
- Création de réponses informées par le contexte
- Implémentation : vous utiliserez un modèle OpenAI pour générer des réponses basées sur le contenu récupéré
Votre implémentation :
- Traite l’article Transformer pour en créer des embeddings
- Les stocke dans LibSQLVector pour une récupération rapide
- Utilise une recherche par similarité pour trouver les sections pertinentes
- Génère des réponses précises avec le contexte récupéré
Créer l’AgentLien direct vers Créer l’Agent
Définissez le comportement de l’Agent, connectez-le à votre projet Mastra et créez le stockage vectoriel.
Installez les dépendances supplémentaires.
Après avoir suivi le guide d’installation, vous devrez installer des dépendances supplémentaires :
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/rag@latest aipnpm add @mastra/rag@latest aiyarn add @mastra/rag@latest aibun add @mastra/rag@latest aiVous allez maintenant créer votre assistant de recherche compatible RAG. L’Agent utilise :
- Un Tool de requête vectorielle pour effectuer une recherche sémantique dans le stockage vectoriel et trouver du contenu pertinent dans les articles
- Un modèle OpenAI pour comprendre les requêtes et générer des réponses
- Des instructions personnalisées qui guident l’Agent dans l’analyse des articles, l’utilisation efficace du contenu récupéré et la reconnaissance de ses limites
Créez un fichier
src/mastra/agents/researchAgent.tset définissez votre Agent :src/mastra/agents/researchAgent.tsimport { Agent } from '@mastra/core/agent'import { ModelRouterEmbeddingModel } from '@mastra/core/llm'import { createVectorQueryTool } from '@mastra/rag'// Create a tool for semantic search over the paper embeddingsconst vectorQueryTool = createVectorQueryTool({vectorStoreName: 'libSqlVector',indexName: 'papers',model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),})export const researchAgent = new Agent({id: 'research-agent',name: 'Research Assistant',instructions: `You are a helpful research assistant that analyzes academic papers and technical documents.Use the provided vector query tool to find relevant information from your knowledge base,and provide accurate, well-supported answers based on the retrieved content.Focus on the specific content available in the tool and acknowledge if you cannot find sufficient information to answer a question.Base your responses only on the content provided, not on general knowledge.`,model: 'openai/gpt-5.6-sol',tools: {vectorQueryTool,},})À la racine du projet, récupérez le chemin absolu avec la commande
pwd. Il peut ressembler à ceci :> pwd/Users/your-name/guides/research-assistantDans votre fichier
src/mastra/index.ts, ajoutez ce qui suit au fichier et à la configuration existants :src/mastra/index.tsimport { Mastra } from '@mastra/core'import { LibSQLVector } from '@mastra/libsql'const libSqlVector = new LibSQLVector({id: 'research-vectors',url: 'file:/Users/your-name/guides/research-assistant/vector.db',})export const mastra = new Mastra({vectors: { libSqlVector },})Pour
url, utilisez le chemin absolu obtenu avec la commandepwd. Le fichiervector.dbest ainsi créé à la racine du projet.remarqueDans ce guide, vous utilisez un chemin absolu codé en dur vers votre fichier libSQL local. Cela ne fonctionnera toutefois pas en production : utilisez alors une base de données persistante distante.
Dans le fichier
src/mastra/index.ts, ajoutez l’Agent à Mastra :src/mastra/index.tsimport { Mastra } from '@mastra/core'import { LibSQLVector } from '@mastra/libsql'import { researchAgent } from './agents/researchAgent'const libSqlVector = new LibSQLVector({id: 'research-vectors',url: 'file:/Users/your-name/guides/research-assistant/vector.db',})export const mastra = new Mastra({agents: { researchAgent },vectors: { libSqlVector },})
Traiter les documentsLien direct vers Traiter les documents
Dans les étapes suivantes, vous récupérerez l’article de recherche et le découperez en segments plus petits. Vous générerez ensuite les embeddings et stockerez les segments dans la base de données vectorielle.
À cette étape, l’article de recherche est récupéré à partir d’une URL, converti en objet document, puis découpé en segments plus petits et gérables. Ce découpage rend le traitement plus rapide et efficace.
Créez un fichier
src/store.tset ajoutez ce qui suit :src/store.tsimport { MDocument } from '@mastra/rag'// Load the paperconst paperUrl = 'https://arxiv.org/html/1706.03762'const response = await fetch(paperUrl)const paperText = await response.text()// Create document and chunk itconst doc = MDocument.fromText(paperText)const chunks = await doc.chunk({strategy: 'recursive',maxSize: 512,overlap: 50,separators: ['\n\n', '\n', ' '],})console.log('Number of chunks:', chunks.length)Exécutez le fichier dans votre terminal :
npx bun src/store.tsVous devriez obtenir cette réponse :
Number of chunks: 892Enfin, préparez le contenu pour RAG en :
- Générant les embeddings de chaque segment de texte
- Créant un index de stockage vectoriel pour conserver les embeddings
- Stockant les embeddings et les métadonnées, texte original et informations de source, dans la base vectorielle
remarqueCes métadonnées sont cruciales, car elles permettent de retourner le contenu réel lorsque le stockage vectoriel trouve des correspondances pertinentes.
L’Agent utilise l’index vectoriel pour rechercher et récupérer des informations pertinentes.
Ouvrez le fichier
src/store.tset ajoutez ce qui suit :src/store.tsimport { MDocument } from '@mastra/rag'import { embedMany } from 'ai'import { mastra } from './mastra'// Load the paperconst paperUrl = 'https://arxiv.org/html/1706.03762'const response = await fetch(paperUrl)const paperText = await response.text()// Create document and chunk itconst doc = MDocument.fromText(paperText)const chunks = await doc.chunk({strategy: 'recursive',maxSize: 512,overlap: 50,separators: ['\n\n', '\n', ' '],})// Generate embeddingsconst { embeddings } = await embedMany({model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),values: chunks.map(chunk => chunk.text),})// Get the vector store instance from Mastraconst vectorStore = mastra.getVector('libSqlVector')// Create an index for paper chunksawait vectorStore.createIndex({indexName: 'papers',dimension: 1536,})// Store embeddingsawait vectorStore.upsert({indexName: 'papers',vectors: embeddings,metadata: chunks.map(chunk => ({text: chunk.text,source: 'transformer-paper',})),})Enfin, stockez les embeddings en exécutant à nouveau le script :
npx bun src/store.tsSi l’opération réussit, votre terminal ne doit afficher aucune sortie ni erreur.
Tester l’assistantLien direct vers Tester l’assistant
Maintenant que la base de données vectorielle contient tous les embeddings, vous pouvez tester l’assistant de recherche avec différents types de requêtes.
Créez un fichier src/ask-agent.ts et ajoutez différents types de requêtes :
import { mastra } from './mastra'
const agent = mastra.getAgent('researchAgent')
// Basic query about concepts
const query1 = 'What problems does sequence modeling face with neural networks?'
const response1 = await agent.generate(query1)
console.log('\nQuery:', query1)
console.log('Response:', response1.text)
Exécutez le script :
npx bun src/ask-agent.ts
Vous devriez voir une sortie semblable à :
Query: What problems does sequence modeling face with neural networks?
Response: Sequence modeling with neural networks faces several key challenges:
1. Vanishing and exploding gradients during training, especially with long sequences
2. Difficulty handling long-term dependencies in the input
3. Limited computational efficiency due to sequential processing
4. Challenges in parallelizing computations, resulting in longer training times
Essayez une autre question :
import { mastra } from './mastra'
const agent = mastra.getAgent('researchAgent')
// Query about specific findings
const query2 = 'What improvements were achieved in translation quality?'
const response2 = await agent.generate(query2)
console.log('\nQuery:', query2)
console.log('Response:', response2.text)
Sortie :
Query: What improvements were achieved in translation quality?
Response: The model showed significant improvements in translation quality, achieving more than 2.0
BLEU points improvement over previously reported models on the WMT 2014 English-to-German translation
task, while also reducing training costs.
Servir l’applicationLien direct vers Servir l’application
Démarrez le serveur Mastra afin d’exposer votre assistant de recherche via l’API :
mastra dev
Votre assistant de recherche sera disponible à l’adresse :
http://localhost:4111/api/agents/researchAgent/generate
Testez avec curl :
curl -X POST http://localhost:4111/api/agents/researchAgent/generate \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "user", "content": "What were the main findings about model parallelization?" }
]
}'
Exemples RAG avancésLien direct vers Exemples RAG avancés
Explorez ces exemples pour découvrir des techniques RAG plus avancées :
- Filter RAG pour filtrer les résultats avec des métadonnées
- Cleanup RAG pour optimiser la densité d’information
- Chain of Thought RAG pour les requêtes de raisonnement complexe avec des Workflows
- Rerank RAG pour améliorer la pertinence des résultats