Self-Query RAG: як LLM автоматично будує фільтри із запиту

Відповіді з умовами «тільки за минулий квартал, тільки за філіями» часто втрачають точність: фільтри в запиті заважають пошуку. Ми налаштовуємо self-query RAG під ключ — модель сама виокремлює умови з питання та будує фільтри метаданих, а ви отримуєте керований пошук без ручних правил на кожен випадок.
Часті запитання

Чому self-query RAG ламається на фільтрах із запиту

Типовий збій self-query rag: користувач пише «покажи лише активні договори за останній квартал», система проганяє фразу через векторний пошук і повертає семантично близькі документи — але із закритих угод минулих років. Умова в запиті була, а пошук її не побачив.

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

Self-query RAG змінює схему: мовна модель розбирає запит на дві частини. Смислова йде у векторний пошук, а умови перетворюються на фільтри із запиту — статус, період, тип документа, власник. Відбір іде за об'єднаним правилом, а не лише за близькістю векторів.

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

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

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

Що дає автоматична побудова фільтрів метаданих

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

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

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

«Порожньо» частіше приходило не від відсутності даних, а від того, що потрібний фрагмент не проходив за типом або періодом.

Другий — складені умови. Запити з двома-трьома обмеженнями («акти за підрядниками за минулий рік, лише підписані») дають більше хибних відповідей: частина умов губиться, і модель відповідає за фрагментом з іншої категорії.

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

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

Розмиті умови («свіжі», «основні») не можна мовчки перетворювати на жорсткий фільтр: їх або уточнюють діапазоном, або пропускають у семантичний пошук — інакше система відсікає дані, які користувач вважав доступними.

Режими self-query RAG: порівняння підходів до фільтрації

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

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

Режим Коли підходить Обмеження фільтрації
Умови будує модель під час запиту Різнорідні дані, багато атрибутів, склад запитів наперед невідомий Модель може послатися на неіснуюче поле або неприпустиме значення; без перевірки видача тихо втрачає документи
Умови задані схемою наперед Вузький стабільний набір атрибутів, жорсткі вимоги до передбачуваності Нове поле означає правку схеми та повторні перевірки; запити виду «все, крім цього джерела» доводиться розкладати вручну
Гібридний: модель пропонує, схема перевіряє Навантаження зростає, кількість атрибутів збільшується, ціна помилки висока Потрібен шар перевірки та журнал: має бути видно, які умови відкинуто і чому

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

Важлива деталь — відкинутий фільтр не повинен мовчки перетворювати відповідь на порожню видачу: розширюємо пошук і логуємо причину, інакше користувач бачить «нічого не знайдено» там, де документи є.

Впровадження автоматичної фільтрації: етапи робіт

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

  1. Аудит пошуку. Вивантажуємо журнал запитів, прибираємо службовий шум і групуємо за намірами. Дивимося частку запитів із порожньою видачею — одразу видно, яких фільтрів бракує.
  2. Таксономія полів. Зводимо ознаки до єдиних типів: категорія, діапазон, дата, наявність, регіон. Від типу поля залежить, які умови взагалі можна побудувати.
  3. Еталонна вибірка. Вручну розмічаємо кілька сотень запитів парами «формулювання → очікуваний фільтр» — це лінійка, з якою порівнюються варіанти налаштування.
  4. Налаштування фільтрів. Описуємо схему полів для моделі та правила для неоднозначних випадків: де умова не виводиться і запит залишається звичайним текстовим пошуком.
  5. Перевірка на конфліктах. Прогоняємо заперечення, взаємовиключні умови та граничні значення — шукаємо формулювання, де побудований фільтр обнуляє видачу.
  6. Тестування видачі. Порівнюємо до і після на закритій вибірці: частка релевантних перших результатів, частка порожніх видач, поведінка на рідкісних формулюваннях.
  7. Передача. Віддаємо документацію за полями, правила розбору, панель із нетиповими запитами та регламент оновлення словника при зміні каталогу.

Артефакти впровадження: схеми, правила, регламенти

Впровадження self-query RAG закінчується не працюючим прототипом, а набором артефактів, з якими команда замовника живе далі без нас. Схема метаданих і правила допустимих умов визначають, які фільтри система збере із запиту, а які відхилить ще до звернення до індексу.

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

  • Схема метаданих: поля, типи, обов'язковість і список операторів порівняння, допустимих для кожного поля.
  • Словник значень: нормалізовані варіанти та синоніми — щоб різні написання одного значення давали однаковий фільтр.
  • Правила допустимих умов: які комбінації фільтрів дозволені, де стоїть заборона на діапазони за текстовими полями та порожні умови.
  • Регламент оновлення: хто переглядає словник при появі нових значень, у який момент правка потрапляє в реліз і хто її підтверджує.
  • Правила доступу: розмежування за ролями на рівні фільтрів — обмеження вибірки не обходиться формулюванням запиту.
  • Інструкції для аналітиків: як додати поле, як перевірити, що воно потрапило в розбір запиту, як відкотити зміну.
  • Документація та журнал правок: версія схеми, дата й причина зміни, тестовий набір запитів для перевірки після кожної правки.

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

Кейс: точність відповідей на запитах з умовами

Потік запитів був однотипним: користувачі запитували з явними умовами — «договори з оплатою після постачання за минулий квартал», «вакансії в Мінську з релокацією», «тарифи, що діють від початку року».

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

Відсіяти їх на виході не вдавалося — модель впевнено переказувала нерелевантне джерело, і це виглядало переконливіше, ніж чесне «не знайшов».

Що показали заміри на контрольній вибірці

Метрика До Після
Частка коректних відповідей 61% 89%
Частка порожніх видач 23% 4%
Відповіді з неправильної категорії 9% 0,4%
Запити з умовами, що пішли на уточнення 31% 6%

Що саме змінили

Додали шар розбору запиту на смислову частину та структуровані умови: рівність, діапазон дат, входження до списку.

Модель повертає фільтр за заздалегідь описаною схемою метаданих, шар перевіряє його валідність до виконання пошуку і лише потім передає в індекс — як у підході Self-Query Retriever із LangChain. Схему метаданих завели декларативно, тому нові поля не потребують переписування коду пошуку.

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

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

Що робити, якщо індекс уже зібрано під жорсткі фільтри?

Пересобирати індекс повністю не потрібно, якщо документи вже зберігають атрибути окремими полями — датою, категорією, регіоном, статусом.

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

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

Еталонна реалізація такого підходу — Self-Query Retriever: поверх жорстких умов лягає смисловий пошук, і обидва критерії застосовуються в одному запиті, а не двома послідовними проходами.

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

Метрики прості: частка запитів з автоматично виведеними умовами, частка розпізнаних полів, частка відкатів на попередню логіку.

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

Технічні сумніви інженерів і відповіді на них

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

Що буде, якщо модель вигадає поле, якого немає в схемі?

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

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

Як обробляються розмовні формулювання?

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

Нерозпізнані частини запиту не блокують пошук: вони залишаються в семантичній гілці й працюють як звичайний векторний відбір.

Ми розширюємо схему метаданих — що доведеться переробляти?

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

Як перевірити, що умови побудовано коректно?

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

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

Обговоримо вашу задачу з фільтрації запитів

Щоб обговорити задачу із Self-Query RAG, не потрібен готовий набір вимог — достатньо того, як зараз влаштовано пошук за документами.

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

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

Цього достатньо, щоб повернутися з оцінкою робіт і планом впровадження — без загальних формулювань:

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

Опишіть задачу у вільній формі — повернемося з оцінкою та планом, які розбираються за пунктами.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142