Enterprise-grade RAG (Retrieval-Augmented Generation) platform — Upload documents, ask questions, get cited answers powered by OpenAI, Anthropic Claude, or Ollama.
| Feature | Description |
|---|---|
| Multi-format Ingestion | PDF (with OCR), DOCX, TXT, Markdown, Web URLs |
| Hybrid RAG Search | Semantic (ChromaDB) + BM25 keyword search |
| Cross-encoder Re-ranking | MS-MARCO re-ranking for top results |
| Multi-LLM Support | OpenAI GPT-4, Anthropic Claude, Ollama (local) |
| LLM Fallback Chain | Auto-retry with next provider on failure |
| SSE Streaming | Real-time token-by-token answer streaming |
| Source Citations | Every answer references exact document chunks |
| Async Processing | Celery + Redis for non-blocking document ingestion |
| Conversation Memory | Per-session chat history with question condensation |
| Collections | Organize docs into named knowledge bases |
| REST API | Full OpenAPI/Swagger documented FastAPI backend |
| Web UI | Flask + Tailwind chat, upload, and collections UI |
| Docker | One-command docker-compose up deployment |
┌─────────────────────────────────────────────────────────┐
│ Flask Web UI (chat, upload, collections) │
└──────────────────────┬──────────────────────────────────┘
│ HTTP (via Nginx)
┌──────────────────────▼──────────────────────────────────┐
│ FastAPI Backend (REST API) │
│ /upload /query /collections /health /stream │
└────┬──────────────┬──────────────────┬──────────────────┘
│ │ │
Ingestion RAG Query LLM Router
Service Service (LangChain)
│ │ │
▼ ▼ ▼
Celery + ChromaDB OpenAI / Claude
Redis VectorDB / Ollama
│
PostgreSQL
(metadata)
- Docker & Docker Compose
- At least one LLM API key (OpenAI or Anthropic) or Ollama running locally
git clone https://github.com/yourname/documind-ai.git
cd documind-ai
# Copy and edit env file
cp .env.example .envEdit .env and set your API keys:
DEFAULT_LLM_PROVIDER=openai
OPENAI_API_KEY=sk-your-key-here
# OR for Claude:
# DEFAULT_LLM_PROVIDER=anthropic
# ANTHROPIC_API_KEY=sk-ant-your-key-here
# OR for local Ollama:
# DEFAULT_LLM_PROVIDER=ollama
# OLLAMA_BASE_URL=http://host.docker.internal:11434docker-compose up --build| Service | URL |
|---|---|
| Web UI | http://localhost |
| API Docs (Swagger) | http://localhost/api/docs |
| ChromaDB | http://localhost:8001 |
| Flower (Celery UI) | http://localhost:5555 |
GET /api/v1/collections # List all
POST /api/v1/collections # Create
GET /api/v1/collections/{id} # Get one
DELETE /api/v1/collections/{id} # Delete (with all docs)POST /api/v1/documents/upload # Upload files (multipart)
POST /api/v1/documents/url # Ingest from URL
GET /api/v1/documents/{id}/status # Check ingestion status
DELETE /api/v1/documents/{id} # Delete documentPOST /api/v1/query # Blocking RAG query
GET /api/v1/query/stream # SSE streaming query
POST /api/v1/sessions # Create chat session
GET /api/v1/sessions/{id}/messages # Get session historyGET /api/v1/health # Health of all services
GET /api/v1/metrics # Usage statisticscurl -X POST http://localhost/api/v1/query \
-H "Content-Type: application/json" \
-d '{
"question": "What are the key findings?",
"collection_id": "your-collection-uuid",
"llm_provider": "openai",
"top_k": 5,
"include_sources": true
}'| Service | Port | Description |
|---|---|---|
nginx |
80 | Reverse proxy & load balancer |
api |
8000 | FastAPI backend |
web |
5000 | Flask frontend |
chromadb |
8001 | Vector store |
postgres |
5432 | Metadata & chat history |
redis |
6379 | Celery broker & cache |
celery_worker |
— | Async ingestion worker |
documind-ai/
├── docker-compose.yml # All services
├── .env.example # Environment template
│
├── api/ # FastAPI backend
│ ├── main.py # App entry point
│ ├── core/
│ │ ├── config.py # Pydantic settings
│ │ └── dependencies.py # DB, ChromaDB deps
│ ├── routers/
│ │ ├── collections.py # Collection CRUD
│ │ ├── documents.py # File upload / URL ingest
│ │ ├── query.py # RAG query + SSE stream
│ │ └── health.py # Health + metrics
│ ├── services/
│ │ ├── rag_service.py # Core RAG pipeline
│ │ ├── ingestion_service.py # Document loading + chunking
│ │ ├── vector_store.py # ChromaDB abstraction
│ │ └── llm_router.py # Multi-LLM provider router
│ ├── models/
│ │ ├── database.py # SQLAlchemy ORM
│ │ └── schemas.py # Pydantic v2 schemas
│ └── workers/
│ └── celery_worker.py # Async Celery tasks
│
├── web/ # Flask frontend
│ ├── app.py # Flask app
│ └── templates/
│ ├── base.html # Nav + layout
│ ├── index.html # Dashboard
│ ├── chat.html # Chat UI
│ ├── upload.html # Upload UI
│ └── collections.html # Collections UI
│
└── infra/
├── nginx/nginx.conf # Reverse proxy config
└── postgres/init.sql # DB schema
All settings are in .env. Key options:
| Variable | Default | Description |
|---|---|---|
DEFAULT_LLM_PROVIDER |
openai |
openai, anthropic, or ollama |
CHUNK_SIZE |
1000 |
Characters per document chunk |
CHUNK_OVERLAP |
200 |
Overlap between chunks |
TOP_K_RESULTS |
5 |
Number of chunks to retrieve |
SIMILARITY_THRESHOLD |
0.3 |
Min similarity score for retrieval |
MAX_UPLOAD_SIZE_MB |
50 |
Max file size in MB |
# Run without Docker (development)
cd api && pip install -r requirements.txt
uvicorn main:app --reload
# Run Celery worker
celery -A workers.celery_worker worker --loglevel=info
# Run Flask UI
cd web && pip install -r requirements.txt
python app.pyMIT License — see LICENSE file for details.