Files
rag-from-scratch/CLAUDE.md
T
davide 64dc403e80 refactor: ottimizza pipeline PDF→Markdown — struttura piatta e verbosità
- Unifica deps.py + checker.py + converter.py in extract.py (fronte PDF)
- Sposta transforms/ in _pipeline/ (struttura piatta, no sottocartelle)
- Aggiunge spinner animato (thread) durante conversione opendataloader-pdf
- Aggiunge progresso step-by-step [i/37] per apply_transforms via callback
- Mostra punteggio qualità (score/100 grade) a fine elaborazione
- Fix: _DOTLEADER_RE spostata in _constants.py (non più definita inline)
- Fix: report.py importa regex da _constants invece di ridefinirle
- Fix: _t_remove_urls ora conta e ritorna le rimozioni effettive

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 14:30:41 +02:00

8.1 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Missione

Convertire PDF digitali in Markdown perfetto per la vettorizzazione RAG, senza revisione manuale. L'output deve essere testo pulito, strutturato in sezioni semanticamente coerenti, privo di artefatti, pronto per chunking e indicizzazione in un vector store.

Non supportato: PDF scansionati (immagini), PDF protetti da password.


Regole invarianti

  • Lingua: Rispondi sempre in italiano.
  • Venv: Usa .venv/bin/python o source .venv/bin/activate. Mai pip/python di sistema.
  • raw.md immutabile: Non modificare mai raw.md. La copia di lavoro è sempre clean.md.
  • Obiettivo zero revisioni: ogni miglioramento alla pipeline deve ridurre i casi in cui il clean.md richiede correzioni manuali.

Setup

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# Java 11+ richiesto da opendataloader-pdf
sudo apt install default-jdk   # Ubuntu/Debian/WSL
java -version

Comandi

# Converti un PDF (posizionalo prima in sources/<nome>.pdf)
.venv/bin/python conversione/ --stem <nome>

# Tutti i PDF in sources/
.venv/bin/python conversione/

# Forza riesecuzione (sovrascrive clean.md esistente)
.venv/bin/python conversione/ --stem <nome> --force

# Validazione batch di tutti gli stem
.venv/bin/python conversione/ validate

# Validazione con dettaglio penalità
.venv/bin/python conversione/ validate <stem> --detail

# Rimuove l'output di uno stem
bash conversione/clear.sh <nome>

--stem = nome file PDF senza estensione.


Architettura

Il codice è organizzato in conversione/__main__.py (entry point) e il package conversione/_pipeline/ (logica modulare).

conversione/
├── __main__.py          # Entry point unificato: convert + validate
├── clear.sh             # Rimuove output di uno stem
└── _pipeline/
    ├── __init__.py      # Re-export pubblico
    ├── extract.py       # _check_deps() + validate_pdf() + convert_pdf()
    ├── runner.py        # run() — orchestrazione 4 fasi
    ├── structure.py     # analyze() + rilevamento lingua e struttura
    ├── report.py        # build_report() → report.json
    ├── validator.py     # validate() + _score() + _grade()
    ├── _apply.py        # apply_transforms() — orchestratore in ordine semantico
    ├── _constants.py    # Regex compilate e mappe statiche condivise
    ├── _encoding.py     # Gruppo 1: PUA font Symbol, accenti LaTeX, simboli SI
    ├── _artifacts.py    # Gruppo 2: immagini, BR, footnote, URL, righe ricorrenti, watermark
    ├── _headers.py      # Gruppo 3: normalizzazione livelli, concat, bold, ALLCAPS
    ├── _structure.py    # Gruppo 4: TOC, ALLCAPS→##, sezioni numerate, math, articoli
    ├── _text.py         # Gruppo 5: merge paragrafi, whitespace, poesia, versi
    ├── _finish.py       # Gruppo 6: header vuoti/garbage, formula-header, frontmatter
    └── _helpers.py      # Funzioni pure condivise (_sentence_case, _is_allcaps_line, ecc.)

__main__.py — entry point unificato

CLI con due modalità: conversione (default, --stem, --force) e validazione (subcommand validate, con stems opzionali e --detail). Aggiunge conversione/ a sys.path e delega a _pipeline. Uso: python conversione/ [--stem X] [--force] oppure python conversione/ validate [X] [--detail].

_pipeline/extract.py — fronte PDF

Raggruppa in un unico modulo le tre responsabilità legate al PDF: _check_deps() verifica che opendataloader-pdf e Java 11+ siano disponibili; validate_pdf(pdf_path) -> (bool, str) controlla esistenza, dimensione e presenza di testo digitale; convert_pdf(pdf_path, out_dir) -> Path invoca opendataloader-pdf con i parametri RAG-ottimali e restituisce il percorso del .md prodotto. Auto-rileva i PDF taggati (Word/InDesign) per attivare use_struct_tree.

_pipeline/_apply.py — cuore della pipeline

Contiene apply_transforms(text) -> (text, stats) che chiama ~35 trasformazioni atomiche (_t_*) in ordine semantico fisso — non modificare l'ordine senza capire le dipendenze tra gruppi. Ogni _t_* vive nel modulo del suo gruppo; le costanti regex compilate stanno in _constants.py.

Ordine logico dei gruppi:

  1. Encoding (_encoding.py) — PUA font Symbol, accenti backtick LaTeX, moltiplicazione, micro
  2. Pulizia artefatti (_artifacts.py) — immagini, <br>, footnote superscript, URL, box symbol, righe ricorrenti, watermark
  3. Struttura header (_headers.py) — fix header+body concatenati, Capitolo inline, normalizzazione livelli numerati, #######, bold, ALL-CAPS
  4. Costruzione struttura (_structure.py) — TOC rimosso, ALL-CAPS→##, sezioni numerate→###, ambienti matematici, articoli
  5. Testo (_text.py) — merge paragrafi spezzati, whitespace, blank lines, poesia, versi
  6. Rifinitura (_finish.py) — header vuoti, garbage header, merge titoli isolati, frontmatter

Flag automatico: se il testo contiene "Esercizi/Problems/Homework", _t_numbered_sections non converte - N. testo in header (sono numerazioni di esercizi, non titoli).

_pipeline/structure.py — analisi struttura

analyze(md_path) -> dict conta #/##/###, rileva lingua (it/en/fr/de/es), sceglie strategia_chunking:

Strategia Condizione
h3_aware ≥5 ###
h2_paragraph_split ≥3 ##, pochi ###
paragraph struttura rada
sliding_window testo piatto

_pipeline/report.py — metriche qualità

build_report() genera report.json con: statistiche trasformazioni, struttura, distribuzione lunghezze sezioni (min/p25/mediana/p75/max), anomalie (bare headers, sezioni corte/lunghe), residui con esempi (backtick, dot-leader, URL, <br>, simboli encoding, formule inline, footnote, PUA).

validate.py — scoring

Assegna un voto 0100 (A/B/C/D/F) leggendo report.json. Penalità principali:

Problema Penalità Cap
Struttura assente (livello 0) 40
Struttura piatta (livello 1) 15
Backtick residui 2/cad 20
Caratteri PUA font Symbol 2/cad 20
Dot-leader 5/cad 10
URL/watermark 5/cad 15
<br> inline 2/cad 15
Bare headers 3/cad 15

Cosa rende un Markdown perfetto per la vettorizzazione

  • Struttura semantica: header Markdown = confini naturali dei chunk; ogni sezione è un'unità concettuale.
  • Testo pulito: nessun backtick, dot-leader, footnote superscript, carattere PUA, <br>.
  • Paragrafi interi: nessuna frase troncata da salto pagina PDF.
  • Formule e simboli: lettere greche e operatori in Unicode standard, non in font-encoding privato.
  • Nessun rumore strutturale: TOC, header/footer ripetuti, URL, watermark — tutto rimosso.
  • Gerarchia corretta: h1/h2/h3 riflettono la struttura logica, non il layout tipografico.

Linee guida per migliorare la pipeline

Quando si aggiunge una trasformazione in apply_transforms():

  • Ogni _t_* deve restituire (testo, n_modifiche) — il contatore alimenta report.json.
  • Implementare la funzione nel modulo del gruppo corretto (_encoding.py, _artifacts.py, ecc.), importarla in _apply.py e inserire la coppia ("stat_key", _t_nuova) nella lista _transforms nel punto logicamente corretto.
  • Compilare i pattern regex in _constants.py come costanti di modulo, mai dentro la funzione.
  • Testare con .venv/bin/python conversione/ --stem <stem> --force e confrontare report.json.
  • Un nuovo tipo di artefatto: prima aggiungerlo come residuo in report.py (funzione _scan), poi implementare la _t_* che lo rimuove.
  • I residui in report.py usano _MATH_SYMBOLS_RE, _EXERCISE_TRIGGER_RE e _MATH_HDR_RE da transforms._constants — non ridefinirli localmente.

Skills custom

  • /prepare-md <path|stem> — corregge clean.md quando la pipeline non basta: sillabazione, artefatti residui, header malformati, gerarchia incoerente.