RAG from Scratch

Sistema RAG (Retrieval-Augmented Generation) costruito da zero, senza framework di alto livello. Funziona su qualsiasi PDF digitale. Gira interamente in locale, senza GPU, senza cloud.

Stack: Python · Ollama · ChromaDB
Compatibile con: Linux · macOS · Windows (WSL2) · CPU only · ~8 GB RAM


Pipeline

PDF → conversione → chunking → verifica → vettorizzazione → retrieval
Fase Rischio Motivo
Conversione 🟡 Medio Automatica, ma il PDF deve essere digitale e non protetto
Revisione Markdown 🔴 Alto La qualità del MD determina la qualità del RAG
Chunking 🟡 Medio Adattivo, dipende dalla qualità del MD
Vettorizzazione 🟢 Basso Meccanica, lenta ma affidabile
Retrieval 🟡 Medio Dipende dai parametri in config.py

Struttura del progetto

rag/
├── sources/                  # PDF originali — non modificare
├── conversione/              # PDF → Markdown strutturato
│   ├── pipeline.py
│   ├── validate.py
│   └── <stem>/
│       ├── raw.md            # grezzo — non modificare
│       ├── clean.md          # copia di lavoro
│       └── report.json
├── step-5/                   # Chunking
│   ├── chunker.py
│   └── <stem>/chunks.json
├── step-6/                   # Verifica e fix chunk
│   ├── verify_chunks.py
│   ├── fix_chunks.py
│   └── <stem>/
│       ├── chunks.json
│       └── report.json
├── step-8/                   # Vettorizzazione
│   └── ingest.py
├── ollama/                   # Setup ambiente
│   ├── check_env.py
│   └── test_ollama.py
├── chroma_db/                # Vector store (generato)
├── config.py                 # Configurazione pipeline ← modifica qui
├── rag.py                    # Interrogazione RAG interattiva
└── retrieve.py               # Retrieval puro (senza LLM)

--stem = nome del PDF senza estensione = nome della collection ChromaDB.


Setup

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Java 11+ richiesto per la conversione (opendataloader-pdf):

sudo apt install default-jdk   # Ubuntu/Debian/WSL
java -version                  # verifica

Vedi ollama/README.md per l'installazione di Ollama e il download dei modelli.


Workflow

1. Converti il PDF

python conversione/pipeline.py --stem <nome>

Produce conversione/<stem>/clean.md. Vedi conversione/README.md.

2. Rivedi il Markdown

/prepare-md conversione/<stem>/clean.md

Passaggio più importante: la qualità del RAG dipende da questo.

3. Chunking

python step-5/chunker.py --stem <nome>

4. Verifica e fix chunk

python step-6/verify_chunks.py --stem <nome>
python step-6/fix_chunks.py --stem <nome>     # se ci sono 🔴
python step-6/verify_chunks.py --stem <nome>  # ri-verifica

Non procedere alla vettorizzazione se ci sono 🔴.

5. Vettorizza

python step-8/ingest.py --stem <nome>

Vedi step-8/README.md. Usa --force se hai cambiato EMBED_MODEL o i chunk.

6. Interroga

python rag.py --stem <nome>       # risposta LLM
python retrieve.py --stem <nome>  # retrieval puro (debug)

Configurazione (config.py)

Parametro Default Descrizione
EMBED_MODEL "nomic-embed-text" Modello embedding — deve corrispondere tra ingest e retrieval
OLLAMA_MODEL "qwen3.5:0.8b" Modello LLM
OLLAMA_URL "http://localhost:11434" Endpoint Ollama
TOP_K 6 Chunk recuperati per query
TEMPERATURE 0.0 Deterministico a 0.0
NO_THINK True Disabilita chain-of-thought (Qwen3/Qwen3.5)
SYSTEM_PROMPT (vedi file) Istruzioni di comportamento per il LLM

Se cambi EMBED_MODEL, riesegui step-8/ingest.py --stem <nome> --force.


Principi

Atomico — ogni fase fa una cosa sola; se si rompe qualcosa sai esattamente dove.

Verificabile — ogni fase ha un criterio di completamento oggettivo prima di procedere.

Reversibile — puoi tornare indietro senza perdere il lavoro delle altre fasi.

Adattivo — nessuna assunzione sulla struttura del documento; si adatta automaticamente.

Locale — nessuna API esterna, nessun dato trasmesso fuori dalla macchina.

S
Description
Sistema RAG costruito da zero su qualsiasi PDF digitale. Ogni fase della pipeline - estrazione, chunking adattivo, vettorizzazione, retrieval e generazione - è uno step separato e verificabile. Gira interamente in locale su CPU, senza GPU e senza cloud. Stack: Python - Ollama - ChromaDB.
Readme 789 KiB
Languages
Python 99.6%
Shell 0.4%