Consultas Avanzadas con Metadata y Sub-flujos
Esta guía explica cómo crear un sistema de búsqueda robusto (RAG Avanzado) que utiliza metadata para filtrar, re-rankear resultados y manejar casos donde no se encuentra información.
1. El Flujo de Búsqueda Avanzada (Sub-workflow)
Este flujo está diseñado para ser llamado por otro agente. Recibe una consulta (query), busca en la base de datos, filtra por calidad y devuelve los resultados estructurados.
Código del Flujo (Copiar y Pegar en n8n)
{
"nodes": [
{
"parameters": {
"workflowInputs": {
"values": [
{
"name": "query"
}
]
}
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
-1040,
288
],
"id": "a4fe14f4-6240-4309-9d19-c6fdeb01f7e2",
"name": "When Executed by Another Workflow"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "bfa4a047-d5fc-4d6a-82ab-c070b93ef8ae",
"name": "sku",
"value": "={{ $json.document.metadata.sku }}",
"type": "string"
},
{
"id": "4c72c795-c1d2-4b0d-82c5-182307574dd2",
"name": "titulo",
"value": "={{ $json.document.metadata.titulo }}",
"type": "string"
},
{
"id": "16bec3f0-a598-433b-9cd4-cc652996fc5c",
"name": "categoria",
"value": "={{ $json.document.metadata.categoria }}",
"type": "string"
},
{
"id": "f51b2757-7ecc-4cd8-8c9c-f098f40c99b0",
"name": "images_url",
"value": "={{ $json.document.metadata.images_url }}",
"type": "string"
},
{
"id": "a4fe80a0-edac-4e1a-b774-bd3cd2a8adc1",
"name": "link_tienda",
"value": "={{ $json.document.metadata.link_tienda }}",
"type": "string"
},
{
"id": "9edb61d3-158c-42cc-829e-c1386e12c62b",
"name": "descripcion",
"value": "={{ $json.document.metadata.descripcion }}",
"type": "string"
},
{
"id": "a6ecb600-0b82-4c42-a567-74f7dc8da648",
"name": "precio_dolares",
"value": "={{ $json.document.metadata.precio_dolares }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
352,
496
],
"id": "34d966a4-3972-4ac2-9965-b0af98fbd40c",
"name": "Edit Fields2"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "bd979f40-8142-4d56-9b9f-a3e636df251d",
"leftValue": "={{ $json.isEmpty() }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
32,
288
],
"id": "bdeda3de-a0e4-4987-88af-aa92bb3d4566",
"name": "Si no hay nada"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1.2,
"position": [
352,
256
],
"id": "6e1d22ff-0998-4f93-a92e-6eeaec1f6c98",
"name": "Embeddings OpenAI1",
"credentials": {
"openAiApi": {
"id": "gW7r1PFDamaDkSau",
"name": "soproca"
}
}
},
{
"parameters": {
"mode": "load",
"tableName": {
"__rl": true,
"value": "documents_algiorno_products",
"mode": "id"
},
"prompt": "={{ $json.query }}",
"topK": 5,
"useReranker": true,
"options": {
"queryName": "match_documents_algiorno_products"
}
},
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"typeVersion": 1.3,
"position": [
-592,
288
],
"id": "dc959161-3484-4a76-bfa7-effed843183b",
"name": "Supabase Vector Store2",
"credentials": {
"supabaseApi": {
"id": "4Z4FVgU9kqrOJEMV",
"name": "Botinfy Supabase Credentials"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1.2,
"position": [
-592,
512
],
"id": "5e842fff-67d5-4314-9cf9-fda4d90c5570",
"name": "Embeddings OpenAI2",
"credentials": {
"openAiApi": {
"id": "qvRy3T1qgDWkuoZD",
"name": "Algiorno: OpenAI Credentials"
}
}
},
{
"parameters": {
"topN": 5
},
"type": "@n8n/n8n-nodes-langchain.rerankerCohere",
"typeVersion": 1,
"position": [
-432,
528
],
"id": "e4a1f7fd-815b-48c4-bfe5-8c4834b5931d",
"name": "Reranker Cohere1",
"credentials": {
"cohereApi": {
"id": "H9hE2jMOhjsY4STS",
"name": "Botinfy: Cohere Credentials"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "c95fd3e3-a7ce-4e76-8eb0-3068c5918c09",
"leftValue": "={{ $json.score }}",
"rightValue": 0.65,
"operator": {
"type": "number",
"operation": "gte"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
-192,
288
],
"id": "bd3dec53-7ef4-4a48-b3cd-8eb18d1515cb",
"name": "Filter2",
"alwaysOutputData": true
},
{
"parameters": {
"mode": "load",
"tableName": {
"__rl": true,
"value": "documents_algiorno_products",
"mode": "id"
},
"prompt": "={{ $('When Executed by Another Workflow').item.json.query }}",
"topK": 10,
"options": {
"queryName": "match_documents_algiorno_products"
}
},
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"typeVersion": 1.3,
"position": [
288,
48
],
"id": "3e4f8975-e258-4cd5-a55d-5ec6bf54a060",
"name": "Supabase Vector Store3",
"credentials": {
"supabaseApi": {
"id": "4Z4FVgU9kqrOJEMV",
"name": "Botinfy Supabase Credentials"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "5264279e-c279-41ea-a1ba-8b003c31dfb8",
"name": "status",
"value": "productos encontrados",
"type": "string"
},
{
"id": "867e84e2-406d-4adf-b8a3-de195b97877b",
"name": "encontrados",
"value": "={{ $('Edit Fields2').all() }}",
"type": "array"
}
]
},
"options": {
"ignoreConversionErrors": true
}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
560,
496
],
"id": "7b7c099c-60af-44d9-958d-30b2c55af76e",
"name": "Edit Fields",
"executeOnce": true
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "4c72c795-c1d2-4b0d-82c5-182307574dd2",
"name": "titulo",
"value": "={{ $json.document.metadata.titulo }}",
"type": "string"
},
{
"id": "65a17280-2cd4-46f0-a2a3-1b23b1de83f9",
"name": "sku",
"value": "={{ $json.document.metadata.sku }}",
"type": "number"
},
{
"id": "0207d923-c9d9-481e-8951-f26000371742",
"name": "descripcion",
"value": "={{ $json.document.metadata.descripcion }}",
"type": "string"
},
{
"id": "79d41e6b-ce0d-4f21-a3d5-ff9b730f1ce0",
"name": "link_tienda",
"value": "={{ $json.document.metadata.link_tienda }}",
"type": "string"
},
{
"id": "8b4815d3-54e5-427a-919b-ebe057b9137c",
"name": "images_url",
"value": "={{ $json.document.metadata.images_url }}",
"type": "string"
},
{
"id": "d90d245c-a2fb-4039-b5fe-7cd4edfa5ec7",
"name": "precio_dolares",
"value": "={{ $json.document.metadata.precio_dolares }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
688,
112
],
"id": "224987a7-ed54-4ddc-89b4-e80660ee3737",
"name": "Edit Fields3"
},
{
"parameters": {
"inputText": "={{JSON.stringify($json, null, 2)}}",
"categories": {
"categories": [
{
"category": "acertado",
"description": "=El texto proporcionado coincide (en cuanto a marca, tipo de dispositivo o descripcion) con la siguiente descripcion: {{ $('When Executed by Another Workflow').item.json.query }}"
},
{
"category": "no acertado",
"description": "=El texto proporcionado no coincide (en cuanto a marca, tipo de dispositivo o descripcion) con la siguiente descripcion:{{ $('When Executed by Another Workflow').item.json.query }}"
}
]
},
"options": {
"systemPromptTemplate": "Please classify the text provided by the user into one of the following categories: {categories}, and use the provided formatting instructions below. Don't explain, and only output the json."
}
},
"type": "@n8n/n8n-nodes-langchain.textClassifier",
"typeVersion": 1.1,
"position": [
896,
112
],
"id": "2334ee5a-e94b-432d-952a-74ad4420e194",
"name": "Text Classifier"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "gpt-4o-mini",
"mode": "list",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
832,
320
],
"id": "25f4229f-763f-4d54-88dc-b8652f8df2af",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"id": "gW7r1PFDamaDkSau",
"name": "soproca"
}
}
},
{
"parameters": {
"aggregate": "aggregateAllItemData",
"destinationFieldName": "productos_encontrados",
"include": "specifiedFields",
"fieldsToInclude": "titulo, link_tienda, images_url",
"options": {}
},
"type": "n8n-nodes-base.aggregate",
"typeVersion": 1,
"position": [
1248,
-16
],
"id": "9b8fa620-6785-414d-96b9-4c8b479e7639",
"name": "Aggregate"
},
{
"parameters": {
"aggregate": "aggregateAllItemData",
"destinationFieldName": "productos_recomendados",
"include": "specifiedFields",
"fieldsToInclude": "titulo, link_tienda, images_url",
"options": {}
},
"type": "n8n-nodes-base.aggregate",
"typeVersion": 1,
"position": [
1248,
192
],
"id": "0c6ebf3a-a875-4eaf-81fa-0222c1c43386",
"name": "Aggregate1"
},
{
"parameters": {},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [
1600,
32
],
"id": "21197b04-c594-4a4c-8795-a676ee4cc3d4",
"name": "Merge"
},
{
"parameters": {
"content": "# primera busqueda\n\n## se realiza una busqueda general segun la peticion del cliente, segun el resultado del re ranker, el nodo filter los segmenta (resultado 0,7 aceptado como que el producto es el verdadero, se debe manipular segun el negocio)\n",
"height": 384,
"width": 592
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-592,
-16
],
"id": "0290f5de-5a21-47f6-a1c3-0262f6593554",
"name": "Sticky Note"
},
{
"parameters": {
"content": "# Caso donde el resultado no fue el esperado\n\n## cuando el resultado del re ranker es menos de lo establecido en filter, se va por esta rama, y vuelve a hacer otra busqueda sin reranker.\n\n## luego pasa por un text clasiffier, en este caso si preguntan por marcas, los segmente de esa manera\n\n\n# IMPORTANTE\n\n\n## este nodo al final responde con dos arrays, productos encontrados, productos recomendados.\n\n## debe indicarle al agente de IA que recibe esas respuestas que significa cada array.\n",
"height": 512,
"width": 880,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
352,
-512
],
"id": "ab52eb5c-3769-412c-a3c3-0262f6593554",
"name": "Sticky Note1"
}
]
}🧠 Explicación del Flujo Paso a Paso
- Trigger (When Executed by Another Workflow): Recibe la palabra clave o pregunta del usuario (ej. "Zapatos rojos").
- Primera Búsqueda (Supabase + Reranker):
- Busca en la base de datos.
- Usa Cohere Reranker para ordenar los resultados por relevancia real.
- Filtro de Calidad (Filter):
- Evalúa el
score(puntaje) que dio el Reranker. - Regla: Si el score es mayor a
0.65(65% de certeza), se considera un "Buen Resultado".
- Evalúa el
- Camino A (Buen Resultado):
- Pasa directamente a formatear los datos (extrae precio, imagen, link de la metadata) y los entrega como "Productos Encontrados".
- Camino B (Mal Resultado / No encontrado):
- Si el score es bajo, hace una Segunda Búsqueda más amplia (sin Reranker) para ver si encuentra algo parecido.
- Usa un Text Classifier para decidir si lo que encontró tiene sentido o es basura.
- Entrega estos resultados como "Productos Recomendados" (ej. "No encontré zapatos rojos, pero mira estos vinotinto").
2. ¿Cómo llamar a este flujo? (Tool Workflow)
Para que tu Agente de IA principal pueda usar este super-buscador, debes usar la herramienta Call n8n Workflow Tool.
Código de la Tool
{
"nodes": [
{
"parameters": {
"description": "Call this tool to get products information",
"workflowId": {
"__rl": true,
"value": "TW8czaORJwWjjQVO",
"mode": "list",
"cachedResultName": "SubWorkFlow: Busqueda de productos Algiorno"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('query', ``, 'string') }}"
},
"matchingColumns": [
"query"
],
"schema": [
{
"id": "query",
"displayName": "query",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"typeVersion": 2.2,
"position": [
672,
880
],
"id": "7ed75d8f-fd2e-4536-9109-2295aa7dd076",
"name": "products"
}
],
"connections": {
"products": {
"ai_tool": [
[]
]
}
}
}Nota: Debes seleccionar en
Workflow IDel flujo de búsqueda avanzada que creaste en el paso 1.
3. Búsqueda Directa por Metadata (Filtro Exacto)
A veces no quieres buscar por similitud ("algo que parezca un zapato"), sino por un dato exacto ("el producto con código 12345"). Para esto, configuramos el nodo de Supabase con un filtro de metadata.
Código del Nodo con Filtro
{
"nodes": [
{
"parameters": {
"topN": 8
},
"type": "@n8n/n8n-nodes-langchain.rerankerCohere",
"typeVersion": 1,
"position": [
672,
3056
],
"id": "ccc9bb6e-3782-41fb-8023-56039ea41f3c",
"name": "Reranker Cohere1",
"credentials": {
"cohereApi": {
"id": "H9hE2jMOhjsY4STS",
"name": "Botinfy: Cohere Credentials"
}
}
},
{
"parameters": {
"mode": "retrieve-as-tool",
"toolName": "get_info_productos",
"toolDescription": "Usa esta herramienta para obtener, buscar, productos, informacion, precio, disponibilidad, juegos, imagenes ,consolas, telefono y un gran etc y todo sobre los productos de TuPuntoPlay, es la fuente de informacion mas grande de todas, siempre usala",
"tableName": {
"__rl": true,
"value": "documents_tupuntoplay",
"mode": "list",
"cachedResultName": "documents_tupuntoplay"
},
"topK": 10,
"includeDocumentMetadata": false,
"useReranker": true,
"options": {
"queryName": "match_documents_tupuntoplay",
"metadata": {
"metadataValues": [
{
"name": "codigo_producto",
"value": "12345"
}
]
}
}
},
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"typeVersion": 1.1,
"position": [
288,
2832
],
"id": "3a72d10d-cc59-4512-bdc6-dd92880176ad",
"name": "get_info_productos",
"credentials": {
"supabaseApi": {
"id": "lwgrM07n5AFMxLbr",
"name": "Botinfy Supabase Credential"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"typeVersion": 1.2,
"position": [
192,
3024
],
"id": "02f5f72b-66c9-4e2c-b366-aa24e1071d73",
"name": "Embeddings OpenAI1",
"credentials": {
"openAiApi": {
"id": "DaFqrvpcJfdTfrbp",
"name": "OpenIA: TuPuntoPlay"
}
}
}
],
"connections": {
"Reranker Cohere1": {
"ai_reranker": [
[
{
"node": "get_info_productos",
"type": "ai_reranker",
"index": 0
}
]
]
},
"get_info_productos": {
"ai_tool": [
[]
]
},
"Embeddings OpenAI1": {
"ai_embedding": [
[
{
"node": "get_info_productos",
"type": "ai_embedding",
"index": 0
}
]
]
}
}
}¿Qué hace especial a este nodo?
Fíjate en la sección options -> metadata.
- Estamos diciendo: "Busca en la base de datos, PERO solo tráeme los registros donde la columna
codigo_productosea igual a12345". - Esto es extremadamente útil para buscar inventario de un ítem específico o datos de un usuario por su ID.
4. Personalización por Cliente
Para adaptar estos flujos a cada cliente, modifica:
En el Sub-flujo:
- Supabase Vector Store: Cambia el
Table Namey elQuery Name(la función RPC). - Set Nodes (Edit Fields): Asegúrate de que los nombres de las columnas (
sku,precio,imagen) coincidan con los nombres de las columnas en el Excel del cliente. Si el cliente usa "Coste" en vez de "Precio", debes cambiarlo aquí. - Filter: Ajusta el valor
0.65si necesitas ser más estricto o más flexible.
- Supabase Vector Store: Cambia el
En la Tool:
- Workflow ID: Apunta al nuevo sub-flujo del cliente.
- Description: Describe qué tipo de productos vende este cliente para que la IA sepa cuándo usarla.