14 KiB
14 KiB
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
# === 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:
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 originalechunk_index: posizione nel documentopage_number: numero pagina (se PDF)created_at: timestampdoc_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://<container-ip>:8501 │
│ │
└─────────────────────────────────────────────────────────────┘
6.2 Comandi Setup
# Installazione dipendenze sistema
apt update
apt install -y python3-pip tesseract-ocr tesseract-ocr-ita poppler-utils
# Clone progetto
git clone <repo-url> /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)
# /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
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