MÓDULO 10 · RAG · 25 MIN

Chunking: el parámetro que condiciona todo

El chunk es la unidad mínima de lo que tu sistema puede encontrar. Nada más pequeño que un chunk se puede recuperar por separado, y nada más grande se puede recuperar entero. Por eso el tamaño de chunk no es un detalle de implementación: fija el techo de calidad del retrieval antes de que intervenga ningún modelo. Y como se decide al indexar, cambiarlo cuesta reindexar.
01 — El compromiso
Dos formas de equivocarse, una en cada extremo
CHUNK PEQUEÑOCHUNK GRANDE
Demasiado pequeñoLa idea queda partida entre dos chunks. Recuperas media respuesta y el modelo completa la otra mitad por su cuenta.
En su sitioCada chunk contiene una idea completa y poco más. Lo que recuperas es relevante entero.
Demasiado grandeCada chunk trae la respuesta y tres párrafos que no vienen a cuento. El contexto se diluye y pagas tokens por ruido.
// los dos extremos producen respuestas malas, pero se diagnostican distinto

La asimetría útil: los dos fallos se ven diferente. Con chunks demasiado pequeños, las respuestas salen incompletas o mezclan trozos que no encajan. Con chunks demasiado grandes, salen genéricas —el modelo tenía la respuesta delante, enterrada entre material irrelevante—. Antes de mover el número, mira cuál de los dos síntomas tienes.

02 — El solapamiento
Por qué el overlap existe y qué cuesta

Trocear un texto por longitud corta donde toca la cuenta, no donde termina la idea. El chunk_overlap repite el final de cada chunk al principio del siguiente, para que una frase partida por la mitad siga apareciendo completa en al menos uno de los dos.

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,          # se mide en CARACTERES, no en tokens
    chunk_overlap=100,       # el 20% del chunk se repite
    separators=["\n\n", "\n", ". ", " ", ""]
)

Esa lista de separators es la parte que casi nadie mira y la que hace el trabajo: se intenta cortar por párrafo; si el trozo sigue siendo largo, por línea; luego por frase; luego por espacio; y en último extremo, a mitad de palabra. Es decir, el corte por longitud es el último recurso, no el primero. De ahí el nombre «recursivo».

El overlap no es gratis: si repites el 20 % del texto, indexas un 20 % más de material, pagas un 20 % más de embeddings y aumentas la probabilidad de recuperar dos chunks que dicen casi lo mismo. Es un seguro contra los cortes desafortunados, y como todo seguro, tiene prima.

03 — La estrategia
El corte depende del documento, no del gusto

El troceo por longitud es el que se usa cuando el documento no tiene estructura aprovechable. Cuando la tiene, hay cortes mucho mejores, y son gratis:

Tipo de documentoDónde cortarPor qué ahí
Documentación técnicaPor encabezados, respetando la jerarquíaUna sección ya es una unidad de sentido
FAQUn chunk por pregunta-respuestaEl documento ya viene troceado por su autor
Contratos y textos legalesPor párrafo o cláusulaLa cláusula es la unidad que se cita
Conversaciones y emailsUn chunk por mensajeEl turno es la unidad natural
Código fuentePor función o claseMedia función no responde a nada
Texto corrido sin estructuraRecursivo por longitudNo hay nada mejor a mano

Fíjate en el patrón: en cinco de los seis casos, el corte bueno ya está escrito en el documento. El troceo por longitud es lo que se hace cuando se ha renunciado a leer la estructura, y por eso es el que más overlap necesita.

Auditoría El material da cuatro tamaños de chunk distintos sin explicar nunca por qué cambia: «500-1000 caracteres con 100-200 de overlap» como regla práctica, 500/100 en el código de la primera unidad, 800/200 unas páginas después como remedio a «respuestas genéricas», y 1000/200 en la unidad siguiente sin comentario. Todos caen dentro de su propio rango, así que no hay contradicción — pero tampoco hay criterio. Y hay una unidad oculta: su tabla de estrategias pone «256-512 tokens» en una fila y «500-1000 chars» en otra como si fueran la misma magnitud, cuando RecursiveCharacterTextSplitter cuenta caracteres. ¿Cuántos tokens son de verdad tus 500 caracteres en tu idioma y tu tokenizador? Es una llamada al tokenizador y cambia la cuenta de coste por consulta.
Para hacer
Mirar tus chunks antes de indexarlos

Antes de crear ningún embedding, imprime tres cosas de la lista de chunks: cuántos hay, la distribución de sus longitudes ([len(c.page_content) for c in chunks]) y el contenido entero de tres chunks al azar. No un preview de 100 caracteres: el chunk entero.

Lo que buscas es si cada uno se sostiene solo. Si al leer un chunk suelto no sabes de qué habla —empieza a media frase, o es todo cabecera de página—, ningún ajuste de retrieval posterior lo va a salvar. Y esa lectura de tres minutos te dice antes que ninguna métrica si tu estrategia de corte es la correcta para ese documento.