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:
@@ -16,17 +16,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## 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.
|
||||
|
||||
```
|
||||
MinerU (esterno) → sources/<stem>_output/auto/<stem>.md
|
||||
↓
|
||||
chunker.py (chunks.json)
|
||||
↓
|
||||
ingest.py (embedding → ChromaDB)
|
||||
↓
|
||||
rag.py / retrieve.py
|
||||
```
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,20 +26,18 @@ MinerU (esterno) → sources/<stem>_output/auto/<stem>.md
|
||||
|
||||
- **Venv:** Usa `.venv/bin/python`. Mai `pip`/`python` di sistema.
|
||||
- **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
|
||||
|
||||
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/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.
|
||||
|
||||
---
|
||||
|
||||
@@ -62,16 +52,25 @@ python -m venv .venv && source .venv/bin/activate && pip install -r requirements
|
||||
.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
|
||||
|
||||
# Verifica qualità chunk
|
||||
.venv/bin/python chunks/verify_chunks.py --stem <stem>
|
||||
|
||||
# Vettorizzazione (richiede Ollama attivo)
|
||||
.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
|
||||
|
||||
# RAG interattivo
|
||||
.venv/bin/python rag.py --stem <stem>
|
||||
.venv/bin/python retrieve.py --stem <stem> # retrieval puro, senza LLM
|
||||
.venv/bin/python rag/rag.py --collection <nome>
|
||||
.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à |
|
||||
|------|---------------|
|
||||
| `chunker.py` | Legge `<stem>.md`, produce `chunks.json` con regole deterministiche |
|
||||
| `config.py` | Parametri: `MAX_CHARS`, `MIN_CHARS`, `CONTEXT_DEPTH`, `SKIP_HEADINGS`, `ATOMIC_TYPES` |
|
||||
| `verify_chunks.py` | Verifica qualità chunk (lunghezze, frasi spezzate, prefissi) |
|
||||
| `chunker.py` | Entry point: legge `<stem>.md`, orchestra parser → segmenter → packer → validator |
|
||||
| `parser.py` | Markdown → AST di `Block` tramite markdown-it-py |
|
||||
| `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:
|
||||
- 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 per stem: `chunks/<stem>/chunks.json`, `chunks/<stem>/meta.json`, `chunks/<stem>/report.json`
|
||||
|
||||
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à |
|
||||
|------|---------------|
|
||||
| `rag.py` | Loop interattivo: retrieval + generazione Ollama |
|
||||
| `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/`
|
||||
|
||||
```
|
||||
chunks/<stem>/chunks.json
|
||||
chunks/<stem>/meta.json
|
||||
chroma_db/<stem>/ ← collection ChromaDB
|
||||
```
|
||||
| File | Responsabilità |
|
||||
|------|---------------|
|
||||
| `main.py` | Entry point PySide6, argparse `--collection` |
|
||||
| `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 |
|
||||
|
||||
Reference in New Issue
Block a user