Yeda AI Tips · #040

English

Chunk With Overlap: deja de perder significado en los límites

Tu pipeline de RAG recupera el documento correcto, el modelo de embeddings está bien, la base de datos vectorial está bien — y aun así la respuesta llega cortada a mitad de idea. Nueve de cada diez veces, el culpable no es el modelo. Es cómo cortaste el documento antes de que siquiera llegara al modelo de embeddings.

El problema: los embeddings solo ven un fragmento a la vez

Un modelo de embeddings no lee todo tu documento. Lee el fragmento que le entregas, de forma aislada, y convierte ese fragmento en un vector. Divide el documento en un punto fijo e ingenuo — cada 1000 caracteres, sin importar qué haya en la página — y de vez en cuando cortarás justo a través de la frase que responde la pregunta del usuario. La mitad termina en el fragmento 4, la otra mitad en el fragmento 5, y el embedding de ninguno de los dos captura la idea completa. En el momento de la consulta, el recuperador solo puede devolver fragmentos completos, así que el modelo recibe media respuesta y o bien duda o bien alucina el resto.

La solución: solapamiento entre fragmentos

Haz que fragmentos consecutivos compartan una porción de texto. En lugar de que los límites entre fragmentos sean cortes tajantes, cada fragmento repite la parte final del fragmento anterior. Si una frase queda dividida por el corte principal, hay una buena probabilidad de que la frase completa aún aparezca intacta dentro de la región de solapamiento de un fragmento vecino — de modo que al menos un embedding representa la idea por completo.

Un punto de partida de uso común:

chunk_size = 1000      # characters per chunk
chunk_overlap = 200    # characters shared with the previous chunk

Eso es aproximadamente un 20% de solapamiento — un valor predeterminado razonable desde el cual ajustar, no una regla a seguir a ciegas.

Cómo hacerlo de verdad: usa un splitter recursivo, no un corte fijo

Solapar un splitter ingenuo de tamaño fijo sigue cortando donde caiga el conteo de caracteres — a mitad de palabra, a mitad de frase, donde sea. Un splitter recursivo de caracteres intenta el corte más limpio posible primero y solo recurre a uno más tosco si el fragmento sigue siendo demasiado grande:

  1. Intenta dividir primero en saltos de párrafo.
  2. Si un "párrafo" sigue siendo demasiado grande, recurre a saltos de línea sencillos.
  3. Si eso sigue siendo demasiado grande, recurre a dividir en espacios.
  4. Solo como último recurso corta a mitad de palabra.

La mayoría de los cortes caen en límites naturales del documento, y el solapamiento absorbe los que no. (La biblioteca y el nombre de la clase variarán según tu stack — la división recursiva con solapamiento es el concepto que importa, no el paquete específico.)

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
)
chunks = splitter.split_text(document_text)

Ajuste por corpus

Trucos avanzados

Recursos

¿Estás construyendo una función de IA? Yeda AI diseña, audita y lanza sistemas LLM en producción.

Habla con nosotros · Lee el blog