Dominio de la agrupación de documentos RAG: Guía de estrategias de agrupación para crear sistemas de recuperación eficaces

Si su RAG La aplicación no está dando los resultados deseados, así que quizá sea el momento de revisar su estrategia de fragmentación.Una mejor fragmentación significa una recuperación más precisa, lo que en última instancia conduce a respuestas de mayor calidad.

Sin embargo, la fragmentación no es un enfoque único, y ninguno es absolutamente óptimo. Hay que considerar y elegir la estrategia más adecuada en función de las necesidades específicas del proyecto, las características del documento y el presupuesto, entre otros factores.

 

¿Por qué la calidad de la fragmentación afecta directamente a la calidad de las respuestas del GAR?

Estoy seguro de que al leer este artículo has comprendido los conceptos básicos de fragmentación y GAR. A modo de resumen rápido, la idea central de la RAG es hacer que el LLM Responda a las preguntas basándose en la información contextual dadaEsto se debe a que, aunque LLM dispone de una rica base de conocimientos, tiene un retraso en la actualización de sus conocimientos y no puede acceder directamente a los datos privados. Esto se debe a que, aunque LLM tiene una rica base de conocimientos, tiene un retraso en la actualización de sus conocimientos y no tiene acceso directo a los datos privados.

El GAR compensa las deficiencias del propio LLM inyectando fragmentos de documentos relevantes (es decir, contexto) en las preguntas y dirigiendo al LLM para que genere respuestas basadas en estos fragmentos. El contexto puede obtenerse de diversas formas, como consultas a bases de datos, búsquedas en Internet o extracción de documentos PDF.

La creación de una aplicación GAR eficaz plantea dos retos fundamentales:

  1. Límites de la ventana contextual para LLMLLM: Los primeros LLM, como GPT-2 y GPT-3, tenían ventanas de contexto pequeñas, lo que limitaba la cantidad de texto que se podía procesar en una sola pasada. Aunque ahora hay modelos que admiten ventanas de contexto más grandes, esto no significa que podamos meter un documento entero en un LLM.
  2. problema del ruido contextualLa ventana de contexto: Incluso si la ventana de contexto del LLM es lo suficientemente grande, si la información de contexto proporcionada contiene mucho contenido (ruido) que no es relevante para la pregunta, puede afectar a la comprensión y juicio del LLM, llevando a una degradación de la calidad de la respuesta o incluso a alucinaciones.

Para abordar estas cuestiones.Agrupación de documentosAsí nació esta tecnología. La idea central es dividir los documentos grandes en segmentos (trozos) más pequeños y semánticamente coherentes, y luego, en la fase de recuperación, sólo se seleccionan los trozos más relevantes como contexto proporcionado al LLM.

Existen varias formas de fragmentación de documentos, como la fragmentación simple de frases y párrafos, la fragmentación semántica compleja, la fragmentación agéntica, etc. Es importante elegir una estrategia de fragmentación adecuada, que afecta directamente a la eficacia del sistema GAR y a la calidad de la respuesta final. La elección de una estrategia de chunking adecuada es crucial, ya que afecta directamente a la eficacia de recuperación del sistema RAG y a la calidad de la respuesta final.

En este artículo, nos sumergiremos en varias estrategias de fragmentación de documentos más avanzadas y prácticas que le ayudarán a crear aplicaciones RAG más sólidas. Nos saltaremos el simple troceado de frases y párrafos y nos centraremos en técnicas que son más valiosas en aplicaciones RAG del mundo real.

A continuación, detallaré algunas estrategias de fragmentación que he aprendido y practicado.

 

Segmentación recursiva de caracteres: un enfoque básico rápido y rentable

Recursive Character Splitting, podría pensarse que éste es el método más básico. Efectivamente, es básico, pero en mi opinión sigue siendo una de las técnicas de fragmentación más utilizadas y rentables. Es fácil de entender, sencillo de aplicar, rápido y barato, lo que lo hace especialmente adecuado para la creación rápida de prototipos y los proyectos sensibles a los costes.

La idea central de la segmentación recursiva de caracteres es la siguienteUtilizar una ventana corredera de tamaño fijoy permite el solapamiento entre ventanas. Genera bloques de texto deslizando continuamente la ventana desde la posición inicial del documento con un tamaño de bloque y un número de caracteres superpuestos preestablecidos.

La siguiente figura muestra cómo funciona la segmentación recursiva de caracteres:

精通 RAG 文档分块策略:构建高效检索系统的分块策略指南Cómo funciona la segmentación recursiva de caracteres - dibujado por Thuwarakesh
El ejemplo de la figura, en el que el tamaño del bloque se fija en 20 caracteres y el número de caracteres solapados es 2, muestra cómo puede generarse un bloque de texto mediante una ventana deslizante.

La ventaja de la segmentación recursiva de caracteres es su sencillez y eficacia. Permite procesar con rapidez documentos de gran tamaño y fragmentar los informes anuales al minuto. La implementación de la segmentación recursiva de caracteres en Langchain es muy sencilla:

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 ventanas correderas

En la práctica, el tamaño de la ventana de deslizamiento y el paso de deslizamiento pueden variar para adaptarse a distintas necesidades:

  • Ventanas correderas basadas en caracteres o en fichasEl ejemplo anterior es una ventana deslizante basada en caracteres. También es posible utilizar una Ficha ventana deslizante para que el tamaño del bloque se ajuste más a la forma en que lo maneja LLM.Langchain's RecursiveCharacterTextSplitter Se admiten los modos de caracteres y fichas.
  • Tamaño de ventana dinámicoAunque la segmentación recursiva de caracteres se caracteriza por el tamaño fijo de las ventanas, en algunos casos también puede considerarse la posibilidad de redimensionarlas de forma dinámica. Por ejemplo, ajustar adaptativamente el tamaño de la ventana en función de la longitud de la frase o la estructura del párrafo para garantizar la integridad semántica del bloque.

limitaciones

La segmentación recursiva de caracteres es unaEnfoque chunking basado en la posición. Simplemente asume que el texto que es posicionalmente adyacente en un documento también está relacionado semánticamente. Sin embargo, esta suposición no se cumple en muchos casos.

Piensa: ¿Por qué el chunking basado en la localización da lugar a malos resultados de las GAR? Cómo aplicar el chunking semántico y obtener mejores resultados?

Por ejemplo, en un mismo capítulo, el autor puede tratar primero varios conceptos diferentes antes de relacionarlos finalmente. Si sólo se utiliza la segmentación recursiva de caracteres, pueden dividirse contenidos que deberían pertenecer a la misma unidad semántica o combinarse contenidos no relacionados semánticamente, lo que afectaría a la recuperación.

A pesar de sus limitaciones, la segmentación recursiva de caracteres es ideal para iniciarse en el uso de la GAR. A menudo proporciona resultados satisfactorios durante la fase de creación de prototipos, o para documentos de estructura sencilla. La segmentación recursiva de caracteres también es una opción que merece la pena si su proyecto tiene unos requisitos de coste y velocidad elevados.

 

Chunking semántico: un enfoque de chunking para comprender el significado del texto

El chunking semántico es una estrategia de chunking más avanzada queEn lugar de basarse únicamente en la información posicional del texto, se consigue una comprensión más profunda del significado semántico del mismo. La idea central es segmentar los documentos cuando su semántica cambia significativamente, asegurándose de que cada trozo se centra en torno a un único tema en la medida de lo posible.

La figura siguiente muestra cómo funciona el chunking semántico:

精通 RAG 文档分块策略:构建高效检索系统的分块策略指南El chunking semántico funciona - dibujado por Thuwarakesh
Por ejemplo, en las dos primeras frases se habla de agricultura hidropónica, en las dos siguientes se abordan temas globales y luego se vuelve a la agricultura hidropónica. El chunking semántico es capaz de reconocer estos cambios semánticos de tema y segmentar en los cambios de tema.

A diferencia de la segmentación recursiva de caracteres, la fragmentación semántica genera bloques de longitud variable. Determina los límites del bloque basándose en la integridad semántica, en lugar de preestablecer un número fijo de caracteres o tokens.

Pasos clave hacia la fragmentación semántica

La dificultad de la fragmentación semántica estriba en cómoProgramado para comprender la semántica de las frases**. Esto suele hacerse con la ayuda deModelos de incrustaciónimplementar. La incorporación de modelos como el de OpenAI text-embedding-3-largeLas frases pueden convertirse en representaciones vectoriales, y los vectores son capaces de captar la información semántica de una frase. Las frases que son semánticamente similares tienen vectores que también están más cerca en el espacio. **

Un proceso típico de fragmentación semántica consta de los cinco pasos siguientes:

  • Construcción del bloque inicial: Inicialmente divide el documento en frases o párrafos y combina frases o párrafos adyacentes en un bloque inicial.
  • Generar incrustación en bloqueUtiliza el modelo de incrustación para generar incrustaciones vectoriales para cada bloque inicial.
  • Calcular la distancia entre bloquesCalcula la distancia semántica entre bloques vecinos. Entre las métricas de distancia más utilizadas se encuentran la distancia coseno, etc. Cuanto mayor sea la distancia, mayor será la diferencia semántica.
  • Determinar el punto de división: Establece un umbral de distancia. Cuando la distancia entre bloques vecinos supera el umbral, los rompe para formar nuevos bloques semánticos. La selección del umbral debe ajustarse en función del documento concreto y del efecto experimental.
  • Visualización (opcional)La visualización de la distancia entre bloques ayuda a comprender el efecto de fragmentación de forma más intuitiva y a ajustar los umbrales.

El siguiente código muestra cómo implementar el chunking semántico:

# 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
)

Gráfico Seborn para visualizar las distancias:

精通 RAG 文档分块策略:构建高效检索系统的分块策略指南Utilizado para ilustrar el chunking semántico Diagrama Seaborn - dibujado por Thuwarakesh
En la figura, cuando la distancia entre bloques supera un umbral de 0,12, los bloques anteriores se fusionan en un bloque semántico mayor. Al final se generaron seis bloques semánticos de distintas longitudes.

Ventajas de la fragmentación semántica y escenarios aplicables

La ventaja de la fragmentación semántica es la capacidad deCapta mejor la estructura semántica de los documentos y agrega fragmentos de texto relacionados semánticamente, mejorando así la calidad de recuperación del sistema RAG. Es más adecuado para procesar los siguientes tipos de documentos:

  • Documentos con estructuras complejas y temas diversosPor ejemplo, informes extensos, documentos técnicos, libros, etc. que contienen múltiples subtemas.
  • Documentos con grandes saltos semánticosLos autores pueden dar saltos en sus pensamientos al escribir, y la fragmentación semántica puede adaptarse mejor a este estilo de escritura.

En comparación con la segmentación recursiva de caracteres, la fragmentación semántica delEl cálculo es más caro** y lento. Esto se debe principalmente a la necesidad de calcular el vector de incrustación y las métricas de distancia. Por lo tanto, en escenarios con recursos limitados, hay que tener en cuenta las ventajas y desventajas.

 

Agentic chunking: estrategias de fragmentación que imitan la comprensión humana

La clasificación por agentes es un paso más hacia la clasificación inteligente. Se puede consultar enBasándose en la forma en que los humanos leen y comprenden los documentos, LLM se utiliza como "agente inteligente" para ayudar a la fragmentación.

Los hábitos de lectura humanos no son completamente linealesEl agentic chunking intenta simular este proceso de comprensión humana. Cuando leemos, saltamos de un tema a otro o de un concepto a otro y construimos mentalmente la estructura lógica de un documento.

A diferencia de los dos métodos anteriores, el Agentic chunkingno presupone que contenidos semánticamente similares aparezcan consecutivamente en un documento**. Puede agregar fragmentos dispersos pero semánticamente relacionados de un documento para formar trozos semánticos más compatibles con la percepción humana.

Flujo de trabajo de fragmentación

La idea central del Agentic chunking esDeje que LLM "lea" el documento como un ser humano, identificando los conceptos y temas centrales del documento y agrupándolos en función de ellos. Un proceso de fragmentación típico de Agentic incluye:

  • ProponerConvertir cada frase de un documento en una Proposición más independiente. Por ejemplo, sustituyendo pronombres desconocidos por objetos para dar a cada frase un significado semántico más completo.
  • Contenedores de bloques de construcciónCreación de uno o más Chunk Containers para proposiciones semánticamente relacionadas. Cada Chunk Container puede tener un título y un resumen que describe el tema de ese contenedor.
  • Asignación proposicional dirigida por agentes: Utilizando LLM como Agente, "lee" las proposiciones una a una y determina a qué contenedor de bloques debe pertenecer la proposición.
    • Si el Agente considera que la proposición es relevante para el tema de uno de los contenedores de bloques existentes, se añade a ese contenedor.
    • Si el Agente considera que la proposición propone un nuevo tema, crea un nuevo bloque contenedor para albergar la proposición.
  • Reprocesamiento de contenedores en bloquePosprocesamiento de contenedores de bloques, por ejemplo, generando resúmenes y títulos de bloques más refinados basados en las proposiciones dentro del contenedor.

El siguiente código muestra la implementación de Agentic chunking:

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)

Ejemplos de proposicionalización

原始文本
===================
A crow sits near the pond. It's a white one.
命题化文本
==================
A crow sits near the pond. This crow is a white one.

Ventajas y retos de la agrupación de agentes

Agentic chunkedSu mayor ventaja es su flexibilidad e inteligencia**. Puede comprender mejor la estructura semántica profunda de los documentos y generar trozos semánticos más acordes con la cognición humana, y es especialmente bueno en el tratamiento de los siguientes tipos de documentos:**.

  • Documentación de estructuras no linealesPor ejemplo, los documentos que dan saltos de pensamiento y contienen muchos conocimientos previos o información implícita.
  • Documentos que necesitan integrar información entre párrafos y seccionesEl Agentic Chunking permite la agregación de fragmentos semánticamente relacionados que se encuentran dispersos en distintas ubicaciones de un documento.

Sin embargo, la fragmentación agéntica también se enfrenta a algunos retos:

  • alto costeLa fragmentación agéntica requiere llamadas frecuentes al LLM, lo que es costoso en términos de tiempo y cálculo.
  • Preguntar dependencias del proyectoLa eficacia del Agentic chunking depende en gran medida del diseño de la Prompt. Las prompts deben diseñarse cuidadosamente para guiar al LLM a trocear eficazmente.
  • Incertidumbre de los resultadosEl problema es que puede haber cierta incertidumbre en la salida del LLM, lo que lleva a resultados de fragmentación inestables.

Escenarios de aplicación de la fragmentación de agentes

La fragmentación de agentes, aunque más costosa, sigue siendo una opción que merece la pena considerar en algunos escenarios en los que la eficacia de los GAR es crítica. Por ejemplo:

  • Base de conocimientos en áreas especializadasPor ejemplo, las bases de conocimientos en campos como el derecho, la medicina, las finanzas, etc. requieren una precisión de búsqueda y una recuperación extremadamente altas.
  • complejo sistema de preguntas y respuestasSistema de preguntas y respuestas: un sistema de preguntas y respuestas que debe tratar cuestiones complejas que requieren razonamiento e integración de la información.

Lectura en profundidad:Agentic Chunking: clasificación semántica de textos basada en agentes de inteligencia artificial

 

Estrategias de fragmentación para distintos formatos de documento

La discusión anterior se ha centrado principalmente en el troceado de texto plano. Sin embargo, en la práctica, a menudo nos encontramos con distintos formatos de documento, como Markdown, HTML, PDF, código, etc. Para los distintos formatos, se necesita una estrategia de fragmentación más refinada que aproveche al máximo la información estructural del documento. Para los distintos formatos, se necesita una estrategia de fragmentación más refinada que aproveche al máximo la información estructural del documento.

Fragmentación de documentos Markdown y HTML

Los documentos Markdown y HTML tienen información de etiquetado estructurada, como encabezados, párrafos, listas, bloques de código, etc. PodemosUtilice estas etiquetas como base para la clasificación** para una clasificación más precisa. **

  • Bloque por títuloBloque de encabezamiento : Trate cada encabezamiento y el contenido que contiene como un bloque independiente. Esto es adecuado para documentos claramente estructurados con secciones diferenciadas.
  • trozoPárrafo: Trata cada párrafo como un chunk. Los párrafos suelen ser unidades semánticamente completas y son adecuadas como unidades básicas de fragmentación.
  • fragmentaciónCombine encabezamientos y párrafos para la fragmentación. Por ejemplo, primero divida el documento por encabezados de primer nivel, luego en el contenido bajo cada encabezado de primer nivel, luego divida por párrafos.

Ejemplo: fragmentación basada en etiquetas 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)

Agrupación de documentos PDF

La fragmentación de documentos PDF es relativamente compleja porque el PDF es esencialmente un formato tipográfico en el que se mezclan el contenido textual y la información tipográfica. Dividir los PDF directamente por caracteres o líneas puede destruir la integridad semántica.

Los pasos clave en la fragmentación de PDF suelen incluir:

  • Extracción de texto PDFUso de bibliotecas de análisis sintáctico de PDF (por ejemplo, PyPDF2, pdfminer u otras más profesionales). sin estructurar.io) para extraer contenido de texto de archivos PDF.
  • Limpieza y pretratamiento de textosEliminación de caracteres ruidosos, gestión de saltos de línea, corrección de errores de OCR, etc.
  • Extracción de información estructuradaIntenta extraer información estructurada de los PDF, como títulos, encabezados y pies de página, tablas, listas, etc. Algunas bibliotecas avanzadas de análisis sintáctico de PDF (por ejemplo, unstructured.io) pueden ayudar en la extracción de información estructurada.
  • Opciones de estrategia de fragmentaciónSelección de estrategias de fragmentación apropiadas (por ejemplo, fragmentación semántica, segmentación recursiva de caracteres, etc.) basadas en el contenido del texto extraído y la información estructural.

llamar la atención sobre algounstructured.io es una potente herramienta que puede manejar una amplia gama de formatos de documento (incluido PDF) e intenta extraer información estructurada de los documentos, simplificando el proceso de fragmentación de PDF.

Fragmentación de la documentación del código

La fragmentación de documentos de código (por ejemplo, archivos de código Python, Java o C++) exige tener en cuenta la estructura sintáctica y las unidades lógicas del código. Dividir el código simplemente por líneas o caracteres puede destruir la integridad y la ejecutabilidad del código.

Entre las estrategias habituales para fragmentar la documentación del código se incluyen las siguientes:

  • Clasificación por función/claseFunción o clase: Trate cada función o clase como un bloque independiente. Las funciones y clases suelen ser unidades lógicas de código.
  • Clasificación por bloques de códigoIdentifica bloques de lógica en el código (por ejemplo, bucles, sentencias condicionales, bloques try-except, etc.), tratando cada bloque como un chunk.
  • Combinado con la fragmentación de comentarios del códigoLos comentarios de código suelen ser explicaciones de la funcionalidad y la lógica del código. Los comentarios de código y sus bloques de código asociados pueden trocearse como un todo.

artefactoEl análisis estructurado y la fragmentación del código pueden verse facilitados por el uso de herramientas de análisis sintáctico como tree-sitter, que analiza código de diversos lenguajes de programación y genera árboles sintácticos abstractos (AST) que facilitan la fragmentación del código según su estructura sintáctica.

 

Elegir el tamaño de trozo y el solapamiento adecuados

Chunk Size y Chunk Overlap son dos parámetros importantes en la política de chunking que afectan directamente al rendimiento del sistema RAG.

  • tamaño del trozoLa cantidad de texto que contiene cada trozo. Un tamaño de trozo demasiado pequeño puede dar lugar a información semántica incompleta; un tamaño de trozo demasiado grande puede introducir ruido y reducir la precisión de la recuperación.
  • Tamaño del solapamientosolapamiento: la cantidad de texto que se solapa entre bloques vecinos. El objetivo del solapamiento es garantizar la continuidad contextual y evitar la pérdida de información en los límites de los bloques.

¿Cómo elijo el tamaño de trozo y el solapamiento adecuados?

No existe una respuesta absolutamente óptima para elegir el tamaño de trozo y el solapamiento adecuados, y normalmente debe determinarse por elCaracterísticas del documentoresponder cantandoefecto experimentaldeterminar. He aquí algunas reglas generales y sugerencias:

  • método heurístico::
    • En función de la longitud de la frase o del párrafoLa longitud media de las frases o párrafos de un documento puede servir de referencia para el tamaño de los trozos. Por ejemplo, si la longitud media de los párrafos es de 150 tokens, puede intentar fijar el tamaño del trozo en 150-200 tokens.
    • Considere la ventana contextual LLMEl tamaño del bloque no debe ser demasiado grande para no sobrepasar las limitaciones de la ventana de contexto del LLM. Al mismo tiempo, no debe ser demasiado pequeño para garantizar que el bloque contenga suficiente información semántica.
  • Experimentación y evaluación:
    • Ajuste iterativoParámetros: Establezca un conjunto inicial de parámetros de tamaño de trozo y solapamiento (por ejemplo, 500 tokens para el tamaño de trozo y 50 tokens para el solapamiento), construya el sistema RAG y evalúelo. A continuación, ajuste gradualmente los parámetros, observe los cambios en la recuperación y los efectos de las preguntas y respuestas, y elija la combinación óptima de parámetros.
    • Evaluación de los indicadoresCuantificar el rendimiento del sistema RAG utilizando métricas de evaluación adecuadas, como Recall@k, Precision@k, NDCG (Normalised Discounted Cumulative Gain), etc. para la recuperación. Estas métricas pueden ayudarle a evaluar objetivamente la eficacia de las distintas estrategias de fragmentación.

Herramientas de evaluación en Langchain

Langchain proporciona una serie de herramientas de evaluación que pueden ayudar en la evaluación y el ajuste de parámetros de los sistemas RAG. Por ejemplo, herramientas como DatasetEvaluator y RetrievalQAChain pueden ayudarle a automatizar la evaluación de los efectos de combinaciones de diferentes estrategias de chunking, modelos de recuperación y modelos LLM.

 

Evaluación de la eficacia de la estrategia de fragmentación

Una vez elegida la estrategia de fragmentación adecuada, ¿cómo se evalúa su eficacia? "Una mejor fragmentación significa una mejor recuperación", pero ¿cómo cuantificar "mejor"? Necesitamos algunos parámetros para evaluar los méritos de las estrategias de fragmentación.

A continuación se presentan algunas métricas de evaluación comunes que pueden ayudarle a valorar el impacto de una estrategia de fragmentación en el rendimiento de un sistema GAR:

  • Recuperación de indicadores:
    • Recuperación (Recall@k): se refiere a la proporción de documentos (o trozos) relevantes entre los resultados Top-k recuperados. Cuanto mayor sea la recuperación, más información relevante se obtendrá mediante la estrategia de fragmentación.
    • Precisión (Precision@k): se refiere a la proporción de documentos (o trozos) realmente relevantes entre los resultados Top-k recuperados. Cuanto mayor sea la precisión, mayor será la calidad de los resultados de la búsqueda.
    • NDCG (Ganancia acumulada actualizada normalizada)es una métrica de evaluación de la calidad de la clasificación más precisa que tiene en cuenta el nivel de relevancia y la posición de los resultados recuperados. un NDCG más alto indica una mejor calidad de la clasificación de la recuperación.
  • Indicadores de preguntas y respuestas:
    • Respuesta PertinenciaEvaluar la pertinencia de las respuestas generadas por el LLM con respecto a la pregunta. Cuanto mayor sea la relevancia de la respuesta, mejor será el sistema GAR a la hora de generar respuestas significativas basadas en la información recuperada.
      • Exactitud/fidelidad de la respuestaEvaluar si las respuestas generadas por el LLM son fieles a la información contextual recuperada, evitando "ilusiones" e información imprecisa. Una mayor precisión en las respuestas indica que la estrategia de fragmentación es más capaz de proporcionar un contexto fiable y guiar al LLM para que genere respuestas más creíbles.
      • Fluidez y coherencia de las respuestasEstrategia de fragmentación: Aunque principalmente influida por las propias habilidades del LLM, una buena estrategia de fragmentación también puede mejorar indirectamente la fluidez y coherencia de las respuestas. Por ejemplo, la fragmentación semántica proporciona un contexto más coherente y ayuda a los estudiantes a producir un lenguaje más natural.

Herramientas y metodologías de evaluación

  • evaluación manual:: El método más directo y fiable. Se invita a un evaluador humano a puntuar los resultados de búsqueda y las respuestas a preguntas y respuestas del sistema GAR basándose en criterios de evaluación predefinidos. Las desventajas de la evaluación manual son que es costosa, requiere mucho tiempo y es muy subjetiva.
  • Evaluación automatizada:: Uso de indicadores y herramientas de evaluación automatizados, por ejemplo:
    • Recuperación de indicadoresPor ejemplo, el recuerdo, la precisión, la NDCG, etc. pueden medirse utilizando herramientas estándar de evaluación de la recuperación de información (p. ej. rank_bm25sentence-transformers etc.) para cálculos automatizados.
    • Indicadores de preguntas y respuestasAlgunas métricas de evaluación de la PNL (por ejemplo, BLEU, ROUGE, METEOR, BERTScore, etc.) pueden utilizarse para ayudar a evaluar la calidad de las respuestas. Sin embargo, hay que señalar que las métricas automatizadas de evaluación de preguntas y respuestas siguen teniendo limitaciones y no pueden sustituir por completo a la evaluación manual.
    • Herramienta de evaluación de Langchain: Langchain ofrece una serie de herramientas de evaluación integradas, tales como DatasetEvaluator responder cantando RetrievalQAChainEsto simplifica el proceso de evaluación automatizada del sistema GAR.

Recomendaciones para el proceso de evaluación

  1. Construcción del conjunto de datos de evaluaciónEvaluación: Prepare un conjunto de datos de evaluación que contenga preguntas y sus correspondientes respuestas estándar. El conjunto de datos debe cubrir, en la medida de lo posible, escenarios de aplicación y tipos de preguntas típicos de los sistemas GAR.
  2. Selección de indicadores de evaluaciónEvaluación: selección de los indicadores adecuados de búsqueda y de preguntas y respuestas en función del objetivo de la evaluación. Puede utilizarse simultáneamente una combinación de evaluación manual y automatizada.
  3. Funcionamiento del sistema RAGEjecutar el sistema RAG en el conjunto de datos de evaluación utilizando diferentes combinaciones de estrategias de fragmentación, modelos de recuperación y modelos LLM para registrar los resultados de la evaluación.
  4. Análisis y comparación: Compara las métricas de evaluación de diferentes estrategias, analiza sus puntos fuertes y débiles y selecciona la combinación óptima de estrategias.
  5. Optimización iterativaEn función de los resultados de la evaluación, los parámetros de la estrategia de fragmentación, el modelo de recuperación y el modelo LLM se ajustan continuamente mediante optimización iterativa para mejorar el rendimiento del sistema RAG.

 

En resumen: elige la estrategia de fragmentación que mejor te funcione

En este artículo se analizan en profundidad las técnicas de fragmentación de documentos que son cruciales en las aplicaciones RAG, desde la segmentación recursiva básica de caracteres, pasando por la fragmentación semántica más inteligente y la fragmentación agéntica, hasta estrategias de fragmentación refinadas para distintos formatos de documentos, así como métodos para seleccionar y evaluar el tamaño de los trozos y los parámetros de solapamiento.

Revisión de los puntos esenciales

  • La masa del trozo determina la masa del GARUna buena estrategia de fragmentación es la piedra angular de un sistema GAR de alto rendimiento.
  • No existe una estrategia única de fragmentaciónEl chunking: Las distintas estrategias de chunking tienen sus propias ventajas e inconvenientes y son adecuadas para distintos escenarios. Hay que elegir la estrategia más adecuada en función de los requisitos específicos del proyecto, las características del documento y las limitaciones de recursos.
  • Segmentación recursiva de caracteres: Sencillo, rápido y económico para la creación de prototipos y proyectos sensibles a los costes.
  • fragmentación semánticaLa comprensión de la semántica del texto y la generación de trozos semánticamente coherentes mejora la calidad de la recuperación, pero es costosa desde el punto de vista informático.
  • Agrupación de agentes: Simula la comprensión humana, es más inteligente, más flexible y puede manejar documentos complejos, pero es costoso y la ingeniería de Prompt es compleja.
  • Clasificación por formatosPara distintos formatos, como Markdown, HTML, PDF, código, etc., se requiere una estrategia de fragmentación fina que aproveche la información estructural del documento.
  • Tamaño de los trozos y solapamientoValor óptimo: Debe ajustarse en función de las características del documento y de los resultados experimentales, no existe un valor óptimo absoluto.
  • La evaluación es clave:: Cuantificar la eficacia de la estrategia de fragmentación mediante métricas de evaluación y evaluación manual, y realizar una optimización iterativa.

¿Cómo elegir? Mi consejo.

  • Creación rápida de prototipos:: Intentos de prioridadSegmentación recursiva de caracteresLa RAG es una forma rápida de construir un prototipo de RAG y verificar la viabilidad del sistema.
  • La búsqueda de una mayor calidad: Si hay una gran demanda de calidad RAG y los recursos computacionales lo permiten, se puede probar elfragmentación semántica.
  • Tramitación de documentos complejos:: Para documentos con estructuras complejas y saltos semánticos.Agrupación de agentesPuede ser la opción preferida, pero hay que sopesar cuidadosamente el coste y la eficacia.
  • Formato específicoSi está trabajando con documentos en un formato específico como Markdown, HTML, PDF, código, etc., asegúrese de utilizar la funciónEstrategia de fragmentación selectivaAdemás, es importante aprovechar al máximo la información estructural del documento.
  • Optimización iterativa continua:: La elección de la estrategia de fragmentación no es un proceso que se realice de la noche a la mañana. En los proyectos reales, es necesarioExperimentación, evaluación y optimización iterativacon el fin de encontrar la mejor solución de fragmentación para usted.

Espero que este artículo te ayude a comprender mejor la tecnología de fragmentación RAG y a seleccionar y aplicar las estrategias de fragmentación adecuadas en proyectos reales para crear aplicaciones RAG más potentes.

© declaración de copyright

Artículos relacionados

Sin comentarios

Debe iniciar sesión para participar en los comentarios.
Acceder ahora
ninguno
Sin comentarios...