docs(README): aggiungi istruzioni manuali senza Claude per step 4 e 6
Step 4: sostituisce la sezione "Revisione manuale residua" con 6 check
grep/python eseguibili da terminale (sillabazione, righe orfane, frasi
spezzate, header, sezioni vuote, gerarchia).
Step 6: aggiunge sottosezione "Senza Claude Code" con tabella delle 3
condizioni di output di verify_chunks, spiegazione delle operazioni di
fix_chunks --dry-run e tabella dei 4 casi di 🔴 persistenti con la
correzione specifica in clean.md.
This commit is contained in:
@@ -359,12 +359,75 @@ La skill analizza `step-4/<stem>/clean.md` e produce un report strutturato:
|
||||
|
||||
Poi propone le correzioni e le applica solo su tua approvazione.
|
||||
|
||||
#### Revisione manuale residua
|
||||
#### Revisione manuale (senza Claude Code)
|
||||
|
||||
Apri `step-4/<stem>/clean.md` nel tuo editor e verifica quanto segnalato
|
||||
dalla skill. Il criterio di qualità rimane lo stesso:
|
||||
Se non usi Claude Code, esegui questi 6 check dal terminale.
|
||||
In tutti i comandi sostituisci `<stem>` con il nome reale del documento.
|
||||
|
||||
**Struttura target:**
|
||||
**Check 1 — Sillabazione residua**
|
||||
Parole spezzate a fine riga con trattino (artefatto da PDF non risolto):
|
||||
```bash
|
||||
grep -n "\-$" step-4/<stem>/clean.md | head -20
|
||||
```
|
||||
Se trovi risultati: unisci la riga con la successiva eliminando il trattino
|
||||
e il ritorno a capo.
|
||||
|
||||
**Check 2 — Righe orfane**
|
||||
Righe brevi (<60 char) isolate che sembrano numeri di pagina, autori, intestazioni:
|
||||
```bash
|
||||
grep -n "^[^#\-\*\|].\{1,59\}$" step-4/<stem>/clean.md | grep -v "^\s*$" | head -30
|
||||
```
|
||||
Per ogni riga: valuta se è testo legittimo (frase breve) o artefatto
|
||||
(numero di pagina, nome autore ripetuto, intestazione PDF). Gli artefatti vanno eliminati.
|
||||
|
||||
**Check 3 — Frasi spezzate**
|
||||
Paragrafi che terminano senza punteggiatura di fine frase:
|
||||
```bash
|
||||
grep -n "[^.!?»)\]\'\"]$" step-4/<stem>/clean.md \
|
||||
| grep -v "^[0-9]*:#" \
|
||||
| grep -v "^[0-9]*:\s*$" \
|
||||
| grep -v "^\s*[-\*]" \
|
||||
| head -20
|
||||
```
|
||||
Segnala le righe brevi che finiscono a metà concetto. Uniscile alla riga successiva.
|
||||
|
||||
**Check 4 — Header sospetti**
|
||||
```bash
|
||||
grep -n "^##\? " step-4/<stem>/clean.md | head -40
|
||||
```
|
||||
Verifica:
|
||||
- Header con testo >80 caratteri → probabilmente è testo normale, non un header
|
||||
- Header in MAIUSCOLO non convertito → cambia in formato sentence-case
|
||||
- Header duplicati (stesso testo due volte) → valuta se unire o rinominare
|
||||
- `###` senza un `##` padre → salto di gerarchia anomalo
|
||||
|
||||
**Check 5 — Sezioni quasi vuote**
|
||||
```bash
|
||||
python3 -c "
|
||||
import re
|
||||
text = open('step-4/<stem>/clean.md').read()
|
||||
sections = re.split(r'^(#{1,3} .+)$', text, flags=re.MULTILINE)
|
||||
for i in range(1, len(sections)-1, 2):
|
||||
header = sections[i].strip()
|
||||
body = sections[i+1].strip() if i+1 < len(sections) else ''
|
||||
if not body:
|
||||
print(f'VUOTA: {header!r}')
|
||||
elif len(body) < 80:
|
||||
print(f'CORTA ({len(body)} char): {header!r} → {body[:60]!r}')
|
||||
"
|
||||
```
|
||||
Le sezioni vuote generano chunk inutili. Eliminale o accorpale alla sezione precedente.
|
||||
|
||||
**Check 6 — Gerarchia strutturale**
|
||||
```bash
|
||||
grep -n "^#\{1,3\} " step-4/<stem>/clean.md | head -50
|
||||
```
|
||||
Deve esserci un solo `# h1` all'inizio. Poi `## h2` e opzionalmente `### h3`.
|
||||
Segnala `###` prima del primo `##`, o più di un `#`.
|
||||
|
||||
---
|
||||
|
||||
**Struttura target dopo la revisione:**
|
||||
|
||||
```markdown
|
||||
# Titolo del documento
|
||||
@@ -378,20 +441,10 @@ Ogni paragrafo è semanticamente autonomo.
|
||||
Una riga vuota separa le sezioni.
|
||||
```
|
||||
|
||||
**Il criterio di qualità:**
|
||||
Leggi ogni sezione ad alta voce. Se suona naturale e fluente è corretta.
|
||||
**Criterio di qualità:**
|
||||
Leggi ogni sezione ad alta voce. Se suona naturale è corretta.
|
||||
Se si interrompe c'è una riga spezzata. Se suona ripetitiva c'è un artefatto.
|
||||
|
||||
**Traccia il lavoro:**
|
||||
|
||||
```bash
|
||||
# step-4/revision_log.md viene aggiornato automaticamente da revise.py
|
||||
# Commita dopo la revisione manuale
|
||||
|
||||
git add step-4/revision_log.md
|
||||
git commit -m "step-4: revisione nietzsche completata"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 5 — Chunking adattivo
|
||||
@@ -444,37 +497,107 @@ da solo sarebbe ambiguo.
|
||||
|
||||
---
|
||||
|
||||
### Step 6 — Verifica chunk
|
||||
### Step 6 — Verifica e fix chunk
|
||||
|
||||
**Tipo:** automatico
|
||||
**Input:** `step-5/<stem>/chunks.json`
|
||||
**Output:** report problemi + statistiche
|
||||
**Script:** `step-6/verify_chunks.py`
|
||||
**Output:** `step-6/<stem>/chunks.json` verificato + `report.json`
|
||||
**Script:** `step-6/verify_chunks.py`, `step-6/fix_chunks.py`
|
||||
|
||||
```bash
|
||||
python step-6/verify_chunks.py --stem documento
|
||||
Questo step si articola in un ciclo: verifica → fix automatico → ri-verifica. Non si va allo step 8 finché non ci sono 🔴.
|
||||
|
||||
**Workflow completo:**
|
||||
|
||||
```
|
||||
1. Verifica
|
||||
python step-6/verify_chunks.py --stem documento
|
||||
|
||||
2a. Se ✅ OK o solo 🟡 → vai allo step 8
|
||||
|
||||
2b. Se ci sono 🔴 → prova il fix automatico:
|
||||
python step-6/fix_chunks.py --stem documento --dry-run # anteprima
|
||||
python step-6/fix_chunks.py --stem documento # applica
|
||||
|
||||
3. Ri-verifica dopo il fix:
|
||||
python step-6/verify_chunks.py --stem documento
|
||||
|
||||
4. Se rimangono 🔴 → torna allo step 4 e correggi clean.md,
|
||||
poi riesegui dall'inizio:
|
||||
python step-5/chunker.py --stem documento --force
|
||||
python step-6/verify_chunks.py --stem documento
|
||||
```
|
||||
|
||||
Analizza ogni chunk e segnala i problemi. Non corregge nulla.
|
||||
Se ci sono problemi torni allo step 4 o aggiusti i parametri
|
||||
dello step 5. Non si va allo step 8 finché questo step è pulito.
|
||||
> **Shortcut con Claude:** usa `/step6-fix <stem>` — esegue dry-run, spiega le operazioni, chiede conferma e ri-verifica automaticamente.
|
||||
|
||||
**Cosa verifica:**
|
||||
#### Senza Claude Code — come leggere l'output e decidere
|
||||
|
||||
- Ogni chunk ha il prefisso di contesto
|
||||
- Nessun chunk è vuoto
|
||||
- Nessun chunk è sotto `MIN_CHARS`
|
||||
- Nessun chunk è sopra `MAX_CHARS` * 1.5
|
||||
- Ogni chunk finisce con punteggiatura (frase completa)
|
||||
**1. Leggi l'output di `verify_chunks.py`**
|
||||
|
||||
**Tabella diagnosi:**
|
||||
L'output termina con una delle tre condizioni:
|
||||
|
||||
| Problema | Causa probabile | Soluzione |
|
||||
| Condizione | Significato | Cosa fare |
|
||||
|---|---|---|
|
||||
| Molti chunk troppo corti | `MIN_CHARS` troppo alto | Abbassa `MIN_CHARS` |
|
||||
| Molti chunk troppo lunghi | `MAX_CHARS` troppo basso | Alza `MAX_CHARS` |
|
||||
| Chunk senza prefisso | Bug nel parsing | Controlla `###` nel MD |
|
||||
| Chunk che finiscono a metà frase | Riga spezzata nel MD | Correggi nello step 4 |
|
||||
| `✅ N/N documenti senza problemi` | Nessun problema | Vai allo step 8 |
|
||||
| `🟡 Solo avvisi minori` | Chunk corti o lunghi, non bloccanti | Puoi andare allo step 8 oppure ottimizzare con `fix_chunks.py` |
|
||||
| `⚠️ 0/N documenti senza problemi` + 🔴 | Frasi spezzate o chunk vuoti | Esegui `fix_chunks.py`, poi ri-verifica |
|
||||
|
||||
**2. Prima di applicare il fix: leggi il dry-run**
|
||||
|
||||
```bash
|
||||
python step-6/fix_chunks.py --stem <stem> --dry-run
|
||||
```
|
||||
|
||||
L'output elenca le operazioni pianificate. Significato:
|
||||
|
||||
| Operazione | Cosa fa | Sicurezza |
|
||||
|---|---|---|
|
||||
| `fondi N chunk incompleti` | Unisce il chunk troncato col successivo | Sempre sicura |
|
||||
| `fondi N chunk troppo corti` | Unisce chunk <200 char col successivo | Sicura se il risultato non supera MAX×1.5 |
|
||||
| `spezza N chunk troppo lunghi` | Divide chunk >1200 char su frasi | Sicura solo se esistono frasi naturali dove spezzare |
|
||||
| `rimuovi N chunk vuoti` | Elimina chunk senza testo | Sempre sicura |
|
||||
|
||||
**3. Se i 🔴 persistono dopo il fix**
|
||||
|
||||
`fix_chunks.py` non riesce ad autocorreggersi quando il problema
|
||||
è nella struttura del testo sorgente. I casi tipici e la soluzione in `clean.md`:
|
||||
|
||||
| Sintomo nel report | Causa in `clean.md` | Correzione |
|
||||
|---|---|---|
|
||||
| Chunk finisce con `:` | Intro di un elenco separata dall'elenco da una riga vuota | Rimuovi la riga vuota tra l'intro e la lista |
|
||||
| Chunk finisce a metà parola | Salto di pagina PDF con numero di pagina nel mezzo | Trova e rimuovi il numero di pagina, unisci le righe |
|
||||
| Chunk con testo artefatto (URL, watermark) | Artefatto non rimosso allo step 4 | Elimina la sezione in `clean.md` |
|
||||
| Chunk con frase enorme non spezzabile | Singolo paragrafo >MAX_CHARS senza frasi intermedie | Spezza manualmente il paragrafo su frasi logiche |
|
||||
|
||||
Dopo ogni correzione in `clean.md` riesegui dall'inizio dello step 5:
|
||||
|
||||
```bash
|
||||
python step-5/chunker.py --stem <stem> --force
|
||||
rm -f step-6/<stem>/chunks.json # forza la rilettura da step-5
|
||||
python step-6/verify_chunks.py --stem <stem>
|
||||
```
|
||||
|
||||
**Cosa verifica `verify_chunks.py`:**
|
||||
|
||||
- Nessun chunk è sotto `MIN_CHARS` 🟡
|
||||
- Nessun chunk è sopra `MAX_CHARS × 1.5` 🟡
|
||||
- Ogni chunk finisce con punteggiatura di fine frase 🔴
|
||||
|
||||
**Cosa corregge `fix_chunks.py`:**
|
||||
|
||||
| Operazione | Quando |
|
||||
|---|---|
|
||||
| Rimuovi chunk vuoti | Chunk privi di testo |
|
||||
| Fondi chunk incompleto col successivo | Chunk che finisce senza punteggiatura |
|
||||
| Fondi chunk troppo corto col successivo | Chunk sotto `MIN_CHARS` |
|
||||
| Spezza chunk troppo lungo | Chunk sopra `MAX_CHARS × 1.5` |
|
||||
|
||||
**Tabella diagnosi — problemi non risolvibili con fix_chunks:**
|
||||
|
||||
| Sintomo | Causa probabile | Soluzione |
|
||||
|---|---|---|
|
||||
| Molti chunk corti dopo il fix | `MIN_CHARS` troppo alto o testo frammentato nel MD | Abbassa `MIN_CHARS` o correggi step 4 |
|
||||
| Chunk spezzato creato dal fix stesso | Frase singola > `MAX_CHARS` non spezzabile | Spezza manualmente il paragrafo in step 4 |
|
||||
| Chunk che finisce a metà frase non risolvibile | Salto di pagina PDF non sanato nel MD | Correggi la riga spezzata in `clean.md` |
|
||||
|
||||
**Output se tutto ok:**
|
||||
|
||||
@@ -487,7 +610,7 @@ Distribuzione lunghezze:
|
||||
Max: 923 char
|
||||
Media: 401 char
|
||||
|
||||
✅ Nessun problema — procedi con la vettorizzazione.
|
||||
✅ 1/1 documenti senza problemi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user