# RAGGER - Design Document **Sistema RAG per Associazione di Volontariato** --- ## 1. Contesto ### 1.1 Obiettivo Sistema AI per estrarre informazioni dai documenti dell'associazione e supportare: - Generazione lettere e progetti - Chatbot conversazionale - Automazione documentale ### 1.2 Vincoli - **Singolo utente** - **100-500 documenti** stimati - **Proxmox in LAN** con server Ollama esistente (https://ollama.solarpi.net) - **Solo CPU** (no GPU) - **On-premise** con fallback API opzionale ### 1.3 Documenti Supportati - PDF scansionati (OCR) - PDF digital-born - Documenti con tabelle/form - DOCX, XLSX, immagini --- ## 2. Architettura ### 2.1 Diagramma ``` ┌─────────────────────────────────────────────────────────┐ │ RAGGER │ │ Single Python App │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────────────────────┐ │ │ │ Streamlit │───▶│ Core Logic │ │ │ │ UI │ │ - upload & OCR │ │ │ └─────────────┘ │ - chunking │ │ │ │ - RAG retrieval │ │ │ │ - chat generation │ │ │ └──────────┬──────────────────┘ │ │ │ │ │ ┌───────────────────────┴───────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌───────────┐ ┌───────────┐ ┌──────┐│ │ │ Tesseract │ │ Qdrant │ │.env ││ │ │ OCR │ │ (local) │ │config││ │ └───────────┘ └─────┬─────┘ └──────┘│ │ │ │ └────────────────────────────────┼───────────────────────┘ │ ┌───────────┴───────────┐ ▼ ▼ ┌────────────────┐ ┌────────────────┐ │ OLLAMA SERVER │ │ API ESTERNA │ │ (solarpi.net) │ │ (fallback) │ │ │ │ │ │ gemma2:9b │ │ openai/claude │ │ nomic-embed │ │ │ └────────────────┘ └────────────────┘ ``` ### 2.2 Principi - **Un comando**: `streamlit run app.py` - **Tutto via Ollama**: embedding e generazione - **Fallback opzionale**: API esterna se Ollama down - **Zero modelli Python locali**: tutto remoto via HTTP --- ## 3. Struttura Progetto ``` ragger/ ├── app.py # Streamlit UI + logica principale ├── core.py # Classi RAG, chunking, retrieval ├── ocr.py # Tesseract wrapper ├── config.py # Settings da .env ├── requirements.txt # Dipendenze minime ├── .env.example # Template configurazione ├── data/ │ ├── uploads/ # Documenti caricati │ └── qdrant/ # Vector DB persistente └── README.md ``` ### 3.1 Dipendenze (requirements.txt) ``` streamlit qdrant-client pytesseract pdf2image Pillow httpx python-dotenv ``` ### 3.2 Niente - FastAPI (semplificato con Streamlit) - sentence-transformers (usa Ollama) - langchain (overkill per singolo utente) --- ## 4. Configurazione ### 4.1 File .env ```env # === OLLAMA SERVER === OLLAMA_HOST=https://ollama.solarpi.net OLLAMA_MODEL=gemma2:9b OLLAMA_EMBED_MODEL=nomic-embed-text # === API ESTERNA (Fallback opzionale) === LLM_FALLBACK_PROVIDER= # openai | anthropic | vuoto = disabilitato LLM_FALLBACK_API_KEY= LLM_FALLBACK_MODEL= # === QDRANT === QDRANT_PATH=./data/qdrant QDRANT_COLLECTION=documents # === OCR === TESSERACT_LANG=ita+eng # === CHUNKING === CHUNK_SIZE=512 CHUNK_OVERLAP=50 # === APP === UPLOAD_DIR=./data/uploads MAX_FILE_SIZE_MB=50 ``` ### 4.2 Modelli Ollama Richiesti Sul server `ollama.solarpi.net`: ```bash ollama pull gemma2:9b # Generazione testo ollama pull nomic-embed-text # Embedding multilingue ``` --- ## 5. Flussi Dati ### 5.1 Ingestione Documento ``` ┌─────────────────────────────────────────────────────────────┐ │ INGESTIONE DOCUMENTO │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Upload PDF/Img ──▶ Tesseract OCR ──▶ Testo estratto │ │ │ │ │ ▼ │ │ Chunking (512 token, overlap) │ │ │ │ │ ▼ │ │ Ollama Embed (nomic-embed-text) │ │ │ │ │ ▼ │ │ Qdrant Store + Metadata │ │ │ └─────────────────────────────────────────────────────────────┘ ``` **Metadata salvati per chunk:** - `source_file`: nome file originale - `chunk_index`: posizione nel documento - `page_number`: numero pagina (se PDF) - `created_at`: timestamp - `doc_type`: tipo documento ### 5.2 Query / Chat ``` ┌─────────────────────────────────────────────────────────────┐ │ QUERY / CHAT │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Domanda utente ──▶ Ollama Embed (nomic-embed-text) │ │ │ │ │ ▼ │ │ Qdrant Search (top-k chunks) │ │ │ │ │ ▼ │ │ Context Assembly │ │ │ │ │ ▼ │ │ Ollama Generate (gemma2:9b) │ │ │ │ │ ▼ │ │ Risposta + Fonti │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 5.3 Fallback LLM ``` ┌─────────────────────────────────────┐ │ TENTATIVO OLLAMA │ │ │ │ │ ┌───────┴───────┐ │ │ ▼ ▼ │ │ SUCCESSO FALLIMENTO │ │ │ │ │ │ ▼ ▼ │ │ Risposta API_FALLBACK? │ │ │ │ │ ┌───────┴───────┐ │ │ ▼ ▼ │ │ SI NO │ │ │ │ │ │ ▼ ▼ │ │ API Esterna Errore │ └─────────────────────────────────────┘ ``` --- ## 6. Deployment ### 6.1 Container Proxmox ``` ┌─────────────────────────────────────────────────────────────┐ │ PROXMOX LXC CONTAINER │ ├─────────────────────────────────────────────────────────────┤ │ │ │ OS: Debian 12 / Ubuntu 22.04 │ │ Python: 3.11+ │ │ Packages: tesseract-ocr, poppler-utils │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ragger/ │ │ │ │ ├── app.py │ │ │ │ ├── core.py │ │ │ │ ├── .env │ │ │ │ └── data/ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ Avvio: streamlit run app.py --server.port 8501 │ │ Accesso: http://:8501 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 6.2 Comandi Setup ```bash # Installazione dipendenze sistema apt update apt install -y python3-pip tesseract-ocr tesseract-ocr-ita poppler-utils # Clone progetto git clone /opt/ragger cd /opt/ragger # Installazione Python pip install -r requirements.txt # Configurazione cp .env.example .env # Editare .env con i propri valori # Avvio streamlit run app.py --server.port 8501 ``` ### 6.3 Servizio Systemd (opzionale) ```ini # /etc/systemd/system/ragger.service [Unit] Description=RAGGER - RAG System After=network.target [Service] Type=simple User=ragger WorkingDirectory=/opt/ragger ExecStart=/usr/local/bin/streamlit run app.py --server.port 8501 Restart=always [Install] WantedBy=multi-user.target ``` ```bash systemctl enable ragger systemctl start ragger ``` --- ## 7. Roadmap Implementazione ### Fase 1: Core (MVP) - [ ] Config e .env - [ ] OCR con Tesseract - [ ] Chunking testo - [ ] Ollama embedding client - [ ] Qdrant storage - [ ] Ricerca semantica base - [ ] Generazione risposta ### Fase 2: UI Streamlit - [ ] Upload documenti - [ ] Lista documenti indicizzati - [ ] Chat interface - [ ] Visualizzazione fonti ### Fase 3: Miglioramenti - [ ] Fallback API esterna - [ ] Gestione errori robusta - [ ] Export conversazioni - [ ] Statistiche uso --- ## 8. Decisioni Prese | Decisione | Scelta | Motivo | |-----------|--------|--------| | Architettura | Monolitica | Singolo utente, semplicità | | LLM | Ollama remoto | Già esistente, on-premise | | Modello generazione | gemma2:9b | Qualità italiana, capace | | Modello embedding | nomic-embed-text | Multilingue, testato | | Vector DB | Qdrant | Veloce, Docker-friendly | | OCR | Tesseract | On-premise, gratuito | | UI | Streamlit | Rapido, singolo file | | Fallback | API esterna opzionale | Affidabilità | --- ## 9. Riferimenti - Ollama: https://ollama.com - Qdrant: https://qdrant.tech - Tesseract: https://github.com/tesseract-ocr/tesseract - Streamlit: https://streamlit.io - nomic-embed-text: https://ollama.com/library/nomic-embed-text - gemma2: https://ollama.com/library/gemma2 --- *Design completato: 2025-02-21*