AutomationFlowsAI & RAG › RAG Search Workflow Before RAG API

RAG Search Workflow Before RAG API

Rag Search Workflow Before Rag Api. Uses httpRequest, agent, lmChatOpenRouter, memoryBufferWindow. Webhook trigger; 10 nodes.

Webhook trigger★★★★☆ complexityAI-powered10 nodesHTTP RequestAgentOpenRouter ChatMemory Buffer Window
AI & RAG Trigger: Webhook Nodes: 10 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "jsCode": "// Analyze question and determine optimal top_k\nconst question = $json.body.chatInput || '';\nconst lowerQ = question.toLowerCase();\n\nlet top_k = 10;\nif (lowerQ.includes('szczeg\u00f3\u0142') || lowerQ.includes('jak') || lowerQ.includes('por\u00f3wn')) {\n  top_k = 15;\n} else if (lowerQ.includes('przyk\u0142ad') || lowerQ.includes('lista')) {\n  top_k = 12;\n}\n\nreturn {\n  json: {\n    query: question,\n    top_k: top_k\n  }\n};"
      },
      "id": "e9357206-6f9d-49b3-a157-a296fb990115",
      "name": "Code: Analyze Question",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        608,
        688
      ]
    },
    {
      "parameters": {
        "jsCode": "// Get embedding response from Fireworks\n  const responseInfo = $input.item.json;                                        \n  const params = $('Code: Analyze Question').item.json;                         \n\n  // --- 1. EXTRACT VECTOR FROM FIREWORKS RESPONSE ---\n  let vector;\n  if (responseInfo.data && responseInfo.data[0] &&\n  responseInfo.data[0].embedding) {\n    vector = responseInfo.data[0].embedding;\n  } else if (Array.isArray(responseInfo)) {\n    vector = responseInfo;\n  } else {\n    throw new Error('Brak wektora z API Fireworks. Response: ' +\n  JSON.stringify(responseInfo).substring(0, 200));\n  }\n\n  // --- 2. BUILD QDRANT QUERY (NAMED VECTORS) ---\n  const qdrantQuery = {\n    vector: {\n      name: \"dense\",\n      vector: vector\n    },\n    limit: params.top_k || 10,\n    with_payload: true,\n    score_threshold: 0.3\n  };\n\n  // --- 3. ADD SLUG FILTER IF articleSlug PROVIDED ---\n  const articleSlug = $('Webhook: RAG Question').item.json.body.articleSlug;\n  if (articleSlug) {\n    qdrantQuery.filter = {\n      must: [{ key: \"slug\", match: { value: articleSlug } }]\n    };\n  }\n\n  return {\n    json: {\n      qdrantQuery,\n      originalQuestion: params.query,\n      top_k: params.top_k,\n      articleSlug: articleSlug || null\n    }\n  };\n"
      },
      "id": "f6ddef9c-be78-4f5b-912e-fe4903595ba1",
      "name": "Code: Prepare Qdrant Query",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1184,
        688
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://79a7ee05-96b9-4ab0-8670-25d5b081a97d.europe-west3-0.gcp.cloud.qdrant.io/collections/wordpress_articles/points/search",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json.qdrantQuery }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          },
          "timeout": 60000
        }
      },
      "id": "dfe0d749-ecdf-4fe6-9775-64e6a6514951",
      "name": "HTTP: Qdrant Search",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1472,
        688
      ],
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Qdrant results for LLM context\nconst response = $input.item.json;\nconst originalQuestion = $('Code: Prepare Qdrant Query').item.json.originalQuestion;\n\n// Check for results\nif (!response || !response.result || response.result.length === 0) {\n  return {\n    json: {\n      context: 'Brak wynik\u00f3w. System RAG nie znalaz\u0142 odpowiednich artyku\u0142\u00f3w.',\n      hasResults: false,\n      resultCount: 0,\n      results: [],\n      originalQuestion\n    }\n  };\n}\n\nconst results = response.result;\n\n// Build formatted context\nlet context = `Znaleziono ${results.length} wynik\u00f3w z bazy wiedzy:\\n\\n`;\nconst formattedResults = [];\n\nresults.forEach((hit, index) => {\n  const payload = hit.payload || {};\n\n  context += `--- Wynik ${index + 1} (Score: ${(hit.score * 100).toFixed(1)}%) ---\\n`;\n  context += `Tytu\u0142: ${payload.title || 'Brak tytu\u0142u'}\\n`;\n  context += `URL: ${payload.url || ''}\\n`;\n  context += `Typ sekcji: ${payload.section_type || 'content'}\\n`;\n\n  if (payload.publication_date) {\n    context += `Data publikacji: ${payload.publication_date}\\n`;\n  }\n\n  if (payload.tags && payload.tags.length > 0) {\n    context += `Tagi: ${payload.tags.join(', ')}\\n`;\n  }\n\n  if (payload.categories && payload.categories.length > 0) {\n    context += `Kategorie: ${payload.categories.join(', ')}\\n`;\n  }\n\n  context += `\\nTre\u015b\u0107:\\n${payload.text || ''}\\n\\n`;\n\n  formattedResults.push({\n    title: payload.title || 'Brak tytu\u0142u',\n    url: payload.url || '',\n    score: hit.score,\n    text: payload.text || '',\n    section_type: payload.section_type || 'content'\n  });\n});\n\nreturn {\n  json: {\n    context,\n    hasResults: true,\n    resultCount: results.length,\n    results: formattedResults,\n    originalQuestion\n  }\n};"
      },
      "id": "ed996b1b-06db-4b83-bc0c-3abf77d14c3b",
      "name": "Code: Format Qdrant Results",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1760,
        688
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "=Jeste\u015b ekspertem i asystentem na blogu o UX. Twoim zadaniem jest udzielenie wyczerpuj\u0105cej odpowiedzi na pytanie u\u017cytkownika.\n\nTwoja odpowied\u017a ma struktur\u0119 odwr\u00f3conej piramidy: najpierw og\u00f3lna, merytoryczna odpowied\u017a (korzystaj\u0105ca z Twojej ca\u0142ej wiedzy), a nast\u0119pnie wskazanie konkretnych \u017ar\u00f3de\u0142 dost\u0119pnych w dostarczonym kontek\u015bcie.\n\n=== HISTORIA ROZMOWY ===\n{{ $json.chat_history }}\n\n=== KONTEKST ARTYKU\u0141\u00d3W ===\n{{ $json.context }}\n\n=== ONE-SHOT LEARNING (WZ\u00d3R ODPOWIEDZI) ===\nPytanie: \"Co lepsze: Sketch czy Figma?\"\nKontekst: [Artyku\u0142: \"Migracja do Figmy\", Tre\u015b\u0107: \"Przeszli\u015bmy na Figm\u0119 ze wzgl\u0119du na tryb multiplayer.\"]\n\n(ODPOWIED\u0179):\nWyb\u00f3r zale\u017cy od \u015brodowiska pracy. Sketch to natywna aplikacja na macOS, \u015bwietna dla indywidualnych projektant\u00f3w ceni\u0105cych wydajno\u015b\u0107 lokaln\u0105. Figma dominuje jednak w zespo\u0142ach, poniewa\u017c dzia\u0142a w chmurze, co umo\u017cliwia prac\u0119 wielu os\u00f3b na jednym pliku jednocze\u015bnie i jest niezale\u017cna od systemu operacyjnego. Je\u015bli pracujesz w zespole, Figma zazwyczaj wygrywa \u0142atwo\u015bci\u0105 kolaboracji.\n\n### Warto przeczyta\u0107\n* Szczeg\u00f3\u0142owy opis procesu przej\u015bcia na narz\u0119dzia chmurowe i korzy\u015bci z trybu multiplayer znajdziesz w tek\u015bcie: [Migracja do Figmy](Link).\n\n=== TWOJE ZADANIA ===\nTw\u00f3rz odpowied\u017a zawsze w dw\u00f3ch krokach:\n\nKROK 1: Merytoryczna Odpowied\u017a (Bez nag\u0142\u00f3wka)\n1. Odpowiedz na pytanie u\u017cytkownika, wykorzystuj\u0105c swoj\u0105 szerok\u0105 wiedz\u0119 og\u00f3ln\u0105 ORAZ informacje z kontekstu.\n2. Nie ograniczaj si\u0119 tylko do artyku\u0142\u00f3w \u2013 je\u015bli u\u017cytkownik pyta o narz\u0119dzie, kt\u00f3rego nie ma w kontek\u015bcie (np. Cursor), opisz je rzetelnie bazuj\u0105c na swojej wiedzy.\n3. W tej sekcji nie u\u017cywaj link\u00f3w, skup si\u0119 na wyja\u015bnieniu problemu.\n\nKROK 2: Sekcja \u0179r\u00f3d\u0142owa (Nag\u0142\u00f3wek: \"### Warto przeczyta\u0107\")\n1. To miejsce WY\u0141\u0104CZNIE na tre\u015bci z sekcji `=== KONTEKST ARTYKU\u0141\u00d3W ===`.\n2. Wypunktuj konkretne artyku\u0142y, kt\u00f3re rozszerzaj\u0105 temat.\n3. Nie lej wody. Napisz konkretnie, co wnosi ten tekst, np.: \"Omawiamy tam techniki [X] i [Y]: [Tytu\u0142](Link)\".\n4. Je\u015bli w dostarczonym kontek\u015bcie nie ma nic pasuj\u0105cego do pytania \u2013 **ca\u0142kowicie pomi\u0144 t\u0119 sekcj\u0119** (nie pisz \"brak wynik\u00f3w\", po prostu zako\u0144cz wypowied\u017a na Kroku 1).\n\n=== ZAKAZY ===\n- Nie pisz wst\u0119p\u00f3w typu \"Jako model AI...\", \"Bazuj\u0105c na bazie wiedzy...\" ani \"W naszych artyku\u0142ach...\".\n- Nie u\u017cywaj sformu\u0142owa\u0144 sugeruj\u0105cych w\u0142asno\u015b\u0107 (\"nasze\", \"moje\"). Pisz bezosobowo lub bezpo\u015brednio.\n- Nie u\u017cywaj emoji.\n\nOdpowiedz teraz w j\u0119zyku polskim:"
        }
      },
      "id": "fb304eda-18f6-4d82-bddb-dcfb1f76db0d",
      "name": "AI Agent: Generate Answer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        2336,
        688
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.fireworks.ai/inference/v1/embeddings",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ { \"model\": \"nomic-ai/nomic-embed-text-v1.5\", \"input\": \"search_query: \" + $json.query } }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          },
          "timeout": 30000
        }
      },
      "id": "f8cdf396-ee07-4b06-8002-6d5677ea5842",
      "name": "HTTP: Fireworks Nomic Embed1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        896,
        688
      ],
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Format Chat History from webhook payload\nconst context = $json.context;\nconst chatInput = $('Webhook: RAG Question').item.json.body.chatInput;\nconst chatHistoryArray = $('Webhook: RAG Question').item.json.body.chatHistory || [];\n\n// Format history as text\nlet chatHistoryText = '';\nif (chatHistoryArray && chatHistoryArray.length > 0) {\n  chatHistoryArray.forEach(msg => {\n    const role = msg.role === 'user' ? 'U\u017cytkownik' : 'Asystent';\n    chatHistoryText += `${role}: ${msg.content}\\n\\n`;\n  });\n} else {\n  chatHistoryText = 'Brak poprzedniej rozmowy.';\n}\n\nreturn {\n  json: {\n    context,\n    chatInput,\n    chat_history: chatHistoryText\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2048,
        688
      ],
      "id": "5e92ca7c-6016-4e34-9fbf-9c82c18e3f8e",
      "name": "Code: Format Chat History1"
    },
    {
      "parameters": {
        "model": "anthropic/claude-haiku-4.5",
        "options": {
          "temperature": 0.5
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        2288,
        960
      ],
      "id": "b30e576a-3858-4f5e-af68-96627ab9a4c4",
      "name": "OpenRouter Chat Model2",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Webhook: RAG Question').item.json.body.sessionId || 'default' }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        2432,
        976
      ],
      "id": "3454a5e6-7e95-49c6-964a-0d5a0d0951eb",
      "name": "Simple Memory1"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "rag-agent",
        "responseMode": "lastNode",
        "options": {}
      },
      "id": "7e7472c5-fa8e-480d-81d0-5ffc61129b1f",
      "name": "Webhook: RAG Question",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        128,
        640
      ]
    }
  ],
  "connections": {
    "Code: Analyze Question": {
      "main": [
        [
          {
            "node": "HTTP: Fireworks Nomic Embed1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Prepare Qdrant Query": {
      "main": [
        [
          {
            "node": "HTTP: Qdrant Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP: Qdrant Search": {
      "main": [
        [
          {
            "node": "Code: Format Qdrant Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Format Qdrant Results": {
      "main": [
        [
          {
            "node": "Code: Format Chat History1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP: Fireworks Nomic Embed1": {
      "main": [
        [
          {
            "node": "Code: Prepare Qdrant Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code: Format Chat History1": {
      "main": [
        [
          {
            "node": "AI Agent: Generate Answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent: Generate Answer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory1": {
      "ai_memory": [
        [
          {
            "node": "AI Agent: Generate Answer",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: RAG Question": {
      "main": [
        [
          {
            "node": "Code: Analyze Question",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Rag Search Workflow Before Rag Api. Uses httpRequest, agent, lmChatOpenRouter, memoryBufferWindow. Webhook trigger; 10 nodes.

Source: https://github.com/a-michalski/wordpress-rag/blob/87141bd131e299f2b80489e37b71036c6922550a/n8n_workflows/rag_search_workflow_before_rag_api.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

🧪 LABR - nuevo asistente (REPARADO). Uses httpRequest, postgres, postgresTool, toolCalculator. Webhook trigger; 63 nodes.

HTTP Request, Postgres, Postgres Tool +9
AI & RAG

This workflow acts as an AI-powered research assistant that takes a topic from the user, performs multi-step intelligent research, and stores the final report in Notion. It uses advanced search, conte

Memory Buffer Window, Output Parser Structured, Agent +6
AI & RAG

This n8n template demonstrates how to build O'Carla, an advanced all-in-one Discord AI assistant. It intelligently handles natural conversations, professional image generation, and visual file analysi

Memory Buffer Window, Agent, Google Gemini Chat +2
AI & RAG

Jacobo Chatbot V2. Uses agent, memoryBufferWindow, toolThink, httpRequest. Webhook trigger; 37 nodes.

Agent, Memory Buffer Window, Tool Think +4
AI & RAG

This workflow is for automating and centralizing your bookmarking process using AI-powered tagging and seamless integration between your Android device and a self-hosted Read Deck platform (https://re

Tool Serp Api, Output Parser Autofixing, Output Parser Structured +5