feat(chunks): target-based chunking con config centralizzata
Introduce chunks/config.py come unica fonte di verità per tutti i parametri della pipeline di chunking. TARGET_CHARS + CHUNK_TOLERANCE sostituiscono MIN_CHARS/MAX_CHARS: il chunker mira a una dimensione target e si avvicina il più possibile rispettando il vincolo assoluto di terminare ogni chunk su un confine di frase (punto/punteggiatura). - config.py: TARGET_CHARS, CHUNK_TOLERANCE, SPLIT_THRESHOLD_FACTOR, PROTECT_TABLES, FIX_MAX_ITERATIONS, STRATEGY_OVERRIDES per strategia - chunker.py: algoritmo target-based (emit quando frase successiva sfora upper_body = upper - prefix_len), table protection atomica, override MIN/MAX/overlap per ciascuna delle 4 strategie - verify_chunks.py: soglie derivate da target*(1±tolerance) - fix_chunks.py: _split_at_boundary sempre su punteggiatura finale, loop ricorsivo fix→verify fino a FIX_MAX_ITERATIONS, split solo per chunk > upper × SPLIT_THRESHOLD_FACTOR Risultato su bitcoin: 694 chunk, 0 incompleti, 83% in range [450,750], tutti terminanti su punteggiatura indipendentemente dalla dimensione. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Parametri di configurazione della pipeline di chunking.
|
||||
|
||||
Modifica questo file per cambiare il comportamento di chunker.py,
|
||||
verify_chunks.py e fix_chunks.py senza toccare il codice applicativo.
|
||||
"""
|
||||
|
||||
# ─── Grandezza target dei chunk ───────────────────────────────────────────────
|
||||
#
|
||||
# TARGET_CHARS è la dimensione ideale a cui il chunker mira.
|
||||
# CHUNK_TOLERANCE è la tolleranza relativa (es. 0.25 = ±25%).
|
||||
#
|
||||
# range accettabile = [TARGET × (1 − TOL), TARGET × (1 + TOL)]
|
||||
#
|
||||
# Con TARGET=600 e TOL=0.25 → ogni chunk sarà tra 450 e 750 char,
|
||||
# il più vicino possibile a 600, terminando sempre su un confine di frase.
|
||||
#
|
||||
TARGET_CHARS = 600
|
||||
CHUNK_TOLERANCE = 0.25
|
||||
|
||||
# ─── Overlap ──────────────────────────────────────────────────────────────────
|
||||
|
||||
# Numero di frasi ripetute all'inizio del chunk successivo per preservare
|
||||
# il contesto tra chunk adiacenti della stessa sezione.
|
||||
OVERLAP_SENTENCES = 1
|
||||
|
||||
# ─── Soglie di validazione ────────────────────────────────────────────────────
|
||||
|
||||
# fix_chunks.py spezza un chunk "too_long" solo se supera upper × questo fattore.
|
||||
# Es. upper=750, fattore=1.5 → split solo per chunk > 1125 char.
|
||||
# Chunk in [upper, upper×fattore] restano come warning non bloccanti.
|
||||
SPLIT_THRESHOLD_FACTOR = 1.5
|
||||
|
||||
MATH_SYMS_MIN = 3 # min. simboli math per declassare incomplete → incomplete_math
|
||||
|
||||
# ─── Pattern e formato ────────────────────────────────────────────────────────
|
||||
|
||||
SENTENCE_SPLIT_PATTERN = r"(?<=[.!?»])\s+"
|
||||
PREFIX_TEMPLATE = "[{sezione} > {titolo}]"
|
||||
|
||||
# ─── Protezione contenuti speciali ────────────────────────────────────────────
|
||||
|
||||
# Se True, un blocco prevalentemente tabella Markdown (≥50% righe |…|)
|
||||
# viene emesso come chunk atomico senza sentence-splitting.
|
||||
PROTECT_TABLES = True
|
||||
|
||||
# Riservato — blocchi LaTeX non spezzabili (implementazione futura).
|
||||
PROTECT_MATH = True
|
||||
|
||||
# ─── Fix behavior ─────────────────────────────────────────────────────────────
|
||||
|
||||
# Numero massimo di iterazioni del loop fix → verify → fix.
|
||||
# Con 1 si ottiene il comportamento originale (fix singolo senza re-verifica).
|
||||
FIX_MAX_ITERATIONS = 3
|
||||
|
||||
# ─── Override per strategia ───────────────────────────────────────────────────
|
||||
#
|
||||
# Sovrascrivono TARGET_CHARS / CHUNK_TOLERANCE / OVERLAP_SENTENCES
|
||||
# per la specifica strategia indicata in structure_profile.json.
|
||||
# Chiavi riconosciute: "target_chars", "tolerance", "overlap".
|
||||
#
|
||||
STRATEGY_OVERRIDES: dict[str, dict] = {
|
||||
"h3_aware": {
|
||||
# Documenti strutturati H2→H3: chunk medi, overlap moderato.
|
||||
"target_chars": 600,
|
||||
"tolerance": 0.25,
|
||||
"overlap": 2,
|
||||
},
|
||||
"h2_paragraph_split": {
|
||||
# Documenti piatti (solo H2): chunk più ampi, overlap ridotto.
|
||||
"target_chars": 800,
|
||||
"tolerance": 0.25,
|
||||
"overlap": 1,
|
||||
},
|
||||
"paragraph": {
|
||||
# Documenti senza header significativi: chunk più corti.
|
||||
"target_chars": 500,
|
||||
"tolerance": 0.30,
|
||||
"overlap": 1,
|
||||
},
|
||||
"sliding_window": {
|
||||
# Testo lineare/narrativo: finestre ampie, overlap generoso.
|
||||
"target_chars": 800,
|
||||
"tolerance": 0.25,
|
||||
"overlap": 3,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user