Imagínate este escenario: acabas de desplegar un asistente de IA para la documentación técnica de tu empresa o para el boletín legal corporativo. Utilizas uno de los mejores modelos del mercado, pero cuando los usuarios hacen preguntas concretas sobre normativas o procedimientos, el chatbot se va por las ramas, omite cláusulas clave o directamente inventa detalles. Tras horas ajustando prompts, llegas a la misma conclusión: el modelo no tiene la culpa. El problema está en cómo estás dividiendo el contexto antes de pasárselo. Cuando construyes un sistema de Generación Aumentada por Recuperación (RAG), la estrategia de fragmentación (chunking) determina hasta dónde puede llegar la calidad del sistema. Si la información se corta por la mitad, el modelo no puede reconstruirla. Al terminar este artículo sabrás qué estrategia usar según tu tipo de datos, presupuesto y requisitos de latencia.
1. ¿Qué es RAG y por qué importa para los productos de IA?
Retrieval-Augmented Generation (RAG) es la arquitectura que conecta un LLM con bases de conocimiento externas y actualizadas sin necesidad de reentrenar el modelo.
Casos de uso reales en productos
- Chatbot de documentación interna: consulta manuales, wikis y PDFs corporativos
- Asistente legal: responde con base en contratos, normativas y resoluciones (BOE, BOJA)
- Copiloto de soporte: responde usando tickets anteriores y FAQs actualizadas
- Buscador semántico: consultas en lenguaje natural sobre un catálogo de productos
RAG vs. Fine-tuning: ¿cuándo usar cada uno?
| Criterio | RAG | Fine-Tuning |
|---|---|---|
| Objetivo principal | Acceso a conocimiento dinámico, específico o privado | Adaptación de estilo, formato o tono |
| Actualización de datos | Inmediata (solo reindexar el documento) | Costosa y lenta (requiere reentrenar) |
| Trazabilidad y citas | Alta (puedes mostrar la fuente del fragmento) | Baja (el conocimiento queda en los pesos) |
| Prevención de alucinaciones | Elevada (el modelo se ciñe al contexto) | Moderada (propenso a memorización sesgada) |
| Coste inicial | Bajo | Alto |
| Si necesitas que el modelo conozca información específica de tu dominio, empieza por RAG. El fine-tuning es para ajustar cómo responde el modelo, no qué sabe. |
2. El problema del chunking: por qué el tamaño del contexto importa tanto
Un chunk es la unidad de texto que se convierte en un vector y se almacena en una base de datos vectorial. Cuando un usuario hace una pregunta, el sistema busca los chunks más similares y los pasa al LLM como contexto. La trampa más común: usar la configuración por defecto de los tutoriales, fragmentos rígidos de 512 tokens con un solapamiento de 50-100 tokens.
[--- Chunk 1 (512 tokens) ---] [--- Chunk 2 (512 tokens) ---]El tamaño del chunk crea un trade-off que no tiene una respuesta universal:
| Chunks pequeños | Chunks grandes | |
|---|---|---|
| Precisión del retrieval | Alta | Baja |
| Contexto preservado | Bajo | Alto |
| Coste en tokens | Bajo | Alto |
| Riesgo de fragmentar ideas | Alto | Bajo |
Si cortas una cláusula legal o un procedimiento técnico a la mitad, los embeddings resultantes representarán fragmentos incompletos y la búsqueda devolverá resultados inútiles. El chunk ideal contiene exactamente la información necesaria para responder la pregunta, y nada más.
3. Las principales estrategias de chunking
3.1. Fixed-Size Chunking (por caracteres o tokens)
Divide el texto tras un número fijo de caracteres o tokens, sin tener en cuenta las fronteras semánticas. Muy rápido y fácil de implementar, pero rompe oraciones y párrafos a la mitad. Útil para prototipado rápido o procesamiento masivo de datos poco estructurados.
from langchain_text_splitters import CharacterTextSplittertext_splitter = CharacterTextSplitter( chunk_size=500, chunk_overlap=50, separator="")chunks = text_splitter.split_text(documento)3.2. Recursive Character Text Splitting
La estrategia por defecto en la mayoría de pipelines de producción. Intenta dividir buscando separadores naturales en orden jerárquico: párrafos (\n\n), líneas (\n), espacios y finalmente caracteres.
Buena para propósito general, artículos, guías y prosa continua. Empieza aquí si no sabes por dónde empezar.
from langchain_text_splitters import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter( chunk_size=400, chunk_overlap=50, # 10-20% del chunk_size es un buen punto de inicio separators=["\n\n", "\n", " ", ""])chunks = text_splitter.create_documents([texto_prosa])Empieza con chunk_size entre 400 y 1000 y un overlap del 15%, luego ajusta evaluando con métricas reales.
3.3. Semantic Chunking (basado en embeddings)
En lugar de fijar un número de caracteres, calcula la similitud semántica entre oraciones consecutivas usando embeddings. Cuando la similitud cae por debajo de un umbral, detecta un cambio de tema e inserta un corte.
Funciona bien en documentos con cambios temáticos frecuentes e impredecibles (informes anuales, corpus heterogéneo). El precio a pagar: requiere llamadas a embeddings por oración durante la ingesta, lo que lo hace más lento y caro que las opciones anteriores.
from langchain_experimental.text_splitter import SemanticChunkerfrom langchain_openai import OpenAIEmbeddingsembeddings = OpenAIEmbeddings(model="text-embedding-3-small")chunker = SemanticChunker( embeddings, breakpoint_threshold_type="percentile", breakpoint_threshold_amount=85)chunks = chunker.create_documents([texto_contrato])3.4. Document-Structure Chunking (Markdown, HTML, PDF)
Divide respetando la jerarquía nativa del documento: headers, secciones, listas, tablas. Cada chunk hereda el metadata de su posición en la jerarquía.
Es la opción más precisa cuando los documentos tienen estructura definida. Vale para documentación técnica, manuales, boletines oficiales (BOE/BOJA) y contratos estructurados.
from langchain_text_splitters import MarkdownHeaderTextSplitterheaders = [ ("#", "H1"), ("##", "H2"), ("###", "H3"),]splitter = MarkdownHeaderTextSplitter( headers_to_split_on=headers, strip_headers=False)chunks = splitter.split_text(markdown_content)# Cada chunk incluye metadata: {"H1": "Nombre sección", "H2": "Subsección"}Para PDFs complejos con tablas, imágenes o layouts multi-columna, usa Docling o Unstructured.io en lugar de leer el texto plano directamente. Para secciones muy largas, combina structure chunking con recursive splitting como fallback.
3.5. Parent-Document Retrieval y Propositional Chunking (avanzado)
Dos estrategias que resuelven el trade-off granularidad/contexto de formas distintas.
Parent-Document Retrieval indexa chunks pequeños (~100 tokens) en el vector store para tener alta precisión semántica en la búsqueda, pero devuelve al LLM el fragmento “padre” más amplio (400-800 tokens) para garantizar contexto suficiente.
Propositional Chunking descompone el documento en proposiciones lógicas atómicas: aserciones independientes y autocontenidas. Cada chunk representa una sola idea. Está inspirado en el paper Dense X Retrieval.
# Pseudocódigo: extracción de proposiciones con LLMpropositions = llm.invoke(f"""Descompón el siguiente texto en proposiciones independientes.Cada proposición debe ser autocontenida y verificable por sí sola.Texto: {texto}Responde con una lista JSON de proposiciones.""")Estas estrategias tienen sentido en sistemas empresariales donde la precisión justifica el coste computacional adicional, por ejemplo asistentes legales o médicos.
3.6. GraphRAG: Recuperación Basada en Grafos de Conocimiento (avanzado)
Cuando el chunking basado en texto plano no es suficiente para responder preguntas transversales o de razonamiento complejo, GraphRAG es la alternativa. En lugar de indexar bloques de texto aislados, extrae la estructura de relaciones del corpus para construir un Grafo de Conocimiento: las entidades son nodos y sus relaciones son aristas. Esto permite superar el límite más crítico del RAG vectorial clásico: el razonamiento multi-hop, conectar la entidad A con la C a través de B en distintos documentos, y responder preguntas como “¿cuáles son los temas principales de todo el corpus?”.
Cómo funciona Microsoft GraphRAG (la implementación de referencia):
- Un LLM extrae entidades y relaciones del corpus completo (sujeto-predicado-objeto)
- Se detectan comunidades de nodos estrechamente vinculados (algoritmo de Leiden)
- Se generan resúmenes jerárquicos a distintos niveles de abstracción
- Ante una consulta, el sistema combina recorrido por subgrafos con resúmenes comunitarios
En producción, la mejor práctica es combinar búsqueda vectorial para precisión rápida en pasajes concretos con el grafo de conocimiento para contextualizar relaciones globales.
Tiene sentido en corpus con alta interconexión de entidades (jurisprudencia, historiales médicos, arquitectura de software), para preguntas multi-hop como “¿cómo afecta el artículo X a la entidad Y mencionada en la sección Z?”, y en análisis transversales de grandes volúmenes documentales.
El coste es real: la fase de construcción del grafo requiere entre 3 y 5 veces más tiempo y tokens que el RAG vectorial clásico, y es considerablemente más difícil de mantener. Librerías de referencia: Microsoft GraphRAG, LlamaIndex Property Graph.
4. Comparativa de estrategias
| Estrategia | Facilidad | Calidad retrieval | Coste compute | Caso de uso ideal |
|---|---|---|---|---|
| Fixed-Size | ★★★★★ | ★★☆☆☆ | ★★★★★ | Prototipado rápido, corpora homogéneos |
| Recursive | ★★★★☆ | ★★★☆☆ | ★★★★☆ | Propósito general, artículos, prosa |
| Semantic | ★★★☆☆ | ★★★★☆ | ★★★☆☆ | Docs heterogéneos con cambios de tema |
| Estructura | ★★★☆☆ | ★★★★★ | ★★★☆☆ | Docs estructurados (Markdown, HTML, Leyes) |
| Parent / Propositional | ★★☆☆☆ | ★★★★★ | ★★☆☆☆ | Alta precisión, dominio legal/médico |
| GraphRAG | ★☆☆☆☆ | ★★★★★ | ★☆☆☆☆ | Razonamiento multi-hop, relaciones complejas |
5. ¿Qué estrategia elegir?
Antes de elegir, evalúa estas variables:
- Tipo de documento: ¿Markdown, PDF, HTML, texto plano?
- Volumen: miles de documentos implica priorizar velocidad; pocos pero críticos implica priorizar calidad.
- Tipo de consulta: ¿preguntas factuales concretas o consultas amplias?
- Presupuesto de tokens: ¿cuánto puedes gastar en indexación y retrieval?
- Latencia: ¿el usuario espera respuesta en tiempo real?
6. Cómo evaluar el pipeline RAG
No intentes adivinar qué estrategia funciona mejor por intuición. Usa métricas cuantitativas con frameworks como RAGAS, DeepEval o TruLens:
| Métrica | Qué mide |
|---|---|
| Context Recall | ¿Se recuperaron todos los chunks relevantes? |
| Context Precision | ¿Qué porcentaje de chunks recuperados son realmente útiles? |
| Answer Relevancy | ¿La respuesta responde la pregunta del usuario? |
| Faithfulness | ¿La respuesta se basa únicamente en el contexto dado, sin alucinaciones? |
Para hacer A/B testing de chunking en producción:
- Indexa tu corpus con dos estrategias en vector stores separados
- Para un porcentaje del tráfico, captura los chunks recuperados por cada estrategia
- Evalúa Context Precision y Answer Relevancy con RAGAS
- Elige la ganadora y migra el 100% del tráfico
7. Stack recomendado
Para un pipeline RAG listo para producción:
- Orquestación: LangChain, LlamaIndex o Semantic Kernel (Microsoft, especialmente recomendado si tu stack es .NET/C#)
- Embeddings: OpenAI
text-embedding-3-smallo modelos open-source comonomic-embed-text - Vector store: Qdrant (filtros por metadatos, muy rápido) o pgvector (si ya usas PostgreSQL)
- Búsqueda híbrida: combina búsqueda vectorial con BM25 y añade un modelo de reranking (Cohere Rerank o
cross-encoder/ms-marco-MiniLM) para reordenar los resultados antes de pasarlos al LLM - Evaluación: RAGAS desde el primer día
El error más frecuente es implementar RAG sin medir. Configura evaluación desde el inicio, aunque sea con un conjunto pequeño de preguntas de prueba. Es la única forma de saber si tus cambios mejoran o empeoran el sistema.
💬 ¿Qué estrategia de chunking estás usando en producción? ¿Has probado alguna combinación que funcione especialmente bien?
¿Te ha resultado útil? Compártelo con tu equipo. La mayoría de los problemas de RAG tienen solución en la capa de chunking.
Comentarios
Aún no hay comentarios. ¡Sé el primero!
Deja un comentario