# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. --- ## Lingua e comportamento - **Lingua:** Rispondi sempre in italiano. - **Prima di eseguire qualsiasi istruzione**, esponi: 1. Come intendi procedere (approccio, file coinvolti). 2. Se l'istruzione ha problemi concettuali — e perché — con una proposta alternativa. 3. Aspetta conferma o correzione prima di toccare il codice, salvo che l'istruzione sia banale (rinomina, formattazione). --- ## Missione 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. --- ## Regole invarianti - **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 scrive solo in `chunks//`. --- ## Input — struttura MinerU ``` sources/_output/auto/.md ← Markdown strutturato (input della pipeline) sources/_output/auto/images/ ← immagini estratte ``` `` = nome del documento, usato come identificatore in tutti i comandi. --- ## Comandi ```bash # Setup python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt # Chunking .venv/bin/python chunks/chunker.py --stem .venv/bin/python chunks/chunker.py # tutti gli stem in sources/ .venv/bin/python chunks/chunker.py --stem --force # rigenera anche se già presente # Vettorizzazione (richiede Ollama attivo) .venv/bin/python ingestion/ingest.py --stem .venv/bin/python ingestion/ingest.py --collection --stems doc1 doc2 doc3 .venv/bin/python ingestion/ingest.py --stem --force # RAG interattivo .venv/bin/python rag/rag.py --collection .venv/bin/python rag/rag.py --stem # Retrieval puro (debug senza LLM) .venv/bin/python rag/retrieve.py --stem .venv/bin/python rag/retrieve.py --collection --top-k 10 # GUI desktop .venv/bin/python gui/main.py .venv/bin/python gui/main.py --collection # Verifica ambiente Ollama .venv/bin/python ollama/check_env.py ``` --- ## Architettura ### Chunking — `chunks/` | File | Responsabilità | |------|---------------| | `chunker.py` | Entry point: legge `.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` | Output per stem: `chunks//chunks.json`, `chunks//meta.json`, `chunks//report.json` **Schema chunk** (`chunks.json`): | 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` | ### Vettorizzazione — `ingestion/` | 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`, `NO_THINK`, `OLLAMA_MODEL`, `OLLAMA_URL`, `SYSTEM_PROMPT` | ### GUI — `gui/` | 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`. ### Utility — `ollama/` | 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 |