Building SmartDoc with RAG and Qdrant

SmartDoc is an advanced document search engine leveraging Retrieval-Augmented Generation (RAG) and the Qdrant vector database. This guide covers setting up the environment, backend development, frontend development, and testing.

Combining RAG and Vector Databases

When used together, RAG and vector databases complement each other to enhance search and information retrieval tasks:

  1. Vector Storage and Retrieval: The vector database stores vector embeddings of documents. When a query is made, the database performs a similarity search to retrieve the most relevant documents based on their vector representations.

  2. Contextual Generation: Once relevant documents are retrieved, the RAG model uses these documents to generate a response. This ensures that the response is not only based on the retrieved documents but is also tailored to the query context.

Prerequisites

Before starting, ensure you have:

  • Python (preferably 3.8+)

  • Node.js and npm

  • Docker for running Qdrant

Step 1: Setting Up the Environment

  1. Create and Activate a Python Virtual Environment

     python -m venv env
     source env/bin/activate  # On Windows use `env\Scripts\activate`
    
  2. Install Backend Dependencies

    Install the required Python packages:

     pip install fastapi uvicorn haystack qdrant-client sentence-transformers
    
  3. Create a React App

    Create a new React application for the frontend:

     npx create-react-app document-search
     cd document-search
    

Step 2: Backend Development

  1. Create the FastAPI Application

    Create a file named main.py in your project directory. This will handle the backend API:

     from fastapi import FastAPI, HTTPException
     from pydantic import BaseModel
     from sentence_transformers import SentenceTransformer
     from haystack.pipelines import GenerativeQAPipeline
     from haystack.nodes import DenseRetriever, FARMReader
     from qdrant_client import QdrantClient
     from qdrant_client.http.models import PointStruct
    
     app = FastAPI()
    
     # Initialize Qdrant client
     qdrant_client = QdrantClient(url='http://localhost:6333')
    
     # Load Sentence Transformer model
     model = SentenceTransformer('all-MiniLM-L6-v2')
    
     # Define Haystack components
     retriever = DenseRetriever(document_store=qdrant_client)
     reader = FARMReader(model_name_or_path="deepset/roberta-base-squad2")
     pipe = GenerativeQAPipeline(reader=reader, retriever=retriever)
    
     class QueryModel(BaseModel):
         query: str
    
     @app.post("/search/")
     async def search(query_model: QueryModel):
         query = query_model.query
         # Perform search using RAG pipeline
         result = pipe.run(query=query, params={"Retriever": {"top_k": 5}, "Reader": {"top_k": 1}})
         return {"results": result}
    
     if __name__ == "__main__":
         import uvicorn
         uvicorn.run(app, host="0.0.0.0", port=8000)
    

    Explanation:

    • FastAPI: Framework for creating the backend API.

    • SentenceTransformer: Model to convert text into vectors.

    • DenseRetriever and FARMReader: Components of Haystack used for retrieval and reading.

    • GenerativeQAPipeline: Combines retrieval and generation for enhanced responses.

  2. Vectorize and Store Documents

    Create a script named index_documents.py:

     from sentence_transformers import SentenceTransformer
     from qdrant_client import QdrantClient
    
     model = SentenceTransformer('all-MiniLM-L6-v2')
     qdrant_client = QdrantClient(url='http://localhost:6333')
    
     def vectorize_document(text: str):
         return model.encode(text).tolist()
    
     def store_document(doc_id: str, text: str):
         vector = vectorize_document(text)
         qdrant_client.upsert(collection_name='documents', points=[{
             'id': doc_id,
             'vector': vector,
             'payload': {'text': text}
         }])
    
     # Example usage
     store_document("1", "Example document text to index.")
    

    Explanation:

    • vectorize_document: Converts text to a vector representation.

    • store_document: Stores the vectorized document in Qdrant.


Step 3: Frontend Development

  1. Create the Search Interface

    Update src/App.js:

     import React, { useState } from 'react';
    
     function App() {
       const [query, setQuery] = useState('');
       const [results, setResults] = useState([]);
    
       const handleSearch = async () => {
         const response = await fetch('http://localhost:8000/search/', {
           method: 'POST',
           headers: {
             'Content-Type': 'application/json',
           },
           body: JSON.stringify({ query }),
         });
         const data = await response.json();
         setResults(data.results);
       };
    
       return (
         <div>
           <h1>SmartDoc: AI-Powered Contextual Document Search</h1>
           <input
             type="text"
             value={query}
             onChange={(e) => setQuery(e.target.value)}
             placeholder="Enter your query"
           />
           <button onClick={handleSearch}>Search</button>
           <div>
             <h2>Results</h2>
             <pre>{JSON.stringify(results, null, 2)}</pre>
           </div>
         </div>
       );
     }
    
     export default App;
    

    Explanation:

    • handleSearch: Sends a POST request to the FastAPI backend with the user query.

    • Results Display: Shows the search results returned from the backend.

  2. Run the React App

     npm start
    

    Explanation:

    • npm start: Launches the React development server.

Step 4: Running and Testing

  1. Start Qdrant

    Use Docker to run Qdrant:

     docker run -p 6333:6333 qdrant/qdrant
    

    Explanation:

    • docker run: Runs Qdrant as a Docker container, exposing it on port 6333.
  2. Run the FastAPI Server

     uvicorn main:app --reload
    

    Explanation:

    • uvicorn: Runs the FastAPI server with auto-reload enabled.
  3. Start the React Frontend

     npm start
    

    Explanation:

    • npm start: Launches the React application.
  4. Test Your Application

    Open your browser and go to http://localhost:3000. Enter a query and test the functionality.


Conclusion

You’ve now built SmartDoc, an advanced document search engine utilizing RAG and Qdrant. This application demonstrates how modern AI techniques can be used to enhance document retrieval. Here’s a summary of what you’ve accomplished:

  • Backend: Implemented using FastAPI, integrating RAG for contextual document retrieval.

  • Vector Storage: Managed with Qdrant, which stores and retrieves vectorized document data.

  • Frontend: Created with React to provide an intuitive user interface.

Happy coding! If you need further assistance, don’t hesitate to ask!


0
Subscribe to my newsletter

Read articles from Oduor Jacob Muganda directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Oduor Jacob Muganda
Oduor Jacob Muganda

👨‍💻 Experienced Software Developer & Data Scientist 👨‍🔬 Passionate about leveraging cutting-edge technology to solve complex problems and drive innovation. With a strong background in both programming and data science, I specialize in building robust software solutions and extracting actionable insights from data. 🖥️ As a Software Developer: Proficient in multiple programming languages including Python, JavaScript, Java, and C++. Skilled in full-stack web development, with expertise in frontend (HTML/CSS/JavaScript) and backend (Node.js, Django, Flask). Experienced in developing scalable web applications, e-commerce platforms, and social media platforms. 📊 As a Machine Learning Engineer: Expertise in data analysis, machine learning, and predictive modeling using Python libraries such as NumPy, Pandas, Scikit-learn, TensorFlow, and PyTorch. Skilled in data visualization and storytelling with tools like Matplotlib, Seaborn, and Plotly. Proficient in handling big data with technologies like Apache Spark and Hadoop. 🚀 I thrive on tackling challenging problems and transforming data into actionable insights that drive business growth and innovation. Whether it's developing a user-friendly web application or building predictive models to optimize business processes, I'm dedicated to delivering impactful solutions that exceed expectations. Let's connect and collaborate on exciting projects that push the boundaries of technology and data science! 🌟