If you've worked on more than one Retrieval-Augmented Generation (RAG) project, you've probably run into the same annoying pattern: every project ends up with its own little vector store, its own embedding logic, its own duplicate code for chunking files, and its own inconsistent way of tracking what's actually been indexed.
I got tired of that, so I built a centralized vector database service that every project in my organization can plug into. One backend, one embedding model, one clean set of endpoints - and every project gets its own isolated, admin-controlled storage space.
Here's how it works.
The Problem
When you're running multiple RAG-powered projects at once, a few pain points show up fast:
Every team reinvents chunking and embedding logic
There's no single place to see what data lives where
Deleting or updating stored documents becomes a manual, error-prone process
Nobody has a clear picture of which files are indexed in which project
I wanted one system that solves this once, for everyone.
The Idea: One Service, Many Isolated Databases
Instead of giving each project its own standalone vector database, I built a shared service where:
Each project gets its own named storage directory
All directories live under one base storage path
An admin layer controls the full lifecycle - create, insert, update, delete, list - across every project's storage
Every project only ever talks to a small set of simple endpoints to embed and retrieve its own data
This means projects don't need to know anything about vector databases, embedding models, or similarity search internals. They just send text in and get relevant results back.
Architecture Overview
Here's the high-level flow:
In plain terms:
A project sends a file or text to the service
The service breaks it into clean text chunks
Those chunks get embedded and stored (upserted) into that project's own FAISS index
Later, the project sends a query, and the service returns the most similar stored chunks
An admin layer sits on top of all of this, with full control to create, update, or delete data across any project's storage
What's Under the Hood
Embedding model: a lightweight sentence-transformer model, chosen for speed and low resource usage
Vector engine: FAISS, for fast similarity search at scale
Backend framework: a modern Python web framework built for speed and simplicity
Storage layout: every project's database lives in its own folder, containing:
the FAISS index itself
a metadata/pickle file for the index
a tracked-files registry (so you always know what's indexed)
a source map (so you always know how many chunks came from each file)
Each project is fully sandboxed. Nothing bleeds across storage directories.
The Core Workflow
Every project follows the same simple lifecycle:
- Create a storage directory A new, isolated space is created for the project. Invalid or unsafe directory names are automatically rejected.
- Process a file into chunks Upload a document (PDF, TXT, DOCX, or Markdown) and it comes back as clean, ready-to-embed text chunks. This step doesn't store anything yet - it just prepares the data.
- Upsert the chunks The chunks get embedded and stored. If the project's index doesn't exist yet, it's created automatically. If it does exist, new vectors are simply appended. Duplicate sources are automatically prevented.
- Search A query comes in, gets embedded the same way, and the service returns the top-k most similar chunks - along with which source file they came from. A similarity score threshold filters out weak matches.
- Manage the data At any point, an admin can: List every database in the system, with file counts and tracked sources Delete a specific file's vectors from a project's index Have all of this triggered externally through a single webhook event, so other systems can kick off any step of this pipeline programmatically
Why This Matters
The real win here isn't the vector search itself - FAISS and sentence-transformers are well-understood tools. The win is centralization with isolation:
One codebase to maintain instead of N duplicated ones
One admin view into every project's stored data
Every project gets embedding and retrieval "for free," without owning any of the infrastructure
Adding a brand-new project to RAG-powered search takes minutes: create a directory, start upserting
It turns "set up a vector database" from an infrastructure task into a two-endpoint integration for whoever's building the next project.
What's Next
A few directions I'm considering for this pipeline:
Authentication and per-project access scoping
Async batch processing for very large files
Pluggable embedding models per project (not just one global model)
A lightweight admin dashboard on top of the existing list/delete endpoints
If you're building multiple RAG projects and keep rebuilding the same vector storage logic every time, this pattern - one shared service, isolated storage per project, centralized admin control - is worth stealing.
Have you built something similar, or run into different tradeoffs with multi-project RAG infrastructure? I'd love to hear how you approached it.

Top comments (0)