Skip to main content
Completed
  • AI and RAG
  • Backend
  • Full-Stack

SmartShop RAG Product Advisor

A personal Retrieval-Augmented Generation project that answers shopper questions from a store’s own data: recommendations, product and policy Q&A, comparisons and cached review summaries. The catalogue lives in SQLite and is indexed in Qdrant with BGE-M3; retrieval runs dense and sparse together, fuses the two with reciprocal rank fusion and reranks with a bge-reranker-v2-m3 cross-encoder. Generation runs on Qwen2.5 through Ollama, so the whole system works offline with no API cost, and answers come back in the language they were asked in — Arabic or English.

role
Personal project
period
July 2026
status
Completed

01Overview

SmartShop is a personal project about a narrow question: what actually improves retrieval quality when the corpus is a product catalogue rather than prose?

It ended up as a complete shopping assistant. It recommends products, answers questions about a specific item, compares two of them, answers return, shipping and warranty questions out of policy PDFs, and summarises what reviewers said — each answer grounded in the store’s own records and citing them.

Everything runs locally. The catalogue sits in SQLite, the index in an embedded Qdrant, the embeddings and reranker on CPU, and the language model in Ollama, so there is no API key anywhere in the system and no per-query cost.

02Context

Recommendation systems are usually judged by anecdote: a few queries are tried, the results look reasonable, and the system is declared to work.

This project took the opposite approach — the golden set and the evaluation harness were built alongside the retrieval, so a change could be shown to help rather than assumed to. The same discipline shows up in the planning: thirteen documents — retrieval architecture, model selection, chunking, filter schema, grounding strategy — were written before the first sprint.

03Problem

Dense retrieval alone misses exact matches; sparse retrieval alone misses intent. Neither is sufficient for product search, and choosing between them is the wrong question.

  • Exact tokens such as model numbers must be matched exactly, not approximately.
  • Queries expressing intent rather than keywords must still return sensible products.
  • Questions arrive in Arabic or English, and the answer has to come back in the same language.
  • Structured attributes — category, price, availability — need to constrain results, not just influence them.
  • Everything runs on one machine with no GPU budget and no paid API, which caps the model size and rules out hosted embeddings.
  • Retrieval changes need to be measurable rather than judged by inspection.

04My Role

My Role

This is my own project, built end to end: the planning documents, the ingestion of the catalogue and the policy PDFs, the hybrid retrieval and reranking pipeline, filter extraction, the answering paths for recommendation, product Q&A, comparison, policy Q&A and review summaries, session personalization, the FastAPI service, the Streamlit and single-page front ends, the golden set and evaluation harness, and the test suite.

05Responsibilities

Retrieval

  • Hybrid dense and sparse retrieval over Qdrant, fused with reciprocal rank fusion.
  • BGE-M3 embeddings, computed on CPU.
  • Cross-encoder reranking with bge-reranker-v2-m3.
  • Filter extraction: turning a sentence into category, price, stock and rating constraints.
  • Arabic and English queries, answered in the language they arrived in.

Answering

  • Recommendation with reasoning and cited product records.
  • Product Q&A and side-by-side comparison.
  • Policy Q&A over chunked return, shipping, warranty and FAQ documents.
  • Cached review summaries, regenerated on demand from an admin re-index.
  • Session history that carries preferences forward while still surfacing alternatives.

Platform and evaluation

  • A FastAPI service, a Streamlit chat UI and a single-page web front end served from the same app.
  • Ingestion from CSV and PDF into SQLite and the vector index.
  • A golden set and an evaluation harness for retrieval and filter extraction.
  • A deterministic pytest suite that runs without the model or the index.

06Technical Approach

Keep the catalogue in a relational store as the source of truth, index it for vector search, retrieve with both strategies at once, then spend the remaining effort on reranking and measurement.

  1. 01Ingest the catalogue and the policy documents into SQLite, and index them in Qdrant with BGE-M3.
  2. 02Read the question first: resolve its intent and turn its wording into structured filters before searching anything.
  3. 03Retrieve candidates densely and sparsely at once, and fuse the two rankings, so exact-token and intent-style queries are both served.
  4. 04Rerank the fused candidates with a cross-encoder, because first-stage retrieval optimises for recall and reranking is where precision is recovered.
  5. 05Answer from the retrieved records only, in the language of the question, citing the products or policy passages used.
  6. 06Assess changes against the golden set rather than by inspecting a handful of queries.

07Architecture

The catalogue and the policy PDFs are ingested into SQLite and embedded with BGE-M3 into an embedded Qdrant index holding both dense and sparse vectors. A question is first resolved into an intent and a set of structured filters; hybrid retrieval then runs both strategies and fuses them with reciprocal rank fusion, a cross-encoder reranks what comes back, and Qwen2.5 answers from those records alone, in the language of the question. Session history feeds preferences back into retrieval, and the golden set measures the pipeline offline.

IndexAnswerMeasureCatalogue & policiesCSV · PDFSQLiteSource of truthBGE-M3 indexQdrant · dense + sparseShopper questionArabic or EnglishIntent & filtersCategory · price · stockHybrid retrievalRRF fusionRerankbge-reranker-v2-m3Grounded answerQwen2.5 · citedSession historySticky preferencesGolden setRetrieval · extraction
  1. 01Ingest: the product catalogue and the policy PDFs are loaded into SQLite as the source of truth.
  2. 02Index: records and policy chunks are embedded with BGE-M3 and stored in Qdrant, dense and sparse.
  3. 03Question: a shopper asks in Arabic or English.
  4. 04Filters: the question is resolved into an intent and structured constraints — category, price, availability.
  5. 05Hybrid retrieval: dense and sparse candidates are fused with reciprocal rank fusion.
  6. 06Reranking: a bge-reranker-v2-m3 cross-encoder reorders the fused set for precision.
  7. 07Answer: Qwen2.5 answers from the retrieved records only, citing them, in the language of the question.
  8. 08Measurement: the golden set scores retrieval and filter extraction across changes.

08Features

  • Hybrid retrieval

    Dense and sparse candidates fused with reciprocal rank fusion, so exact tokens and intent both work.

  • Cross-encoder reranking

    bge-reranker-v2-m3 recovers precision after a recall-oriented first pass.

  • Filters read from the sentence

    “A phone case under fifteen dollars” becomes a category, a price ceiling and a stock constraint.

  • Grounded answers with sources

    Recommendations, comparisons, policy answers and review summaries all cite the records they came from.

  • Arabic and English

    The answer comes back in the language the question was asked in.

  • Runs entirely offline

    Ollama, an embedded Qdrant and CPU embeddings — no API key, no per-query cost.

  • A golden set, not impressions

    Retrieval and filter extraction are scored against a fixed question set before a change is kept.

09Challenges

  • Semantic search returns plausible-looking products that are the wrong model or the wrong size, because embeddings blur exactly the tokens that matter most.

    Pairing sparse retrieval with dense retrieval keeps exact tokens addressable while intent-style queries still work, and the cross-encoder settles the order afterwards.

  • The filter extractor was the weakest link: it would settle on the wrong category, or silently drop a constraint the shopper had actually stated, and a good retriever cannot rescue a query that has already been narrowed wrongly.

    Constraining the category to the ones that exist and recovering dropped filters explicitly fixed more retrieval failures than any change to the search itself.

  • A 7B model, an embedding model and a reranker all resident at once is more than a laptop comfortably holds.

    Embeddings and reranking were kept on CPU, a smaller model was wired in as a fast fallback, and review summaries were cached rather than regenerated per question.

10Decisions and Tradeoffs

DecisionAlternative consideredWhy
Keep SQLite as the primary data source with Qdrant as the vector index.Treating the vector store as the system of record.A relational store keeps structured attributes queryable and authoritative; the vector index stays a derived artefact that can be rebuilt. The cost is keeping the two in step.
Run the language model locally through Ollama.Calling a hosted frontier model per query.Local inference costs nothing per query and keeps the catalogue on the machine, which is what made it reasonable to run the pipeline hundreds of times while tuning it. The price is answer quality: a 7B model writes noticeably plainer prose than a hosted one, and the design leans on retrieval being right rather than on the model covering for it.
Add a cross-encoder reranking stage.Returning the fused first-stage results directly.Reranking costs time on every query and keeps another model in memory, but first-stage retrieval is tuned for recall — without a second stage, precision stays capped.
Narrow the languages to Arabic and English.Keeping the third language the pipeline originally carried.A third language doubled the surface to check on every answering path while adding nothing to the retrieval question the project was actually about. It was dropped deliberately, not for lack of support in the models.

11Result

A finished local assistant: it recommends, compares, answers questions about products and about return, shipping and warranty policy, and summarises reviews — grounded in a sample catalogue of ninety products, their reviews and four policy documents, with every answer citing the records behind it.

It runs on one machine with no API key and no network, and it is measured rather than demonstrated: a golden set scores retrieval and filter extraction, and the deterministic test suite runs without the model or the index. It is a personal project, not a deployed store system.

12Lessons Learned

  1. 01Hybrid retrieval is not a hedge. Dense and sparse strategies fail on different queries, which is exactly why running both is better than picking one.
  2. 02Reranking is where precision is won, once first-stage retrieval has done its job on recall.
  3. 03The step before retrieval decided more outcomes than retrieval did: if the question is turned into the wrong filters, no amount of search quality recovers it.
  4. 04Building the golden set first changes how you work on retrieval — it turns opinions into measurements.

13Technology Stack

Language

  • Python

AI and retrieval

  • Ollama
  • Qwen2.5 (7B / 3B)
  • BGE-M3 embeddings
  • bge-reranker-v2-m3 cross-encoder
  • Hybrid dense and sparse retrieval (RRF)
  • Filter extraction from natural language
  • Arabic and English answers

Data

  • SQLite
  • Qdrant

Backend

  • FastAPI
  • REST API
  • Session personalization

Frontend

  • Streamlit
  • Single-page web UI

Practices

  • pytest
  • Ruff
  • mypy
  • Golden-set evaluation
  • Sprint planning documents

14Screenshots

  • The SmartShop AI Advisor start screen: a sidebar with recent chats, data sources and admin tools beside six suggested analyses such as gaming laptops, return policies and price trends, above a free-text product query box.

    The entry point: suggested analyses stand in for the empty state, and any of them can be typed as a free-form question instead.

  • An exported conversation in which a request for a phone case under fifteen dollars returns two ranked recommendations with reasoning, the applied category and price filters, product cards showing price, rating and stock, and the source product identifiers.

    An exported answer. The filters the query resolved to are shown alongside the results, and every recommendation cites the product record it came from.

Let’s discuss your project

Have a software, AI, RAG, or web application project in mind? Let’s discuss what you need and determine the right technical approach.