# 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 │ └── / │ ├── raw.md # grezzo — non modificare │ ├── clean.md # copia di lavoro │ └── report.json ├── step-5/ # Chunking │ ├── chunker.py │ └── /chunks.json ├── step-6/ # Verifica e fix chunk │ ├── verify_chunks.py │ ├── fix_chunks.py │ └── / │ ├── 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 ```bash python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` **Java 11+** richiesto per la conversione (`opendataloader-pdf`): ```bash sudo apt install default-jdk # Ubuntu/Debian/WSL java -version # verifica ``` Vedi [`ollama/README.md`](ollama/README.md) per l'installazione di Ollama e il download dei modelli. --- ## Workflow ### 1. Converti il PDF ```bash python conversione/pipeline.py --stem ``` Produce `conversione//clean.md`. Vedi [`conversione/README.md`](conversione/README.md). ### 2. Rivedi il Markdown ``` /prepare-md conversione//clean.md ``` Passaggio più importante: la qualità del RAG dipende da questo. ### 3. Chunking ```bash python step-5/chunker.py --stem ``` ### 4. Verifica e fix chunk ```bash python step-6/verify_chunks.py --stem python step-6/fix_chunks.py --stem # se ci sono 🔴 python step-6/verify_chunks.py --stem # ri-verifica ``` Non procedere alla vettorizzazione se ci sono 🔴. ### 5. Vettorizza ```bash python step-8/ingest.py --stem ``` Vedi [`step-8/README.md`](step-8/README.md). Usa `--force` se hai cambiato `EMBED_MODEL` o i chunk. ### 6. Interroga ```bash python rag.py --stem # risposta LLM python retrieve.py --stem # 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 --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.