<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SONU OLIKKARA SABU </title>
    <description>The latest articles on DEV Community by SONU OLIKKARA SABU  (@sonuolikkara).</description>
    <link>https://dev.to/sonuolikkara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4102192%2F0b9cbd97-94fa-4bac-b3fb-3716153432f3.jpg</url>
      <title>DEV Community: SONU OLIKKARA SABU </title>
      <link>https://dev.to/sonuolikkara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sonuolikkara"/>
    <language>en</language>
    <item>
      <title>I Built an Agentic Hybrid RAG System with FAISS and BM25</title>
      <dc:creator>SONU OLIKKARA SABU </dc:creator>
      <pubDate>Mon, 31 Aug 2026 06:16:04 +0000</pubDate>
      <link>https://dev.to/sonuolikkara/i-built-an-agentic-hybrid-rag-system-with-faiss-and-bm25-3kej</link>
      <guid>https://dev.to/sonuolikkara/i-built-an-agentic-hybrid-rag-system-with-faiss-and-bm25-3kej</guid>
      <description>&lt;p&gt;I've been learning about &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt; and wanted to understand how it actually works by building something myself.&lt;/p&gt;

&lt;p&gt;Instead of just following tutorials, I decided to create a small project where I could experiment with document retrieval, embeddings, vector search, keyword search, and an AI agent.&lt;/p&gt;

&lt;p&gt;The result is my &lt;strong&gt;Agentic Hybrid RAG System&lt;/strong&gt;, built using Python, FAISS, BM25, smolagents, and a large language model.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Sonuolikkara/AgenticAI" rel="noopener noreferrer"&gt;https://github.com/Sonuolikkara/AgenticAI&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RAG?
&lt;/h2&gt;

&lt;p&gt;RAG stands for &lt;strong&gt;Retrieval-Augmented Generation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea is to give an LLM relevant information from an external knowledge base before asking it to generate an answer.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question → LLM → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a RAG system works more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Question
      ↓
Retrieve relevant information
      ↓
Provide the information to the LLM
      ↓
Generate an answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to understand this process practically, so I built my own retrieval pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Hybrid Search?
&lt;/h2&gt;

&lt;p&gt;While working on the project, I came across an interesting problem.&lt;/p&gt;

&lt;p&gt;There are different ways to search for relevant information.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;semantic search&lt;/strong&gt; system can understand the meaning behind a query, while a &lt;strong&gt;keyword search&lt;/strong&gt; system is better when exact words or technical terms matter.&lt;/p&gt;

&lt;p&gt;So I decided to combine both.&lt;/p&gt;

&lt;p&gt;My project uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FAISS&lt;/strong&gt; → semantic/vector search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BM25&lt;/strong&gt; → keyword-based search&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, imagine the knowledge base contains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Users can authenticate using their registered credentials."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A semantic search can potentially understand the relationship between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How can I authenticate?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and the information above, even though the wording is different.&lt;/p&gt;

&lt;p&gt;On the other hand, keyword search can be useful when someone searches for a specific term such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAISS vector search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining both approaches gives the retrieval system two different ways of finding useful information.&lt;/p&gt;

&lt;h2&gt;
  
  
  How My System Works
&lt;/h2&gt;

&lt;p&gt;The overall flow of my project looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    User Question
                          ↓
                       CodeAgent
                          ↓
                  Knowledge Base
                     Retrieval
                    ↙         ↘
                FAISS         BM25
             Vector Search  Keyword Search
                    ↘         ↙
                   Retrieved
                    Context
                       ↓
                      LLM
                       ↓
                  Final Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent can use a custom knowledge-base search tool to retrieve information before generating the final response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Embeddings
&lt;/h2&gt;

&lt;p&gt;For semantic retrieval, I use the:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;all-MiniLM-L6-v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;sentence-transformer model.&lt;/p&gt;

&lt;p&gt;The documents are converted into embeddings, which are numerical representations of the text.&lt;/p&gt;

&lt;p&gt;These embeddings are then indexed using &lt;strong&gt;FAISS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This allows the system to search for chunks that are semantically similar to the user's question.&lt;/p&gt;

&lt;h2&gt;
  
  
  BM25 Keyword Search
&lt;/h2&gt;

&lt;p&gt;FAISS isn't the only retrieval method in my project.&lt;/p&gt;

&lt;p&gt;I also use &lt;strong&gt;BM25&lt;/strong&gt; for keyword-based retrieval.&lt;/p&gt;

&lt;p&gt;BM25 works differently from vector search. Instead of comparing the meaning of sentences through embeddings, it considers the occurrence and importance of words in the documents.&lt;/p&gt;

&lt;p&gt;This can be useful when the exact terminology in the user's question is important.&lt;/p&gt;

&lt;p&gt;So the two retrieval methods complement each other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAISS → "What information has a similar meaning?"

BM25 → "What information contains important matching words?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Document Chunking
&lt;/h2&gt;

&lt;p&gt;Another important part of the project is &lt;strong&gt;document chunking&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Large documents aren't always useful to send directly into a retrieval pipeline.&lt;/p&gt;

&lt;p&gt;So I split the documents into smaller pieces using a recursive character text splitter.&lt;/p&gt;

&lt;p&gt;The current configuration I experimented with is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chunk Size   : 500
Chunk Overlap: 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The overlap helps preserve context between neighboring chunks.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Document
─────────────────────────────────────
       Chunk 1
            ┌───────────────┐
            │               │
            └───────────────┘
                    Chunk 2
                    ┌───────────────┐
                    │               │
                    └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes retrieval more manageable and can help prevent useful information from being separated too aggressively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an AI Agent
&lt;/h2&gt;

&lt;p&gt;I also wanted to experiment with the idea of an &lt;strong&gt;agent&lt;/strong&gt;, rather than building only a fixed retrieval pipeline.&lt;/p&gt;

&lt;p&gt;For this, I used &lt;strong&gt;smolagents&lt;/strong&gt; and a &lt;code&gt;CodeAgent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The agent has access to a custom knowledge-base search tool.&lt;/p&gt;

&lt;p&gt;So instead of the application simply doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Question → Search → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the agent can use the search capability as a tool during the process of generating the response.&lt;/p&gt;

&lt;p&gt;For the language model, I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Qwen/Qwen2.5-72B-Instruct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Overall Pipeline
&lt;/h2&gt;

&lt;p&gt;Putting everything together, the process looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Documents
    ↓
Document Chunking
    ↓
Embeddings
    ↓
FAISS Index
    +
BM25 Index
    ↓
User Question
    ↓
Hybrid Retrieval
    ↓
Relevant Chunks
    ↓
Agent
    ↓
LLM
    ↓
Final Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component has a different responsibility.&lt;/p&gt;

&lt;p&gt;That's what made this project interesting for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Before building this project, I mainly thought about RAG as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Give documents to an LLM and ask questions about them."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After building it, I realized there is much more happening in between.&lt;/p&gt;

&lt;p&gt;There are several important steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preparing the documents&lt;/li&gt;
&lt;li&gt;Splitting them into chunks&lt;/li&gt;
&lt;li&gt;Creating embeddings&lt;/li&gt;
&lt;li&gt;Building a vector index&lt;/li&gt;
&lt;li&gt;Performing keyword search&lt;/li&gt;
&lt;li&gt;Combining retrieval results&lt;/li&gt;
&lt;li&gt;Selecting useful context&lt;/li&gt;
&lt;li&gt;Giving that context to an agent&lt;/li&gt;
&lt;li&gt;Generating the final response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The retrieval stage is especially important.&lt;/p&gt;

&lt;p&gt;If the system retrieves irrelevant information, the LLM doesn't magically know which information should have been retrieved.&lt;/p&gt;

&lt;p&gt;That made me understand why &lt;strong&gt;retrieval quality matters so much in RAG applications&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges I Faced
&lt;/h2&gt;

&lt;p&gt;Getting the different AI libraries and components to work together was not always easy.&lt;/p&gt;

&lt;p&gt;I faced compatibility and API-related issues while experimenting with the project.&lt;/p&gt;

&lt;p&gt;There were times when something didn't work as expected, and I had to go back and understand what that particular component was actually doing.&lt;/p&gt;

&lt;p&gt;Honestly, debugging these problems taught me more than simply running a working tutorial.&lt;/p&gt;

&lt;p&gt;It forced me to understand how the different parts of the system communicate with each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This project is still a learning project, and there are several things I want to experiment with next.&lt;/p&gt;

&lt;p&gt;Some of them are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a reranking model&lt;/li&gt;
&lt;li&gt;Evaluate retrieval quality properly&lt;/li&gt;
&lt;li&gt;Experiment with different chunking strategies&lt;/li&gt;
&lt;li&gt;Improve hallucination handling&lt;/li&gt;
&lt;li&gt;Compare different hybrid-search configurations&lt;/li&gt;
&lt;li&gt;Build a better user interface&lt;/li&gt;
&lt;li&gt;Improve the overall agent workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I especially want to compare pure vector search, pure keyword search, and hybrid search to see how much difference each approach makes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I started this project because I wanted to understand RAG better.&lt;/p&gt;

&lt;p&gt;Instead, I ended up learning about embeddings, vector databases, keyword search, document chunking, agents, and LLM-based applications.&lt;/p&gt;

&lt;p&gt;The project is far from perfect, but that's actually what makes it useful for me.&lt;/p&gt;

&lt;p&gt;I'm still learning, experimenting, and improving it.&lt;/p&gt;

&lt;p&gt;If you're also learning &lt;strong&gt;RAG, Agentic AI, or Generative AI&lt;/strong&gt;, you can check out the code and experiment with it yourself.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/Sonuolikkara/AgenticAI" rel="noopener noreferrer"&gt;https://github.com/Sonuolikkara/AgenticAI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of the projects I'm building while learning AI engineering, and I'll be sharing more of what I learn along the way.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>llm</category>
      <category>python</category>
      <category>rag</category>
    </item>
  </channel>
</rss>
