Architecture

RAGatm Open is a modular web application: a user interface, an API, workers, a PostgreSQL database with pgvector, and an inference gateway that is the only path to the local models.

How a question travels

Every answer follows the same path, observable in the published code: import, extraction, chunking, embeddings, hybrid retrieval, reranking, generation, citations.

How a question travels through RAGatm OpenFlow diagram: from document import to the cited answer, with the local models called through the gateway.Application (RAGatm Open)Local models (AI Gateway Open → Ollama / TEI)How a question travels through RAGatm Open01Userbrowser, FR/EN02Document spacepermissions, isolation, MFA03Importsignature-based validation04Extractiontext, tables, OCR if built05Chunkingchunks ≤ 1,200 characters06Embeddingsgranite 768 d, via gateway07Hybrid retrievalfull text + vectors, RRF08Rerankingcross-encoder, lexical fallback09Generationlocal model, streamed10Cited answertyped sources, SSE
Text alternative for the diagram
  1. User — browser, FR/EN
  2. Document space — permissions, isolation, MFA
  3. Import — signature-based validation
  4. Extraction — text, tables, OCR if built
  5. Chunking — chunks ≤ 1,200 characters
  6. Embeddings — granite 768 d, via gateway (local model via the gateway)
  7. Hybrid retrieval — full text + vectors, RRF
  8. Reranking — cross-encoder, lexical fallback (local model via the gateway)
  9. Generation — local model, streamed (local model via the gateway)
  10. Cited answer — typed sources, SSE
  • Files are validated by their binary signature, never by extension alone.
  • Chunks are capped at 1,200 characters: the gateway rejects longer texts at embedding time.
  • Retrieval combines PostgreSQL full-text search and pgvector cosine similarity through RRF fusion, then a cross-encoder reranks the 20 best passages; if the reranker is unavailable, the RRF order is kept.
  • Generation is streamed: NDJSON between the gateway and the backend, SSE to the browser, with typed sources (document, page or slide, excerpt).
  • When a dependency is missing, the API returns an explicit error: never a fabricated answer.

Components and responsibilities

Three repositories, nine services in the Compact profile.

Frontend — Next.js 15 / React 19

FR/EN interface; same-origin proxy to the API (the browser only talks to the frontend).

Backend — Django 5.2 + Django REST Framework

API, authentication with mandatory TOTP second factor, workspace roles (owner, admin, member, viewer), per-space isolation, ingestion, retrieval, SSE chat, audit log.

Workers — Celery 5.6

Asynchronous ingestion, reindexing, maintenance, analytics; beat scheduler for periodic tasks.

PostgreSQL 16 + pgvector

Data, 768-dimension vectors (HNSW index), full-text search, embedding pipeline identity; source of truth for backups.

Redis 7.2

Task queue, results, cache. Never a source of truth.

AI Gateway Open — FastAPI

Sole inference path: generation, embeddings, reranking; strict model registry (digests), typed errors, non-inferential health probes, concurrency limits.

Ollama

Runs the generation and embedding models locally; reachable only from the gateway.

Text Embeddings Inference (TEI)

Serves the reranking cross-encoder on CPU, inside the gateway’s network namespace.

AI Gateway Pool Open — optional

HTTP router in front of one or more gateways; no inference; absent from the Compact profile.

Compact profile topology

One machine, nine Docker Compose services, five networks of which four are internal.

Compact profile topology (9 services)The nine Docker Compose services and their internal networks; a single port published on loopback; Ollama reachable only by the gateway.Linux host — Docker Composedata (internal) · app (internal) · ai (internal)inference (internal)Browser → only published port: 127.0.0.1:18080frontendNext.jsbackendDjango / APIworkerCelerybeatCelery beatdbPostgreSQL + pgvectorredisRedis 7.2ai-gatewayAI Gateway Openollamageneration, embeddingsrerankerTEI, cross-encoderInternet: only while provisioning models
Text alternative for the diagram
  • The browser reaches only the frontend, published on 127.0.0.1:18080 (edge network).
  • frontend → backend (app network); backend, worker, beat → db and redis (data network).
  • backend and worker → ai-gateway (ai network); ai-gateway → ollama and reranker (inference network). Ollama is reachable only by the gateway.
  • No Internet egress in nominal operation; a temporary network is used only to download models.
  • A single published port, on loopback (127.0.0.1:18080): any other access goes through a TLS reverse proxy you add.
  • The app, data, ai and inference networks are internal: no Internet egress in nominal operation, verified by a script (offline-check).
  • Models are downloaded during an explicit provisioning phase, on a temporary network removed afterwards.
  • All application images run without root privileges; base images are pinned by digest.
  • No authentication between services: trust relies on the host’s network partitioning.
The 9 Compact services and their default memory budgets
ServiceTechnologyRoleNetworksMemory
frontendNext.js 15 / React 19 (node:22-alpine)FR/EN web UI; same-origin proxy to the API; the only published port (127.0.0.1:18080). — 127.0.0.1:18080edge, app512m
backendDjango 5.2 + DRF (python:3.12-slim)REST API, authentication with mandatory TOTP MFA, spaces and permissions, ingestion, hybrid retrieval, generation with citations (SSE).app, data, ai1536m
workerCelery 5.6Asynchronous processing: ingestion, reindexing, maintenance, analytics; concurrency 2.data, ai2g
beatCelery beatScheduler for periodic tasks.data256m
dbPostgreSQL 16 + pgvectorRelational data, 768-dimension vectors (HNSW), full-text search; source of truth for backups.data1g
redisRedis 7.2Celery broker, results and cache; not a source of truth.data256m
ai-gatewayAI Gateway Open — FastAPI (python:3.12-slim)Sole inference path: generation (aggregated or streamed), embeddings, reranking, strict model registry, typed errors.ai, inference512m
ollamaOllama 0.30Local execution of generation and embedding models; reachable only by the gateway.inference5g
rerankerText Embeddings Inference (CPU)bge-reranker-v2-m3 cross-encoder sharing the gateway’s network namespace (loopback).inference (namespace de la passerelle)6g

Direct or Pool mode

The Compact profile calls the gateway directly. The Pool is a separate, optional component that relays the same API contract without changing it.

Inference mode
Direct mode: the backend calls the gatewayRAGatm Open calls AI Gateway Open directly for generation, embeddings and reranking.RAGatm Openbackend · workerHTTP/JSON · NDJSONAI Gateway Opengenerate · embeddings · rerankOllama / TEICPU / GPU
RAGatm Open calls AI Gateway Open directly for generation, embeddings and reranking.
Pool mode: an HTTP router in front of one or more gatewaysAI Gateway Pool Open relays the same routes, picks an eligible node, caps concurrency and suspends a saturated node; it performs no inference.RAGatm Openbackend · workerAI Gateway Pool Openregistre de nœuds · max_inflightdisjoncteur · Retry-After · allowlistAI Gateway Opengateway 1Ollama / TEIAI Gateway Opengateway 2Ollama / TEIAI Gateway Opengateway 3…nOllama / TEInodes 2…n: implemented, tested on simulated nodes, not hardware-qualified
AI Gateway Pool Open relays the same routes, picks an eligible node, caps concurrency and suspends a saturated node; it performs no inference.
Text alternative

Direct mode: RAGatm Open (backend and worker) sends HTTP/JSON requests to AI Gateway Open, which calls Ollama and TEI. No other component.

Pool mode: RAGatm Open sends the same requests to AI Gateway Pool Open, which relays them byte for byte to an eligible AI Gateway Open (node 1 parity-qualified; nodes 2 to n implemented but not hardware-qualified). The Pool runs no model.

Error contract

When a component is missing, the application says so. Codes returned by the RAGatm Open API:

Explicit error codes (RAGatm Open API)
HTTPCodeMeaning
503ai_gateway_unavailableThe gateway is unreachable: no fabricated answer.
502ai_gateway_errorThe gateway returned an error.
503dependency_unavailableA dependency (database, cache, model) is unavailable.

Scaling: what is established

The published code targets one machine first. Here are the documented limits.

  • One Celery worker (concurrency 2): sequential ingestion at workstation scale.
  • Gateway: 2 concurrent generations, 2 embeddings and 2 rerankings; beyond that, a 503 with Retry-After. Ollama serialises requests (OLLAMA_NUM_PARALLEL=1).
  • Original documents live on a local volume (ADR-001): spreading the backend across hosts would require shared network storage or object storage.
  • The Pool implements multi-node policies (weighted round-robin, least in-flight) tested on simulated nodes; single-node parity is qualified.

Deployment profiles

One tested profile, two proposed target architectures. Statuses are explicit.

Compact

Tested

One machine, 9 services
local models on CPU
8 threads · 14 GB RAM · no GPU

Functional qualification executed (RC2). 8 GB and 12 GB GPU variants described, not qualified.

Standard

Proposed

Application and models separated
same gateway-api/1.0 contract
more resources, dedicated GPU possible

Target architecture proposed by the project, not described in the Open documentation. Original document storage remains bound to one host (ADR-001).

Distributed

Proposed

Pool in front of several gateways
distributed inference nodes
per-node capacity, circuit breaker

Multi-node policies implemented and tested on simulated nodes; hardware multi-node not qualified.

Text alternative
  • Compact (Tested) — One machine, 9 services; local models on CPU; 8 threads · 14 GB RAM · no GPU. Functional qualification executed (RC2). 8 GB and 12 GB GPU variants described, not qualified.
  • Standard (Proposed) — Application and models separated; same gateway-api/1.0 contract; more resources, dedicated GPU possible. Target architecture proposed by the project, not described in the Open documentation. Original document storage remains bound to one host (ADR-001).
  • Distributed (Proposed) — Pool in front of several gateways; distributed inference nodes; per-node capacity, circuit breaker. Multi-node policies implemented and tested on simulated nodes; hardware multi-node not qualified.

Gateway API contract

The gateway exposes 19 routes described by an OpenAPI 3.1 contract (gateway-api/1.0.yaml, version 1.0.0-candidate.2). The contract is a candidate, not ratified: it may still change before a final 1.0. Every response carries a request identifier (X-Request-ID) relayed end to end.

gateway-api/1.0.yaml (external link) · Pool architecture (external link) · Architecture (repository) (external link)