Inicio / Artículos

Selección de fragmentos sin consulta: Uso de K-Means cuando RAG no tiene pregunta que hacer

Sin una consulta del usuario, RAG no puede seleccionar el contexto. Considere K como la cantidad de resultados, agrupe las incrustaciones de los fragmentos con k-means y conserve los fragmentos centrípetos y sus fuentes.

Editor: REACTAPP.TOP13 min de lectura3095 palabras

Fuentes: You Don’t Need RAG. You Need Semantic Compression.

Algunos problemas relacionados con los LLM no cuentan con nombre, marco de trabajo ni mucha literatura al respecto. Este se presenta de la siguiente manera: una cantidad muy grande de texto, sin pregunta del usuario, y la tarea de seleccionar qué fragmentos entregar a un modelo para que se aborden todos los temas y cada fragmento pueda rastrearse hasta su origen.

No se trata de generación reforzada por recuperación de información, ya que no se busca nada. Tampoco es compresión de prompts ni resumen. La comunidad de investigación aún no ha definido claramente este tipo de problema, y las herramientas habituales no son adecuadas para él. Lo que sigue describe el problema, explica por qué las técnicas existentes son insuficientes y presenta una solución sencilla que coincide con las ideas académicas existentes al mismo tiempo que cubre una laguna que esos trabajos omiten.

Cuando no hay nada que buscar

Cualquiera que haya trabajado con modelos de lenguaje grande en los últimos años conoce el ciclo RAG: un usuario hace una pregunta, la consulta se incrusta, se recuperan fragmentos similares de un almacén vectorial, estos se incluyen en el prompt y se genera una respuesta basada en ellos. Este patrón es elegante, está bien documentado y es compatible con todos los frameworks más importantes. También asume, de forma implícita, que existe una consulta.

A menudo no la hay. Frameworks como LangChain y LlamaIndex están organizados en torno a la consulta y la recuperación de información, y la mayoría de los artículos sobre compresión de contexto también parten de una consulta. Al buscar formas de elegir los mejores fragmentos para un modelo de lenguaje grande, cada resultado asume la existencia de una pregunta del usuario que guíe esa elección.

Considere una aplicación de aprendizaje. Los estudiantes suben material del curso: libros de texto, diapositivas, transcripciones de videos, notas manuscritas, a veces cientos de páginas. No buscan nada; en esencia dicen: “Aquí están mis cursos, créame materiales de estudio”. El sistema debe entonces generar resultados estructurados como hojas de cuestionarios, tarjetas de memoria, resúmenes y mapas conceptuales. Cada resultado debe abordar un tema diferente e indicar su fuente, mientras que el volumen total de los materiales originales supera con creces cualquier ventana de contexto.

Tres requisitos al mismo tiempo

Los enfoques existentes incumplen al menos una de las tres restricciones que este caso de uso impone simultáneamente.

  1. Sin señal de consulta. Nada proveniente del usuario guía la selección, por lo que el sistema debe determinar qué es importante únicamente a partir de los datos.
  2. Cobertura temática garantizada. El resultado es un conjunto de resultados que abarcan conjuntamente toda la amplitud del material. Omitir un tema completo constituye un fracaso grave; un cuestionario de biología que nunca aborda la genética es inútil.
  3. Rastreabilidad de la fuente. Cada resultado debe remitir a un fragmento específico del original, por ejemplo “basado en el Capítulo 3, páginas 12 a 14 del libro de texto de bioquímica”. En la educación esto no es opcional, ya que los estudiantes necesitan saber dónde seguir leyendo.

Ningún método existente cumple con los tres requisitos al mismo tiempo. Ese es el vacío.

Lo que ofrece la literatura y hasta dónde llega

Por qué enviarlo todo falla

El enfoque ingenuo consiste en introducir todo el material en la ventana de contexto. Dado que los modelos pueden procesar de 128k a 200k tokens, es tentador pensar que eso funciona. Pero no es así. El estudio “Lost in the Middle” mostró una curva de rendimiento en forma de U: los modelos manejan bien el inicio y el final del contexto, pero fallan sistemáticamente con lo que se encuentra en el medio. La precisión disminuyó en más del 30% cuando el contenido clave pasó de los bordes al centro, incluso en modelos diseñados para contextos largos.

Por lo tanto, incluso cuando todo cabe, grandes partes del material son ignoradas. El cuestionario abarcaría los primeros y últimos capítulos, omitiendo el resto. Más contexto no equivale a un mejor contexto.

La compresión de prompts responde a otra pregunta

Cada vez hay más estudios que acortan las entradas eliminando tokens redundantes antes de que lleguen al modelo.

Selective Context cuenta con un pequeño modelo de lenguaje que calcula la autoinformación de las unidades léxicas, ya sean tokens, frases nominales o oraciones, y descarta aquellas que poseen poca información. No necesita ninguna consulta, lo que cumple con la primera restricción. Sin embargo, filtra dentro del texto existente, generando una copia comprimida del mismo texto y no una selección de contenido representativo de distintos temas. No puede garantizar una cobertura completa, y el texto modificado pierde su vínculo directo con los fragmentos originales, por lo que fallan la segunda y la tercera restricciones.

LLMLingua y LLMLingua-2 amplían esta idea mediante compresión iterativa y clasificadores de tokens aprendidos, logrando ratios de hasta 20 veces. Comparten la misma limitación básica: el texto se comprime para la máquina, no se organiza para una persona. El resultado es un prompt que el modelo puede analizar, no un conjunto estructurado de contenido que pueda rastrearse.

RECOMP entrena compresores capaces de resumir o extraer información de documentos recuperados, tanto en enfoques extractivos como abstractivos. Es el más sofisticado del grupo, pero necesita explícitamente una consulta para decidir qué conservar, por lo que incumple la primera restricción.

En resumen, la compresión mediante prompts reduce el número de tokens. No selecciona contenido representativo, no garantiza la cobertura temática ni mantiene la estructura original.

El ranking de grafos representa pero no organiza

TextRank y LexRank construyen un grafo de similitud entre oraciones y aplican PageRank para identificar las más centrales, es decir, aquellas que mejor representan al documento completo. No necesitan ninguna consulta, y durante dos décadas han sido el estándar para la resumen extractivo no supervisado. Su debilidad conocida es la redundancia: las oraciones similares obtienen una centralidad similar, por lo que las opciones principales suelen repetirse con palabras diferentes. Un resumen de TextRank de un libro de texto de biología podría incluir tres oraciones sobre la replicación del ADN y ninguna sobre la síntesis de proteínas, simplemente porque la replicación se menciona con más frecuencia.

Eso afecta la cobertura, incluso si los temas principales tienden a aparecer, y como los métodos funcionan con oraciones, la trazabilidad solo se satisface parcialmente.

El clustering es lo más cercano

La resumen basado en clustering, mediante K-means, HDBSCAN u otros algoritmos similares aplicados a embeddings de oraciones, agrupa las oraciones similares en clústeres temáticos y selecciona una representante de cada uno. Esto elimina eficazmente la redundancia: cada clúster aporta una sola oración y los clústeres diferentes abarcan temas distintos.

El trabajo más reciente y destacado en esta área, “Graphs in Clusters”, combina K-means con TextRank. Primero se realiza el clustering para lograr una cobertura amplia, y luego se aplica el ranking dentro de cada clúster para determinar su importancia. Este enfoque supera a los métodos basados únicamente en grafos o únicamente en clustering en pruebas con documentos largos como ArXiv y PubMed.

Es el pariente más cercano, pero difiere en varios aspectos importantes. Su objetivo es un resumen de texto plano, mientras que aquí el objetivo son N salidas estructuradas. Ajusta K mediante el método del codo, mientras que aquí K proviene de la solicitud del usuario. Funciona con oraciones, mientras que aquí se necesita una granularidad por bloques para conservar los metadatos de origen. Sus clústeres son un paso intermedio invisible, mientras que aquí son los resultados finales. Además, no tiene concepto alguno de rastreo obligatorio del origen.

Comparación directa

Frente a estas tres restricciones, surge un patrón claro. RAG conserva las fuentes pero requiere una consulta y no puede garantizar la cobertura total. Selective Context y LLMLingua no necesitan consulta, pero eliminan la estructura de las fuentes y tampoco pueden asegurar la cobertura. RECOMP necesita una consulta. TextRank y LexRank funcionan sin ella, pero generan resultados redundantes y una trazabilidad deficiente. La resumen por clústeres satisface las dos primeras restricciones, al no necesitar consulta y garantizar la cobertura, pero opera a nivel de oración, lo que interrumpe la conexión con la fuente original.

No existe un método establecido para la selección de fragmentos que sea independiente de consultas, garantice la cobertura y permita rastrear las fuentes.

Reorientando el enfoque basado en clústeres

La solución radica en invertir la forma en que normalmente se utiliza el clustering en el procesamiento del lenguaje natural. En la literatura especializada, K es un hiperparámetro. Los investigadores prueban valores como K=5, K=10, K=50, grafican las puntuaciones de silueta o las curvas de inercia y eligen un valor “mejor”. Los clústeres son objetos matemáticos que sirven al algoritmo, y el usuario nunca los ve.

En este enfoque, K es una especificación de producto. Un estudiante que solicita 10 hojas de exámenes establece K en 10. Cinco páginas de resumen significan K=5, y treinta tarjetas de memoria significan K=30. Cada clúster se corresponde con exactamente una salida. El clúster no es una abstracción intermedia; es el resultado final. Existe un cuestionario sobre la mitosis porque existe un clúster de fragmentos relacionados con la mitosis en el espacio semántico del contenido subido.

Los métodos existentes utilizan el clustering para comprimir texto para la máquina. Este método, en cambio, emplea el clustering para organizar el contenido para el ser humano.

En la etapa posterior, eso cambia todo. Tradicionalmente, K se ajusta matemáticamente y los clústeres permanecen ocultos; lo que sigue al clustering es la generación de un resumen simplificado. Aquí, K proviene de la solicitud: cada clúster se convierte en algo que recibe el usuario, y cada clúster desencadena una llamada al LLM que genera una salida que cita su fuente.

El pipeline de cinco pasos

1. División en fragmentos. Los documentos se dividen con herramientas estándar de LlamaIndex o LangChain, o con reglas personalizadas. Cada fragmento conserva su texto, archivo de origen, número de página, posición y cualquier otro metadato. Un tamaño típico es de 500 a 1000 tokens, con superposición entre fragmentos vecinos del 10 al 20%, como compromiso entre mantener las ideas completas y lograr clústeres más detallados. Los fragmentos pueden enriquecerse opcionalmente con resúmenes, palabras clave o etiquetas de entidades, lo cual ayuda en el clustering pero no es obligatorio.

2. Incrustación. Cada fragmento se convierte en un vector denso. El modelo depende del conjunto de herramientas utilizado: Sentence-Transformers es una opción rápida y gratuita como referencia, text-embedding-3-small de OpenAI es eficaz en varios idiomas, y Mistral Embed o Cohere Embed son alternativas competitivas. Lo importante es que los fragmentos semánticamente similares generen vectores similares, independientemente del vocabulario.

3. K-means. Este es el paso fundamental. K-means divide el espacio de incrustación en exactamente K grupos, donde K corresponde al número de resultados que desea obtener el usuario:

from sklearn.cluster import KMeans
n_outputs = 10  # User wants 10 quiz sheets
kmeans = KMeans(n_clusters=n_outputs, random_state=42, n_init=10)
kmeans.fit(embeddings)

Tres propiedades se derivan directamente y satisfacen las tres restricciones. No se necesita ninguna consulta, ya que K-means agrupa según la similitud entre los fragmentos y no según su relevancia con respecto a una señal externa. Se garantiza la cobertura temática, ya que cada fragmento queda en exactamente un clúster y cada tema de los datos está representado. La redundancia desaparece, ya que los fragmentos que dicen lo mismo tienen embeddings similares, terminan juntos y aportan un único representante.

4. Selección del representante. Para cada clúster, se toma el fragmento más cercano al centroide, el cual expresa mejor el tema del clúster:

import numpy as np
selected = []
for i in range(n_outputs):
    cluster_indices = np.where(kmeans.labels_ == i)[0]
    centroid = kmeans.cluster_centers_[i]
    distances = np.linalg.norm(
        embeddings[cluster_indices] - centroid, axis=1
    )
    best_local_idx = np.argmin(distances)
    best_global_idx = cluster_indices[best_local_idx]
    selected.append(chunks[best_global_idx])  # Full chunk with metadata

El fragmento seleccionado conserva toda su metadatos originales, por lo que no se pierde nada y todo puede ser citado. Para resultados más detallados, se pueden utilizar los tres fragmentos más cercanos a cada centroide en lugar de uno; el principio sigue siendo el mismo.

5. Generación. Los fragmentos elegidos de cada clúster se envían al LLM con una instrucción adecuada al tipo de resultado, y los metadatos de origen van junto a ellos para que el modelo pueda hacer las citaciones. El clúster 1 genera el Cuestionario 1, citando las páginas 12 a 14 del primer PDF. El clúster 2 genera el Cuestionario 2, citando una transcripción de video a las 14:30. Este patrón se repite hasta el clúster K.

Cuando no se indica un número

No todo usuario solicita diez cuestionarios; algunos simplemente quieren “un cuestionario” o “un resumen”. Funcionan tres alternativas. El presupuesto de tokens divide el contexto efectivo del modelo por el tamaño promedio de los fragmentos: en un modelo de 16k tokens y fragmentos de 800 tokens, K se sitúa cerca de 20. El método del codo prueba varios valores de K y elige el punto en el que la inercia deja de disminuir de manera significativa. También funciona una regla aproximada de un clúster por cada 5 a 10 páginas de texto original. En la práctica, el presupuesto de tokens es el más fiable, ya que se relaciona directamente con lo que el modelo puede manejar.

Lo que garantiza el método

Estas son propiedades matemáticas de K-means, no observaciones empíricas.

  • Cobertura. Cada punto se asigna a un clúster, por lo que no hay fragmentos olvidados. Si existe un tema, pertenece a un clúster que cuenta con un representante. Por el contrario, la recuperación Top-K puede devolver K fragmentos sobre un tema popular y pasar por alto completamente otros.
  • Sin redundancia. Los fragmentos similares se agrupan y solo uno representa a cada grupo. Dos fragmentos que dicen lo mismo con palabras diferentes comparten un clúster, y solo uno sobrevive.
  • Granularidad ajustable. Un valor bajo de K genera clústeres amplios para temas extensos, mientras que un valor alto produce clústeres más estrechos para conceptos específicos; el usuario controla esto a través de la solicitud.
  • Preservación de la fuente. Al trabajar con fragmentos y no con tokens o oraciones, se mantiene toda la cadena de metadatos en cada pieza seleccionada. La compresión a nivel de token no puede ofrecer esto por diseño.
  • Velocidad. K-means con 500 embeddings de 384 dimensiones tarda menos de un segundo. No se realiza ninguna llamada a un LLM durante la selección, solo en la generación final, por lo que la latencia adicional es insignificante.
  • Donde falla

    Suposiciones esféricas. K-means espera clústeres más o menos redondos, y los espacios de embeddings no siempre son tan ordenados. Un tema con una forma compleja y no convexa podría dividirse entre varios clústeres. HDBSCAN o los modelos de mezcla gaussiana podrían ayudar, aunque no garantizan exactamente K clústeres.

    Típico, pero no necesariamente informativo. El fragmento más cercano al centroide es el más típico. Ejecutar TextRank dentro de cada clúster, como lo hace la técnica Graphs in Clusters, permitiría una selección más detallada y representa una mejora prometedora.

    Los temas pequeños se ven comprimidos. Si el material está compuesto en un 95% por biología y en un 5% por química, probablemente la química tendrá un único grupo mientras que la biología tendrá de K a 1. El grupo de química existe, pero está comprimido en proporción. Un esquema ponderado o estratificado podría solucionar este problema.

    La calidad de los fragmentos lo determina todo. Si el proceso de fragmentación divide un concepto por la mitad o mezcla temas no relacionados, el agrupamiento hereda los efectos negativos. Una buena fragmentación, con división semántica, solapamiento y enriquecimiento con metadatos, no es opcional.

    Comparación en una sola pasada

    RAG es rápido y mantiene las fuentes, pero necesita una consulta y puede devolver K fragmentos sobre un mismo tema. Selective Context y LLMLingua son rápidos y no requieren consulta, pero descartan la estructura de las fuentes y no pueden garantizar una cobertura completa. RECOMP es potente, pero depende de la consulta. TextRank y LexRank son rápidos y no requieren consulta, sin embargo la cobertura es parcial debido a la redundancia y la trazabilidad se detiene en la oración. Graphs in Clusters no necesita consulta y ofrece una buena cobertura, pero funciona con oraciones y elimina los metadatos de las fuentes. La resumen mediante MapReduce tampoco requiere consulta, aunque la cobertura es parcial, los enlaces a las fuentes desaparecen durante los pasos de resumen y es lento porque necesita varias pasadas con modelos de lenguaje grande.

    La selección de bloques mediante K-means descrita aquí es la única opción que funciona sin realizar consultas, garantiza la cobertura temática por diseño, mantiene una trazabilidad completa a nivel de bloques, termina en menos de un segundo y no requiere modelos ajustados ni una base de datos vectorial.

    Denominación del problema

    Lo que lo hace difícil no es la complejidad técnica, sino la falta de un nombre específico. Si se busca RAG, aparecen miles de resultados. Si se busca compresión de prompts, surge LLMLingua. Si se busca resumen extractivo, aparecen métodos basados en TextRank, LexRank y BERT. Pero si se busca la forma de elegir los mejores bloques de un corpus grande, sin realizar consultas, para maximizar la cobertura temática manteniendo la trazabilidad de la fuente, casi no se obtiene información alguna.

    Un nombre adecuado para esto es compresión semántica sin consulta. No se trata de recuperación, ya que no hay consulta. Tampoco es resumen, porque en esta etapa no se genera texto nuevo. No es compresión de prompts, ya que no se eliminan tokens del texto existente. Se trata de una selección con cobertura garantizada: elegir el conjunto más pequeño de fragmentos que represente el rango más amplio del material, manteniendo al mismo tiempo el vínculo hacia los documentos.

    El problema surge siempre que un sistema convierte contenido proporcionado por el usuario en outputs estructurados sin una intención de búsqueda explícita. Ejemplos incluyen materiales de estudio de contenidos de cursos, informes de grandes colecciones de documentos, resúmenes de reuniones a partir de horas de transcripciones, resúmenes de revisiones de grandes solicitudes de integración y análisis legales, donde la cobertura de las cláusulas es más importante que responder a una sola pregunta.

    El enfoque K-means es una solución, posiblemente la más sencilla. Los híbridos que combinan el clustering con clasificación basada en grafos, puntuación de densidad de información o un análisis ligero con un LLM para la detección de temas podrían ofrecer mejores resultados, y este campo está aún muy abierto.

    Todo en código

    El pipeline completo de selección cabe en menos de 50 líneas:

    from sentence_transformers import SentenceTransformer
    from sklearn.cluster import KMeans
    import numpy as np
    def select_representative_chunks(chunks, n_outputs, model_name='all-MiniLM-L6-v2'):
        """
        Select the most representative chunks from a large corpus
        using K-means clustering. One cluster = one output.
    
        Args:
            chunks: list of dicts with 'text', 'source', 'page', etc.
            n_outputs: number of outputs the user wants (= K)
            model_name: embedding model to use
    
        Returns:
            list of selected chunks with cluster metadata
        """
        # Embed
        model = SentenceTransformer(model_name)
        embeddings = model.encode([c['text'] for c in chunks], show_progress_bar=True)
    
        # Cluster
        kmeans = KMeans(n_clusters=n_outputs, random_state=42, n_init=10)
        kmeans.fit(embeddings)
    
        # Select representatives
        selected = []
        for i in range(n_outputs):
            cluster_indices = np.where(kmeans.labels_ == i)[0]
            centroid = kmeans.cluster_centers_[i]
            distances = np.linalg.norm(embeddings[cluster_indices] - centroid, axis=1)
            best_local_idx = np.argmin(distances)
            best_global_idx = cluster_indices[best_local_idx]
    
            selected.append({
                'cluster': i,
                'chunk': chunks[best_global_idx],
                'distance_to_centroid': float(distances[best_local_idx]),
                'cluster_size': len(cluster_indices),
            })
    
        return selected
    

    No existe ninguna base de datos vectorial, ningún pipeline de recuperación, ningún modelo ajustado ni ninguna llamada a un LLM en la fase de selección. Solo se necesitan embeddings, clustering y selección de centroides.

    Dónde se implementó en la práctica

    El pipeline se desarrolló y probó dentro de una aplicación de aprendizaje que genera materiales de estudio interactivos, como cuestionarios, tarjetas de memoria, resúmenes y mapas conceptuales, a partir de todo lo que sube el estudiante: apuntes de clase, libros de texto, transcripciones de videos y diapositivas. También incluye herramientas adaptadas para personas con dislexia, TDAH u otras dificultades cognitivas, además de elementos de gamificación. El proyecto sigue en fase de I+D activa, actualmente disponible en francés, con una versión en inglés prevista.

    En ese entorno, la capa K-means se encarga de la selección de contenido. Agrupar 500 fragmentos toma menos de un segundo, escala bien y mantiene una cobertura temática en fuentes muy diferentes, desde densos libros de texto de biología hasta grabaciones dispersas de clases.

    Por qué la idea es deliberadamente sencilla

    Elegir fragmentos representativos de un corpus grande, sin consulta previa, con cobertura temática y con trazabilidad de la fuente, es una necesidad más común de lo que sugiere la literatura especializada. Cualquiera que desarrolle herramientas de LLM para la educación, generación de informes, análisis de reuniones o revisión legal probablemente ya se haya encontrado con alguna versión de este problema.

    El enfoque es intencionadamente sencillo. K-means lleva décadas en uso y los embeddings de oraciones son herramientas estándar. La contribución radica en la forma de abordarlo: tomar la intención del usuario como el parámetro K, tratar cada clúster como un resultado final y mantener intacta la cadena de relación entre los fragmentos y sus fuentes a lo largo de todo el proceso.

    Todavía hay espacio para mejoras. El agrupamiento podría combinarse con clasificación basada en grafos, puntuación de densidad de información o pasadas ligeras de LLM para la detección de temas. La selección del centroide podría ser reemplazada por algo más sutil, como la clasificación dentro de los clústeres, una selección ponderada por diversidad o una llamada breve a un LLM para elegir el fragmento más informativo. La idea está ahí para ser tomada, adaptada y mejorada.

    Leer más