Maîtriser le regroupement de documents RAG : un guide des stratégies de regroupement pour construire des systèmes de recherche efficaces
Si votre RAG L'application ne donne pas les résultats escomptés, il est donc peut-être temps de revoir votre stratégie de découpage.Un meilleur découpage signifie une recherche plus précise, ce qui conduit en fin de compte à des réponses de meilleure qualité.
Cependant, le regroupement n'est pas une approche universelle et aucune approche n'est absolument optimale. Vous devez envisager et choisir la stratégie la plus appropriée en fonction des besoins spécifiques du projet, des caractéristiques du document, du budget et d'autres facteurs.
Pourquoi la qualité du découpage affecte-t-elle directement la qualité des réponses RAG ?
Je suis sûr qu'en lisant cet article, vous avez compris les concepts de base du chunking et du RAG. Pour récapituler rapidement, l'idée principale de RAG est de rendre le LLM Répondre aux questions en se basant sur les informations contextuelles donnéesCela s'explique par le fait que le LLM dispose d'une base de connaissances riche, mais qu'il tarde à mettre à jour ses connaissances et qu'il ne peut accéder directement aux données privées. En effet, bien que le LLM dispose d'une base de connaissances riche, il accuse un retard dans la mise à jour de ses connaissances et n'a pas d'accès direct aux données privées.
Le RAG compense les lacunes du LLM lui-même en injectant des fragments de documents pertinents (c'est-à-dire le contexte) dans les messages-guides et en demandant au LLM de générer des réponses basées sur ces fragments. Le contexte peut être obtenu de différentes manières, par exemple par interrogation d'une base de données, par recherche sur Internet ou par extraction de documents PDF.
La mise en place d'une application RAG efficace se heurte à deux difficultés majeures :
- Limites de la fenêtre contextuelle pour le LLMLes premiers LLM, tels que GPT-2 et GPT-3, avaient de petites fenêtres contextuelles, ce qui limitait la quantité de texte pouvant être traitée en un seul passage. Bien qu'il existe aujourd'hui des modèles qui prennent en charge des fenêtres contextuelles plus grandes, cela ne signifie pas que nous pouvons simplement faire entrer un document entier dans un LLM.
- problème de bruit de fondMême si la fenêtre contextuelle du LLM est suffisamment grande, si les informations contextuelles fournies contiennent beaucoup de contenu (bruit) qui n'est pas pertinent pour la question, cela peut affecter la compréhension et le jugement du LLM, conduisant à une dégradation de la qualité de la réponse ou même à des hallucinations.
Afin de répondre à ces questions.Regroupement de documentsLa technologie est née. L'idée de base est de diviser les documents volumineux en segments plus petits et sémantiquement cohérents (chunks), puis, dans la phase de recherche, seuls les chunks les plus pertinents sont sélectionnés en tant que contexte fourni au LLM.
Il existe plusieurs façons de découper les documents, comme le découpage simple des phrases et des paragraphes, le découpage sémantique complexe, le découpage agentique, etc. Il est important de choisir une stratégie de découpage appropriée, qui a une incidence directe sur l'efficacité du système RAG et sur la qualité de la réponse finale. Il est important de choisir une stratégie de découpage appropriée, qui affecte directement l'efficacité du système RAG et la qualité de la réponse finale.
Dans cet article, nous allons nous plonger dans plusieurs stratégies de découpage de documents plus avancées et plus pratiques pour vous aider à créer des applications RAG plus robustes. Nous laisserons de côté le découpage simple des phrases et des paragraphes pour nous concentrer sur des techniques plus utiles dans les applications RAG du monde réel.
Ensuite, je détaillerai quelques stratégies de découpage que j'ai apprises et pratiquées.
Segmentation récursive des caractères : une approche de base rapide et économique
Vous pourriez penser que le découpage récursif des caractères est la méthode la plus basique. En effet, elle est basique, mais elle reste, à mon avis, l'une des techniques de découpage les plus couramment utilisées et les plus rentables. Elle est facile à comprendre, simple à mettre en œuvre, rapide et peu coûteuse, ce qui la rend particulièrement adaptée au prototypage rapide et aux projets sensibles aux coûts.
L'idée de base de la segmentation récursive des caractères est la suivanteUtiliser une fenêtre coulissante de taille fixeet permet le chevauchement entre les fenêtres. Il génère des blocs de texte en faisant glisser continuellement la fenêtre à partir de la position initiale du document, avec une taille de bloc et un nombre de caractères chevauchants prédéfinis.
La figure suivante montre comment fonctionne la segmentation récursive des caractères :

L'avantage de la segmentation récursive des caractères est sa simplicité et son efficacité. Elle permet le traitement rapide de documents volumineux et le découpage des rapports annuels au niveau de la minute. L'implémentation de la segmentation récursive des caractères dans Langchain est très simple :
from langchain.text_splitter import RecursiveCharacterTextSplitter
text = """
Hydroponics is an intelligent way to grow veggies indoors or in small spaces. In hydroponics, plants are grown without soil, using only a substrate and nutrient solution. The global population is rising fast, and there needs to be more space to produce food for everyone. Besides, transporting food for long distances involves lots of issues. You can grow leafy greens, herbs, tomatoes, and cucumbers with hydroponics.
"""
rc_splits = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=20, chunk_overlap=2
).split_text(text)
Variantes de fenêtres coulissantes
Dans la pratique, la taille de la fenêtre coulissante et le pas de glissement peuvent être modifiés pour répondre à différents besoins :
- Fenêtres coulissantes basées sur des caractères ou sur des jetonsL'exemple ci-dessus est une fenêtre coulissante basée sur des caractères. Il est également possible d'utiliser une Jeton fenêtre glissante pour s'assurer que la taille des blocs est plus conforme au traitement LLM.Langchain's RecursiveCharacterTextSplitter (Séparateur de texte) Les modes caractère et jeton sont tous deux pris en charge.
- Taille de la fenêtre dynamiqueLa segmentation récursive des caractères se caractérise par des tailles de fenêtre fixes, mais le redimensionnement dynamique des fenêtres peut également être envisagé dans certains scénarios. Par exemple, l'ajustement adaptatif de la taille de la fenêtre en fonction de la longueur de la phrase ou de la structure du paragraphe afin de garantir l'intégrité sémantique du bloc.
limitations
La segmentation récursive des caractères est unApproche de regroupement basée sur la position. Elle suppose simplement que le texte qui est positionné de manière adjacente dans un document est également sémantiquement lié. Toutefois, cette hypothèse n'est pas valable dans de nombreux cas.
Réflexion : Pourquoi le découpage basé sur la localisation conduit-il à des performances médiocres des RAG ? Comment mettre en œuvre le découpage sémantique et obtenir de meilleurs résultats ?
Par exemple, dans un même chapitre, l'auteur peut aborder plusieurs concepts différents avant de les mettre en relation. Si seule une segmentation récursive des caractères est utilisée, le contenu qui devrait appartenir à la même unité sémantique peut être divisé, ou un contenu sémantiquement non lié peut être combiné, ce qui affecte la recherche.
Malgré ses limites, la segmentation récursive des caractères est idéale pour débuter avec RAG. Elle fournit souvent des résultats satisfaisants pendant la phase de prototypage, ou pour des documents simplement structurés. La segmentation récursive des caractères est également une option intéressante si votre projet a des exigences élevées en matière de coût et de vitesse.
Le découpage sémantique : une approche du découpage pour comprendre le sens d'un texte
Le découpage sémantique est une stratégie de découpage plus avancée quiAu lieu de s'appuyer uniquement sur les informations de position du texte, on obtient une compréhension plus profonde de la signification sémantique du texte. L'idée de base est de segmenter les documents lorsque leur sémantique change de manière significative, en veillant à ce que chaque morceau soit centré sur un seul sujet dans la mesure du possible.
La figure ci-dessous montre comment fonctionne le découpage sémantique :

Contrairement à la segmentation récursive des caractères, le découpage sémantique génère des blocs de longueur généralement variable. Il détermine les limites du bloc sur la base de l'intégrité sémantique, plutôt que de fixer un nombre fixe de caractères ou de jetons.
Principales étapes vers le découpage sémantique
La difficulté du découpage sémantique est de savoir commentProgrammé pour comprendre la sémantique des phrases**. Cela se fait généralement à l'aide deIntégration de modèlesà mettre en œuvre. L'intégration de modèles tels que celui d'OpenAI texte-embedding-3-grandLes phrases peuvent être converties en représentations vectorielles et les vecteurs sont capables de capturer l'information sémantique d'une phrase. Les phrases qui sont sémantiquement similaires ont des vecteurs qui sont également proches dans l'espace. **
Un processus typique de découpage sémantique comprend les cinq étapes suivantes :
- Construction du bloc initialLe document est d'abord divisé en phrases ou en paragraphes et les phrases ou paragraphes adjacents sont combinés en un bloc initial.
- Générer l'intégration des blocsLe modèle d'intégration est utilisé pour générer des intégrations vectorielles pour chaque bloc initial.
- Calculer la distance entre les blocsCalculer la distance sémantique entre les blocs voisins. Les mesures de distance couramment utilisées comprennent la distance cosinusoïdale, etc. Plus la distance est grande, plus la différence sémantique est importante.
- Déterminer le point de séparationLa méthode est la suivante : Fixer un seuil de distance. Lorsque la distance entre les blocs voisins dépasse le seuil, les séparer pour former de nouveaux blocs sémantiques. Le choix du seuil doit être ajusté en fonction du document spécifique et de l'effet expérimental.
- Visualisation (facultatif)La visualisation de la distance entre les blocs permet de comprendre l'effet de regroupement de manière plus intuitive et d'ajuster les seuils.
Le code suivant montre comment mettre en œuvre le découpage sémantique :
# Step 1 : Create initial chunks by combining concecutive sentences.
# ------------------------------------------------------------------
#Split the text into individual sentences.
sentences = re.split(r"(?<=[.?!])\s+", text)
initial_chunks = [
{"chunk": str(sentence), "index": i} for i, sentence in enumerate(sentences)
]
# Function to combine chunks with overlapping sentences
def combine_chunks(chunks):
for i in range(len(chunks)):
combined_chunk = ""
if i > 0:
combined_chunk += chunks[i - 1]["chunk"]
combined_chunk += chunks[i]["chunk"]
if i < len(chunks) - 1:
combined_chunk += chunks[i + 1]["chunk"]
chunks[i]["combined_chunk"] = combined_chunk
return chunks
# Combine chunks
combined_chunks = combine_chunks(initial_chunks)
# Step 2 : Create embeddings for the initial chunks.
# ------------------------------------------------------------------
# Embed the combined chunks
chunk_embeddings = embeddings.embed_documents(
[chunk["combined_chunk"] for chunk in combined_chunks]
# If you haven't created combined_chunk, use the following.
# [chunk["chunk"] for chunk in combined_chunks]
)
# Add embeddings to chunks
for i, chunk in enumerate(combined_chunks):
chunk["embedding"] = chunk_embeddings[i]
# Step 3 : Calculate distance between the chunks
# ------------------------------------------------------------------
def calculate_cosine_distances(chunks):
distances = []
for i in range(len(chunks) - 1):
current_embedding = chunks[i]["embedding"]
next_embedding = chunks[i + 1]["embedding"]
similarity = cosine_similarity([current_embedding], [next_embedding])[0][0]
distance = 1 - similarity
distances.append(distance)
chunks[i]["distance_to_next"] = distance
return distances
# Calculate cosine distances
distances = calculate_cosine_distances(combined_chunks)
# Step 4 : Find chunks with significant different to it's previous ones.
# ----------------------------------------------------------------------
import numpy as np
threshold_percentile = 90
threshold_value = np.percentile(cosine_distances, threshold_percentile)
crossing_points = [
i for i, distance in enumerate(distances) if distance > threshold_value
]
len(crossing_points)
# Step 5 (Optional) : Create a plot of chunk distances to get a better view
# -------------------------------------------------------------------------
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
def visualize_cosine_distances_with_thresholds_multicolored(
cosine_distances, threshold_percentile=90
):
# Calculate the threshold value based on the percentile
threshold_value = np.percentile(cosine_distances, threshold_percentile)
# Identify the points where the cosine distance crosses the threshold
crossing_points = [0] # Start with the first segment beginning at index 0
crossing_points += [
i
for i, distance in enumerate(cosine_distances)
if distance > threshold_value
]
crossing_points.append(
len(cosine_distances)
) # Ensure the last segment goes to the end
# Set up the plot
plt.figure(figsize=(14, 6))
sns.set(style="white") # Change to white to turn off gridlines
# Plot the cosine distances
sns.lineplot(
x=range(len(cosine_distances)),
y=cosine_distances,
color="blue",
label="Cosine Distance",
)
# Plot the threshold line
plt.axhline(
y=threshold_value,
color="red",
linestyle="--",
label=f"{threshold_percentile}th Percentile Threshold",
)
# Highlight segments between threshold crossings with different colors
colors = sns.color_palette(
"hsv", len(crossing_points) - 1
) # Use a color palette for segments
for i in range(len(crossing_points) - 1):
plt.axvspan(
crossing_points[i], crossing_points[i + 1], color=colors[i], alpha=0.3
)
# Add labels and title
plt.title(
"Cosine Distances Between Segments with Multicolored Threshold Highlighting"
)
plt.xlabel("Segment Index")
plt.ylabel("Cosine Distance")
plt.legend()
# Adjust the x-axis limits to remove extra space
plt.xlim(0, len(cosine_distances) - 1)
# Display the plot
plt.show()
return crossing_points
# Example usage with cosine_distances and threshold_percentile
crossing_poings = visualize_cosine_distances_with_thresholds_multicolored(
distances, threshold_percentile=bp_threashold
)
Tableau de Seborn pour visualiser les distances :

Avantages du découpage sémantique et scénarios applicables
L'avantage du découpage sémantique est la possibilité deIl capture mieux la structure sémantique des documents et regroupe les fragments de texte sémantiquement liés, améliorant ainsi la qualité de recherche du système RAG. Il convient mieux au traitement des types de documents suivants :
- Documents aux structures complexes et aux sujets variésLes documents d'information : par exemple, les rapports volumineux, les documents techniques, les livres, etc. qui contiennent de nombreux sous-thèmes.
- Documents à fort saut sémantiqueLes auteurs peuvent sauter dans leurs pensées lorsqu'ils écrivent, et le découpage sémantique peut mieux s'adapter à ce style d'écriture.
Par rapport à la segmentation récursive des caractères, le découpage sémantique de laLe calcul est plus coûteux** et plus lent. Cela est principalement dû à la nécessité de calculer le vecteur d'intégration et les mesures de distance. Par conséquent, dans les scénarios où les ressources sont limitées, des compromis doivent être envisagés.
Chunking agentique : stratégies de chunking qui imitent la compréhension humaine
Le découpage agentique est une étape supplémentaire vers le découpage intelligent. Il s'agit d'une étape supplémentaire vers le découpage intelligent.S'inspirant de la manière dont les humains lisent et comprennent les documents, LLM est utilisé comme un "agent intelligent" pour aider au découpage.
Les habitudes de lecture de l'homme ne sont pas complètement linéairesLe découpage agentique tente de simuler ce processus de compréhension humain. Lorsque nous lisons, nous sautons d'un sujet à l'autre ou d'un concept à l'autre et construisons la structure logique d'un document dans notre esprit. Le découpage agentique tente de simuler ce processus de compréhension humain.
Contrairement aux deux méthodes précédentes, le découpage agentique (Agentic chunking)ne part pas du principe que les contenus sémantiquement similaires sont consécutifs dans un document**. Il peut regrouper des éléments épars mais sémantiquement liés d'un document pour former des morceaux sémantiques plus compatibles avec la perception humaine.
Flux de travail de découpage agentique
L'idée centrale du découpage agentique est la suivanteLaissez LLM "lire" le document comme un humain, en identifiant les concepts et les thèmes centraux du document et en procédant à un découpage basé sur ces concepts et ces thèmes. Un processus typique de découpage Agentic comprend :
- Proposition: Convertir chaque phrase d'un document en une proposition plus indépendante. Par exemple, remplacer les pronoms inconnus par des objets pour donner à chaque phrase un sens sémantique plus complet.
- Conteneurs modulairesCréer un ou plusieurs conteneurs de morceaux pour les propositions sémantiquement liées. Chaque conteneur de morceaux peut avoir un titre et un résumé qui décrivent le sujet de ce conteneur.
- Affectation propositionnelle pilotée par un agentLes propositions : en utilisant LLM comme agent, "lisez" les propositions une par une et déterminez à quel bloc la proposition doit appartenir.
- Si l'agent considère que la proposition est en rapport avec le thème de l'un des conteneurs de blocs existants, elle est ajoutée à ce conteneur.
- Si l'agent estime que la proposition constitue un nouveau sujet, il crée un nouveau bloc contenant la proposition.
- Retraitement des conteneurs en blocTraitement ultérieur des conteneurs de blocs, par exemple en générant des résumés et des titres de blocs plus raffinés sur la base des propositions contenues dans le conteneur.
Le code suivant illustre la mise en œuvre du découpage agentique :
from langchain import hub
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
# Step 1: Convert paragraphs to propositions.
# --------------------------------------------
# Load the propositioning prompt from langchain hub
obj = hub.pull("wfh/proposal-indexing")
# Pick the LLM
llm = ChatOpenAI(model="gpt-4o")
# A Pydantic model to extract sentences from the passage
class Sentences(BaseModel):
sentences: List[str]
extraction_llm = llm.with_structured_output(Sentences)
# Create the sentence extraction chain
extraction_chain = obj | extraction_llm
# NOTE: text is your actual document
paragraphs = text.split("\n\n")
propositions = []
for i, p in enumerate(paragraphs):
propositions = extraction_chain.invoke(p
propositions.extend(propositions)
# Step 2: Create a placeholder to store chunks
chunks = {}
# Step 3: Deine helper classes and functions for agentic chunking.
class ChunkMeta(BaseModel):
title: str = Field(description="The title of the chunk.")
summary: str = Field(description="The summary of the chunk.")
def create_new_chunk(chunk_id, proposition):
summary_llm = llm.with_structured_output(ChunkMeta)
summary_prompt_template = ChatPromptTemplate.from_messages(
[
(
"system",
"Generate a new summary and a title based on the propositions.",
),
(
"user",
"propositions:{propositions}",
),
]
)
summary_chain = summary_prompt_template | summary_llm
chunk_meta = summary_chain.invoke(
{
"propositions": [proposition],
}
)
chunks[chunk_id] = {
"summary": chunk_meta.summary,
"title": chunk_meta.title,
"propositions": [proposition],
}
def add_proposition(chunk_id, proposition):
summary_llm = llm.with_structured_output(ChunkMeta)
summary_prompt_template = ChatPromptTemplate.from_messages(
[
(
"system",
"If the current_summary and title is still valid for the propositions return them."
"If not generate a new summary and a title based on the propositions.",
),
(
"user",
"current_summary:{current_summary}\n\ncurrent_title:{current_title}\n\npropositions:{propositions}",
),
]
)
summary_chain = summary_prompt_template | summary_llm
chunk = chunks[chunk_id]
current_summary = chunk["summary"]
current_title = chunk["title"]
current_propositions = chunk["propositions"]
all_propositions = current_propositions + [proposition]
chunk_meta = summary_chain.invoke(
{
"current_summary": current_summary,
"current_title": current_title,
"propositions": all_propositions,
}
)
chunk["summary"] = chunk_meta.summary
chunk["title"] = chunk_meta.title
chunk["propositions"] = all_propositions
# Step 5: The main functino that creates chunks from propositions.
def find_chunk_and_push_proposition(proposition):
class ChunkID(BaseModel):
chunk_id: int = Field(description="The chunk id.")
allocation_llm = llm.with_structured_output(ChunkID)
allocation_prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You have the chunk ids and the summaries"
"Find the chunk that best matches the proposition."
"If no chunk matches, return a new chunk id."
"Return only the chunk id.",
),
(
"user",
"proposition:{proposition}" "chunks_summaries:{chunks_summaries}",
),
]
)
allocation_chain = allocation_prompt | allocation_llm
chunks_summaries = {
chunk_id: chunk["summary"] for chunk_id, chunk in chunks.items()
}
best_chunk_id = allocation_chain.invoke(
{"proposition": proposition, "chunks_summaries": chunks_summaries}
).chunk_id
if best_chunk_id not in chunks:
best_chunk_id = create_new_chunk(best_chunk_id, proposition)
return
add_proposition(best_chunk_id, proposition)
Exemples de propositionnalisation
原始文本
===================
A crow sits near the pond. It's a white one.
命题化文本
==================
A crow sits near the pond. This crow is a white one.
Avantages et défis du découpage agentique
Agentic chunkedSon principal avantage réside dans sa flexibilité et son intelligence**. Il peut mieux comprendre la structure sémantique profonde des documents et générer des morceaux sémantiques plus conformes à la cognition humaine. Il est particulièrement efficace pour traiter les types de documents suivants:**
- Documentation sur les structures non linéairesLes documents qui sautent d'une pensée à l'autre et contiennent beaucoup de connaissances de base ou d'informations implicites, par exemple.
- Les documents qui doivent intégrer des informations dans des paragraphes et des sections.Le chunking agentique permet d'agréger des fragments sémantiquement liés qui sont dispersés à différents endroits d'un document.
Cependant, le découpage agentique est également confronté à certains défis :
- coût élevéLe découpage agentique nécessite des appels fréquents au LLM, ce qui est coûteux en temps et en argent.
- Demander les dépendances du projetL'efficacité du découpage agentique dépend fortement de la conception de l'invite. Les invites doivent être finement conçues pour guider le LLM vers un découpage efficace.
- Incertitude du résultatLes résultats du LLM peuvent être incertains, ce qui conduit à des résultats instables en matière de découpage.
Scénarios d'application du découpage agentique
Le regroupement d'agents, bien que plus coûteux, reste une option qui mérite d'être envisagée dans certains scénarios où l'efficacité du RAG est cruciale. Exemple :
- Base de connaissances dans des domaines spécialisésLes bases de connaissances dans les domaines du droit, de la médecine, de la finance, etc., exigent une précision de recherche et un rappel extrêmement élevés.
- système complexe de questions-réponsesSystème de questions-réponses : un système de questions-réponses qui doit traiter des questions complexes nécessitant un raisonnement et l'intégration d'informations.
Lecture approfondie :Agentic Chunking : AI Agent-Driven Semantic Text Chunking (découpage sémantique de texte piloté par un agent)
Stratégies de regroupement pour différents formats de documents
La discussion précédente s'est principalement concentrée sur le découpage de texte brut. Cependant, dans les applications pratiques, nous rencontrons souvent une variété de formats de documents différents, tels que Markdown, HTML, PDF, code, etc. Pour ces différents formats, une stratégie de découpage plus fine est nécessaire pour exploiter pleinement les informations structurelles du document.
Le découpage en morceaux des documents Markdown et HTML
Les documents Markdown et HTML contiennent des informations de balisage structurées, telles que des titres, des paragraphes, des listes, des blocs de code, etc. Nous pouvonsUtilisez ces étiquettes comme base de découpage** pour un découpage plus précis. **
- Bloc par titreTraiter chaque titre et son contenu comme un bloc distinct. Cette méthode convient aux documents clairement structurés comportant des sections distinctes.
- morceauTraiter chaque paragraphe comme un bloc. Les paragraphes sont généralement des unités sémantiquement complètes et conviennent comme unités de découpage de base.
- découpageCombiner les titres et les paragraphes pour le découpage en morceaux. Par exemple, divisez d'abord le document par titres de premier niveau, puis dans le contenu sous chaque titre de premier niveau, puis divisez par paragraphes.
Exemple : découpage en morceaux basé sur les balises HTML (Python)
from bs4 import BeautifulSoup
html_text = """
<h1>Section 1</h1>
<p>This is the first paragraph of section 1.</p>
<p>This is the second paragraph of section 1.</p>
<h2>Subsection 1.1</h2>
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
"""
soup = BeautifulSoup(html_text, 'html.parser')
chunks = []
# 按 h1 标题分块
for h1_tag in soup.find_all('h1'):
chunk_text = h1_tag.text + "\n"
next_sibling = h1_tag.find_next_sibling()
while next_sibling and next_sibling.name not in ['h1', 'h2']: # 假设按 h1 和 h2 分级
chunk_text += str(next_sibling) + "\n" # 保留 HTML 标签,或 next_sibling.text 只保留文本
next_sibling = next_sibling.find_next_sibling()
chunks.append(chunk_text)
# 可以类似地处理 h2, p, ul, ol 等标签
print(chunks)
Découpage de documents PDF
Le découpage des documents PDF est relativement complexe car le PDF est essentiellement un format de composition où le contenu textuel et les informations typographiques sont mélangés. Le découpage des PDF directement par caractère ou par ligne peut détruire l'intégrité sémantique.
Les étapes clés de la fragmentation des PDF sont généralement les suivantes :
- Extraction de texte en PDFLes bibliothèques d'analyse de fichiers PDF (par exemple PyPDF2, pdfminer, ou d'autres bibliothèques plus professionnelles) sont utilisées pour l'analyse de fichiers PDF. non structuré.io) pour extraire le contenu textuel des fichiers PDF.
- Nettoyage et prétraitement du texteIl permet de supprimer les caractères parasites, de gérer les sauts de ligne, de corriger les erreurs d'OCR et bien plus encore.
- Extraction d'informations structuréesLes informations structurées : Essayez d'extraire des informations structurées des PDF, telles que les titres, les en-têtes et les pieds de page, les tableaux, les listes, et ainsi de suite. Certaines bibliothèques avancées d'analyse de PDF (par exemple unstructured.io) peuvent aider à l'extraction d'informations structurées.
- Options de la stratégie de regroupementLes stratégies de découpage (par exemple, le découpage sémantique, la segmentation récursive des caractères, etc.) sont sélectionnées en fonction du contenu du texte extrait et des informations structurelles.
attirer l'attention sur qqch.: unstructured.io est un outil puissant qui peut gérer un large éventail de formats de documents (y compris PDF) et qui tente d'extraire des informations structurées des documents, simplifiant ainsi le processus de découpage des PDF.
Regroupement de la documentation du code
Le découpage des documents de code (par exemple, les fichiers de code Python, Java, C++) nécessite la prise en compte de la structure syntaxique et des unités logiques du code. Le simple découpage du code en lignes ou en caractères est susceptible de détruire l'intégrité et l'exécutabilité du code.
Les stratégies courantes de découpage de la documentation du code sont les suivantes :
- Chunking par fonction/classeLes fonctions et les classes sont généralement des unités logiques de code. Les fonctions et les classes sont généralement des unités logiques de code.
- Regroupement par bloc de codeLe système de gestion de l'information : il identifie les blocs de logique dans le code (par exemple, les boucles, les instructions conditionnelles, les blocs "essayer-excepter", etc.
- Combiné avec le découpage des commentaires de codeLes commentaires de code sont généralement des explications de la fonctionnalité et de la logique du code. Les commentaires de code et les blocs de code qui leur sont associés peuvent être regroupés en un tout.
artefactL'analyse structurée et le découpage du code peuvent être facilités par l'utilisation d'outils d'analyse syntaxique tels que tree-sitter, qui analyse le code dans une variété de langages de programmation et génère un arbre syntaxique abstrait (AST), ce qui facilite le découpage du code en fonction de sa structure syntaxique.
Choisir la bonne taille de morceau et le bon chevauchement
La taille et le chevauchement des morceaux sont deux paramètres importants de la politique de découpage qui affectent directement les performances du système RAG.
- Taille des morceauxTaille de l'élément : La quantité de texte contenue dans chaque élément. Une taille trop petite peut conduire à des informations sémantiques incomplètes ; une taille trop grande peut introduire du bruit et réduire la précision de la recherche.
- Taille du chevauchementLe chevauchement : il s'agit de la quantité de texte qui se superpose à celle des blocs voisins. L'objectif du chevauchement est d'assurer la continuité contextuelle et d'éviter la perte d'informations aux limites des blocs.
Comment choisir la bonne taille de morceau et le bon chevauchement ?
Il n'existe pas de solution optimale pour choisir la bonne taille de morceau et le bon chevauchement.Caractéristiques du documentrépondre en chantanteffet expérimentalà déterminer. Voici quelques règles empiriques et suggestions :
- méthode heuristique: :
- Basé sur la longueur de la phrase/du paragrapheLa longueur moyenne d'une phrase ou d'un paragraphe d'un document peut être analysée comme référence pour la taille du bloc. Par exemple, si la longueur moyenne d'un paragraphe est de 150 tokens, vous pouvez essayer de fixer la taille du bloc à 150-200 tokens.
- Considérons la fenêtre contextuelle LLMLa taille du bloc ne doit pas être trop importante pour éviter de dépasser les limites de la fenêtre contextuelle du LLM. En même temps, elle ne doit pas être trop petite pour garantir que le bloc contient suffisamment d'informations sémantiques.
- Expérimentation et évaluation:
- Accord itératifLe système RAG est conçu de la manière suivante : définir un ensemble initial de paramètres relatifs à la taille des morceaux et au chevauchement (par exemple, 500 tokens pour la taille des morceaux et 50 tokens pour le chevauchement), mettre en place le système RAG et l'évaluer. Ensuite, on ajuste progressivement les paramètres, on observe les changements dans les effets de recherche et de questions-réponses, et on choisit la combinaison optimale de paramètres.
- Évaluation des indicateursQuantifier les performances du système RAG à l'aide de mesures d'évaluation appropriées, telles que Recall@k, Precision@k, NDCG (Normalised Discounted Cumulative Gain), etc. pour la recherche. Ces mesures peuvent vous aider à évaluer objectivement l'efficacité des différentes stratégies de regroupement.
Outils d'évaluation dans Langchain
Langchain fournit un certain nombre d'outils d'évaluation qui peuvent aider à l'évaluation et au réglage des paramètres des systèmes RAG. Par exemple, des outils tels que DatasetEvaluator et RetrievalQAChain peuvent vous aider à automatiser l'évaluation des effets des combinaisons de différentes stratégies de découpage, de modèles de recherche et de modèles LLM.
Évaluer l'efficacité de la stratégie de découpage en morceaux
Après avoir choisi la bonne stratégie de découpage, comment évaluer son efficacité ? "Un meilleur découpage signifie une meilleure récupération", mais comment quantifier ce "meilleur" ? Nous avons besoin de certains paramètres pour évaluer les mérites des stratégies de découpage.
Voici quelques mesures d'évaluation courantes qui peuvent vous aider à évaluer l'impact d'une stratégie de regroupement sur les performances d'un système RAG :
- Récupération des indicateurs:
- Rappel (Recall@k)Le rappel : il s'agit de la proportion de documents (ou de morceaux) pertinents parmi les résultats Top-k récupérés. Plus le rappel est élevé, plus la stratégie de regroupement des documents permet d'extraire des informations pertinentes.
- Précision (Precision@k)La précision : fait référence à la proportion de documents (ou de morceaux) réellement pertinents parmi les résultats Top-k récupérés. Plus la précision est élevée, plus la qualité des résultats de la recherche est grande.
- NDCG (Normalised Discounted Cumulative Gain)Le NDCG est une mesure d'évaluation de la qualité du classement plus fine qui prend en compte le niveau de pertinence et la position des résultats retrouvés.
- Indicateurs Q&R:
- Pertinence de la réponseLe système RAG est un système d'évaluation de la pertinence des réponses générées par le mécanisme d'apprentissage à distance par rapport à la question. Plus la pertinence de la réponse est élevée, plus le système RAG est capable de générer des réponses pertinentes sur la base des informations extraites.
- Précision/fidélité des réponsesLes résultats de l'étude sont les suivants : évaluer si les réponses générées par le LLM sont fidèles aux informations contextuelles récupérées, en évitant les "illusions" et les informations inexactes. Une plus grande précision des réponses indique que la stratégie de découpage en morceaux est plus à même de fournir un contexte fiable et de guider le LLM pour qu'il génère des réponses plus crédibles.
- Fluidité et cohérence des réponsesBien que principalement influencée par les capacités du LLM, une bonne stratégie de découpage peut également améliorer indirectement la fluidité et la cohérence des réponses. Par exemple, le découpage sémantique fournit un contexte plus cohérent et aide les LLM à produire un langage plus naturel.
- Pertinence de la réponseLe système RAG est un système d'évaluation de la pertinence des réponses générées par le mécanisme d'apprentissage à distance par rapport à la question. Plus la pertinence de la réponse est élevée, plus le système RAG est capable de générer des réponses pertinentes sur la base des informations extraites.
Outils et méthodologies d'évaluation
- évaluation manuelleLa méthode la plus directe et la plus fiable. Un évaluateur humain est invité à évaluer les résultats de recherche et les réponses aux questions-réponses du système RAG sur la base de critères d'évaluation prédéfinis. Les inconvénients de l'évaluation manuelle sont qu'elle est coûteuse, qu'elle prend du temps et qu'elle est très subjective.
- Évaluation automatiséeLes indicateurs et les outils d'évaluation automatisés, par exemple : l'utilisation d'indicateurs et d'outils d'évaluation automatisés, par exemple :
- Récupération des indicateursPar exemple, le rappel, la précision, le NDCG, etc. peuvent être mesurés à l'aide d'outils standard d'évaluation de la recherche d'informations (par exemple
rank_bm25
,sentence-transformers
etc.) pour des calculs automatisés. - Indicateurs Q&RLes métriques d'évaluation NLP (par exemple BLEU, ROUGE, METEOR, BERTScore, etc.) peuvent être utilisées pour aider à l'évaluation de la qualité des réponses. ) peuvent être utilisées pour faciliter l'évaluation de la qualité des réponses. Toutefois, il convient de noter que les mesures d'évaluation automatisées des questions-réponses ont encore des limites et ne peuvent pas remplacer complètement l'évaluation manuelle.
- Outil d'évaluation de LangchainLangchain offre un certain nombre d'outils d'évaluation intégrés, tels que
DatasetEvaluator
répondre en chantantRetrievalQAChain
Cela simplifie le processus d'évaluation automatisé du système RAG.
- Récupération des indicateursPar exemple, le rappel, la précision, le NDCG, etc. peuvent être mesurés à l'aide d'outils standard d'évaluation de la recherche d'informations (par exemple
Recommandations pour le processus d'évaluation
- Construction de l'ensemble de données d'évaluationPréparation d'un ensemble de données d'évaluation contenant des questions et les réponses standard correspondantes. L'ensemble de données doit couvrir, dans la mesure du possible, les scénarios d'application et les types de questions typiques des systèmes RAG.
- Sélection des indicateurs d'évaluationLes indicateurs de recherche et de questions-réponses doivent être sélectionnés en fonction de l'objectif de l'évaluation. Une combinaison d'évaluation manuelle et automatisée peut être utilisée simultanément.
- Fonctionnement du système RAGLe système RAG est exécuté sur l'ensemble de données d'évaluation en utilisant différentes combinaisons de stratégies de regroupement, de modèles de recherche et de modèles LLM afin d'enregistrer les résultats de l'évaluation.
- Analyse et comparaisonLes stratégies d'évaluation : comparer les paramètres d'évaluation de différentes stratégies, analyser leurs forces et leurs faiblesses, et sélectionner la combinaison optimale de stratégies.
- Optimisation itérativeLes résultats de l'évaluation permettent d'ajuster en permanence les paramètres de la stratégie de regroupement, du modèle de recherche et du modèle LLM pour une optimisation itérative afin d'améliorer les performances du système RAG.
En résumé : choisissez la stratégie de découpage qui vous convient le mieux.
Cet article présente une discussion approfondie des techniques de découpage de documents qui sont essentielles dans les applications RAG, de la segmentation récursive de base des caractères, au découpage sémantique plus intelligent et au découpage agentique, en passant par des stratégies de découpage raffinées pour différents formats de documents, ainsi que des méthodes de sélection et d'évaluation de la taille des morceaux et des paramètres de chevauchement.
Examen des points essentiels
- La masse des morceaux détermine la masse du RAGUne bonne stratégie de découpage est la pierre angulaire de la construction d'un système RAG performant.
- Il n'existe pas de stratégie de découpage unique.Les différentes stratégies de découpage ont leurs propres avantages et inconvénients et conviennent à différents scénarios. Vous devez choisir la stratégie la plus appropriée en fonction des exigences spécifiques de votre projet, des caractéristiques du document et des contraintes de ressources.
- Segmentation récursive des caractèresLe système est simple, rapide et économique pour le prototypage et les projets dont le coût est limité.
- découpage sémantiqueLa compréhension de la sémantique du texte et la génération de morceaux sémantiquement cohérents améliorent la qualité de la recherche, mais sont coûteuses en termes de calcul.
- Chunking agentiqueLa technologie Prompt : simule la compréhension humaine, est plus intelligente, plus souple et peut traiter des documents complexes, mais elle est coûteuse et l'ingénierie Prompt est complexe.
- Chunking pour différents formatsPour différents formats tels que Markdown, HTML, PDF, code, etc., une stratégie de découpage à grain fin est nécessaire pour exploiter les informations structurelles du document.
- Taille des morceaux et chevauchementIl n'y a pas de valeur optimale absolue, mais elle doit être ajustée en fonction des caractéristiques du document et des résultats expérimentaux.
- L'évaluation est essentielle: : Quantifier l'efficacité de la stratégie de regroupement par le biais de mesures d'évaluation et d'une évaluation manuelle, et procéder à une optimisation itérative.
Comment choisir ? Mon conseil.
- Prototypage rapide: : Tentatives de prioritéSegmentation récursive des caractèresLe RAG est un moyen rapide de construire un prototype de RAG et de vérifier la faisabilité du système.
- La recherche d'une meilleure qualitéSi la demande de qualité RAG est importante et que les ressources informatiques le permettent, vous pouvez essayer la méthodedécoupage sémantique.
- Traitement de documents complexesPour les documents présentant des structures complexes et des sauts sémantiques.Chunking agentiqueIl peut s'agir de l'option préférée, mais le coût et l'efficacité doivent être soigneusement évalués.
- Format spécifiqueSi vous travaillez avec des documents dans un format spécifique tel que Markdown, HTML, PDF, code, etc.Stratégie de découpage cibléEn outre, il est important d'utiliser pleinement les informations structurelles du document.
- Optimisation itérative continueLe choix de la stratégie de découpage n'est pas un processus qui se fait du jour au lendemain. Dans les projets réels, il est nécessaire de constammentExpérimentation, évaluation et optimisation itérativeafin de trouver la meilleure solution de regroupement pour vous.
J'espère que cet article vous aidera à mieux comprendre la technologie de découpage RAG et à sélectionner et appliquer des stratégies de découpage appropriées dans des projets réels afin de créer des applications RAG plus puissantes !
© déclaration de droits d'auteur
Article copyright Cercle de partage de l'IA Tous, prière de ne pas reproduire sans autorisation.
Articles connexes
Pas de commentaires...