Sostituisce tutti i simboli grafici con testo: - checkmark/cross -> OK / ERRORE: / AVVISO: - icone tema GUI -> testo Chiaro / Scuro Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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
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
pip install "mineru[all]"
Al primo avvio scarica automaticamente i modelli (~15 GB).
Uso — CLI
mineru -p <documento.pdf> -o <output_dir> -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
<stem>_output/
└── auto/
├── <stem>.md ← Markdown (input della pipeline)
├── <stem>_content_list_v2.json
├── <stem>_model.json
└── images/
Il file usato dalla pipeline è <stem>.md nella cartella auto/.
2. Ollama — embedding e generazione
Scarica e avvia Ollama, poi installa i modelli:
ollama pull qwen3-embedding:0.6b # embedding (obbligatorio)
ollama pull qwen3.5:4b # generazione LLM (o altro modello)
Setup
git clone <questo-repo>
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/<stem>_output/auto/<stem>.md
│
▼ python chunks/chunker.py --stem <stem>
chunks/<stem>/chunks.json
│
▼ python chunks/verify_chunks.py --stem <stem>
(verifica qualità — opzionale ma consigliato)
│
▼ python ingestion/ingest.py --stem <stem>
chroma_db/<stem>/
│
▼ python rag.py --stem <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/
└── <stem>_output/
└── auto/
├── <stem>.md ← usato dalla pipeline
├── <stem>_content_list_v2.json
├── <stem>_model.json
└── images/
Opzione B — Installazione locale
mineru -p documento.pdf -o sources/<stem>_output/ -b pipeline
Passo 2 — Chunking
# Singolo documento
.venv/bin/python chunks/chunker.py --stem <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 <stem> --force
Il chunker legge sources/<stem>_output/auto/<stem>.md e produce chunks/<stem>/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/<stem>/:
| 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)
.venv/bin/python chunks/verify_chunks.py --stem <stem>
| Verdict | Significato |
|---|---|
ok |
Nessun problema — procedi |
warnings_only |
Solo avvisi minori — puoi procedere |
blocked |
Problemi strutturali — rivedi il sorgente .md |
Passo 4 — Vettorizzazione
# Singolo documento → collection omonima
.venv/bin/python ingestion/ingest.py --stem <stem>
# Più documenti → collection condivisa (RAG cross-documento)
.venv/bin/python ingestion/ingest.py --collection <nome> --stems doc1 doc2 doc3
# Rigenera dopo aver aggiornato i chunk o cambiato modello embedding
.venv/bin/python ingestion/ingest.py --stem <stem> --force
Se cambi
EMBED_MODELinconfig.pydevi rieseguire l'ingestion con--force.
Passo 5 — Interrogazione
# RAG interattivo (retrieval + generazione LLM)
.venv/bin/python rag.py --stem <stem>
.venv/bin/python rag.py --collection <nome>
# Retrieval puro (debug, senza LLM)
.venv/bin/python retrieve.py --stem <stem>
.venv/bin/python retrieve.py --stem <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 |
qwen3-embedding:0.6b |
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)
│ └── <stem>_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