Parent Document Retriever: де втрачається контекст відповіді
Документ на 40 сторінок ріжеться на фрагменти по 300–500 токенів з перекриттям — інакше пошук не знаходить точних збігів.
Верхні 3–5 фрагментів ідуть у генератор, і відповідь збирається з уривків: умова в одному шматку, виняток до неї — в іншому, а визначення терміна залишилося за межею вибірки. Формально кожен фрагмент релевантний запиту, фактично висновок неправильний.
Повнота витягування падає не через модель, а через нарізку. Релевантність фрагмента не дорівнює повноті вихідного розділу: абзац із ключовим словом у вибірку потрапляє, а сусідній, без якого він читається неправильно, — ні.
На довгих документах — регламентах, договорах, інструкціях — так втрачається до 19% потрібних відомостей, і це вже не рідкісний випадок, а системна властивість схеми.
Ціна збою проявляється не відразу. Перші відповіді виглядають переконливо, перевіряти їх ніхто не йде, а потім юрист або інженер звіряє висновок з першоджерелом і знаходить пропущений виняток.
Після двох-трьох таких знахідок системою перестають користуватися — і впровадження відкочується до ручного пошуку по документах.
Закривається це зміною одиниці пошуку. Parent Document Retriever шукає за дрібними фрагментами, але в контекст віддає батьківський розділ цілком: точність збігу зберігається, зв’язність не рветься, а довгі документи перестають розпадатися на смислові уривки. Розбираємо, як це влаштовано і які параметри нарізки доведеться перезібрати.
Що дає ієрархічний пошук: ефект і межі застосовності
Більше релевантного контексту у відповіді
Схема Parent Document Retriever розділяє пошук і подачу: порівняння йде за дрібними фрагментами, а в модель іде батьківський блок цілком — із заголовком, таблицею та застереженнями. Частка релевантних фрагментів у видачі зростає на 15–19% на корпусах технічної документації.
Дрібний фрагмент точно ловить збіг за змістом, великий не втрачає умов, без яких відповідь формально правильна й по суті порожня.
Затримка відповіді залишається в тому самому класі
Векторний індекс будується за дрібними фрагментами, тому кількість порівнянь не змінюється. Додатковий крок — читання батьківського блоку зі сховища ключ-значення — тоне на тлі звернення до моделі: різниця видна на вимірюваннях, але не в роботі користувача.
Обсяг сховища зростає лише за текстом
Векторна частина рахується один раз за дрібними фрагментами й залишається незмінною. Зростає лише текстова частина: батьківські блоки лежать у вихідному вигляді, підсумковий приріст зазвичай укладається в 1.5–2 раза і далі масштабується разом із корпусом, а не швидше за нього.
Де ієрархічне витягування не виграє
Коротким однорідним документам без структури — регламент на сторінку, картка товару — групувати нічого: батьківський блок збігається з самим фрагментом. Прийом розкривається на довгих текстах із явною ієрархією заголовків, де контекст розсіяний по розділах.
Звичайний Retriever проти ієрархії: порівняння підходів
Однорівневий пошук ріже документ на чанки і повертає top-k найближчих за ембеддингом. Схема передбачувана, поки відповідь лежить усередині одного блоку — цього вистачає для FAQ і коротких статей.
Коли відповідь збирається з кількох розділів, обмеження нарізки видно відразу: таблиці та списки рвуться по межах, сусідні блоки втрачають зв’язок.
Ієрархія документів змінює рівень пошуку: знаходимо дрібні блоки, а в контекст віддаємо батьківський фрагмент цілком. Гібридні схеми доповнюють вектор лексичним пошуком і реранкером. Нижче — чим ці варіанти відрізняються за застосовністю і що в кожного на виході.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Однорівневий пошук за чанками | Однорідні короткі документи, відповідь укладається в блок | Втрачає зв’язки між розділами, просідає на складених питаннях |
| Ієрархія з батьківськими блоками | Регламенти, договори, інструкції, де відповідь розкидана по документу | Два рівні зберігання; під час правки переіндексовується вся гілка |
| Гібрид: вектор + лексика + реранкер | Термінологія, артикули, рідкісні назви, змішані запити | Потрібні налаштування ваг і набір питань для вимірювання, довший відгук |
| Ієрархія і реранк за батьками | Довгі документи з різнорідними розділами | Найважчий варіант, потребує контролю розміру контексту |
Вибір визначається вимірюванням, а не описом підходу: збираємо питання, відповіді на які розкидані по документу, і рахуємо context recall до і після зміни схеми.
На практиці ієрархія та гібрид дають приріст там, де однорівневий пошук стабільно повертає сусідні, але не потрібні фрагменти.
Етапи впровадження: від аудиту корпусу до передачі
Порядок робіт тут задає не зручність, а якість результату: Parent Document Retriever зберігає два рівні — дрібні фрагменти, за якими йде пошук, і батьківські документи, які йдуть у відповідь.
Якщо почати з налаштування замість розбору корпусу, батьки вийдуть різнорідними, і повнота контексту просяде на найчастіших типах запитів.
-
Аудит корпусу. Рахуємо обсяг і мови, частку сканів без текстового шару, дублі та застарілі редакції, розмічаємо типи документів. На виході — карта: що розбивати, що чистити, що виключити з пошуку.
-
Схема рівнів. Фіксуємо ієрархію «фрагмент → розділ → документ», успадкування метаданих і рівень, який подається у відповідь. Узгоджуємо до налаштування — інакше розбиття доведеться переробляти разом із переіндексацією.
-
Налаштування пошуку. Підбираємо розмір фрагмента й перекриття, ваги гібридного пошуку, кількість кандидатів до і після переранжування. Параметри виносимо в конфігурацію, а не в код.
-
Перевірка на відкладеній вибірці. Готуємо питання, які не брали участі в налаштуванні, і проганяємо їх на фінальних параметрах. Так видно, де відповідь спирається на знайдений документ, а де модель відповідає з пам’яті.
-
Розбір провалів. Кожну помилку відносимо до причини: батько не знайдений, знайдений частково, завадили метадані, питання поза корпусом. Далі — правка розбиття, поповнення корпусу або явна відмова у відповіді.
-
Передача рішення й навчання команди. Віддаємо конфігурації, схему рівнів, порядок переіндексації, набір перевірних питань і регламент оновлення корпусу. Розбираємо все з вашими інженерами, щоб далі робота йшла без нас.
Що залишається в команди: схеми, політики, регламенти
Впровадження закінчується не «працюючим пошуком», а набором артефактів, за якими контур можна змінювати, відкочувати й передавати іншій команді.
Нижче — що саме фіксується в репозиторії та поруч із ним, щоб якість видачі не трималася на одному інженері, який пам’ятає, чому параметри виставлені саме так.
- Конфігурація пошукового контуру — у версіонованих файлах: розмір чанка й вікно перекриття, правило збирання parent-блоку, скільки кандидатів віддається на реранжування, ваги при змішуванні лексичного та векторного пошуку. Будь-яка правка проходить обов’язкове рев’ю і потрапляє в історію змін.
- Схема зв’язків блоків — як чанк посилається на parent-документ, які метадані зберігаються поруч (джерело, розділ, дата актуальності), які поля беруть участь у фільтрах. З прикладами запитів, щоб зв’язки не доводилося відновлювати за логами.
- Політики доступу — розмежування за ролями на рівні чанків і parent-документів: хто бачить закриті розділи, хто лише публічні. Перевірка вбудована в сам запит до індексу, а не в постобробку готової видачі.
- Регламент оновлення індексу — періодичність переіндексації, поведінка при видаленні та правці вихідного документа, точка відкату на попередню версію. Окремо — метрика розходження між джерелом та індексом.
- Набір перевірних питань — фіксований список з еталонними відповідями та розміткою потрібних фрагментів. На ньому після кожної правки конфігурації вимірюється повнота видачі, а не «стало начебто краще».
- Регламент розбору помилок — які запити вважаються провалом пошуку, як вони потрапляють у перевірний набір, хто і з якою періодичністю його перезбирає. Плюс відповідальний за рішення щодо кожної категорії збоїв.
- Документація й передача — опис схеми контуру, точок розширення, інструкція з локального запуску, журнал рішень з обґрунтуванням вибраних параметрів. Новий інженер виходить на робочий запуск без супроводу автора.
Кейс: повнота витягування контексту зросла на 19%
Корпус — нормативна документація: регламенти, методики, накази з додатками та перехресними посиланнями. До впровадження пошук ішов за фрагментами фіксованої довжини: потрібний пункт знаходився, але губилися застереження, сфера застосування та винятки із сусідніх абзаців. Повнота витягування трималася на 0,68 — приблизно кожен третій запит вимагав ручного доопрацювання.
Перейшли на дворівневе витягування: пошук іде за дрібними фрагментами, а в контекст моделі підставляється батьківський розділ цілком — підхід Parent Document Retriever.
Корпус перезібрали в ієрархію «пункт → розділ → документ» з метаданими про редакцію та сферу дії: фільтри за ними відсікають скасовані редакції, вони більше не підмішуються у видачу.
Розмір дочірнього фрагмента підбирали під структуру тексту, а не під фіксовану кількість знаків: пункт із підпунктами залишається цілісним. Верхню межу контексту обмежили, щоб час відповіді не зростав лінійно з довжиною документа.
Метрики до і після
Повнота витягування зросла з 0,68 до 0,81 — плюс 19% до базового рівня на тому самому наборі запитів. Частка відповідей із посиланням на скасований або неіснуючий пункт упала майже втричі.
Поведінка користувачів змінилася помітніше за самі метрики: уточнювальних питань усередині сесії стало на третину менше, а частка випадків, коли працівник відкривав першоджерело після відповіді, скоротилася вдвічі. Посилання перевіряють, коли сумніваються, — падіння цієї частки і є ознакою довіри до видачі.
На коротких довідкових запитах приріст майже непомітний — там вистачає звичайного пошуку. Виграш видно на складених питаннях: відповідь збирається з кількох розділів, і важливий кожен пропущений пункт.
Що робити, якщо корпус уже розбитий на дрібні фрагменти
Поки пошук працює, повна переіндексація не обов’язкова. Вектори дрібних фрагментів залишаються валідними — змінюється лише шар метаданих: до кожного фрагмента дописуємо ідентифікатор батька (шлях документа, заголовок розділу, порядковий номер блоку). Такий прохід перераховує зв’язки, а не вектори, і займає години замість діб.
Батьківський текст підтягується в момент видачі: запит потрапляє в точний дрібний фрагмент, а в контекст моделі йде весь розділ, з якого він вирізаний. Це Parent Document Retriever у прикладному вигляді — пошук за дрібним, відповідь за великим. Якщо поля батька в схемі ще немає, його додають міграцією метаданих без зупинки пошуку.
Міграція без простою будується на двох паралельних індексах. Старий обслуговує трафік, новий наповнюється зв’язками у фоні, перемикання йде за збігом видачі на контрольному наборі запитів. Відкат — повернення покажчика: попередній індекс живе до кінця перевірки.
Гібридна схема потрібна, коли корпус неоднорідний. Нові документи одразу індексуються парами «фрагмент — батько», архів добудовується обходом за розкладом, тому свіжі надходження не чекають обробки всього масиву.
Повна переіндексація виправдана лише при битому розбитті на фрагменти: шматки рвуть речення, перекриття немає, метадані не несуть структури.
Контроль результату — context recall на відкладеній вибірці реальних запитів і частка відповідей, де батьківський блок цілком уклався у вікно контексту.
Часті питання інженерів: що ламається на практиці
Метод закриває конкретний клас збоїв: в індекс потрапляє короткий фрагмент, і відповідь втрачає деталі, які в документі були.
Parent Document Retriever шукає за дрібними фрагментами, а в контекст подає батьківський документ цілком — у наших вимірюваннях повнота знайденого контексту зросла на 19%. Ціна у схеми теж є, і питання про неї інженери ставлять першими.
Чи не почнемо ми подавати один і той самий текст кілька разів?
Так, якщо у видачу потрапили різні фрагменти одного документа. Знімається дедуплікацією за ідентифікатором батька до збирання контексту: залишаємо один екземпляр із найбільшою вагою, а місце, що звільнилося, добираємо документами, які у вибірку не потрапили.
Обмеження методу — фіксований бюджет контексту, тому дедуплікацію та усічення рахують разом, а не окремо.
Наскільки зросте обсяг зберігання?
Зросте, бо поруч із фрагментом лежить його батько. Відносно схеми з одними фрагментами це збільшення в один-два рази, точна величина залежить від довжини батька й перекриття при нарізці.
Керується конфігурацією: батько зберігається в одному екземплярі, фрагменти посилаються на нього, рідкісні документи виносяться в холодне сховище і не займають швидкий індекс.
Як вимірювати якість, якщо еталонної розмітки немає?
Повний набір питань з відповідями коштує дорого і швидко застаріває. Беремо непряму метрику: генеруємо питання з самих документів і дивимося частку випадків, де потрібний фрагмент потрапив нагору видачі, а його батько дійшов у контекст.
Додатково звіряємо на невеликій ручній розмітці — кількох десятків пар вистачає, щоб зловити системний провал, але мало, щоб стверджувати, що метод тримається на рідкісних запитах.
Обговоримо задачу: як ми приходимо до плану впровадження
План впровадження будується не на загальних словах, а на вашій фактурі: без неї будь-яка оцінка термінів перетворюється на ворожіння. Тому обговорення задачі починаємо з короткого переліку того, що потрібно від вашої сторони, і відразу фіксуємо, що повернемо взамін.
- Вибірка реальних запитів користувачів за останній період і документів, на які ці відповіді мали спиратися, — на ній перевіряємо, чи повертає пошук батьківський фрагмент цілком, а не уривок фрази.
- Список місць, де зараз іде не туди: звернення до підтримки, ручні правки операторів, повторні уточнювальні питання.
- Правила доступу до розділів бази — кому що видно і що не можна виносити за межі вашого контуру.
- Експерт з вашого боку, який підтвердить коректність відповідей на перевірному наборі та зніме спірні випадки.
- Числові критерії приймання: частка запитів, де потрібний фрагмент потрапив у підбірку, і частка відповідей із посиланням на джерело.
- Обмеження за середовищем: контур розміщення, обсяг бази, частота її оновлення та спосіб синхронізації.
У відповідь ви отримуєте оцінку термінів за етапами, план впровадження та порядок пілотного запуску: спочатку прототип пошуку на вашій же вибірці, потім пілот на одному підрозділі з вимірюванням метрик, і тільки після цього — розширення на решту команд.
Кожен етап закінчується перевірним результатом і точкою повернення до попереднього стану індексу, тому рішення можна зупинити без втрати вже працюючого пошуку.
Опишіть задачу — повернемося з оцінкою та планом.







