Quickstart
From an empty directory to a searchable corpus.
What you need
| Python | 3.10 or newer |
| An embedder | Anything with an OpenAI-shaped /v1/embeddings endpoint |
| A vector store | SQLite (the default — a local file, nothing to run), Qdrant or Postgres with pgvector |
The embedder is the one thing you need. Ollama is the easiest one to start with, and it runs on your machine:
ollama serve
ollama pull bge-largeIf you would rather not run a server at all, the local extra runs a
small ONNX embedding model in your own process:
pip install "atrium-rag[local]"The vector store does not need a server either. VECTOR_DB=sqlite
keeps the corpus in a SQLite file next to your project; switch to
Qdrant or pgvector when the corpus outgrows a file.
Install
pip install atrium-ragOptional extras, when you need them:
pip install "atrium-rag[ocr]" # Tesseract or RapidOCR
pip install "atrium-rag[rerank]" # cross-encoder reranking
pip install "atrium-rag[ocr,rerank]" # several at onceOCR with OCR_PROVIDER=tesseract also needs the Tesseract binary on
PATH — brew install tesseract, apt install tesseract-ocr. The
rapidocr provider is pip-only and needs no binary.
Configure
atrium initThe wizard writes a .env. It asks five questions, and every answer is
a choice you pick from a list with the arrow keys:
- The vector store — SQLite, Qdrant or pgvector. SQLite needs nothing; the other two ask for a host and a port.
- The embedding provider — a local server, OpenAI, another
OpenAI-compatible server, or the in-process one from the
localextra. - The model — picked from the list the endpoint actually serves, with its dimension beside it. The models that are not embedding models are named separately, so they cannot be chosen by accident.
- OCR — off, or a provider and a language.
- Reranking — off, or a provider and a model.
- Vision — off, or a model.
Then it shows you what it chose, lets you change any value, verifies the result with a real embedding call, and prints the next command.
To write the file yourself instead:
cp https://raw.githubusercontent.com/ItsMeYash777/atrium/main/.env.example .envThe defaults are laptop-correct — localhost, not a Docker hostname —
so a plain .env works on a machine and the container's .env.docker
is what compose uses.
Check the result:
atrium validate # is the file well-formed and consistent with the install?
atrium doctor # can it reach the embedder and the vector store?atrium doctor exits non-zero when something is actually broken, so it
works as a deploy gate.
Run it
atrium serveThe API is on http://localhost:8000 and the OpenAPI schema is at
/docs.
Ingest
From the shell:
atrium ingest ./documents/It walks directories, parses each file, chunks it, embeds it and upserts the chunks. The output is a table of what was ingested.
Over HTTP:
curl -X POST http://localhost:8000/ingest \
-F "files=@./report.pdf" \
-F "files=@./notes.docx"The response comes back after the document is parsed, embedded and stored:
{
"jobs": [
{"job_id": "…", "doc_id": "…", "filename": "report.pdf"}
]
}For a large document you may not want to hold the connection open.
POST /jobs queues it and answers immediately with a job_id; a
worker picks it up:
python -m atrium.workerPoll GET /jobs/{job_id} for pending, running, complete or
failed.
Search
From the shell:
atrium search "What is the retention policy?"Over HTTP:
curl -X POST http://localhost:8000/search \
-H 'Content-Type: application/json' \
-d '{"query": "What is the retention policy?", "top_k": 8}'Each result carries the page it came from, the heading path, the element type and the strategy that produced it:
{
"rank": 1,
"score": 0.781,
"doc_id": "policy",
"text": "Records are retained for 24 months…",
"page_number": 14,
"section_path": ["Retention", "Data lifecycle"],
"element_type": "paragraph",
"chunking_strategy": "structure_aware",
"is_parent": false,
"parent_id": null
}Look before you store
POST /preview parses and chunks a document and hands back the chunks
without embedding or storing anything — the fastest way to find out
whether the chunking is right for your corpus before you pay for the
embeddings:
curl -X POST http://localhost:8000/preview \
-F "file=@./report.pdf" \
-F "chunking_mode=precise"Re-chunk later
If the strategy was wrong, re-chunk the document with a different one. The previous chunks are replaced, not mixed in:
atrium reingest ./documents/policy.md --doc-id policy --chunking-mode context_richAuth
Set API_KEY and every route except /health and /visualize needs a
bearer token:
API_KEY=… atrium serve
curl -H "Authorization: Bearer $API_KEY" -X POST http://localhost:8000/search -d '{"query":"…"}'With Docker
docker compose --profile qdrant up -dThat starts the API, a worker and Qdrant, with a shared volume for the
job queue. Scale the workers with
docker compose --profile qdrant up -d --scale worker=3.
Atrium Cloud
Don't want to run it yourself? Atrium Cloud is coming.
It is not here yet — the list is what there is until it is. The library is free, MIT licensed, and yours either way.