raggit
A plug-and-play production-grade RAG system that connects to local and remote object storage, automatically indexes documents, and answers questions using hybrid retrieval with reranking and LLM augmentation.
What raggit does
raggit is built for teams that need reliable retrieval-augmented generation without managing a patchwork of vector databases, parsers, and rerankers. It handles the full document lifecycle: watching storage, parsing common formats, chunking intelligently, embedding, searching, and generating cited answers.
- Hybrid retrieval combines BM25 keyword search with dense semantic search, fused with weighted Reciprocal Rank Fusion.
- Format-aware chunking preserves document structure for Markdown, code, PDFs, and plain text.
- Safety and observability with optional PII redaction, prompt-injection hardening, and structured audit logs.
- Multi-tenant filtering by source URI, filename, tenant, tags, document IDs, and date range.
- Multiple storage backends: local filesystem, S3, Google Cloud Storage, and Azure Blob Storage.
raggit is in early development. The core ingestion, retrieval, and CLI flows are functional and tested. API server mode and analytics are on the roadmap.
Quick Start
You need Docker Desktop (or Docker Engine + Compose) and uv installed.
-
Start PostgreSQL and Qdrant
docker compose up -d postgres qdrantPostgreSQL is mapped to host port
5433to avoid conflicts with a local postgres on5432. -
Install dependencies
uv sync -
Run database migrations
uv run alembic upgrade head -
Configure raggit
uv run raggit setup \ --database-url postgresql+asyncpg://raggit:raggit@localhost:5433/raggit \ --qdrant-url http://localhost:6333 \ --storage-source-type local \ --storage-uri ./data/documents \ --llm-provider openai \ --llm-model gpt-4o-mini \ --llm-api-key $OPENAI_API_KEY -
Add documents and ingest
mkdir -p data/documents cp my-docs/*.pdf data/documents/ uv run raggit ingest ./data/documents -
Ask questions
uv run raggit query "What is raggit?" -
Run the watcher for continuous indexing
uv run raggit watch
See the storage backends section for S3, GCS, and Azure setup.
Architecture
raggit is organized into clear layers: storage, ingestion, data, retrieval, LLM, audit, and interface. All I/O is async, and every significant input and output is logged to PostgreSQL.
Design goals
- Accuracy through hybrid retrieval, cross-encoder reranking, query rewriting, and parent-document expansion.
- Safety by isolating untrusted document text from system instructions and optionally redacting PII.
- Observability with lifecycle statuses, model-scoped collections, and structured audit logs.
- Multi-tenancy via
tenant_idand tags applied consistently across BM25 and vector search. - Evolvability via model-scoped Qdrant collections so changing embedding models does not corrupt existing indexes.
Ingestion Pipeline
When a file is added or changed, the watcher triggers the indexer, which runs the document through parsing, format-aware chunking, cleaning, optional safety steps, embedding, and persistence.
tiktoken cl100k_base when available, with configurable overlap.logs table.Retrieval Pipeline
Queries are sanitized, optionally rewritten, run through BM25 and semantic search in parallel, fused, reranked, expanded, and then passed to the LLM with citations.
multi_query generates alternative phrasings; hyde generates a hypothetical answer passage to embed.tsvector GIN index.BAAI/bge-reranker-base.min_score and refuse empty or low-score retrieval.parent_window > 0.logs table.CLI Reference
The raggit CLI is the primary interface for setup, ingestion, watching, and querying.
| Command | Description |
|---|---|
raggit setup |
Interactive configuration for local, S3, GCS, and Azure backends. |
raggit ingest <path> |
One-time ingestion with a progress bar. Path is optional for cloud storage. |
raggit watch <path> |
Continuously watch and index with live event indicators. |
raggit query "<question>" |
Ask a question; shows status spinners, chunk table, answer panel, and citation tree. |
raggit status |
Show indexed document status and active embedding collections. |
Query options
raggit query supports --top-k, --source-prefix, --filename-prefix, --tenant, --tag (repeatable), --min-score, and --rewrite.
Docker Deployment
Build and run the entire stack with one command:
docker compose up -d
This starts:
raggit-postgreson port5433raggit-qdranton ports6333and6334raggit-apprunning the watcher
Mount your documents into ./data/documents.
Configuration
Configuration is loaded from environment variables and a ~/.config/raggit/raggit.env file generated by raggit setup. The setup command writes the file with 0600 permissions.
Environment variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | postgresql+asyncpg://raggit:raggit@localhost:5433/raggit | PostgreSQL connection string. |
QDRANT_URL | http://localhost:6333 | Qdrant URL. |
QDRANT_COLLECTION | raggit_chunks | Qdrant collection name. |
STORAGE_SOURCE_TYPE | local | Storage backend: local, s3, gcs, azure_blob. |
STORAGE_URI | ./data/documents | Storage URI or local path. |
STORAGE_BUCKET | None | S3/GCS bucket name. |
STORAGE_CONTAINER | None | Azure container name. |
STORAGE_PREFIX | None | Object prefix or folder. |
STORAGE_REGION | None | S3 region. |
STORAGE_AWS_ACCESS_KEY_ID | None | AWS access key ID. |
STORAGE_AWS_SECRET_ACCESS_KEY | None | AWS secret access key. |
STORAGE_GCS_SERVICE_ACCOUNT_PATH | None | GCS service account JSON path. |
STORAGE_AZURE_CONNECTION_STRING | None | Azure Blob connection string. |
LLM_PROVIDER | openai | LLM provider. |
LLM_MODEL | gpt-4o-mini | Model name. |
LLM_API_KEY | None | API key. |
EMBEDDING_PROVIDER | sentence-transformers | Embedding provider. |
EMBEDDING_MODEL | BAAI/bge-small-en-v1.5 | Embedding model. |
Storage Backends
raggit supports local filesystem, S3, Google Cloud Storage, and Azure Blob Storage. Remote backends are installed as optional extras to keep the base install small.
AWS S3
Install the S3 extra:
uv pip install 'raggit[s3]'
Then run setup with S3 options:
uv run raggit setup \
--database-url postgresql+asyncpg://raggit:raggit@localhost:5433/raggit \
--qdrant-url http://localhost:6333 \
--storage-source-type s3 \
--storage-uri s3://my-bucket/documents \
--storage-bucket my-bucket \
--storage-prefix documents \
--storage-region us-east-1 \
--aws-access-key-id $AWS_ACCESS_KEY_ID \
--aws-secret-access-key $AWS_SECRET_ACCESS_KEY \
--llm-provider openai \
--llm-model gpt-4o-mini \
--llm-api-key $OPENAI_API_KEY
Google Cloud Storage
Install the GCS extra:
uv pip install 'raggit[gcs]'
uv run raggit setup \
--database-url postgresql+asyncpg://raggit:raggit@localhost:5433/raggit \
--qdrant-url http://localhost:6333 \
--storage-source-type gcs \
--storage-uri gs://my-bucket/documents \
--storage-bucket my-bucket \
--storage-prefix documents \
--gcs-service-account-path /path/to/service-account.json \
--llm-provider openai \
--llm-model gpt-4o-mini \
--llm-api-key $OPENAI_API_KEY
Azure Blob Storage
Install the Azure extra:
uv pip install 'raggit[azure]'
uv run raggit setup \
--database-url postgresql+asyncpg://raggit:raggit@localhost:5433/raggit \
--qdrant-url http://localhost:6333 \
--storage-source-type azure_blob \
--storage-uri azure://my-container/documents \
--storage-container my-container \
--storage-prefix documents \
--azure-connection-string $AZURE_STORAGE_CONNECTION_STRING \
--llm-provider openai \
--llm-model gpt-4o-mini \
--llm-api-key $OPENAI_API_KEY
Cloud storage watchers use periodic polling and snapshot diffing instead of native push notifications. This keeps the implementation portable across providers without requiring SQS, Pub/Sub, or Event Grid.
Development
# Run linting
uv run ruff check .
# Run type checking
uv run mypy src
# Run tests
uv run pytest
License
raggit is released under the MIT License.