160 lines
4.5 KiB
Markdown
160 lines
4.5 KiB
Markdown
# 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
|
|
|
|
```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 <nome>
|
|
```
|
|
|
|
Produce `conversione/<stem>/clean.md`. Vedi [`conversione/README.md`](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
|
|
|
|
```bash
|
|
python step-5/chunker.py --stem <nome>
|
|
```
|
|
|
|
### 4. Verifica e fix chunk
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
python step-8/ingest.py --stem <nome>
|
|
```
|
|
|
|
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 <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.
|