Files

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 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://<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


Design completato: 2025-02-21