RAG y embeddings
¿Qué tamaño de chunk usar en un RAG en español? Medido con 3 modelos de embeddings
Con 2048 tokens de contexto, los chunks de 128 tokens encuentran la respuesta en el 99,4 % de 1190 preguntas en español; los de 1024, en el 91,7 %. El límite del modelo pesa más.
- Fecha
- 20 oct 2026
- Lectura
- 7 min
- Resultado
- 99,4 % vs 91,7 % con chunks de 128 y 1024 (bge-m3) • MiniLM trunca el 91,1 % a 256 • solape del 20 %: ≤ 2 puntos
En un RAG en español, los chunks pequeños (128–256 tokens) recuperan más respuestas con el mismo contexto: con 2048 tokens para el LLM y bge-m3, los chunks de 128 tokens contienen la respuesta en el 99,4 % de las preguntas y los de 1024 tokens, en el 91,7 %. El tamaño importa todavía más cuando el chunk pasa del límite del modelo de embeddings: paraphrase-multilingual-MiniLM-L12-v2 corta el 91,1 % de los chunks de 256 tokens y su recall@5 cae del 89,7 % (128 tokens) al 80,5 %. El solapamiento del 20 % mueve el resultado 2 puntos como mucho. Medido el 20 de octubre de 2026 sobre 1190 preguntas de XQuAD en español.
Las guías de RAG repiten «entre 256 y 512 tokens con un 10–20 % de solapamiento», casi siempre con corpus en inglés. No encontramos una medida en español con código publicado, así que la hemos hecho.
Definiciones
- Chunk: cada trozo en que se parte un documento antes de convertirlo en vector (embedding) y guardarlo en la base vectorial. Aquí su tamaño se mide en tokens de o200k_base, el tokenizador de GPT-4o y GPT-5.
- Solapamiento: parte del final de un chunk que se repite al principio del siguiente, para no partir una idea en dos.
- recall@k: porcentaje de preguntas en las que alguno de los k chunks más parecidos a la pregunta contiene la respuesta entera.
- Recall con presupuesto de contexto: lo mismo, pero en vez de k chunks se cogen los mejores mientras quepan en 1024 o 2048 tokens, que es lo que se mandaría al LLM. Es la comparación justa entre tamaños: cinco chunks de 1024 tokens son cinco veces más contexto que cinco de 128.
- Truncado: cada modelo de embeddings tiene un máximo de tokens de entrada (
max_seq_length). Si el chunk lo supera, el modelo solo «lee» el principio.
Hipótesis
- Con el mismo presupuesto de contexto, los chunks pequeños recuperan más respuestas que los grandes.
- Superar el máximo del modelo de embeddings hunde el recall, y en español ocurre antes de lo que parece, porque el tokenizador del modelo gasta más tokens que o200k_base con el mismo texto.
- El solapamiento del 20 % mejora poco y aumenta el número de chunks que hay que indexar.
Montaje
- Corpus: XQuAD en español: 1190 preguntas con su respuesta exacta, sobre 240 párrafos de 48 artículos de Wikipedia traducidos profesionalmente. Los párrafos se juntan por artículo (47.870 tokens en total), así que cada artículo es un documento largo que hay que trocear.
- Troceo: frases enteras empaquetadas hasta 128, 256, 512 o 1024 tokens, con 0 % y 20 % de solapamiento. Una frase solo se parte si por sí sola no cabe.
- Modelos de embeddings (3), todos multilingües y gratuitos en local: multilingual-e5-small (máximo 512 tokens), paraphrase-multilingual-MiniLM-L12-v2 (máximo 128) y bge-m3 (máximo 8192, solo vector denso).
- Búsqueda: similitud coseno exacta sobre todos los chunks de los 48 artículos a la vez, sin reranker ni búsqueda híbrida.
- Repeticiones: 5 por configuración (24 configuraciones). El recall fue idéntico en las 5; el tiempo de indexado se da en mediana. Intervalo de confianza del 95 % por bootstrap sobre las preguntas.
- Equipo: portátil Apple M1 Max con 64 GB, macOS 26.6.2, GPU de Apple Silicon (MPS), Python 3.12.4.
Resultados
Recall por tamaño de chunk (sin solapamiento)
| Modelo y tamaño | Chunks | Truncados | recall@1 | recall@5 | Recall con 1024 tokens | Recall con 2048 tokens |
|---|---|---|---|---|---|---|
| bge-m3 · 128 | 469 | 0,0 % | 82,4 % | 97,1 % | 98,7 % | 99,4 % |
| bge-m3 · 256 | 225 | 0,0 % | 82,1 % | 97,4 % | 97,0 % | 98,2 % |
| bge-m3 · 512 | 117 | 0,0 % | 78,3 % | 96,1 % | 91,5 % | 95,8 % |
| bge-m3 · 1024 | 66 | 0,0 % | 82,4 % | 96,1 % | 82,6 % | 91,7 % |
| e5-small · 128 | 469 | 0,0 % | 81,3 % | 97,9 % | 98,7 % | 99,4 % |
| e5-small · 256 | 225 | 0,0 % | 82,9 % | 97,6 % | 96,9 % | 98,4 % |
| e5-small · 512 | 117 | 25,6 % | 83,8 % | 97,5 % | 94,4 % | 96,9 % |
| e5-small · 1024 | 66 | 75,8 % | 77,6 % | 91,3 % | 77,8 % | 86,0 % |
| MiniLM-L12 · 128 | 469 | 15,4 % | 63,3 % | 89,7 % | 93,7 % | 96,6 % |
| MiniLM-L12 · 256 | 225 | 91,1 % | 52,5 % | 80,5 % | 77,8 % | 85,2 % |
| MiniLM-L12 · 512 | 117 | 94,0 % | 49,2 % | 76,1 % | 64,1 % | 73,9 % |
| MiniLM-L12 · 1024 | 66 | 92,4 % | 55,0 % | 77,2 % | 55,1 % | 67,5 % |
Intervalos de confianza del 95 % de la cifra clave (recall con 2048 tokens, bge-m3): 98,9–99,8 % con chunks de 128 tokens y 90,1–93,2 % con chunks de 1024. No se solapan.
Efecto del solapamiento del 20 % (bge-m3)
| Tamaño | Chunks sin solape | Chunks con solape | recall@5 sin → con | Recall con 2048 tokens sin → con |
|---|---|---|---|---|
| 128 | 469 | 494 | 97,1 % → 97,5 % | 99,4 % → 99,6 % |
| 256 | 225 | 249 | 97,4 % → 98,5 % | 98,2 % → 99,2 % |
| 512 | 117 | 129 | 96,1 % → 96,6 % | 95,8 % → 96,1 % |
| 1024 | 66 | 66 | 96,1 % → 96,4 % | 91,7 % → 92,4 % |
En los tres modelos y los cuatro tamaños, el solapamiento cambia el recall@5 en 2 puntos como mucho, y no siempre a mejor: con MiniLM-L12 y chunks de 1024 tokens baja del 77,2 % al 75,2 %. Cuesta entre un 5,3 % y un 10,7 % más de chunks que indexar. Sin solapamiento y con chunks de 128 o 256 tokens, la respuesta cabe entera en algún chunk en el 99,7 % de las preguntas: el resto queda partida entre dos y ningún modelo puede acertarla.
Tiempo de indexado (mediana de 5 repeticiones, 48 artículos, sin solapamiento)
| Modelo | 128 tokens | 256 tokens | 512 tokens | 1024 tokens |
|---|---|---|---|---|
| multilingual-e5-small | 1,216 s | 1,153 s | 1,116 s | 0,67 s |
| paraphrase-multilingual-MiniLM-L12-v2 | 1,129 s | 0,593 s | 0,326 s | 0,198 s |
| bge-m3 | 8,775 s | 8,416 s | 9,643 s | 10,616 s |
bge-m3 tarda entre 7,2 y 15,8 veces lo que multilingual-e5-small y no recupera más: con chunks de 128 o 256 tokens, los dos quedan dentro del mismo intervalo de confianza. MiniLM-L12 es rápido con chunks grandes porque solo lee sus primeros 128 tokens.
Qué significa
- Las tres hipótesis se cumplen. Con el mismo contexto para el LLM, los chunks de 128 tokens superan a los de 1024 en 7,7 puntos con bge-m3 (presupuesto de 2048 tokens) y en 16,1 puntos con un presupuesto de 1024.
- El recall@5 a secas engaña. Con bge-m3, el recall@5 casi no cambia entre 128 y 1024 tokens (97,1 % y 96,1 %), pero cinco chunks de 1024 tokens llenan el contexto con cinco veces más texto. Si comparas tamaños de chunk, compáralos con el mismo presupuesto de tokens.
- Mide el chunk con el tokenizador del modelo de embeddings, no con el del LLM. Un chunk de 512 tokens de o200k_base pasa de los 512 tokens de multilingual-e5-small en el 25,6 % de los casos con este corpus en español. El modelo trunca sin avisar.
- Para una empresa con documentos en español: empieza con chunks de 128–256 tokens, frases enteras y sin solapamiento. Un modelo pequeño como multilingual-e5-small basta para este tipo de preguntas y se puede ejecutar en cualquier portátil.
Cuándo usar cada opción
- Chunks de 128–256 tokens: preguntas de dato concreto (quién, cuándo, cuánto) sobre manuales, contratos o bases de conocimiento. Es el caso medido aquí.
- Chunks de 512 tokens o más: solo con un modelo que los admita sin truncar (bge-m3 o similar) y cuando la respuesta necesite varios párrafos seguidos. No lo hemos medido con ese tipo de preguntas.
- Solapamiento: no lo actives por defecto; pruébalo si tus documentos tienen frases muy largas o listas que se parten mal.
- paraphrase-multilingual-MiniLM-L12-v2: solo con chunks de 128 tokens o menos. Por encima, trunca casi todos los chunks.
Limitaciones
- Un solo corpus: Wikipedia traducida, con preguntas de respuesta corta y literal. Documentos de empresa (PDF, tablas, jerga) y preguntas que piden razonar sobre varios párrafos pueden dar otro tamaño óptimo.
- El corpus es pequeño (48 artículos). Con chunks de 1024 tokens quedan 66 chunks, y muchos artículos caben en uno o dos. En una base de miles de documentos la competencia entre chunks es mayor.
- Acierto estricto: la respuesta tiene que estar entera dentro del chunk. No se midió si el LLM responde bien con ese contexto.
- Solo búsqueda densa exacta: sin BM25, búsqueda híbrida, reranker ni índice aproximado (HNSW). bge-m3 se usó solo con su vector denso.
- Tres modelos de embeddings abiertos. No se probaron los de pago por API (OpenAI, Cohere, Voyage, Gemini) porque exigen clave.
- Los tiempos vienen de un solo portátil con otras apps abiertas y la GPU de Apple Silicon, en float32. Sirven para comparar modelos entre sí, no para dimensionar un servidor.
Cómo repetirlo
Código, entorno y resultados en bruto (acierto de cada pregunta en cada configuración y cada repetición del indexado): yeswelab-laboratorio/chunk-size-rag-espanol-embeddings en GitHub. Sin cuentas ni claves; descarga el corpus y los modelos de Hugging Face.
Relacionado
- ¿Cuántos tokens más gasta el español que el inglés? Medido en 7 tokenizadores
- Context engineering: los 2 tipos de context bloat en agentes de IA
- Memoria para agentes en n8n: window buffer frente a memoria persistente
¿Quieres saber qué troceo y qué modelo de embeddings funcionan con tus documentos y tus preguntas antes de montar el RAG? Encárganos el experimento.