Building the Ultimate RAG setup with Contextual Summaries, Sparse Vectors and Reranking

Hey @Jim_Le ,

Thanks for your prompt response. Yea, that is the reason I am still using v1.97.1 . I am not sure about 1.102.0 as they mention about some change in the Code node.

Fyi, I am totally new in js/python programming, learning bit by bit from your great work. Would really appreciate if you can share your latest workflow.

Read about Qdrant hybrid search and I am using Qdrant (instead of Supabase vector DB) because I saw you recommending it in some YT video.

Hi @Jim_Le Thank you for the amazing template

I am not familiar with Qdrant and already all set up with Supabase

Could you elaborate on the choice of Qdrant for this template ? Would Supabase do the job as well or do you anticipate major challenges ?

Thanks !

Hey @Olivi
Great question!

In my opinion, Qdrant is more optimised for the multi-vector support you need for this template.

  1. Really easy to define Dense & Sparse Vectors for your document collection. See Vectors - Qdrant
  2. Qdrant’s single powerful Hybrid Search API comes readily available with the product and simplifies querying using both vector types (relevant doc for the template).
  3. Qdrant is a really performant vector store which is critical when collections get really big and you need to keep response times low.

It should be noted, the Hybrid Search API isn’t a simple join of vector types and scores but rather it performs multi-stage queries. Definitely could be replicated in Supabase + application space but would be a lot of work and where the major challenge could be.

Hope this helps!

2 Likes

Thanks Jim for these inputs!

Please tell me in the correspondence you say that there is already a 1.73.0 Workflow version for n8n “Building the Ultimate RAG setup with Contextual Summaries, Sparse Vectors and Reranking”, but in the topic you can download only version 1.62.1, Tell me, is the 1.73.0 Workflow version available for download???

Hey @Stanislav_Zedis Welcome to the community!
Unfortunately, I’ve lost track of the template versions but the last time I touched this, I put the updated version on my n8n creator page (see link in previous posts).

Just to note this template is quite outdated and due to recent n8n updates, some of the techniques/hacks don’t work anymore. If you’re after deep research usage, check out Perplexity or Jina.ai who are faster and cheaper to integrate. [Check out the other Deep Research n8n Templates from other creators as well](Discover 5164 Automation Workflows from the n8n's Community).

1 Like

Hello @Jim_Le - is it based on a Hybrid RAG?

Jim_Le please help me your “Qdrant with Cohere ReRank“ give error “Not Found” I already check all qdrant setings It correct but it doesn’t work

const { QdrantClient } = require(‘@qdrant/js-client-rest’);
const { CohereRerank } = require(“@langchain/cohere”);
const { DynamicTool } = require(“@langchain/core/tools”);

// 1. Tool Config
//const name = ‘bitcoin_whitepaper_tool’;
//const description = ‘Call this tool to get information and/or context from the Bitcoin Whitepaper’;

// 1. Tool Config
const name = ‘qdrant_document_retrieval_tool’;
const description = ‘Call this tool to get information and/or context from any document stored in Qdrant’;

// 2. Qdrant config
const client = new QdrantClient({
url: ‘https://localhost:6333’,
apiKey: ‘*****’
});
const collectionName = ‘RAG8.10_Sparse’;
const limit = 20;

// 3. Cohere config
const cohereRerank = new CohereRerank({
apiKey: ‘*****’, // Default
model: “rerank-multilingual-v3.0”, // Default
});

// 4. Inputs
const embeddings = await this.getInputConnectionData(‘ai_embedding’, 0);
const sparseVectorTool = await this.getInputConnectionData(‘ai_tool’, 0);

// 5. Tool definition
const vectorStoreTool = new DynamicTool({
name,
description,
func: async (input) => {
const denseVector = await embeddings.embedQuery(input);
const sparseVector = JSON.parse(await sparseVectorTool.invoke(input));

const response = await client.query(collectionName, {
  prefetch: [
    {
      query: denseVector,
      using: 'default',
      limit: 100
    },
    {
      query: sparseVector,
      using: 'bm42',
      limit: 100
    }
 ],
 query: { fusion: 'rrf' },
 with_payload: true,
 limit,
});

const docs = response.points.map(res => ({
  pageContent: res.payload.content,
  metadata: res.payload.metadata
}));
const rankings = await cohereRerank.rerank(docs, input);
rankings.forEach(rank => { docs[rank.index].score = rank.relevanceScore });

const rankedDocs = docs.toSorted((a,b) => b.score-a.score);
return JSON.stringify(rankedDocs);

}
});

return vectorStoreTool;