Avanzato 11 minOttimizzazione

strategie di chunking

Risposta diretta

Per un RAG locale, parti da chunk di 300–500 token con una sovrapposizione dello 0–10%, suddivisi in corrispondenza dei paragrafi e dei titoli anziché in base al numero di caratteri, poi valuta i risultati sulle tue domande prima di modificare i parametri. Non è stato dimostrato che il chunking semantico valga il suo costo: uno studio del 2024 conclude che i suoi benefici non giustificano il calcolo aggiuntivo. L'impostazione più importante è suddividere il testo nei suoi punti di separazione naturali.

La suddivisione dei documenti in passaggi determina ciò che la ricerca può recuperare: un passaggio tagliato nel punto sbagliato non contiene mai la risposta completa, mentre un passaggio troppo ampio fa perdere la risposta nel rumore. Questa guida confronta le strategie più comuni, fornisce dimensioni iniziali basate su studi pubblicati, segnala la trappola delle unità (token o caratteri) e propone un protocollo per verificare la tua scelta sui tuoi documenti.

Di Mohamed Meguedmi·Agg. 2026-09-30·Testato su Windows, macOS e Linux

#Perché il chunking pesa tanto quanto il modello di embedding

Il chunking è l'operazione che suddivide un documento in passaggi prima di indicizzarli: ogni passaggio riceve un vettore, ed è un passaggio, mai l'intero documento, a essere recuperato e poi trasmesso al modello linguistico. Tutto ciò che segue dipende da questa suddivisione. Se la frase che risponde alla domanda viene divisa tra due passaggi, nessuno dei due la contiene per intero e la ricerca non la trova; se il passaggio mescola tre argomenti, il suo vettore è una media poco definita che non presenta una forte somiglianza con nessuna domanda. Un embedding più potente non corregge una suddivisione difettosa, perché può vettorizzare solo ciò che gli viene fornito.

Uno studio di Chroma sulla valutazione delle strategie di suddivisione lo dimostra: i metodi euristici come RecursiveCharacterTextSplitter danno spesso buoni risultati nella pratica quando sono configurati correttamente, e i risultati variano nettamente a seconda della dimensione e della sovrapposizione scelte. Questa guida non promette quindi alcun miglioramento generale espresso in cifre: l'unica cosa affidabile è effettuare misurazioni sui tuoi documenti.

i
Un buon chunk
Un buon brano contiene un'idea completa, comprensibile da sola. Se è troppo breve, l'idea viene troncata e il vettore è poco definito; se è troppo lungo, più idee si mescolano e la ricerca restituisce rumore.

#Quale dimensione dei chunk scegliere

Il kit RAG Locale

I tuoi documenti, la tua IA: un RAG locale affidabile sui tuoi PDF, sulle tue note e sulle tue email — senza inviare nulla nel cloud.

  • Spazio online a vita
  • PDF + file
  • Aggiornamenti a vita

Non esiste una dimensione universale, ma ci sono dei punti di riferimento. Nello studio di Chroma, la strategia ricorsiva supera la suddivisione per token per dimensioni di 400 token o meno senza sovrapposizione, mentre il comportamento cambia per dimensioni maggiori e con sovrapposizione. La configurazione predefinita dello strumento di ricerca nei file di OpenAI, 800 token con 400 di sovrapposizione, ottiene in questo banco di prova un recall leggermente inferiore alla media e i punteggi più bassi su tutte le altre metriche. Le indicazioni qui sotto ne derivano, senza pretendere di essere esatte per il tuo corpus.

Dimensioni iniziali in base al tipo di documento e di domanda
DimensioneAdatto aRischio
Da 200 a 300 tokenDomande fattuali precise (una data, una clausola, un valore) in documenti densiPerde il contesto attorno alla risposta; ricorda di aggiungere il titolo della sezione
Da 300 a 500 tokenPunto di partenza generale per documentazione, procedure, articoliPochi rischi; è l'area da testare per prima
Da 500 a 800 tokenTesti argomentativi in cui le idee si estendono su diversi paragrafiIl vettore diluisce diverse idee; il prompt si riempie più velocemente
Più di 1.000 tokenRaramente adatto alla ricerca; da riservare a un livello padre in una suddivisione gerarchicaVettore troppo generico, passaggi difficili da ordinare
→
Punto di partenza
Inizia con 400 token e una sovrapposizione da 0 a 50 token, prova 250 e 700 e cambia solo dopo aver misurato il recall sulle tue domande.

#Token o caratteri: la trappola delle unità

Non tutte le librerie usano la stessa unità di misura. Il SentenceSplitter di LlamaIndex esprime chunk_size e chunk_overlap in token, con valori predefiniti di 1024 e 200 secondo la sua documentazione. Altri strumenti, tra cui il RecursiveCharacterTextSplitter di LangChain, contano per impostazione predefinita in caratteri; verifica il parametro length_function della tua versione. Impostare «500» nell'uno o nell'altro produce chunk le cui dimensioni differiscono di un fattore dell'ordine di quattro. Secondo vincolo: il modello di embedding ha una propria lunghezza massima di input. Il modello BGE-M3 gestisce input fino a 8.192 token secondo la sua scheda; altri modelli di embedding, più vecchi o più leggeri, ne accettano nettamente meno, e oltre il limite la parte finale del passaggio viene ignorata. Verifica il limite del tuo modello prima di scegliere la dimensione e conta usando il tokenizer del modello anziché stimare a occhio.

#Sovrapposizione: utile, ma non sempre

La sovrapposizione ripete la fine di un chunk all'inizio del successivo, affinché una frase interrotta al confine tra due chunk resti leggibile per intero almeno in uno dei due. Ha un costo: più chunk, un indice più grande e duplicati nei risultati. Lo studio di Chroma osserva che riducendo la sovrapposizione si migliora il punteggio IoU, una metrica che penalizza le informazioni ridondanti. La sovrapposizione è giustificata se suddividi il testo in chunk di dimensione fissa; conta meno se lo suddividi già in corrispondenza dei paragrafi e dei titoli, perché in quel caso le divisioni coincidono con i confini naturali del testo.

0 token
Sufficiente con una suddivisione per paragrafi o in base alla struttura; il più economico.
Dal 10 al 15% della dimensione
Un buon compromesso quando si suddivide il testo per frasi o caratteri.
Più del 25 %
Raramente giustificato: molta ridondanza, passaggi quasi identici nei risultati.

#Strategie di suddivisione, dalla più semplice alla più costosa

#1. Con un numero fisso di caratteri

Tagliare ogni N caratteri o token, senza esaminare il testo. Il metodo più semplice e più distruttivo: taglia nel mezzo di parole, frasi e tabelle. Da riservare ai prototipi.

#2. Per paragrafi o per frasi

Suddividere in corrispondenza dei doppi ritorni a capo o dei segni di punteggiatura, poi raggruppare le unità fino alla dimensione desiderata. Un netto miglioramento a costo nullo, perché ogni chunk inizia e finisce in corrispondenza di un confine naturale.

#3. Ricorsivo

Si provano prima i separatori che delimitano blocchi più ampi (paragrafo, riga, frase, spazio), e si passa ai singoli caratteri solo come ultima risorsa. È il comportamento predefinito nei principali framework e costituisce una base solida: lo studio di Chroma rileva che questo tipo di suddivisione, se ben configurato, dà spesso buoni risultati.

#4. Secondo la struttura del documento

Si rispettano i titoli, gli elenchi, le tabelle e i blocchi di codice. Il MarkdownNodeParser di LlamaIndex, per esempio, suddivide il testo in base ai titoli e associa a ciascun nodo il percorso dei titoli che conducono a quel nodo, dando così al passaggio un contesto che il suo testo da solo non offre. È la scelta migliore per documentazione tecnica, wiki e pagine HTML esportate.

#5. Semantica

Si calcola un embedding per frase, poi si suddivide il testo nei punti in cui la similarità cala tra due frasi adiacenti. In LlamaIndex, SemanticSplitterNodeParser accetta buffer_size (numero di frasi confrontate insieme, 1 per impostazione predefinita) e breakpoint_percentile_threshold (95 per impostazione predefinita; un valore più basso crea più nodi). Il costo è un calcolo aggiuntivo degli embedding durante l'indicizzazione, e il beneficio non è dimostrato: uno studio di ottobre 2024 su tre compiti di recupero conclude che i costi computazionali della suddivisione semantica non sono giustificati da miglioramenti costanti delle prestazioni. Provalo sul tuo corpus prima di adottarlo.

#6. Gerarchico (padre e figlio)

Indicizziamo piccoli chunk per garantire la precisione della ricerca e restituiamo al modello il blocco padre più ampio per fornire il contesto. HierarchicalNodeParser di LlamaIndex produce questo tipo di gerarchia, ad esempio su tre livelli di 2048, 512 e 128 token secondo la sua documentazione. È la risposta ai passaggi lunghi: né solo chunk piccoli, né solo chunk grandi.

Quale strategia per quale documento
Tipo di documentoStrategia consigliata
Documentazione, wiki, Markdown, HTMLSuddivisione per struttura (titoli), poi suddivisione ricorsiva all'interno delle sezioni lunghe
Contratti, testi giuridiciStruttura per articoli o clausole; dimensione compresa tra 300 e 500 token; il titolo dell'articolo riportato in ogni chunk
Prosa libera senza struttura (email, note, trascrizioni)Ricorsivo, sovrapposizione del 10 %, eventualmente gerarchico
PDF con tabelleEstrazione preliminare della struttura, una tabella per chunk o per riga a seconda delle domande
Codice sorgenteDivisione per funzione o per classe, mai al centro di un blocco

#Implementazioni con LlamaIndex

Divisione per frasi con sovrapposizione
from llama_index.core.node_parser import SentenceSplitter

splitter = SentenceSplitter(chunk_size=400, chunk_overlap=40)  # en tokens
nodes = splitter.get_nodes_from_documents(docs)
Secondo la struttura Markdown
from llama_index.core.node_parser import MarkdownNodeParser

parser = MarkdownNodeParser()
nodes = parser.get_nodes_from_documents(docs)
# le chemin des titres est stocké dans les métadonnées de chaque nœud
Gerarchico
from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes

parser = HierarchicalNodeParser.from_defaults(chunk_sizes=[2048, 512, 128])
nodes = parser.get_nodes_from_documents(docs)
leaves = get_leaf_nodes(nodes)  # ce sont les feuilles qu'on vectorise
Semantica (da testare prima di adottarla)
from llama_index.core.node_parser import SemanticSplitterNodeParser
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed = HuggingFaceEmbedding(model_name="BAAI/bge-m3")
splitter = SemanticSplitterNodeParser(embed_model=embed, buffer_size=1, breakpoint_percentile_threshold=95)
nodes = splitter.get_nodes_from_documents(docs)

#Ripristinare il contesto per ogni chunk

Un passaggio estratto dal suo documento perde i suoi riferimenti: «Il termine è di 30 giorni» non dice di cosa si tratta. Tre semplici pratiche risolvono il problema. Anteporre a ogni chunk il titolo del documento e il percorso della sezione; memorizzare queste informazioni nei metadati per filtrare (per data, per fonte, per tipo di documento); e, per i passaggi che iniziano con un pronome o un riferimento («questa clausola»), considerare il livello padre della suddivisione gerarchica. Spesso basta una sola riga di contesto prima del testo, e costa molto meno di cambiare modello.

#Valutare il chunking prima di fissarlo

  1. 01
    Scrivere da 30 a 50 domande reali
    Domande che i tuoi utenti porrebbero, ciascuna accompagnata dal passaggio del documento di origine atteso; scrivile prima di guardare i risultati.
  2. 02
    Indicizzare con due o tre configurazioni
    Ad esempio 250, 400 e 700 token, con una sovrapposizione dello 0% e del 10%. Mantieni gli altri parametri identici.
  3. 03
    Misurare il recall nei primi 5 risultati
    Per ogni domanda, il passaggio atteso compare nei primi 5 risultati? La percentuale indica il recall a 5.
  4. 04
    Valutare anche la precisione e la ridondanza
    A parità di recall, risultati più vari indicano un'impostazione migliore. Conta i duplicati nei primi 5 risultati.
  5. 05
    Esaminare i casi falliti uno per uno
    Per ogni domanda a cui non è stata data una risposta corretta, apri il chunk che avrebbe dovuto fornire la risposta: è troncato, troppo ampio o estratto male? La causa determina la correzione da apportare.

#Insidie comuni

Tabelle compromesse
Un estrattore PDF che appiattisce una tabella produce righe di celle prive di senso: estrai prima la struttura, prima di suddividere il testo in blocchi.
Blocchi di codice tagliati
Uno strumento di suddivisione che non tiene conto della sintassi spezza un blocco a metà; usa una suddivisione basata sulla struttura.
Documenti misti
Un chunk metà francese, metà inglese, genera un vettore medio poco utile: separa per lingua se il corpus è misto.
Chunk quasi vuoti
Un titolo da solo (« 3.2.1 Obblighi ») senza il testo che segue è rumore: filtra i chunk troppo corti o uniscili a quello successivo.
Cambiare il chunking senza reindicizzare
La suddivisione viene fissata al momento dell'indicizzazione: ogni modifica richiede di ricalcolare i vettori. Prevedi uno script di reindicizzazione fin dall'inizio.
!
Non ottimizzare alla cieca
Senza un insieme di domande, non si sa se una regolazione migliora o peggiora i risultati. Una dimensione «che sembra ragionevole» ha un effetto misurabile, in senso positivo o negativo, sul recall.

#Domande frequenti sul chunking

FAQ
Quale dimensione dei chunk scegliere per un RAG locale?+
Inizia con una dimensione compresa tra 300 e 500 token, con una sovrapposizione dallo 0 al 10%, e suddividi il testo in corrispondenza dei paragrafi o dei titoli. Prova poi 250 e 700 token su un insieme di 30–50 delle tue domande reali, confrontando il recall nei primi 5 risultati. Non esiste un valore universale: dipende dai tuoi documenti e dalle tue domande.
Il chunking semantico giustifica il suo costo?+
Non sempre. Richiede un calcolo aggiuntivo degli embedding durante l'indicizzazione, e uno studio di ottobre 2024 su tre compiti di recupero conclude che questo costo non è giustificato da miglioramenti costanti rispetto a una suddivisione in blocchi di dimensione fissa. Provalo sul tuo corpus: se non offre risultati migliori, mantieni il chunking ricorsivo.
È necessaria una sovrapposizione tra i chunk?+
Non sempre. Se suddividi già il testo in corrispondenza dei paragrafi e dei titoli, spesso non serve alcuna sovrapposizione. Se lo suddividi in blocchi di dimensione fissa o in corrispondenza delle frasi, una sovrapposizione del 10–15% evita di perdere una frase al confine tra i blocchi. Una sovrapposizione elevata moltiplica i duplicati nei risultati e aumenta le dimensioni dell'indice.
Token o caratteri: come impostare chunk_size?+
Verifica l'unità usata dalla tua libreria. Il SentenceSplitter di LlamaIndex conta in token; altri strumenti contano per impostazione predefinita in caratteri, il che cambia la dimensione effettiva di un fattore di circa quattro. Verifica anche la lunghezza massima dell'input del tuo modello di embedding: oltre questo limite, il brano viene troncato durante l'indicizzazione.
Come dividere un PDF con tabelle?+
Estrai prima la struttura con uno strumento che riconosce le tabelle, poi suddividi il contenuto: una tabella per chunk se è piccola, una riga della tabella per chunk accompagnata dall'intestazione se è grande. Un estrattore che appiattisce la tabella in testo semplice produce passaggi inutilizzabili, qualunque sia la suddivisione scelta in seguito.
È necessario reindicizzare quando si cambia la dimensione dei chunk?+
Sì, sempre. I vettori vengono calcolati sui passaggi così com'erano al momento dell'indicizzazione: modificare la dimensione, la sovrapposizione o lo strumento di suddivisione impone di ricalcolare tutti i vettori. Mantieni uno script che ricostruisca l'indice dai documenti sorgente e tieni sotto controllo di versione i parametri di suddivisione utilizzati.
Questa guida ti è stata utile?

Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.