Semantic Chunking
Il chunking semantico suddivide i documenti nei punti in cui cambia l'argomento, misurando la similarità degli embedding tra frasi adiacenti, così ogni blocco contiene un'unica idea.
Il chunking semantico suddivide i documenti in segmenti per la generazione aumentata dal recupero (RAG) e la ricerca, collocando le separazioni nei punti in cui cambia l'argomento, individuati confrontando gli embedding delle frasi adiacenti, anziché ogni numero fisso di caratteri o token. Ogni segmento tratta così una singola idea e il suo vettore nel database vettoriale la rappresenta efficacemente; inoltre, il segmento recuperato fornisce al modello linguistico di grandi dimensioni (LLM) un pensiero completo invece della fine di una sezione e dell'inizio della successiva.
Come funziona il chunking semantico#
L'algoritmo comune, reso popolare dai tutorial sulla suddivisione del testo di Greg Kamradt e implementato come SemanticChunker in LangChain, prevede quattro passaggi. Il testo viene suddiviso in frasi e si calcola l'embedding di ogni frase, spesso raggruppandola con quelle vicine per attenuare il rumore. La similarità coseno tra ogni coppia di frasi consecutive viene convertita in una distanza. Una soglia individua i punti di separazione in corrispondenza di distanze insolitamente elevate: LangChain usa come valore predefinito il 95° percentile di tutte le distanze del documento e offre anche soglie basate sulla deviazione standard, sull'intervallo interquartile e sul gradiente. Le frasi comprese tra due punti di separazione formano un segmento. Il separatore semantico in LlamaIndex usa lo stesso punto di separazione basato sul percentile.
import numpy as np
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
sentences = [
"The XR-12 coolant pump circulates water through the press line.",
"Inspect the XR-12 pump seals for leaks every week.",
"A worn pump bearing grinds loudly before it fails.",
"The staff cafeteria now opens for breakfast at 7:00.",
"The cafeteria menu adds vegetarian lunches in May.",
]
# Distanza coseno tra una frase e la successiva
embeddings = model.encode(sentences, normalize_embeddings=True)
distances = 1 - np.sum(embeddings[:-1] * embeddings[1:], axis=1)
# Inizia un nuovo segmento dove la distanza supera il 95° percentile
threshold = np.percentile(distances, 95)
chunks = [[sentences[0]]]
for sentence, distance in zip(sentences[1:], distances):
if distance > threshold:
chunks.append([])
chunks[-1].append(sentence)
print(np.round(distances, 2))
print(*[" ".join(chunk) for chunk in chunks], sep="\n")Le distanze tra frasi adiacenti sono 0,56, 0,64, 0,98 e 0,62; l'unico punto di separazione è quindi il salto a 0,98 dal cuscinetto della pompa alla mensa, e il risultato è un segmento di tre frasi sulla pompa XR-12 e uno di due frasi sulla mensa.
Confronto tra strategie di suddivisione in segmenti#
- Suddivisione in segmenti di dimensione fissa: divide il testo ogni N token, di solito con una certa sovrapposizione tra segmenti adiacenti. È rapida e prevedibile, ma ignora i confini tra argomenti.
- Suddivisione ricorsiva: divide il testo in corrispondenza delle interruzioni di paragrafo, poi di riga e infine di frase, finché ogni parte rientra in un limite di dimensione. LangChain consiglia il proprio separatore ricorsivo di caratteri per il testo generico.
- Suddivisione consapevole della struttura: segue titoli, sezioni Markdown, elementi HTML o il layout di pagina di un PDF.
- Chunking semantico: segue i cambiamenti di significato, ma richiede di calcolare l'embedding di ogni frase durante l'indicizzazione e produce segmenti di dimensioni molto variabili; per questo le implementazioni aggiungono limiti minimi e massimi.
- Chunking tardivo e recupero contestuale: affrontano i casi in cui un segmento è privo del contesto del resto del documento, per esempio quando un pronome rimanda a un elemento presente in un segmento precedente, e si combinano con uno qualsiasi dei metodi di suddivisione descritti sopra.
Il chunking delle azioni in robotica condivide solo il nome: in questo caso, una policy prevede una sequenza di comandi motori futuri come un'unica unità.
Chunking semantico oltre il testo#
Le trascrizioni dei sistemi di conversione da parlato a testo non hanno interruzioni di paragrafo, quindi i punti di separazione basati sugli embedding sono un metodo comune per individuare i cambi di argomento in una riunione o in un podcast. È possibile suddividere in segmenti anche i video in base al contenuto, così che ogni clip mostri un evento per la comprensione dei video o la RAG multimodale, anziché una porzione arbitraria di 10 secondi. Ultralytics YOLO26 fornisce questi confini per le scene con persone e veicoli: la modalità tracking assegna a ogni oggetto rilevato un ID persistente tra i fotogrammi, così una pipeline può aprire una clip quando entra nella scena un nuovo ID e chiuderla quando tutti gli ID tracciati sono usciti.
Il chunking semantico migliora il recupero?#
I confini basati sugli argomenti sono particolarmente importanti quando temi diversi si trovano uno accanto all'altro senza titoli, come nelle trascrizioni, nelle pagine web raccolte e negli appunti concatenati. I segmenti semantici dipendono anche dal modello di embedding e dalla soglia, quindi lo stesso documento viene suddiviso diversamente quando cambia uno dei due; entrambi andrebbero calibrati in base al richiamo su query reali. Lo studio Il chunking semantico vale il costo computazionale? (2024) ha confrontato la suddivisione semantica e quella a dimensione fissa nel recupero di documenti, nel recupero di prove e nella generazione di risposte basata sul recupero, rilevando che il maggior costo computazionale del chunking semantico non ha prodotto miglioramenti costanti rispetto ai segmenti di dimensione fissa.










