docs: aggiorna CLAUDE.md per riflettere la struttura attuale del repo

Allinea comandi, architettura e schema chunk alla struttura reale:
percorsi rag/, gui/, ingestion/ corretti; pipeline chunking documentata
nei 5 moduli; config split ingestion/rag; sezione GUI aggiunta.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 10:24:51 +02:00
parent 9261e480da
commit 9e0e1a131e
+63 -45
View File
@@ -16,17 +16,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Missione ## Missione
Pipeline RAG su documenti accademici. La conversione PDF → Markdown è delegata a **MinerU** (tool esterno). Questo repository si occupa solo di: chunking, vettorizzazione e retrieval/generazione. Pipeline RAG su documenti PDF, interamente in locale. La conversione PDF → Markdown è delegata a **MinerU** (tool esterno). Questo repository si occupa di: chunking, vettorizzazione, retrieval/generazione e GUI desktop.
``` Il PDF viene convertito da MinerU in Markdown strutturato. Il chunker lo analizza e produce chunk semantici. Il modulo di ingest genera gli embedding tramite Ollama e li indicizza in ChromaDB. Infine `rag/rag.py` (o la GUI) riceve la domanda, recupera i chunk più rilevanti e genera la risposta.
MinerU (esterno) → sources/<stem>_output/auto/<stem>.md
chunker.py (chunks.json)
ingest.py (embedding → ChromaDB)
rag.py / retrieve.py
```
--- ---
@@ -34,20 +26,18 @@ MinerU (esterno) → sources/<stem>_output/auto/<stem>.md
- **Venv:** Usa `.venv/bin/python`. Mai `pip`/`python` di sistema. - **Venv:** Usa `.venv/bin/python`. Mai `pip`/`python` di sistema.
- **Niente LLM nella pipeline:** chunking e pulizia devono essere rule-based e riproducibili. - **Niente LLM nella pipeline:** chunking e pulizia devono essere rule-based e riproducibili.
- **Input immutabile:** Non modificare mai i file in `sources/`. Il `chunker.py` scrive solo in `chunks/<stem>/`. - **Input immutabile:** Non modificare mai i file in `sources/`. Il chunker scrive solo in `chunks/<stem>/`.
--- ---
## Input — struttura MinerU ## Input — struttura MinerU
MinerU produce una cartella per ogni documento. Posizionarla in `sources/`:
``` ```
sources/<stem>_output/auto/<stem>.md ← Markdown strutturato (input della pipeline) sources/<stem>_output/auto/<stem>.md ← Markdown strutturato (input della pipeline)
sources/<stem>_output/auto/images/ ← immagini estratte sources/<stem>_output/auto/images/ ← immagini estratte
``` ```
`<stem>` = nome del documento, usato in tutti i comandi come identificatore. `<stem>` = nome del documento, usato come identificatore in tutti i comandi.
--- ---
@@ -59,19 +49,28 @@ python -m venv .venv && source .venv/bin/activate && pip install -r requirements
# Chunking # Chunking
.venv/bin/python chunks/chunker.py --stem <stem> .venv/bin/python chunks/chunker.py --stem <stem>
.venv/bin/python chunks/chunker.py # tutti gli stem in sources/ .venv/bin/python chunks/chunker.py # tutti gli stem in sources/
.venv/bin/python chunks/chunker.py --stem <stem> --force # rigenera anche se già presente .venv/bin/python chunks/chunker.py --stem <stem> --force # rigenera anche se già presente
# Verifica qualità chunk
.venv/bin/python chunks/verify_chunks.py --stem <stem>
# Vettorizzazione (richiede Ollama attivo) # Vettorizzazione (richiede Ollama attivo)
.venv/bin/python ingestion/ingest.py --stem <stem> .venv/bin/python ingestion/ingest.py --stem <stem>
.venv/bin/python ingestion/ingest.py --collection <nome> --stems doc1 doc2 doc3
.venv/bin/python ingestion/ingest.py --stem <stem> --force .venv/bin/python ingestion/ingest.py --stem <stem> --force
# RAG interattivo # RAG interattivo
.venv/bin/python rag.py --stem <stem> .venv/bin/python rag/rag.py --collection <nome>
.venv/bin/python retrieve.py --stem <stem> # retrieval puro, senza LLM .venv/bin/python rag/rag.py --stem <stem>
# Retrieval puro (debug senza LLM)
.venv/bin/python rag/retrieve.py --stem <stem>
.venv/bin/python rag/retrieve.py --collection <nome> --top-k 10
# GUI desktop
.venv/bin/python gui/main.py
.venv/bin/python gui/main.py --collection <nome>
# Verifica ambiente Ollama
.venv/bin/python ollama/check_env.py
``` ```
--- ---
@@ -82,42 +81,61 @@ python -m venv .venv && source .venv/bin/activate && pip install -r requirements
| File | Responsabilità | | File | Responsabilità |
|------|---------------| |------|---------------|
| `chunker.py` | Legge `<stem>.md`, produce `chunks.json` con regole deterministiche | | `chunker.py` | Entry point: legge `<stem>.md`, orchestra parser → segmenter → packer → validator |
| `config.py` | Parametri: `MAX_CHARS`, `MIN_CHARS`, `CONTEXT_DEPTH`, `SKIP_HEADINGS`, `ATOMIC_TYPES` | | `parser.py` | Markdown → AST di `Block` tramite markdown-it-py |
| `verify_chunks.py` | Verifica qualità chunk (lunghezze, frasi spezzate, prefissi) | | `segmenter.py` | AST → sequenza di `Block` con header_path e contesto heading |
| `packer.py` | `Block[]``Chunk[]` con packing min/target/max |
| `validator.py` | Verifica integrità e coerenza dei chunk prodotti |
| `models.py` | Dataclass: `Block`, `Chunk`, `Diagnostics`, `ChunkingResult` |
| `config.py` | `ChunkerConfig`: `max_chars`, `min_chars`, `target_chars`, `context_depth`, `skip_headings`, `atomic_types` |
Regole applicate dal chunker: Output per stem: `chunks/<stem>/chunks.json`, `chunks/<stem>/meta.json`, `chunks/<stem>/report.json`
- 1 paragrafo = 1 chunk; paragrafi di sezioni diverse non si mescolano
- Split a confine di frase se il paragrafo supera `MAX_CHARS`
- Frasi spezzate tra paragrafi consecutivi vengono ri-fuse automaticamente
- Paragrafi brevi (< `MIN_CHARS`) vengono accorpati al successivo (stesso contesto)
- Sezioni in `SKIP_HEADINGS` saltate completamente; contenuto pre-heading saltato se `SKIP_PRE_HEADING=True`
- Tabelle, liste e code block sono blocchi atomici
Output: `chunks/<stem>/chunks.json`, `chunks/<stem>/meta.json` **Schema chunk** (`chunks.json`):
### Vettorizzazione — `ingestion/ingest.py` | Campo | Descrizione |
|-------|-------------|
| `chunk_id` | Identificatore univoco |
| `content_for_embedding` | Testo con prefisso heading, usato per generare il vettore |
| `content_original` | Testo originale senza prefisso, memorizzato in ChromaDB |
| `header_path` | Lista di dict `{level, text}` — gerarchia heading del chunk |
| `content_type` | Tipo blocco dominante (`paragraph`, `table`, `code`, ecc.) |
| `flags` | Dict: `has_code`, `has_table`, `has_math`, `is_overflow` |
| `chunk_index` | Posizione ordinale nel documento |
| `start_line` / `end_line` | Righe sorgente nel Markdown |
| `chars` | Lunghezza in caratteri di `content_original` |
Legge `chunks/<stem>/chunks.json`, genera embedding via Ollama (`EMBED_MODEL`), indicizza in ChromaDB persistente (`chroma_db/`). Supporta collection multi-documento (`--collection <nome> --stems doc1 doc2`). ### Vettorizzazione — `ingestion/`
### RAG — file radice | File | Responsabilità |
|------|---------------|
| `ingest.py` | Legge `chunks.json`, genera embedding via Ollama, indicizza in ChromaDB |
| `config.py` | `EMBED_MODEL` (default: `bge-m3`), `EMBED_MAX_CHARS`, `OLLAMA_URL` |
ChromaDB persistente in `chroma_db/`. Supporta collection multi-documento (`--collection`).
### RAG — `rag/`
| File | Responsabilità | | File | Responsabilità |
|------|---------------| |------|---------------|
| `rag.py` | Loop interattivo: retrieval + generazione Ollama | | `rag.py` | Loop interattivo: retrieval + generazione Ollama |
| `retrieve.py` | Retrieval puro (debug senza LLM) | | `retrieve.py` | Retrieval puro (debug senza LLM) |
| `config.py` | `TOP_K`, `TEMPERATURE`, `OLLAMA_MODEL`, `EMBED_MODEL`, `SYSTEM_PROMPT`, `OLLAMA_URL` | | `config.py` | `TOP_K`, `TEMPERATURE`, `NO_THINK`, `OLLAMA_MODEL`, `OLLAMA_URL`, `SYSTEM_PROMPT` |
### Output per stem ### GUI — `gui/`
``` | File | Responsabilità |
chunks/<stem>/chunks.json |------|---------------|
chunks/<stem>/meta.json | `main.py` | Entry point PySide6, argparse `--collection` |
chroma_db/<stem>/ ← collection ChromaDB | `chat_window.py` | `QMainWindow`: top bar (combo collection + toggle tema), `QWebEngineView`, input bar |
``` | `worker.py` | `QThread`: esegue retrieve + build_prompt + call_ollama in background |
| `chat.html` | Template HTML con marked.js + KaTeX (CDN); funzioni JS: `addMessage`, `addThinking`, `removeThinking`, `setTheme` |
--- Temi light/dark gestiti via CSS custom properties in `chat.html` e stylesheet Qt in `chat_window.py`.
## Skills custom ### Utility — `ollama/`
- `/prepare-md <path|stem>` — corregge il Markdown MinerU: sillabazione, artefatti, header malformati, gerarchia incoerente. Opera su una copia, non sull'originale. | File | Responsabilità |
|------|---------------|
| `check_env.py` | Verifica che Ollama sia attivo e i modelli configurati siano disponibili |
| `test_ollama.py` | Test embedding e generazione end-to-end |