0Pricing
AI Engineering Academy · Lezione

Chunking semantico con la similarità degli embedding

Implementi un chunking semantico che suddivida il testo nei punti di massima distanza semantica tra frasi consecutive, mantenendo insieme i contenuti coerenti dal punto di vista tematico.

Chunking semantico con la similarità degli embedding è una lezione AI Engineering Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.

Che cos'è il chunking semantico?

Il chunking semantico è una tecnica che suddivide il testo nei punti in cui l'argomento cambia significativamente, anziché dopo un numero fisso di caratteri. Invece di chiedersi "abbiamo raggiunto 500 token?", si chiede "la frase successiva appartiene allo stesso argomento del chunk corrente?", utilizzando la similarità tra embedding per rispondere.

L'idea fondamentale: la distanza tra gli embedding

L'algoritmo funziona creando l'embedding di ogni frase (o piccolo gruppo di frasi) e calcolando la similarità coseno tra gli embedding di frasi consecutive. Quando la similarità diminuisce bruscamente, indicando uno spostamento dell'argomento, l'algoritmo inserisce un confine del chunk. Le frasi che trattano lo stesso concetto rimangono insieme nello stesso chunk.

Passaggio 1: embedding a livello di frase

Il primo passaggio consiste nel suddividere il documento in singole frasi utilizzando un tokenizer per frasi, quindi nel creare l'embedding di ogni frase con un modello di embedding rapido. Servono embedding a livello di frase, non a livello di documento, per poter rilevare i cambiamenti locali dell'argomento mentre si procede nel testo.

from openai import OpenAI
from nltk.tokenize import sent_tokenize
import numpy as np

client = OpenAI()

def embed_sentences(text):
    sentences = sent_tokenize(text)
    response = client.embeddings.create(
        model='text-embedding-3-small',
        input=sentences
    )
    vectors = [item.embedding for item in response.data]
    return sentences, np.array(vectors)

Passaggio 2: calcolo della similarità tra frasi adiacenti

Una volta ottenuti gli embedding delle frasi, calcoli la similarità coseno tra ogni coppia consecutiva: la frase i e la frase i+1. Il risultato è un elenco di punteggi di similarità, uno per ogni confine tra frasi. Punteggi bassi indicano che le frasi adiacenti trattano argomenti diversi: questi sono i punti candidati per la suddivisione.

def cosine_similarity_adjacent(vectors):
    similarities = []
    for i in range(len(vectors) - 1):
        a = vectors[i]
        b = vectors[i + 1]
        sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
        similarities.append(sim)
    return similarities

Passaggio 3: rilevamento dei punti di interruzione

Un punto di interruzione è un confine tra frasi in corrispondenza del quale la similarità scende al di sotto di una soglia. Può utilizzare una soglia fissa (ad es. 0,6) oppure una soglia basata sul percentile che si adatta al documento: per esempio, suddividere il testo ogni volta che la similarità scende al di sotto del 25º percentile di tutti i punteggi di similarità del documento.

def find_breakpoints(similarities, percentile=25):
    threshold = np.percentile(similarities, percentile)
    breakpoints = []
    for i, sim in enumerate(similarities):
        if sim < threshold:
            breakpoints.append(i + 1)  # split AFTER sentence i
    return breakpoints

Passaggio 4: assemblaggio dei chunk

Una volta identificati i punti di interruzione, può assemblare i chunk unendo le frasi consecutive tra un punto di interruzione e l'altro. Ogni chunk risultante contiene una sequenza coerente di frasi sullo stesso argomento. I confini dei chunk corrispondono alle transizioni naturali tra gli argomenti nel documento originale.

def assemble_chunks(sentences, breakpoints):
    chunks = []
    start = 0
    for bp in breakpoints:
        chunk = ' '.join(sentences[start:bp])
        chunks.append(chunk)
        start = bp
    chunks.append(' '.join(sentences[start:]))  # last chunk
    return chunks

Esempio completo di semantic chunker

Riunendo tutti i passaggi in un'unica funzione: creare gli embedding delle frasi, calcolare le similarità adiacenti, trovare i punti di interruzione e assemblare i chunk. L'output è un elenco di segmenti di testo semanticamente coerenti, pronti per essere sottoposti all'embedding come chunk completi e archiviati nel database vettoriale.

def semantic_chunk(text, percentile=25):
    sentences, vectors = embed_sentences(text)
    similarities = cosine_similarity_adjacent(vectors)
    breakpoints = find_breakpoints(similarities, percentile)
    chunks = assemble_chunks(sentences, breakpoints)
    return chunks

chunks = semantic_chunk(my_document)
print(f'Produced {len(chunks)} semantic chunks')
for i, c in enumerate(chunks):
    print(f'Chunk {i+1}: {len(c)} chars')

Scegliere la soglia percentile

La soglia percentile controlla la granularità dei chunk. Un percentile basso (ad es. il 10º) significa suddividere il testo solo in corrispondenza dei principali cambiamenti di argomento, ottenendo meno chunk più lunghi. Un percentile alto (ad es. il 40º) suddivide il testo in modo più aggressivo, ottenendo molti chunk piccoli e altamente focalizzati. Regoli questo valore sulla base del set di valutazione del tasso di riscontro del recupero.

SemanticChunker di LangChain

LangChain offre un SemanticChunker integrato che implementa questo algoritmo. Accetta un modello di embedding e un tipo di soglia per i punti di interruzione. In questo modo non deve implementare l'algoritmo da zero e può integrarlo direttamente con i loader di documenti e i vector store di LangChain.

from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model='text-embedding-3-small')

chunker = SemanticChunker(
    embeddings,
    breakpoint_threshold_type='percentile',
    breakpoint_threshold_amount=25
)

chunks = chunker.create_documents([long_document_text])
print(f'{len(chunks)} semantic chunks created')

Compromessi rispetto al chunking di dimensione fissa

Il chunking semantico produce chunk di qualità superiore e con una migliore coerenza tematica, ma è più costoso: ogni frase deve essere sottoposta all'embedding solo per determinare i confini dei chunk, prima ancora che i chunk vengano indicizzati. Per un documento di 100 pagine, ciò significa migliaia di chiamate di embedding dedicate al solo chunking. Utilizzi il chunking semantico quando la qualità del recupero è più importante della velocità di indicizzazione.

Quando utilizzare il chunking semantico

Il chunking semantico è particolarmente efficace con contenuti narrativi di lunga estensione, come post di blog, articoli di ricerca, documenti legali e libri, in cui gli argomenti cambiano in modo naturale. È meno necessario per documenti altamente strutturati, come cataloghi di prodotti, elenchi di domande frequenti o file di codice, che è meglio gestire con splitter consapevoli della struttura del documento.

Verifica rapida

Verifichi la Sua comprensione del chunking semantico illustrato in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato che: il chunking semantico utilizza la similarità tra embedding per rilevare i cambiamenti di argomento, la soglia percentile controlla la granularità e il SemanticChunker di LangChain implementa questa funzionalità immediatamente. Ora esploreremo il chunking parent-child, che combina chunk piccoli e precisi con passaggi parent più ampi e ricchi di contesto.

Domande Frequenti

La lezione «Chunking semantico con la similarità degli embedding» è gratuita?

Sì — il testo completo di «Chunking semantico con la similarità degli embedding» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.

Cosa imparerò in «Chunking semantico con la similarità degli embedding»?

Implementi un chunking semantico che suddivida il testo nei punti di massima distanza semantica tra frasi consecutive, mantenendo insieme i contenuti coerenti dal punto di vista tematico. Eserciti AI Engineering Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Engineering Academy?

Non è richiesta alcuna esperienza precedente. AI Engineering Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Chunking semantico con la similarità degli embedding»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Engineering Academy?

Sì. Ogni lezione AI Engineering Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Perché il chunking ingenuo danneggia il retrieval
  2. Chunking semantico con la similarità degli embedding
  3. Retrieval parent-child e small-to-big
  4. Strategie specifiche per documenti di codice e HTML
← Torna a AI Engineering Academy