Open-source RAG platform for companies
Your documents become an assistant that answers and shows where the answer came from. Documents, database, vector index and encryption keys stay on your infrastructure. You choose the models, and changing provider is a config file.
Our live demo answers, searches and stores files on Scaleway, a French cloud provider. Encryption keys stay there too. See what runs where
01 · How ingest works
Upload a file. Ragen does the rest in the background.
Seven steps turn any document, even a 400-page PDF, into chunks that know where they come from. It runs asynchronously, so nobody waits for indexing.
-
Upload
The file lands in storage. Any size, any team.
-
Parse
A queued job reads text, headings and tables.
-
Chunk
Split into chunks, with a splitter per file type.
-
Summarize
A summary of the whole file, stored as its own chunk.
-
Add context
Title, section and summary go in front of every chunk.
-
Hybrid embed
Embedded twice: dense for meaning, sparse for exact words.
-
Index
Upserted to Qdrant, ready for the first question.
- Asynchronous. Each file is a BullMQ or Temporal.io job, the app stays responsive.
- Parsing by Docling. Headings and tables survive the trip.
- Stays on your servers. Files, database and index are yours.
Technical details
A file lands in storage and a BullMQ job on Redis, or a Temporal.io workflow, takes over: parse, chunk with a splitter chosen for the file type, generate a summary of the whole document and prepend it as its own chunk, then embed densely and sparsely and upsert into the organization's Qdrant collection. Before the dense embedding, every chunk is given a short prefix: the document's title, the section it sits under and the first sentence of the summary. A passage that says only "the notice period is 30 days" can then be found by a question that names the contract. The prefix costs no model call and is stored beside the chunk, never inside it, so the model and the citation still see the text as written. It runs asynchronously, so a 400-page PDF does not block anything.
02 · How answering works
Asked once, searched twice, answered with sources.
Ragen rewrites the question, searches with two phrasings at once, keeps the best passages with their neighbours, and only then asks the model to answer and cite.
- 01
Understand
How many leave days can I carry over?And part-time staff?↓ STANDALONE
How many leave days can part-time staff carry over?+1 VARIANT
Carry-over rules for part-time employees' annual leaveThe conversation history turns a follow-up into a full question. A second phrasing is generated alongside it.
- 02
Search
2× HYBRID SEARCH
Q1 dense sparseQ2 dense sparseRRF FUSION
DEDUPE
chunk #42chunk #42chunk #17Meaning and exact words, both phrasings, in parallel. Qdrant merges the lists server-side.
- 03
Select
RERANK
optionalchunk #173 → 1chunk #421 → 2chunk #082 → 3±1 NEIGHBOURS
#16 · before#17 · the hit#18 · afterIf reranking is switched on, a reranker re-scores the shortlist. Neighbouring chunks from the same file are joined, overlap trimmed.
- 04
Answer
EXAMPLE
Part-time staff carry over unused leave in proportion to their hours 1. Carried-over days have their own deadline 2.
- 1Employee handbook › 4.2 Part-time
- 2Leave policy › Carry-over
The model gets only the selected passages and is prompted to cite them. Every claim links back to its file.
Technical details
A question is first rewritten into a standalone one using the conversation so far, then a second phrasing is generated. Both run as hybrid searches in parallel. Qdrant fuses dense and sparse results server-side with RRF and the union is deduplicated. When reranking is switched on, the candidates are re-scored by a reranker: Scaleway's by default, or Cohere's cross-encoder. Each chunk that makes the cut is then read together with the chunks on either side of it in the same file, joined into one passage with the overlap trimmed, so an answer that starts at the end of one chunk keeps its first half. The model sees the result with citation prompting on top.
Hybrid search is not a toggle. It is part of the schema collections are created with, so it is always on. Reranking is opt-in: it needs a feature flag and a provider's credentials, and a default install does not rerank. Reading neighbours is on by default, capped at three times the usual context, and can be turned off per organization. Section selection is an opt-in alternative to the reranker: a model is shown the question and the candidates and names the passages worth reading, in one call per turn. Every stage degrades rather than fails – a reranker or selection error falls back to the raw vector order, an expansion error falls back to a single query.
03 · Permissions at retrieval
People only get answers from files they can open.
Every chunk carries an accessible_by filter applied at query time, from the permissions recorded when the document was indexed. A document a user cannot open will not enter an answer, a citation, or the context sent to the model.
Per file and folder, enforced at retrieval, not on display
WHO ASKS
role: finance
QUERY-TIME FILTER
WHAT THE CHUNK REACHES
WHO ASKS
role: sales
QUERY-TIME FILTER
WHAT THE CHUNK REACHES
The filter runs inside the search itself. A chunk the user may not see is never retrieved, so it cannot leak through a summary or a quote. Permissions are read when a document is indexed, so a share revoked later takes effect after the next re-index.
04 · Multi-tenancy
Many companies, one installation, zero shared data.
Each organization gets its own vector collection and roles. A guard in the data layer flags a query on a tenant-scoped table that misses its organization filter.
ONE RAGEN INSTALLATION · YOUR SERVER
Company A
collection_a
Company B
collection_b
Company C
collection_c
- 1 vector collection per organization
- 2 separate role hierarchies
- 1 installation serves many clients
- 0 per-seat fees
How it compares
| Criterion | Hosted "chat with your docs" | Your own LangChain stack | Ragen |
|---|---|---|---|
| Where your documents live | Hosted "chat with your docs" Vendor's cloud | Your own LangChain stack Yours | Ragen Yours |
| Choice of model | Hosted "chat with your docs" Vendor's shortlist | Your own LangChain stack Anything | Ragen Any provider, or any OpenAI-compatible endpoint |
| Access control | Hosted "chat with your docs" Usually per workspace | Your own LangChain stack Whatever you build | Ragen Per file and folder, enforced at retrieval |
| Multi-tenant | Hosted "chat with your docs" Per seat, per workspace | Your own LangChain stack Whatever you build | Ragen Built in, org-scoped data and index |
| Retrieval quality | Hosted "chat with your docs" Opaque | Your own LangChain stack Yours to tune, and to debug | Ragen Hybrid, rerank and multi-query, a recorded decision per change |
| Time to a working answer | Hosted "chat with your docs" Minutes | Your own LangChain stack Weeks | Ragen Minutes, one command plus your own model keys |
| Cost shape | Hosted "chat with your docs" Per seat, forever | Your own LangChain stack Your engineers' time | Ragen Your infrastructure plus model spend |
| When it breaks | Hosted "chat with your docs" Support ticket | Your own LangChain stack You | Ragen You, with the source and the recorded decisions |
If your requirements are genuinely unusual, building it yourself is a legitimate answer. Ragen is the better trade when you want those decisions already made, and documented, rather than made by you.
05 · Requirements
Runs on a modest server. No GPU, unless you want one.
Chat, embeddings and reranking are calls to the providers you name in your configuration, so the machine running Ragen does no LLM or embedding inference of its own. Document parsing runs small CPU models locally.
Where the memory actually goes
idle, per service
- Docling 1.4–1.7 GiB
- Presidio analyzer (optional, PII masking) 959 MB
- Postgres 93 MB
- Presidio anonymizer (optional, PII masking) 55 MB
- Qdrant 43 MB
- Redis 11 MB
| Hardware and software | EVALUATION | PRODUCTION |
|---|---|---|
| CPU | 4 cores | 8 cores |
| RAM | 8 GB | 16 GB |
| Disk | 25 GB | 100 GB SSD |
| Docker | Compose v2 | Compose v2 |
| Node.js | ^24.15.0 || ≥26 | ^24.15.0 || ≥26 |
Guidance, not enforced limits. An API key for an LLM provider is required.
~1.6–1.9 GB
docker compose up
~2.6–2.9 GB
everything switched on
Technical details
Point it at a hosted provider and a laptop is enough. A GPU only enters the picture if you decide to serve models yourself, say with vLLM or Ollama plugged in as a route, which is supported and is a separate box.
RAM is what is available to Docker. Disk grows with your documents. These are recommendations: nothing in the stack enforces them. The Ragen applications run on the host and need Node.js ^24.15.0 or ≥26.0.0, which the installer checks.
Measured on an idle stack, backing services only. A default docker compose up idles at about 1.6–1.9 GB. Presidio is not part of it: both containers sit behind the pii profile and add roughly 1 GB only if you turn PII masking on. DOCUMENT_PARSER=legacy skips Docling and gives back its memory, but your PDFs are then parsed by an external model, so they leave your network. Qdrant is the line that moves as you add documents, because the figure above is a near-empty index. Size that one against your own corpus rather than against this chart. The five Ragen applications run on top of all this and are not included. In development they are the larger half.
Stand it up yourself
One command, npx create-ragen-app, sets up the lot: it clones the repository, generates secrets, starts Postgres, Qdrant, Redis and Docling, and prepares the database. Then start the web app, API and worker, upload a document and ask it something.