AutomationFlowsAI & RAG › Query Naive (baseline)

Query Naive (baseline)

03 — Query naive (baseline). Uses vectorStoreSupabase, embeddingsOpenAi, httpRequest. Webhook trigger; 6 nodes.

Webhook trigger★★★★☆ complexityAI-powered6 nodesSupabase Vector StoreOpenAI EmbeddingsHTTP Request
AI & RAG Trigger: Webhook Nodes: 6 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the OpenAI Embeddings → 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
{
  "name": "03 \u2014 Query naive (baseline)",
  "settings": {
    "executionOrder": "v1"
  },
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "query-naive",
        "responseMode": "lastNode",
        "options": {}
      },
      "id": "a3000000-0000-4000-8000-000000000001",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -620,
        0
      ],
      "notes": "POST { \"question\": \"...\" }. Baseline: no hybrid search, no rerank."
    },
    {
      "parameters": {
        "mode": "load",
        "tableName": "documents",
        "prompt": "={{ $json.body.question }}",
        "topK": 5,
        "options": {
          "queryName": "match_documents"
        }
      },
      "id": "a3000000-0000-4000-8000-000000000002",
      "name": "Retrieve \u2014 pure vector",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1.1,
      "position": [
        -380,
        0
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "notes": "match_documents orders by cosine distance only \u2014 this is the naive baseline the other strategies are measured against."
    },
    {
      "parameters": {
        "model": "text-embedding-3-small",
        "options": {}
      },
      "id": "a3000000-0000-4000-8000-000000000003",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        -380,
        220
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Must be the same model used at ingestion: query and chunk vectors have to live in the same space."
    },
    {
      "parameters": {
        "jsCode": "const question = $('Webhook').first().json.body.question;\nconst hits = $input.all().map((item, i) => {\n  const doc = item.json.document ?? item.json;\n  return {\n    rank: i + 1,\n    similarity: item.json.score ?? null,\n    source: doc.metadata?.source ?? null,\n    lines: doc.metadata?.loc?.lines ?? null,\n    content: doc.pageContent ?? doc.content ?? '',\n  };\n});\n\nconst context = hits\n  .map((h) => `[${h.rank}] (${h.source}${h.lines ? `, lines ${h.lines.from}-${h.lines.to}` : ''})\\n${h.content}`)\n  .join('\\n\\n');\n\nconst system = 'You answer strictly from the provided excerpts of the NIST Cybersecurity Framework 2.0. Cite the excerpt you used as [n] after each claim. If the excerpts do not contain the answer, say so plainly instead of guessing.';\nconst user = `Question: ${question}\\n\\nExcerpts:\\n${context}`;\n\nreturn [{ json: { question, hits, system, user, contextChars: context.length } }];"
      },
      "id": "a3000000-0000-4000-8000-000000000004",
      "name": "Build Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -140,
        0
      ],
      "notes": "No executeOnce: it would clamp the node to the first retrieved chunk."
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: 'gpt-4o-mini', temperature: 0, messages: [ { role: 'system', content: $json.system }, { role: 'user', content: $json.user } ] }) }}",
        "options": {}
      },
      "id": "a3000000-0000-4000-8000-000000000005",
      "name": "Generate \u2014 gpt-4o-mini",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        100,
        0
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Raw HTTP rather than the chat node so the response carries `usage` \u2014 token counts are the cost evidence for this block."
    },
    {
      "parameters": {
        "jsCode": "const res = $input.first().json;\nconst usage = res.usage ?? {};\n// gpt-4o-mini, USD per 1M tokens.\nconst IN = 0.15, OUT = 0.60;\nconst cost = ((usage.prompt_tokens ?? 0) / 1e6) * IN + ((usage.completion_tokens ?? 0) / 1e6) * OUT;\nconst prep = $('Build Prompt').first().json;\n\nreturn [{ json: {\n  strategy: 'naive',\n  question: prep.question,\n  answer: res.choices?.[0]?.message?.content ?? null,\n  retrieved: prep.hits.map((h) => ({\n    rank: h.rank,\n    similarity: h.similarity,\n    source: h.source,\n    lines: h.lines,\n    preview: h.content.slice(0, 220),\n  })),\n  usage,\n  costUsd: Number(cost.toFixed(6)),\n} }];"
      },
      "id": "a3000000-0000-4000-8000-000000000006",
      "name": "Format Answer",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        340,
        0
      ],
      "notes": "Cost is computed here, not estimated afterwards: prompt/completion tokens come back with every generation."
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Retrieve \u2014 pure vector",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve \u2014 pure vector": {
      "main": [
        [
          {
            "node": "Build Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Retrieve \u2014 pure vector",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Build Prompt": {
      "main": [
        [
          {
            "node": "Generate \u2014 gpt-4o-mini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate \u2014 gpt-4o-mini": {
      "main": [
        [
          {
            "node": "Format Answer",
            "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

03 — Query naive (baseline). Uses vectorStoreSupabase, embeddingsOpenAi, httpRequest. Webhook trigger; 6 nodes.

Source: https://github.com/BhrayanM/rag-engine/blob/main/workflows/03-query-naive.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

Bread-Meat-Delivery. Uses lmChatOpenAi, agent, httpRequest, redis. Webhook trigger; 91 nodes.

OpenAI Chat, Agent, HTTP Request +14
AI & RAG

My workflow 14. Uses supabase, redis, openAi, googleCalendarTool. Webhook trigger; 91 nodes.

Supabase, Redis, OpenAI +13
AI & RAG

HeyDinastia. Uses executeCommand, httpRequest, youTube, postgres. Webhook trigger; 66 nodes.

Execute Command, HTTP Request, YouTube +15
AI & RAG

This workflow automates multi-channel AI-driven sales engagement for lead qualification, service information delivery, and consultation booking. It integrates WhatsApp, Facebook Messenger, Instagram D

Agent, OpenAI Embeddings, OpenAI Chat +11
AI & RAG

YouTube Agent. Uses supabase, agent, lmChatAnthropic, outputParserStructured. Webhook trigger; 56 nodes.

Supabase, Agent, Anthropic Chat +10