Système de réponse aux questions de documentation basé sur les embeddings Voyage-Context-3 et MongoDB Atlas
Ceci est unEngineering, AI RAGworkflow d'automatisation du domainecontenant 53 nœuds.Utilise principalement des nœuds comme Set, Code, Wait, Merge, MongoDb. Chatbot de questions-réponses pour documents basé sur Voyage-Context-3 Embeddings et MongoDB Atlas
- •Chaîne de connexion MongoDB
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Clé API OpenAI
Nœuds utilisés (53)
Catégorie
{
"meta": {
"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "cc8db825-4ae4-4795-b3d3-a858af3d62c7",
"name": "Lors du clic sur 'Exécuter le workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-320,
-336
],
"parameters": {},
"typeVersion": 1
},
{
"id": "37a7e1ab-e3f3-4588-92a9-6a3bdf4335dc",
"name": "Importer un Article de Recherche",
"type": "n8n-nodes-base.httpRequest",
"position": [
336,
-336
],
"parameters": {
"url": "={{ $('Set Variables').first().json.url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "34c48356-2d29-41a2-902b-9512bb9bf3c8",
"name": "Extraire depuis le Fichier",
"type": "n8n-nodes-base.extractFromFile",
"position": [
512,
-336
],
"parameters": {
"options": {
"joinPages": false
},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "7a1609c6-19f7-41e0-9054-aa10d31e4529",
"name": "Diviser les Pages",
"type": "n8n-nodes-base.splitOut",
"position": [
688,
-336
],
"parameters": {
"options": {},
"fieldToSplitOut": "text"
},
"typeVersion": 1
},
{
"id": "bbb632c2-a98c-4727-82f1-7a2ddd6cab89",
"name": "Référence de Page",
"type": "n8n-nodes-base.noOp",
"position": [
1808,
0
],
"parameters": {},
"typeVersion": 1
},
{
"id": "9bb0b5a0-bc3a-4d56-92cb-9287f6dd18f3",
"name": "Découper le Texte de la Page",
"type": "n8n-nodes-base.code",
"position": [
2096,
-208
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const chunks = [];\nconst chunkSize = 1000;\nconst chunkOverlap = 0; // Voyage recommends no overlap for contextual embeddings\nconst text = $input.item.json.text.replace(/\\n/, '');\n\nfor (let i=0,j=Math.round(text.length/chunkSize)+1;i<j;i++) {\n chunks.push(\n text.substr(\n Math.max(0,(i * chunkSize)-chunkOverlap),\n chunkSize\n )\n );\n}\n\nreturn { chunks };"
},
"typeVersion": 2
},
{
"id": "cbe2e982-7c4a-48e7-aa2a-3b9615d41deb",
"name": "Embeddings Voyage-Context-3",
"type": "n8n-nodes-base.httpRequest",
"position": [
2288,
-208
],
"parameters": {
"url": "https://api.voyageai.com/v1/contextualizedembeddings",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"inputs\": $input.all().map(item => item.json.chunks.compact()),\n \"input_type\": \"document\",\n \"model\": \"voyage-context-3\"\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "VYN3hfgfq62zjN0I",
"name": "Voyage.ai"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "dfd6df48-a0a6-4995-925b-6dbe8dd58747",
"name": "Sortie de Division",
"type": "n8n-nodes-base.splitOut",
"position": [
2480,
-208
],
"parameters": {
"options": {},
"fieldToSplitOut": "data"
},
"typeVersion": 1
},
{
"id": "4dcbc327-0880-4f3b-9ba1-f6951f95b988",
"name": "Boucler sur les Éléments",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1584,
0
],
"parameters": {
"options": {},
"batchSize": 3
},
"typeVersion": 3
},
{
"id": "19775d9b-fe97-4078-8ef5-252f45796e2c",
"name": "Combiner Contenu et Vecteurs",
"type": "n8n-nodes-base.set",
"position": [
3184,
-208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bba20778-dbf9-459b-a1aa-97a76ba01713",
"name": "text",
"type": "string",
"value": "={{ $('Chunk Page Text').all()[$runIndex].json.chunks[$itemIndex] }}"
},
{
"id": "20069d1a-4893-4823-9b39-9c61e2e88bee",
"name": "embeddings",
"type": "array",
"value": "={{ $json.embedding }}"
},
{
"id": "26d237a5-5991-4deb-867d-07b5bda6d2c2",
"name": "metadata",
"type": "object",
"value": "={{\n{\n \"pageNumber\": $('Page Ref').first().json.pageNumber,\n \"url\": $('Page Ref').first().json.url\n}\n}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "98e580fe-8db3-4e9d-bffd-1034cc8e61a1",
"name": "Déclencheur de Sous-workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
1360,
0
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "text"
},
{
"name": "url"
},
{
"name": "pageNumber",
"type": "number"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "206e4cc4-693f-40df-8c37-45822dd953b5",
"name": "Lot de 10",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1216,
-336
],
"parameters": {
"options": {},
"batchSize": 10
},
"typeVersion": 3
},
{
"id": "2460bcd5-950a-4fbd-96eb-5428e03a32fb",
"name": "Appeler le Sous-workflow d'Embeddings",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
1440,
-336
],
"parameters": {
"options": {
"waitForSubWorkflow": true
},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $workflow.id }}"
},
"workflowInputs": {
"value": {
"url": "={{ $('Set Variables').first().json.url }}",
"text": "={{ $json.text }}",
"pageNumber": "={{ $json.pageNumber }}"
},
"schema": [
{
"id": "text",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "text",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "url",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "pageNumber",
"type": "number",
"display": true,
"removed": false,
"required": false,
"displayName": "pageNumber",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"page"
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "f044e091-b50c-4686-9f0a-e0abeb1022a0",
"name": "Terminé",
"type": "n8n-nodes-base.set",
"position": [
4016,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e2c34b5b-2a3e-4fcd-a639-4d72368b783a",
"name": "response",
"type": "string",
"value": "ok"
}
]
}
},
"executeOnce": true,
"typeVersion": 3.4
},
{
"id": "e52fa239-18e7-4ea9-93d2-010dd3555fa6",
"name": "Embeddings Voyage-Context-3 1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1328,
528
],
"parameters": {
"url": "https://api.voyageai.com/v1/contextualizedembeddings",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"inputs\": [\n [\n $('Get Query').first().json.query\n + ' '\n + $('Aggregate Answers').item.json.answers.map(item => item.chatInput).join(' ')\n ]\n ],\n \"input_type\": \"query\",\n \"model\": \"voyage-context-3\"\n}\n}}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "VYN3hfgfq62zjN0I",
"name": "Voyage.ai"
}
},
"executeOnce": false,
"typeVersion": 4.2
},
{
"id": "6f3c7ef8-891e-4dd4-bbf0-4adf6e193532",
"name": "Effectuer une Recherche de Similarité",
"type": "n8n-nodes-base.mongoDb",
"position": [
1520,
528
],
"parameters": {
"query": "={{\n([\n {\n \"$vectorSearch\": {\n \"index\": \"vector_index\",\n \"path\": \"embeddings\",\n \"queryVector\": $json.data[0].data[0].embedding,\n \"numCandidates\": 150,\n \"limit\": 10\n }\n },\n {\n \"$project\": {\n \"_id\": 0,\n \"text\": 1,\n \"metadata\": 1,\n \"score\": {\n \"$meta\": \"vectorSearchScore\"\n }\n }\n }\n]).toJsonString()\n}}",
"operation": "aggregate",
"collection": "documents"
},
"credentials": {
"mongoDb": {
"id": "OUucWo4Fut06mJ1J",
"name": "MongoDB account"
}
},
"typeVersion": 1.2
},
{
"id": "1a41d58f-b8fc-498f-a807-ffc3edd400ed",
"name": "Ajouter un Numéro de Page",
"type": "n8n-nodes-base.set",
"position": [
848,
-336
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "3103cd6a-5932-432a-8859-7dd14d496258",
"name": "pageNumber",
"type": "number",
"value": "={{ $itemIndex + 1 }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "5af13dae-29e2-4f6f-a8e8-96cf9d01569e",
"name": "Définir des Variables",
"type": "n8n-nodes-base.set",
"position": [
-144,
-336
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7ff25027-cfa5-4f63-8b13-05a724c5bb96",
"name": "url",
"type": "string",
"value": "https://arxiv.org/pdf/2402.06196"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e57a9115-5bb4-469b-9e1c-57e8747c9e79",
"name": "Attendre",
"type": "n8n-nodes-base.wait",
"position": [
1664,
-336
],
"webhookId": "739dc127-4870-4b0c-ada6-e62729935ba2",
"parameters": {},
"typeVersion": 1.1
},
{
"id": "5877e228-c02c-41c1-9fd5-a76f47414ba0",
"name": "Obtenir la Requête",
"type": "n8n-nodes-base.set",
"position": [
-80,
528
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a197e69a-0f22-45ab-9b57-535e80fe12af",
"name": "query",
"type": "string",
"value": "={{ $json.chatInput }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "60f7b22e-e56e-43c6-9651-c36d6bb6fa17",
"name": "Agréger",
"type": "n8n-nodes-base.aggregate",
"position": [
1712,
528
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "d0a430ed-c2a2-4331-98b7-b1929cfe591f",
"name": "Référence de Requête",
"type": "n8n-nodes-base.noOp",
"position": [
800,
704
],
"parameters": {},
"typeVersion": 1
},
{
"id": "fe490208-25a9-4504-97b8-bbf3ce3e0b60",
"name": "Boucler sur les Questions",
"type": "n8n-nodes-base.splitInBatches",
"position": [
592,
528
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "f30d70b4-42d3-48f4-b44d-0f48dd2d459a",
"name": "OpenAI Modèle de Chat",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
176,
672
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "8gccIjcuf3gvaoEr",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "609d43c1-e536-49c7-8470-2c23763302ec",
"name": "Générer des Questions de Clarification",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
96,
528
],
"parameters": {
"text": "={{ $json.query }}",
"options": {
"systemPromptTemplate": "You are a helpful assistant helping a user research a paper titled \"Large Language Models: A Survey\".\n\nYour task is to generate 2 clarifying questions for the user's query so that later search queries can be better refined."
},
"schemaType": "manual",
"inputSchema": "{\n\t\"type\": \"object\",\n \"required\": [\"questions\"],\n\t\"properties\": {\n\t\t\"questions\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t}\n\t}\n}"
},
"typeVersion": 1.2
},
{
"id": "35132610-83bb-4582-ad42-8e3954ea234f",
"name": "Diviser les Questions",
"type": "n8n-nodes-base.splitOut",
"position": [
400,
528
],
"parameters": {
"options": {
"destinationFieldName": "question"
},
"fieldToSplitOut": "output.questions"
},
"typeVersion": 1
},
{
"id": "70b2e1bb-c868-4adc-b21a-a9e95d166198",
"name": "Lors de la réception d'un message de chat",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-336,
528
],
"webhookId": "c2a1187e-7e13-4506-9fcc-527c978a0966",
"parameters": {
"public": true,
"options": {
"responseMode": "responseNodes"
}
},
"typeVersion": 1.3
},
{
"id": "5cba1271-764b-48ea-81b8-1bf5f2b2f813",
"name": "Attendre une Réponse",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
992,
704
],
"parameters": {
"message": "={{ $json.question }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "581a9f27-dc41-40c2-8d91-ace13e3675a0",
"name": "Confirmation Rapide",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
992,
528
],
"parameters": {
"message": "Thanks. Please wait whilst I search the relevant document.",
"options": {},
"waitUserReply": false
},
"typeVersion": 1
},
{
"id": "0c9b0917-b3c2-4c8d-9825-1db4e07b8449",
"name": "Agréger les Réponses",
"type": "n8n-nodes-base.aggregate",
"position": [
800,
528
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "answers"
},
"typeVersion": 1
},
{
"id": "ea32ae52-d7ec-4f35-8ef8-04842d3cce72",
"name": "Répondre à l'Utilisateur",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
2640,
528
],
"parameters": {
"message": "={{ $json.message.content.answer }}",
"options": {},
"waitUserReply": false
},
"typeVersion": 1
},
{
"id": "931f6b89-1c5a-4865-a0cc-3264795ef498",
"name": "Agent RAG",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
2304,
528
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "=You are a helpful assistant. The user session involves answering user question against a research paper. Refer and use only the <documents> context to answer the user questions."
},
{
"role": "assistant",
"content": "=<documents>{{ $json.data.toJsonString() }}</document>"
},
{
"content": "={{\n$('Get Query').first().json.query\n + ' '\n + $('Aggregate Answers').first().json.answers.map(item => item.chatInput).join(' ')\n}}"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "8gccIjcuf3gvaoEr",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "9ded06c0-e7a1-4c5e-82c8-a432347b7b90",
"name": "Récupérer un Document par Numéro de Page",
"type": "n8n-nodes-base.mongoDbTool",
"position": [
2384,
672
],
"parameters": {
"query": "={\n \"metadata.pageNumber\": {{ $fromAI(\"pageNumber\", \"the page number to fetch\", \"number\") }}\n \"embedding\": { \"$exists\": false } // Second condition: ensure 'embedding' key does not exist\n },\n {\n \"text\": 1,\n \"metadata\": 1\n }",
"options": {},
"collection": "documents",
"descriptionType": "manual",
"toolDescription": "Call this tool to fetch a full document page by pageNumber. This could be useful for more deep dive context."
},
"credentials": {
"mongoDb": {
"id": "OUucWo4Fut06mJ1J",
"name": "MongoDB account"
}
},
"typeVersion": 1.2
},
{
"id": "32dd62cd-f55b-4f43-907f-687e30b91e20",
"name": "Combiner Contenu et Métadonnées",
"type": "n8n-nodes-base.set",
"position": [
3360,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bba20778-dbf9-459b-a1aa-97a76ba01713",
"name": "text",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "26d237a5-5991-4deb-867d-07b5bda6d2c2",
"name": "metadata",
"type": "object",
"value": "={{\n{\n \"pageNumber\": $json.pageNumber,\n \"url\": $json.url\n}\n}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cc7eab07-bae3-4838-bdca-45db86e2c734",
"name": "Insérer une Page de Document",
"type": "n8n-nodes-base.mongoDb",
"position": [
3536,
0
],
"parameters": {
"fields": "text,metadata",
"options": {},
"operation": "insert",
"collection": "documents"
},
"credentials": {
"mongoDb": {
"id": "OUucWo4Fut06mJ1J",
"name": "MongoDB account"
}
},
"typeVersion": 1.2
},
{
"id": "4d8c2a48-252a-4fe3-8ada-74bb02098347",
"name": "Fusionner",
"type": "n8n-nodes-base.merge",
"position": [
3840,
0
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 3.2
},
{
"id": "c68e573f-ea44-4ed4-b60c-d27cf8d00d4d",
"name": "Mise à Jour Rapide",
"type": "@n8n/n8n-nodes-langchain.chat",
"position": [
1904,
528
],
"parameters": {
"message": "={{\n(function(numResults) {\n const replies = [\n `Okay, I've found ${numResults} result${numResults === 1 ? '' : 's'}.`,\n `Summarizing ${numResults} result${numResults === 1 ? '' : 's'}...`,\n `Okay, give me a second to review these ${numResults} result${numResults === 1 ? '' : 's'}`\n ];\n return replies[Math.floor((Math.random() * replies.length) + 1)];\n}($json.data.length))\n}}",
"options": {},
"waitUserReply": false
},
"typeVersion": 1
},
{
"id": "1fe9a7c0-40e6-4150-8741-f6fcc9532013",
"name": "Note Adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
-544
],
"parameters": {
"color": 7,
"width": 624,
"height": 448,
"content": "## 1. Starting Fresh\nTo begin, we'll define our document URL to process. Since we breaking down the document in full and don't want duplicate entries in our database the next time we run this ingestion step, we'll clear the our MongoDB Collection and start fresh."
},
"typeVersion": 1
},
{
"id": "ed5cb8a7-381d-430d-a30f-15d04f60b35b",
"name": "Note Adhésive 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
-544
],
"parameters": {
"color": 7,
"width": 800,
"height": 448,
"content": "## 2. Download Paper and Split Into Pages\n[Read more about the HTTP node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nA common way to extract from a PDF is to use the \"Extract from File\" node. This will return the file's metadata as well as the text split into pages - which is exactly what we need for this particular flow. Note however, if charts and images are also required to be searchable then you may need to use a vision model to properly parse these elements."
},
"typeVersion": 1
},
{
"id": "72a31986-7c5e-4600-8c97-63e5cd92a2c1",
"name": "Note Adhésive 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1072,
-544
],
"parameters": {
"color": 7,
"width": 832,
"height": 448,
"content": "## 3. For Large Documents, Use Subworkflows for Better Performance\n[Learn more about Subworkflows](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow)\n\nFor practical applications, smaller executions are generally preferred to help reduce out-of-memory issues in n8n. This is especially so when working with sizable documents and embedding vectors. In this particular setup, we'll process each page separately and in sequence. Though this will take longer, it can ensure our instance's stability for other workflows."
},
"typeVersion": 1
},
{
"id": "0918ad0c-7c8e-473f-900f-194c617132c0",
"name": "Note Adhésive 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1968,
-544
],
"parameters": {
"color": 7,
"width": 736,
"height": 640,
"content": "## 4. Contextual Embeddings Using Voyage-Context-3\n[Learn more about Voyage-Context-3](https://blog.voyageai.com/2025/07/23/voyage-context-3/)\n\nVoyage-Context-3 is a new contextual chunk embedding model which allows you to include document context to improve retrieval accuracy. Whereas previously you may have had to manually augment incoming chunks, Voyage-Context-3 does this automatically by allowing your to bulk upload chunks and encoding context from the aggregate of all.\n\nFor this demonstration, we won't use the full document - that's a lot of data! - but rather, we'll embed sets of 3 sequential pages. This should be enough to cover at least \"chapter\"-level context. "
},
"typeVersion": 1
},
{
"id": "89b50026-e35d-40cb-9c16-9094d36f7ae3",
"name": "Note Adhésive 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2736,
-544
],
"parameters": {
"color": 7,
"width": 1024,
"height": 768,
"content": "## 5. Store Vectors and Full Page Text for Advanced RAG Search\n[Learn about MongoDB node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.mongodb)\n\nWe'll insert these context-aware embedding chunks into our MongoDB Atlas Vector Store along with their equivalent text content and metadata. Additionally, we can also store the full page text in Mongo as well - as we're able to later filter by page number, this can be a handy way of expanding on chunks later on in our searches."
},
"typeVersion": 1
},
{
"id": "f7c73904-bf8a-4b7f-bd07-17e43e1bd51d",
"name": "Insérer des Vecteurs de Documents",
"type": "n8n-nodes-base.mongoDb",
"position": [
3360,
-208
],
"parameters": {
"fields": "text,embeddings,metadata",
"options": {},
"operation": "insert",
"collection": "documents"
},
"credentials": {
"mongoDb": {
"id": "OUucWo4Fut06mJ1J",
"name": "MongoDB account"
}
},
"typeVersion": 1.2
},
{
"id": "f43c511b-b0fc-43a0-b870-dc74175469fa",
"name": "Note Adhésive 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
272
],
"parameters": {
"color": 7,
"width": 1328,
"height": 640,
"content": "## 6. Asking Clarifying Questions For Contextual Search\n[Read more about Respond To Chat](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-langchain.chat)\n\n**Respond to Chat** is a new Human-in-the-loop node where by the \"Human\" isn't an external source but the active user instead! This can make for really interesting multi-turn chat interactions which can feel more personalised and thus improving the user experience.\n\nFor this demonstration, we'll implement a \"clarifying questions\" loop where a set of questions are presented to the user to answer. These questions can help refine the context of the user's query and produce better search results so it's a really useful technique to know. Once the questions are answered, we can again use the \"respond to chat\" node to give a quick acknowledgement but this time with the \"wait for reply\" toggled off - this essentially becomes a \"send message\" operation."
},
"typeVersion": 1
},
{
"id": "43848d5f-2b2c-4698-8aef-940b9b968ade",
"name": "Note Adhésive 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
272
],
"parameters": {
"color": 7,
"width": 880,
"height": 640,
"content": "## 2. MongoDB Atlas Vector Search Using Voyage-Context-3\n[Learn more about MongoDB $vectorSearch queries](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/)\n\nThere's not an official MongoDB vector store node support so we'll have to write raw queries using the MongoDB node. Good thing that they're not really that hard to write once you get over the initial learning curve. Again we'll use Voyage-Context-3 on our query to match the embeddings in our vector store.\n\nOnce the documents are matched, we can use the \"respond to chat\" node to send a quick progress message to the user. These micro-updates can help break up long pauses between user questions and agent responses and provide a feeling of responsiveness.\n"
},
"typeVersion": 1
},
{
"id": "72773183-6b21-4726-88aa-4c5dc09fd8b6",
"name": "Note Adhésive 7",
"type": "n8n-nodes-base.stickyNote",
"position": [
2128,
272
],
"parameters": {
"color": 7,
"width": 784,
"height": 640,
"content": "## 3. Q&A Agent using OpenAI GPT-4.1-Mini\n[Read more about the OpenAI node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.openai)\n\nUsing the retrieved documents with our AI agent completes our Q&A agent flow and let's us respond to the user's query with unmatched relevancy and accuracy - or so we've been promised! Of course, you can't really tell unless you try it out for yourself.\n\nIn testing this workflow, I did find the ranking of retrieved documents to be better than naive document chunking. I could definitely recommend this contextual embeddings approach for the more demanding RAG requirements."
},
"typeVersion": 1
},
{
"id": "ce5101b3-4ec0-4dcf-804e-1cc9f72a8b6e",
"name": "Vider la Collection",
"type": "n8n-nodes-base.mongoDb",
"position": [
32,
-336
],
"parameters": {
"query": "={ \"metadata.url\": \"{{ $json.url }}\" }",
"operation": "delete",
"collection": "documents"
},
"credentials": {
"mongoDb": {
"id": "OUucWo4Fut06mJ1J",
"name": "MongoDB account"
}
},
"typeVersion": 1.2
},
{
"id": "f9ed9fd9-d85a-43fd-b87c-4e30c9fdab72",
"name": "Pour Chaque Groupe",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2832,
-208
],
"parameters": {
"options": {
"reset": "={{ $('For Each Group').context.done }}"
}
},
"typeVersion": 3
},
{
"id": "edb8c7d0-d909-42b9-bfd3-17e0c3c59efe",
"name": "Aucune Opération, ne rien faire",
"type": "n8n-nodes-base.noOp",
"position": [
3536,
-368
],
"parameters": {},
"typeVersion": 1
},
{
"id": "027cca87-9697-4923-88d4-23df75ae4d0e",
"name": "Sortie de Division 1",
"type": "n8n-nodes-base.splitOut",
"position": [
3008,
-208
],
"parameters": {
"options": {},
"fieldToSplitOut": "data"
},
"typeVersion": 1
},
{
"id": "5fbf397a-9054-42e0-890b-28b514e20c99",
"name": "Agréger 1",
"type": "n8n-nodes-base.aggregate",
"position": [
3536,
-208
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "2a706685-6ed5-4760-9127-db8608dc542d",
"name": "Note Adhésive 9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1184,
-720
],
"parameters": {
"width": 608,
"height": 944,
"content": "## Contextual Chunk Embeddings Using Voyage-Context-3 and Mongo Atlas\n\n**On my never-ending quest to find the best embeddings model, I was intrigued to come across [Voyage-Context-3](https://blog.voyageai.com/2025/07/23/voyage-context-3/) by MongoDB and was excited to give it a try.**\n\nThis template implements the embedding model on a Arxiv research paper and stores the results in a Vector store. It was only fitting to use Mongo Atlas from the same parent company. This template also includes a RAG-based Q&A agent which taps into the vector store as a test to helps qualify if the embeddings are any good and if this is even noticeable.\n\n\n### How it works\nThis template is split into 2 parts. The first part being the import of a research document which is then chunked and embedded into our vector store. The second part builds a RAG-based Q&A agent to test the vector store retrieval on the research paper.\n\nRead the steps for more details.\n\n### How to use\n* First ensure you create a Voyage account [voyageai.com](https://voyageai.com) and a MongoDB database ready.\n* Start with Step 1 and fill in the \"Set Variables\" node and Click on the Manual Execute Trigger. This will take care of populating the vector store with the research paper.\n* To use the Q&A agent, it is required to publish the workflow to access the public chat interface. This is because \"Respond to Chat\" works best in this mode and not in editor mode.\n* To use for your own document, edit the \"Set Variables\" node to define the URL to your own document.\n* This embeddings approach should work best on larger documents.\n\n### Requirements\n* [Voyageai.com](https://voyageai.com) account for embeddings. You may need to add credit to get a reasonable RPM for this workflow.\n* MongoDB database either self-hosted or online at [https://www.mongodb.com](https://www.mongodb.com).\n* OpenAI account for RAG Q&A agent.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"
},
"typeVersion": 1
},
{
"id": "cb267ec0-1267-4968-ac5d-0bc17cd09807",
"name": "Note Adhésive 10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1184,
256
],
"parameters": {
"width": 608,
"height": 336,
"content": ""
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"f044e091-b50c-4686-9f0a-e0abeb1022a0": {
"main": [
[
{
"node": "4dcbc327-0880-4f3b-9ba1-f6951f95b988",
"type": "main",
"index": 0
}
]
]
},
"e57a9115-5bb4-469b-9e1c-57e8747c9e79": {
"main": [
[
{
"node": "206e4cc4-693f-40df-8c37-45822dd953b5",
"type": "main",
"index": 0
}
]
]
},
"4d8c2a48-252a-4fe3-8ada-74bb02098347": {
"main": [
[
{
"node": "f044e091-b50c-4686-9f0a-e0abeb1022a0",
"type": "main",
"index": 0
}
]
]
},
"206e4cc4-693f-40df-8c37-45822dd953b5": {
"main": [
[],
[
{
"node": "2460bcd5-950a-4fbd-96eb-5428e03a32fb",
"type": "main",
"index": 0
}
]
]
},
"bbb632c2-a98c-4727-82f1-7a2ddd6cab89": {
"main": [
[
{
"node": "9bb0b5a0-bc3a-4d56-92cb-9287f6dd18f3",
"type": "main",
"index": 0
},
{
"node": "32dd62cd-f55b-4f43-907f-687e30b91e20",
"type": "main",
"index": 0
}
]
]
},
"60f7b22e-e56e-43c6-9651-c36d6bb6fa17": {
"main": [
[
{
"node": "c68e573f-ea44-4ed4-b60c-d27cf8d00d4d",
"type": "main",
"index": 0
}
]
]
},
"5877e228-c02c-41c1-9fd5-a76f47414ba0": {
"main": [
[
{
"node": "609d43c1-e536-49c7-8470-2c23763302ec",
"type": "main",
"index": 0
}
]
]
},
"d0a430ed-c2a2-4331-98b7-b1929cfe591f": {
"main": [
[
{
"node": "5cba1271-764b-48ea-81b8-1bf5f2b2f813",
"type": "main",
"index": 0
}
]
]
},
"931f6b89-1c5a-4865-a0cc-3264795ef498": {
"main": [
[
{
"node": "ea32ae52-d7ec-4f35-8ef8-04842d3cce72",
"type": "main",
"index": 0
}
]
]
},
"dfd6df48-a0a6-4995-925b-6dbe8dd58747": {
"main": [
[
{
"node": "f9ed9fd9-d85a-43fd-b87c-4e30c9fdab72",
"type": "main",
"index": 0
}
]
]
},
"5fbf397a-9054-42e0-890b-28b514e20c99": {
"main": [
[
{
"node": "f9ed9fd9-d85a-43fd-b87c-4e30c9fdab72",
"type": "main",
"index": 0
}
]
]
},
"027cca87-9697-4923-88d4-23df75ae4d0e": {
"main": [
[
{
"node": "19775d9b-fe97-4078-8ef5-252f45796e2c",
"type": "main",
"index": 0
}
]
]
},
"7a1609c6-19f7-41e0-9054-aa10d31e4529": {
"main": [
[
{
"node": "1a41d58f-b8fc-498f-a807-ffc3edd400ed",
"type": "main",
"index": 0
}
]
]
},
"c68e573f-ea44-4ed4-b60c-d27cf8d00d4d": {
"main": [
[
{
"node": "931f6b89-1c5a-4865-a0cc-3264795ef498",
"type": "main",
"index": 0
}
]
]
},
"5af13dae-29e2-4f6f-a8e8-96cf9d01569e": {
"main": [
[
{
"node": "ce5101b3-4ec0-4dcf-804e-1cc9f72a8b6e",
"type": "main",
"index": 0
}
]
]
},
"f9ed9fd9-d85a-43fd-b87c-4e30c9fdab72": {
"main": [
[
{
"node": "edb8c7d0-d909-42b9-bfd3-17e0c3c59efe",
"type": "main",
"index": 0
}
],
[
{
"node": "027cca87-9697-4923-88d4-23df75ae4d0e",
"type": "main",
"index": 0
}
]
]
},
"1a41d58f-b8fc-498f-a807-ffc3edd400ed": {
"main": [
[
{
"node": "206e4cc4-693f-40df-8c37-45822dd953b5",
"type": "main",
"index": 0
}
]
]
},
"9bb0b5a0-bc3a-4d56-92cb-9287f6dd18f3": {
"main": [
[
{
"node": "cbe2e982-7c4a-48e7-aa2a-3b9615d41deb",
"type": "main",
"index": 0
}
]
]
},
"4dcbc327-0880-4f3b-9ba1-f6951f95b988": {
"main": [
[],
[
{
"node": "bbb632c2-a98c-4727-82f1-7a2ddd6cab89",
"type": "main",
"index": 0
}
]
]
},
"35132610-83bb-4582-ad42-8e3954ea234f": {
"main": [
[
{
"node": "fe490208-25a9-4504-97b8-bbf3ce3e0b60",
"type": "main",
"index": 0
}
]
]
},
"5cba1271-764b-48ea-81b8-1bf5f2b2f813": {
"main": [
[
{
"node": "fe490208-25a9-4504-97b8-bbf3ce3e0b60",
"type": "main",
"index": 0
}
]
]
},
"ce5101b3-4ec0-4dcf-804e-1cc9f72a8b6e": {
"main": [
[
{
"node": "37a7e1ab-e3f3-4588-92a9-6a3bdf4335dc",
"type": "main",
"index": 0
}
]
]
},
"0c9b0917-b3c2-4c8d-9825-1db4e07b8449": {
"main": [
[
{
"node": "581a9f27-dc41-40c2-8d91-ace13e3675a0",
"type": "main",
"index": 0
}
]
]
},
"34c48356-2d29-41a2-902b-9512bb9bf3c8": {
"main": [
[
{
"node": "7a1609c6-19f7-41e0-9054-aa10d31e4529",
"type": "main",
"index": 0
}
]
]
},
"f30d70b4-42d3-48f4-b44d-0f48dd2d459a": {
"ai_languageModel": [
[
{
"node": "609d43c1-e536-49c7-8470-2c23763302ec",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"581a9f27-dc41-40c2-8d91-ace13e3675a0": {
"main": [
[
{
"node": "e52fa239-18e7-4ea9-93d2-010dd3555fa6",
"type": "main",
"index": 0
}
]
]
},
"fe490208-25a9-4504-97b8-bbf3ce3e0b60": {
"main": [
[
{
"node": "0c9b0917-b3c2-4c8d-9825-1db4e07b8449",
"type": "main",
"index": 0
}
],
[
{
"node": "d0a430ed-c2a2-4331-98b7-b1929cfe591f",
"type": "main",
"index": 0
}
]
]
},
"98e580fe-8db3-4e9d-bffd-1034cc8e61a1": {
"main": [
[
{
"node": "4dcbc327-0880-4f3b-9ba1-f6951f95b988",
"type": "main",
"index": 0
}
]
]
},
"cc7eab07-bae3-4838-bdca-45db86e2c734": {
"main": [
[
{
"node": "4d8c2a48-252a-4fe3-8ada-74bb02098347",
"type": "main",
"index": 1
}
]
]
},
"37a7e1ab-e3f3-4588-92a9-6a3bdf4335dc": {
"main": [
[
{
"node": "34c48356-2d29-41a2-902b-9512bb9bf3c8",
"type": "main",
"index": 0
}
]
]
},
"f7c73904-bf8a-4b7f-bd07-17e43e1bd51d": {
"main": [
[
{
"node": "5fbf397a-9054-42e0-890b-28b514e20c99",
"type": "main",
"index": 0
}
]
]
},
"edb8c7d0-d909-42b9-bfd3-17e0c3c59efe": {
"main": [
[
{
"node": "4d8c2a48-252a-4fe3-8ada-74bb02098347",
"type": "main",
"index": 0
}
]
]
},
"19775d9b-fe97-4078-8ef5-252f45796e2c": {
"main": [
[
{
"node": "f7c73904-bf8a-4b7f-bd07-17e43e1bd51d",
"type": "main",
"index": 0
}
]
]
},
"6f3c7ef8-891e-4dd4-bbf0-4adf6e193532": {
"main": [
[
{
"node": "60f7b22e-e56e-43c6-9651-c36d6bb6fa17",
"type": "main",
"index": 0
}
]
]
},
"32dd62cd-f55b-4f43-907f-687e30b91e20": {
"main": [
[
{
"node": "cc7eab07-bae3-4838-bdca-45db86e2c734",
"type": "main",
"index": 0
}
]
]
},
"70b2e1bb-c868-4adc-b21a-a9e95d166198": {
"main": [
[
{
"node": "5877e228-c02c-41c1-9fd5-a76f47414ba0",
"type": "main",
"index": 0
}
]
]
},
"2460bcd5-950a-4fbd-96eb-5428e03a32fb": {
"main": [
[
{
"node": "e57a9115-5bb4-469b-9e1c-57e8747c9e79",
"type": "main",
"index": 0
}
]
]
},
"cbe2e982-7c4a-48e7-aa2a-3b9615d41deb": {
"main": [
[
{
"node": "dfd6df48-a0a6-4995-925b-6dbe8dd58747",
"type": "main",
"index": 0
}
]
]
},
"e52fa239-18e7-4ea9-93d2-010dd3555fa6": {
"main": [
[
{
"node": "6f3c7ef8-891e-4dd4-bbf0-4adf6e193532",
"type": "main",
"index": 0
}
]
]
},
"9ded06c0-e7a1-4c5e-82c8-a432347b7b90": {
"ai_tool": [
[
{
"node": "931f6b89-1c5a-4865-a0cc-3264795ef498",
"type": "ai_tool",
"index": 0
}
]
]
},
"609d43c1-e536-49c7-8470-2c23763302ec": {
"main": [
[
{
"node": "35132610-83bb-4582-ad42-8e3954ea234f",
"type": "main",
"index": 0
}
]
]
},
"cc8db825-4ae4-4795-b3d3-a858af3d62c7": {
"main": [
[
{
"node": "5af13dae-29e2-4f6f-a8e8-96cf9d01569e",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Ingénierie, RAG IA
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Jimleuk
@jimleukFreelance AI Automation Engineer based in London, UK. Since 2024, my n8n templates have documented my journey into applied AI and have helped hundreds of businesses and organisations get up to speed with AI automation. Today, I continue to explore use-cases as AI evolves and occasionally upload templates which I find novel and interesting. Subscribe to the RSS Feed: https://cdn.subworkflow.ai/n8n-templates/rss.xml
Partager ce workflow