Головна / Статті

Вибір чанків без запиту: використання алгоритму K-Means, коли у RAG немає запитань для постановки.

Без запиту користувача RAG не може вибрати контекст. Вважайте K кількістю результатів, згрупуйте ембеддинги фрагментів за допомогою k-means, зберігайте фрагменти-центроїди та їхні джерела.

Видавець: REACTAPP.TOP13 хв читання3095 слів

Джерела: You Don’t Need RAG. You Need Semantic Compression.

Деякі проблеми ШІ-моделей не мають назви, відповідної платформи чи значної кількості літератури. Ця проблема виглядає так: дуже велика кількість тексту, відсутність запитання користувача, а завдання полягає у виборі тих частин, які потрібно передати моделі, щоб були охоплені всі теми та щоб кожну частину можна було простежити до її походження.

Це не генерація з підсиленням за допомогою пошуку, оскільки нічого не шукають. Це не стиснення запитів та не стиснення тексту. Дослідницька спільнота ще не дала цьому чіткої назви, а звичайні інструменти не підходять для розв’язання цієї проблеми. У наступному описано саму проблему, показано, чому існуючі методи є недостатніми, та описано просте рішення, яке водночас узгоджується з академічними ідеями та заповнює прогалину, яку ігнорують ці дослідження.

Коли немає чого шукати

Кожен, хто працював із ШІ останні кілька років, знає цикл RAG: користувач ставить запит, запит форматується, з бази векторних даних отримуються схожі фрагменти, вони включаються до промпту, і генерується відповідь, заснована на цих даних. Ця схема є елегантною, добре задокументованою та підтримується кожною великою платформою. Водночас вона мовчки передбачає наявність запиту.

Часто його немає. Платформи на кшталт LangChain та LlamaIndex орієнтовані на формування запитів та їх пошук, а більшість досліджень щодо стиснення контексту також починаються з запиту. У пошуках способів вибору найкращих фрагментів для ШІ кожен результат припускає наявність запиту користувача, який має спрямовувати цей вибір.

Розгляньмо додаток для навчання. Студенти завантажують навчальні матеріали: підручники, презентації, транскрипції відео, рукописні нотатки — іноді сотні сторінок. Вони не шукають нічого; по суті, вони кажуть: «Ось мої курси, створіть для мене навчальні матеріали». Система повинна тоді генерувати структуровані результати, такі як тести, карточки для запам’ятовування, короткі узагальнення та карти понять. Кожен результат має стосуватися різної теми та вказувати джерело, причому загальний обсяг даних значно перевищує можливості будь-якого вікна контексту.

Три вимоги одночасно

Існуючі підходи порушують принаймні одну з трьох обмежень, які разом встановлює цей випадок використання.

  1. Відсутній сигнал запиту. Жодні дані від користувача не впливають на вибір, тому система змушена самостійно визначати, що є важливим, лише на основі даних.
  2. Гарантоване тематичне охоплення. Результатом є набір матеріалів, які разом охоплюють усю сферу теми. Ігнорування цілої теми є серйозною помилкою; тест з біології, який зовсім не стосується генетики, є марним.
  3. Відстежуваність джерела. Кожен матеріал має посилатися на конкретну частину оригіналу, наприклад «за розділом 3, сторінками 12–14 підручника з біохімії». У освіті це не є необов’язковим, адже студенти повинні знати, де продовжити читання.

Жоден існуючий метод не задовольняє всі три критерії одночасно. Ось у чому полягає прогалина.

Що пропонує література та де вона закінчується

Чому надсилання всього призводить до невдачі

Наївний підхід — це ввести весь матеріал у вікно контексту. Оскільки моделі можуть обробляти від 128 тис. до 200 тис. токенів, спокусливо думати, що це спрацює. Але це не так. Дослідження „Lost in the Middle“ показало криву продуктивності у формі літери U: моделі добре та послідовно обробляють початок та кінець контексту, але постійно пропускають інформацію, що знаходиться посередині. Точність знижувалась більш ніж на 30%, коли ключовий контент переміщувався з країв у центр, навіть у моделях, створених для довгих контекстів.

Отже, навіть коли все поміщається, великі частини матеріалу залишаються без уваги. Тест би охоплював перші та останні розділи, ігноруючи решту. Більший обсяг контексту — це не те саме, що кращий контекст.

Стиснення запиту відповідає на інше питання

Все більше досліджень полягає у скороченні вхідних даних шляхом видалення зайвих токенів ще до того, як вони потраплять до моделі.

Selective Context використовує невелику мовну модель для обчислення самоінформації лексичних одиниць – чи то токенів, іменникових фраз, чи речень – та видаляє ті, що мають низьку самоінформацію. Йому не потрібні запити, що відповідає першій умові. Однак він фільтрує інформацію всередині наявного тексту, створюючи стиснуту копію цього тексту, а не вибір представницького контенту з різних тем. Він не може гарантувати повноту охоплення, а змінений текст втрачає пряме зв’язок із оригінальними фрагментами, тому друга та третя умови не дотримуються.

LLMLingua та LLMLingua-2 розширюють цю ідею за допомогою ітеративного стиснення та класифікаторів токенів, які навчаються, досягаючи коефіцієнтів стиснення до 20 разів. Вони мають одну й ту саму основну обмеженість: текст стискається для машини, а не для людини. Результатом є запит, який модель може обробити, а не структурований набір контенту, який можна простежити.

RECOMP навчає компресори, які можуть узагальнювати або видобувати інформацію з отриманих документів у якості екстрактивного, так і абстрактивного підходу. Це найскладніший з цієї групи, але йому безумовно потрібен запит, щоб вирішити, що зберегти, тому він не відповідає першій умові.

Коротко кажучи, компресія за допомогою запитів зменшує кількість токенів. Вона не вибирає репрезентативний контент, не гарантує охоплення теми та не зберігає структуру вихідного тексту.

Ранжування за допомогою графів лише представляє інформацію, але не організовує її

TextRank та LexRank створюють граф схожості між реченнями та застосовують PageRank для визначення найбільш центральних з них, тобто тих, які найкраще представляють увесь документ. Їм не потрібні запити, і протягом двох десятиліть вони залишаються стандартом для некерованого стиснення тексту. Їхня відома слабкість — це Redundантність. Схожі речення отримують схожий рівень центральності, тому найкращі варіанти часто повторюють один одного лише з іншими словами. Аналіз біологічного підручника за допомогою TextRank може повернути три речення про реплікацію ДНК та жодного про синтез білків, просто тому, що реплікація згадується частіше.

Це погіршує охоплення, навіть якщо основні теми зазвичай з’являються, а оскільки методи працюють з реченнями, можливість відстеження є лише частковою.

Кластерування найближче до ідеалу

Сумаризація на основі кластеризації з використанням методів K-means, HDBSCAN чи подібних на ембеддингах речень дозволяє об’єднувати схожі речення у тематичні кластери та обирати по одному представнику з кожного. Це ефективно усуває зайвість: кожен кластер надає одне речення, а різні кластери охоплюють різні теми.

Найкращий сучасний підхід у цій галузі — „Graphs in Clusters“ — поєднує метод K-means із TextRank. Спочатку відбувається кластеризація для охоплення максимальної кількості речень, а потім — ранжування всередині кожного кластера за ступенем важливості. Цей підхід досягає або перевершує результати чисто графових та чисто кластерних методів у тестах на довгі документи, таких як ArXiv та PubMed.

Це найближчий родич, але він відрізняється кількома важливими аспектами. Його метою є одне плоске текстове резюме, тоді як тут метою є N структурованих результатів. Він налаштовує значення K за допомогою методу ліктя, тоді як тут K визначається за запитом користувача. Він працює з реченнями, тоді як тут потрібна гранулярність частин для збереження метаданих вихідного матеріалу. Його кластери є невидимим проміжним кроком, тоді як тут вони є кінцевими результатами. Крім того, у нього немає концепції обов’язкового відстеження вихідного джерела.

Порівняння

З огляду на ці три обмеження з’являється певний патерн. RAG зберігає джерела, але потребує запиту та не може гарантувати повну охопленість. Selective Context та LLMLingua не потребують запиту, але втрачають структуру джерела та не можуть забезпечити повну охопленість. RECOMP також потребує запиту. TextRank та LexRank працюють без нього, але дають зайвий вихідний матеріал та слабку можливість відстеження походження. Агрегація за допомогою кластеризації відповідає першим двом обмеженням – вона не потребує запиту та забезпечує повну охопленість, проте працює на рівні речень, що перериває зв’язок із джерелом.

Не існує усталеного методу вибору фрагментів, який би не потребував запиту, гарантував повну охопленість та дозволяв відстежувати джерело.

Переосмислення кластеризації

Рішення полягає у зміні способу використання кластеризації, який зазвичай застосовується в NLP. У науковій літературі K є гіперпараметром. Дослідники перебирають значення K=5, K=10, K=50, будують графіки оцінок силуету чи кривих інерції та обирають „найкраще“ значення. Кластери є математичними об’єктами, які слугують алгоритму, і користувач ніколи їх не бачить.

У цьому підході K є специфікацією продукту. Якщо студент просить 10 тестових аркушів, K встановлюється як 10. П’ять сторінок зі зведенням означають K=5, а тридцять карточок — K=30. Кожен кластер відповідає саме одному результату. Кластер не є проміжною абстракцією; він є кінцевим продуктом. Тест з мітозу існує тому, що у семантичному просторі завантаженого контенту існує кластер фрагментів, пов’язаних із мітозом.

Існуючі методи використовують кластеризацію для стиснення тексту для машини. Цей метод використовує кластеризацію для організації контенту для людини.

У наступних етапах це змінює все. Традиційно значення K налаштовується математично, і кластери залишаються прихованими, а після кластеризації створюється загальний огляд. Тут значення K визначається за запитом користувача: кожен кластер стає тим, що отримує користувач, а кожен кластер ініціює один виклик ШІ, який дає результат із посиланням на джерело.

П’ятиетапний процес

1. Розділення на частини. Документи розділяються за допомогою стандартних інструментів з LlamaIndex чи LangChain або за власними правилами. Кожна частина зберігає свій текст, вихідний файл, номер сторінки, позицію та будь-які інші метадані. Типовий розмір становить від 500 до 1000 токенів, з перекриттям сусідніх частин на 10–20%, що є компромісом між збереженням цілісності ідей та дрібним розміром кластерів. Частини можна за бажанням доповнити резюме, ключовими словами чи тегами ентитетів, що допомагає у кластеризації, але це не є обов’язковим.

2. Вбудовування. Кожен фрагмент перетворюється на щільний вектор. Вибір моделі залежить від конкретних умов: Sentence-Transformers — це швидкий та безкоштовний базовий варіант, text-embedding-3-small від OpenAI ефективно працює з різними мовами, а Mistral Embed чи Cohere Embed є конкурентоспроможними альтернативами. Важливо те, що семантично близькі фрагменти утворюють близькі за значенням вектори, незалежно від словника.

3. K-means. Це основний крок. Метод K-means ділить простір векторів на рівно K груп, причому значення K визначається кількістю результатів, які бажає отримати користувач:

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)

Існують три властивості, які безпосередньо випливають з цього та відповідають трьом обмеженням. Запити не потрібні, оскільки алгоритм K-means групує елементи за схожістю між ними, а не за їхньою відповідністю зовнішньому сигналу. Тематичне охоплення гарантоване, адже кожен елемент потрапляє саме в один кластер, і кожна тема в даних представлена. Надмірність зникає, оскільки елементи, які передають однакову інформацію, мають схожі ембеддинги, знаходяться разом та створюють один представницький елемент.

4. Вибір представника. Для кожного кластера беріть елемент, який знаходиться найближче до центроїда, адже він найкраще відображає тему кластера:

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

Обраний фрагмент зберігає всі свої початкові метадані, тому нічого не втрачається, і все можна посилатися. Для більш насичених результатів замість одного фрагмента можна використовувати три найближчі фрагменти до кожного центроїда; принцип залишається незмінним.

5. Генерація. Обрані фрагменти кожного кластера надсилаються до LLM із запитом, адаптованим до типу результату, а початкові метадані йдуть разом, щоб модель могла посилатися на них. Кластер 1 створює Тест 1, посилаючись на сторінки 12–14 першого PDF. Кластер 2 створює Тест 2, посилаючись на транскрипцію відео о 14:30. Ця схема повторюється до кластера K.

Коли не вказано кількість

Не кожен користувач просить десять тестів; деякі просто хочуть „тест“ або „підсумок“. Підійдуть три альтернативні підходи. Метод бюджету токенів ділить ефективний контекст моделі на середній розмір частин: для моделі з 16 тис. токенів та частин по 800 токенів значення K становить близько 20. Метод ліктя пробує кілька значень K та обирає ту точку, де інерція більше не знижується значно. Також підходить приблизне правило — один кластер на 5–10 сторінок вихідного тексту. На практиці метод бюджету токенів є найнадійнішим, оскільки він безпосередньо відображає обсяг інформації, яку може обробити модель.

Що гарантує цей метод

Це математичні властивості алгоритму K-means, а не емпіричні спостереження.

  • Покриття. Кожна точка призначається до певного кластера, тож жоден фрагмент не залишається без уваги. Якщо тема існує, вона належить до кластера з його представником. На відміну від цього, метод Top-K може повернути K фрагментів про одну популярну тему та повністю проігнорувати інші.
  • Відсутність дублікатів. Схожі фрагменти групуються разом, і кожна група має лише одного представника. Два фрагменти, які говорять про одне й те саме, але різними словами, знаходяться в одному кластері, причому залишається лише один з них.
  • Регульована дробність. Низьке значення K створює широкі кластери для загальних тем, а високе — вузькі кластери для конкретних понять; користувач може керувати цим через свій запит.
  • Збереження вихідного формату. Робота з фрагментами, а не з токенами чи реченнями, дозволяє зберегти повну ланцюгову структуру метаданих у кожному обраному елементі. Компресія на рівні токенів за своєю суттю не може забезпечити цього.
  • Швидкість. Алгоритм K-means на 500 ембеддингах з розмірністю 384 виконується менш ніж за секунду. Під час вибору не відбувається жодних викликів LLM, лише під час остаточної генерації, тому додаткова затримка є мінімальною.
  • Де він поступається

    Сферичні припущення. Алгоритм K-means очікує приблизно круглих кластерів, а простори ембеддингів не завжди є настільки впорядкованими. Тема з складною, неконвексною формою може розподілитися між кластерами. HDBSCAN або моделі змішаних гауссівських розподілів можуть допомогти, хоча вони не гарантують саме K кластерів.

    Типовий, але не обов’язково інформативний. Фрагмент, найближчий до центроїда, є найбільш типовим. Виконання алгоритму TextRank всередині кожного кластера, як це робить метод Graphs in Clusters, дозволило б зробити більш детальний вибір та є перспективним покращенням.

    Дрібні теми піддаються стисненню. Якщо матеріал складається на 95% з біології та на 5% з хімії, хімія, ймовірно, отримає один кластер, тоді як біологія — від K до 1. Кластер з хімії існує, але є пропорційно стиснутим. Для вирішення цієї проблеми можна використати зважену чи стратифіковану схему.

    Якість частин визначає все. Якщо розділення на частини розділяє концепцію навпіл або змішує непов’язані теми, кластерування успадковує ці наслідки. Хороше розділення на частини з семантичним розбиттям, перекриттям та збагаченням метаданими є обов’язковим.

    Порівняння за один прохід

    RAG працює швидко та зберігає джерела, але потребує запиту та може повернути K фрагментів щодо однієї теми. Selective Context та LLMLingua працюють швидко без запитів, проте втрачають структуру джерел та не можуть гарантувати повну охопленість. RECOMP є потужним, але залежить від запиту. TextRank та LexRank працюють швидко без запитів, проте охоплення є частковим через Redundancy, а відстежуваність припиняється на рівні речення. Graphs in Clusters працює без запитів з хорошим рівнем охоплення, але обробляє лише речення та видаляє метадані джерел. Сумаризація за допомогою MapReduce також не потребує запитів, проте охоплення є частковим, посилання на джерела зникають під час кроків сумаризації, а процес є повільним через необхідність кількох проходжень LLM.

    Описаний тут метод вибору частин за принципом K-means — єдина опція, яка працює без запиту, гарантує тематичне охоплення за своєю суттю, зберігає повну відстежуваність на рівні частин, завершує роботу менш ніж за секунду та не потребує ні налаштованих моделей, ні векторної бази даних.

    Назва проблеми

    Те, що ускладнює її розв’язання, — це не так сильно технічна складність, як відсутність чіткої назви. Якщо пошукати RAG, з’являються тисячі результатів. Якщо шукати стиснення запитів, з’являється LLMLingua. Якщо шукати екстрактивне узагальнення, з’являються методи TextRank, LexRank та методи на основі BERT. Якщо ж шукати спосіб вибору найкращих частин з великого корпусу без запиту для максимізації тематичного охоплення зі збереженням можливості відстеження джерела, майже нічого не знаходиться.

    Відповідною назвою є семантичне стиснення без запитів. Це не пошук, оскільки запиту немає. Це не узагальнення, адже на цьому етапі не створюється новий текст. Це не стиснення за допомогою запрошень, оскільки з існуючого тексту не видаляються токени. Це вибір із гарантованим охопленням: вибір найменшого набору фрагментів, які представляють найширший діапазон матеріалу, зберігаючи при цьому зв’язок із документами.

    Проблема виникає там, де система перетворює великі об’єми контенту, наданого користувачем, на структуровані результати без чіткого наміру на пошук. Прикладами є навчальні матеріали з курсового контенту, звіти з великих колекцій документів, узагальнення зустрічей з годинних транскрипцій, анотації з великих запитів на зміни та юридичний аналіз, де охоплення різних положень важливіше, ніж відповідь на одне запитання.

    Підхід K-means є одним із рішень, мабуть, найпростішим. Гібридні методи, які поєднують кластеризацію з ранжуванням на основі графів, оцінкою інформаційної щільності чи коротким аналізом за допомогою LLM для виявлення тем, можуть дати кращі результати, і ця галузь залишається дуже перспективною.

    Усе це у коді

    Повний процес відбору поміщається у менше ніж 50 рядків:

    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
    

    На етапі відбору немає бази даних векторів, жодної процедури пошуку, жодної налаштованої моделі та жодних викликів LLM. Достатньо лише ембеддингів, кластеризації та вибору центроїда.

    Де це використовувалося на практиці

    Ця процедура була створена та протестована в мовному додатку, який генерує інтерактивні навчальні матеріали — тести, картки для запам’ятовування, короткі узагальнення та карти концепцій — на основі всього, що завантажує студент: конспектів лекцій, підручників, транскрипцій відео та слайдів. Він також містить інструменти, адаптовані для учнів із дислексією, СДУГ чи іншими когнітивними труднощами, а також елементи гейміфікації. Проект все ще знаходиться на стадії активних досліджень та розробок, наразі доступний французькою мовою, а англійська версія планується.

    У цьому форматі шар K-means відповідає за вибір контенту. Об’єднання 500 фрагментів займає менше секунди, він добре масштабується, а тематичне охоплення зберігається навіть у дуже різних джерелах — від насичених підручників з біології до розрізнених записів лекцій.

    Чому ця ідея навмисно проста

    Вибір репрезентативних фрагментів з великого корпусу без запиту, з тематичним охопленням та можливістю відстеження джерела — це потреба, яка трапляється частіше, ніж свідчить література. Кожен, хто створює інструменти на основі LLM для освіти, генерації звітів, аналізу зустрічей чи юридичного огляду, ймовірно, стикався з її версією.

    Підхід навмисно простий. K-means існує вже десятиліття, а ембеддинги речень є стандартними інструментами. Сутність рішення полягає у формулюванні: взяти намір користувача як параметр K, кожен кластер розглядати як результат, та зберегти ланцюжок від фрагмента до джерела протягом усього процесу обробки.

    Є можливості для покращення. Кластерування можна поєднати з ранжуванням на основі графів, оцінкою щільності інформації чи використанням легких моделей LLM для виявлення тем. Вибір центроїда можна замінити на щось більш тонке, наприклад ранжування всередині кластерів, вибір на основі коефіцієнта різноманітності чи використання невеликої моделі LLM для вибору найінформативнішого фрагмента. Ця ідея призначена для використання, адаптації та вдосконалення.

    Пов’язана література