# RAG su documenti accademici Pipeline completa per trasformare PDF accademici in un sistema RAG interrogabile in linguaggio naturale. **Stack:** Python · MinerU · ChromaDB · Ollama **Chunking:** rule-based, deterministico, senza LLM **Embedding + Generazione:** Ollama (locale) --- ## Prerequisiti ### 1. MinerU — conversione PDF → Markdown MinerU è il tool esterno che converte i PDF in Markdown strutturato. Repository: [https://github.com/opendatalab/MinerU](https://github.com/opendatalab/MinerU) #### Requisiti di sistema | Risorsa | Minimo | Raccomandato | |---------|--------|--------------| | Python | 3.10–3.13 | 3.11 | | RAM | 16 GB | 32 GB+ | | Disco | 20 GB (modelli inclusi) | 40 GB+ | | GPU | opzionale | 4–8 GB VRAM (CUDA) | | OS | Linux, macOS, Windows | Linux / WSL2 | #### Installazione ```bash pip install "mineru[all]" ``` Al primo avvio scarica automaticamente i modelli (~15 GB). #### Uso — CLI ```bash mineru -p -o -b pipeline ``` | Flag | Descrizione | |------|-------------| | `-p` | Percorso PDF o cartella | | `-o` | Cartella di output | | `-b` | Backend: `pipeline` (CPU), `hybrid-auto-engine` (GPU raccomandato) | | `-m` | Metodo: `auto`, `txt`, `ocr` | #### Output di MinerU ``` _output/ └── auto/ ├── .md ← Markdown (input della pipeline) ├── _content_list_v2.json ├── _model.json └── images/ ``` Il file usato dalla pipeline è **`.md`** nella cartella `auto/`. ### 2. Ollama — embedding e generazione Scarica e avvia [Ollama](https://ollama.com), poi installa i modelli: ```bash ollama pull nomic-embed-text # embedding (obbligatorio) ollama pull qwen3.5:4b # generazione LLM (o altro modello) ``` --- ## Setup ```bash git clone cd rag python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt ``` --- ## Flusso completo ``` PDF │ ▼ MinerU (esterno — vedi sotto) sources/_output/auto/.md │ ▼ python chunks/chunker.py --stem chunks//chunks.json │ ▼ python chunks/verify_chunks.py --stem (verifica qualità — opzionale ma consigliato) │ ▼ python ingestion/ingest.py --stem chroma_db// │ ▼ python rag.py --stem Interrogazione in linguaggio naturale ``` --- ## Passo 1 — Converti il PDF con MinerU **Opzione A — Google Colab (nessuna installazione locale)** Usa il notebook incluso: ``` mineru.ipynb ``` Aprilo su Google Colab, carica il PDF e segui le celle. Al termine scarica automaticamente lo ZIP con l'output. Decomprimi la cartella in `sources/`: ``` sources/ └── _output/ └── auto/ ├── .md ← usato dalla pipeline ├── _content_list_v2.json ├── _model.json └── images/ ``` **Opzione B — Installazione locale** ```bash mineru -p documento.pdf -o sources/_output/ -b pipeline ``` --- ## Passo 2 — Chunking ```bash # Singolo documento .venv/bin/python chunks/chunker.py --stem # Tutti i documenti in sources/ .venv/bin/python chunks/chunker.py # Rigenera anche se chunks.json esiste già .venv/bin/python chunks/chunker.py --stem --force ``` Il chunker legge `sources/_output/auto/.md` e produce `chunks//chunks.json`. **Regole applicate:** - 1 paragrafo = 1 chunk; paragrafi di sezioni diverse non si mescolano - Split a confine di frase se il paragrafo supera `MAX_CHARS` (mai a metà frase) - Frasi spezzate tra paragrafi consecutivi vengono ri-fuse automaticamente - Paragrafi brevi (< `MIN_CHARS`) vengono accorpati al successivo (stesso contesto) - Sezioni configurabili vengono saltate (indice, sommario, frontespizio) - Tabelle, liste e code block sono blocchi atomici (non si spezzano) Output in `chunks//`: | File | Contenuto | |------|-----------| | `chunks.json` | Chunk con testo, sezione, titolo, n_chars | | `meta.json` | Parametri usati | | `report.json` | Statistiche e anomalie (generato da verify) | --- ## Passo 3 — Verifica i chunk (opzionale) ```bash .venv/bin/python chunks/verify_chunks.py --stem ``` | Verdict | Significato | |---------|-------------| | `ok` | Nessun problema — procedi | | `warnings_only` | Solo avvisi minori — puoi procedere | | `blocked` | Problemi strutturali — rivedi il sorgente `.md` | --- ## Passo 4 — Vettorizzazione ```bash # Singolo documento → collection omonima .venv/bin/python ingestion/ingest.py --stem # Più documenti → collection condivisa (RAG cross-documento) .venv/bin/python ingestion/ingest.py --collection --stems doc1 doc2 doc3 # Rigenera dopo aver aggiornato i chunk o cambiato modello embedding .venv/bin/python ingestion/ingest.py --stem --force ``` > Se cambi `EMBED_MODEL` in `config.py` devi rieseguire l'ingestion con `--force`. --- ## Passo 5 — Interrogazione ```bash # RAG interattivo (retrieval + generazione LLM) .venv/bin/python rag.py --stem .venv/bin/python rag.py --collection # Retrieval puro (debug, senza LLM) .venv/bin/python retrieve.py --stem .venv/bin/python retrieve.py --stem --top-k 10 ``` --- ## Configurazione ### Chunking — `chunks/config.py` | Parametro | Default | Descrizione | |-----------|---------|-------------| | `MAX_CHARS` | 1200 | Lunghezza massima chunk (caratteri) | | `MIN_CHARS` | 80 | Soglia minima (warning sotto questa soglia) | | `CONTEXT_DEPTH` | 3 | Livelli heading inclusi nel prefisso chunk (1–3) | | `SKIP_HEADINGS` | set italiano | Sezioni saltate completamente (indice, sommario…) | | `SKIP_PRE_HEADING` | `True` | Salta contenuto prima del primo heading (frontespizio) | | `MERGE_SHORT_PARAGRAPHS` | `True` | Accorpa paragrafi brevi fino a `MIN_CHARS` | | `SENTENCE_SPLIT_RE` | regex | Confine di fine frase per lo split | | `ATOMIC_TYPES` | `table, code, list` | Blocchi mai spezzati | ### RAG — `config.py` | Parametro | Default | Descrizione | |-----------|---------|-------------| | `OLLAMA_MODEL` | `qwen3.5:4b` | Modello LLM per la generazione | | `EMBED_MODEL` | `nomic-embed-text` | Modello embedding | | `EMBED_MAX_CHARS` | 6000 | Caratteri massimi inviati al modello embedding | | `TOP_K` | 6 | Chunk recuperati per domanda | | `TEMPERATURE` | 0.2 | Creatività del modello (0 = deterministico) | | `OLLAMA_URL` | `localhost:11434` | URL server Ollama | --- ## Struttura del repository ``` rag/ ├── sources/ ← output MinerU (una cartella per documento) │ └── _output/auto/ ├── chunks/ │ ├── chunker.py ← chunking da MD pulito │ ├── config.py ← parametri di chunking │ └── verify_chunks.py ← verifica qualità chunk ├── ingestion/ │ └── ingest.py ← embedding → ChromaDB ├── chroma_db/ ← database vettoriale (ignorato da git) ├── config.py ← parametri RAG (modelli, TOP_K, prompt) ├── rag.py ← loop RAG interattivo ├── retrieve.py ← retrieval puro (debug) └── mineru.ipynb ← notebook Colab per conversione PDF ```