rag-knowledge-assistant is an open-source RAG API with smart chunking, hybrid retrieval, rerankers, and a built-in eval harness.
The API supports lexical TF-IDF retrieval, pluggable semantic embeddings, query traces, and offline retrieval evaluation.
- Version:
0.3.0 - Storage can be run in-memory (default) or with file-backed persistence.
- Auth, rate limiting, request validation responses, metrics, and health endpoints included.
- Ingest and chunk documents via HTTP with
tokens,sentence,paragraph, orsmartchunking. - TF-IDF, semantic, and hybrid retrieval modes.
- Lightweight lexical reranker (
term_overlap) and reciprocal-rank fusion for hybrid search. - Query traces that expose retrieval stages and candidate counts.
- Retrieval eval harness via API and Python helper.
- File-backed persistence with resumable startup index loading.
- Pluggable semantic providers (
sentence_transformers,local,local_tfidf,onnx_local). - Config/env-first runtime configuration.
- Optional static API key middleware.
- Input abuse controls (payload size), request ID headers, and rate limiting.
- Structured error payloads and OpenAPI-documented failure modes.
- Observability endpoint (
/metrics) plus health and readiness checks. - Docker/Compose defaults for durable storage mount.
The app reads settings from environment variables, including:
RAG_SERVICE_NAMERAG_STORAGE_PATH(optional; when set, chunks are persisted to disk)RAG_API_KEY(optional static API key)RAG_RATE_LIMIT_REQUESTSRAG_RATE_LIMIT_WINDOW_SECONDSRAG_MAX_REQUEST_BYTESRAG_DEFAULT_CHUNK_SIZERAG_DEFAULT_CHUNK_OVERLAPRAG_DEFAULT_EMBEDDING_MODELRAG_HOSTRAG_PORTRAG_RELOADRAG_LOG_LEVELRAG_DOCS_ENABLEDRAG_ALLOWED_ORIGINS
See .env.example for a complete starter configuration.
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"For semantic dependencies:
pip install -e ".[dev,embeddings]"For ONNX support:
pip install -e ".[dev,onnx]"cp .env.example .env
uvicorn rag_assistant.api:app --reload --app-dir srcRAG_API_KEY=dev RAG_STORAGE_PATH=./data/rag-index.json uvicorn rag_assistant.api:app --reload --app-dir srchttp://localhost:8000/ui/
The page can ingest content and run both TF-IDF and semantic queries. If you configured an API key, paste it into the UI.
python -m rag_assistant.clicurl -X POST http://localhost:8000/ingest \
-H "Content-Type: application/json" \
-H "x-api-key: ${RAG_API_KEY}" \
-d '{"source_id":"guide-1","content":"RAG combines retrieval with generation.","chunking_strategy":"smart"}'curl -X POST http://localhost:8000/query \
-H "Content-Type: application/json" \
-H "x-api-key: ${RAG_API_KEY}" \
-d '{"question":"What is RAG?","top_k":3,"retrieval":"hybrid","embedding_provider":"local","reranker":"term_overlap","candidate_pool_size":8}'curl -X POST http://localhost:8000/query/semantic \
-H "Content-Type: application/json" \
-H "x-api-key: ${RAG_API_KEY}" \
-d '{"question":"What is RAG?","top_k":3,"embedding_provider":"sentence_transformers","embedding_model":"sentence-transformers/all-MiniLM-L6-v2"}'Local TF-IDF alternative:
curl -X POST http://localhost:8000/query/semantic \
-H "Content-Type: application/json" \
-H "x-api-key: ${RAG_API_KEY}" \
-d '{"question":"How can embeddings be generated?","top_k":3,"embedding_provider":"local_tfidf","local_dimensions":64}'curl -X POST http://localhost:8000/evals/run \
-H "Content-Type: application/json" \
-H "x-api-key: ${RAG_API_KEY}" \
-d '{"cases":[{"question":"What is RAG?","expected_source_ids":["guide-1"],"retrieval":"hybrid","embedding_provider":"local","reranker":"term_overlap"}]}'pytestGET /health— service health and runtime summaryGET /ready— readiness probe (checks storage availability when persistence is enabled)GET /stats— index stats and provider/runtime metadataGET /metrics— in-memory request metricsPOST /ingest— ingest one documentPOST /ingest/bulk— ingest many documentsPOST /query— retrieve top-k relevant chunksPOST /query/semantic— semantic-only query endpointPOST /evals/run— run retrieval eval cases against indexed contentDELETE /documents/{source_id}— remove all chunks for a sourceDELETE /clear— clear index
Docs UI: http://localhost:8000/docs
- In-memory mode remains the default for quick experiments.
- Set
RAG_STORAGE_PATHto enable persistent index writes and reload on restart. - Current persistence format is a local JSON snapshot of chunks and metadata.
-
Backend: Render (from
render.yaml)- Render keeps the existing
rag-knowledge-assistant-apiconfig in this repo. - The service uses Docker and exposes:
GET /healthGET /healthz
- Set these env vars in Render:
RAG_HOST=0.0.0.0RAG_STORAGE_PATH=/var/data/rag-index.jsonRAG_ALLOWED_ORIGINS=https://<YOUR_VERCEL_FRONTEND>RAG_API_KEY(optional, use Sync: false)
- Verify backend health after deploy:
curl https://<backend>/health
- Render keeps the existing
-
Frontend: Vercel (from
vercel.json)- Create a new Vercel project and point it at this repository.
- Keep
vercel.jsonas-is; it publishes files fromui/as static assets. - Deploy the project and open:
https://<frontend>.vercel.app/?api=https://<backend>
- Replace
<backend>with your Render URL. - The UI writes the URL to browser local storage after first use.
-
CORS note:
- Ensure backend
RAG_ALLOWED_ORIGINSincludes your Vercel domain (no trailing slash).
- Ensure backend
- Backend health:
curl https://<backend>/healthcurl -X POST https://<backend>/query -H "Content-Type: application/json" -d '{"question":"What is RAG?"}'- A fresh backend with no docs returns
404.
- Frontend health check button:
- Open UI and click Check /health after setting the API base URL.
- Local smoke check after any deploy:
curl https://<backend>/healthcurl -X POST https://<backend>/query -H "Content-Type: application/json" -d '{"question":"What is RAG?"}'
- If UI says “Set API base URL first”, open it with
?api=https://<backend>.
- See
CONTRIBUTING.md. - For planned work, see
ROADMAP.md. - For release history, see
CHANGELOG.md.
This project is MIT-licensed. See LICENSE.