Parent Document Retriever для RAG: повышение context recall на 19%

Ответы ассистента теряют смысл, когда нужный фрагмент вырван из документа. Мы настраиваем иерархический поиск под ключ: система извлекает крупные блоки и отдаёт модели полный контекст. Полнота извлечения контекста растёт примерно на пятую часть.
Часто задаваемые вопросы

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 хранит два уровня — мелкие фрагменты, по которым идёт поиск, и родительские документы, которые уходят в ответ. Если начать с настройки вместо разбора корпуса, родители получатся разнородными, и полнота контекста просядет на самых частых типах запросов.

  1. Аудит корпуса. Считаем объём и языки, долю сканов без текстового слоя, дубли и устаревшие редакции, размечаем типы документов. На выходе — карта: что разбивать, что чистить, что исключить из поиска.

  2. Схема уровней. Фиксируем иерархию «фрагмент → раздел → документ», наследование метаданных и уровень, который подаётся в ответ. Согласуем до настройки — иначе разбиение придётся переделывать вместе с переиндексацией.

  3. Настройка поиска. Подбираем размер фрагмента и перекрытие, веса гибридного поиска, число кандидатов до и после переранжирования. Параметры выносим в конфигурацию, а не в код.

  4. Проверка на отложенной выборке. Готовим вопросы, не участвовавшие в настройке, и прогоняем их на финальных параметрах. Так видно, где ответ опирается на найденный документ, а где модель отвечает по памяти.

  5. Разбор провалов. Каждую ошибку относим к причине: родитель не найден, найден частично, помешали метаданные, вопрос вне корпуса. Дальше — правка разбиения, пополнение корпуса или явный отказ в ответе.

  6. Передача решения и обучение команды. Отдаём конфигурации, схему уровней, порядок переиндексации, набор проверочных вопросов и регламент обновления корпуса. Разбираем всё с вашими инженерами, чтобы дальше работа шла без нас.

Что остаётся у команды: схемы, политики, регламенты

Внедрение заканчивается не «работающим поиском», а набором артефактов, по которым контур можно менять, откатывать и передавать другой команде. Ниже — что именно фиксируется в репозитории и рядом с ним, чтобы качество выдачи не держалось на одном инженере, который помнит, почему параметры выставлены именно так.

  • Конфигурация поискового контура — в версионируемых файлах: размер чанка и окно перекрытия, правило сборки parent-блока, сколько кандидатов отдаётся на реранжирование, веса при смешивании лексического и векторного поиска. Любая правка проходит обязательное ревью и попадает в историю изменений.
  • Схема связей блоков — как чанк ссылается на parent-документ, какие метаданные хранятся рядом (источник, раздел, дата актуальности), какие поля участвуют в фильтрах. С примерами запросов, чтобы связи не приходилось восстанавливать по логам.
  • Политики доступа — разграничение по ролям на уровне чанков и parent-документов: кто видит закрытые разделы, кто только публичные. Проверка встроена в сам запрос к индексу, а не в постобработку готовой выдачи.
  • Регламент обновления индекса — периодичность переиндексации, поведение при удалении и правке исходного документа, точка отката на предыдущую версию. Отдельно — метрика расхождения между источником и индексом.
  • Набор проверочных вопросов — фиксированный список с эталонными ответами и разметкой нужных фрагментов. На нём после каждой правки конфигурации измеряется полнота выдачи, а не «стало вроде лучше».
  • Регламент разбора ошибок — какие запросы считаются провалом поиска, как они попадают в проверочный набор, кто и с какой периодичностью его пересобирает. Плюс ответственный за решение по каждой категории сбоев.
  • Документация и передача — описание схемы контура, точек расширения, инструкция по локальному запуску, журнал решений с обоснованием выбранных параметров. Новый инженер выходит на рабочий запуск без сопровождения автора.

Кейс: полнота извлечения контекста выросла на 19%

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

Перешли на двухуровневое извлечение: поиск идёт по мелким фрагментам, а в контекст модели подставляется родительский раздел целиком — подход Parent Document Retriever. Корпус пересобрали в иерархию «пункт → раздел → документ» с метаданными о редакции и области действия: фильтры по ним отсекают отменённые редакции, они больше не подмешиваются в выдачу.

Размер дочернего фрагмента подбирали под структуру текста, а не под фиксированное число знаков: пункт с подпунктами остаётся цельным. Верхнюю границу контекста ограничили, чтобы время ответа не росло линейно с длиной документа.

Метрики до и после

Полнота извлечения выросла с 0,68 до 0,81 — плюс 19% к базовому уровню на том же наборе запросов. Доля ответов со ссылкой на отменённый или несуществующий пункт упала почти втрое.

Поведение пользователей изменилось заметнее самих метрик: уточняющих вопросов внутри сессии стало на треть меньше, а доля случаев, когда сотрудник открывал первоисточник после ответа, сократилась вдвое. Ссылку проверяют, когда сомневаются, — падение этой доли и есть признак доверия к выдаче.

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

Что делать, если корпус уже разбит на мелкие фрагменты

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

Родительский текст подтягивается в момент выдачи: запрос попадает в точный мелкий фрагмент, а в контекст модели уходит весь раздел, из которого он вырезан. Это Parent Document Retriever в прикладном виде — поиск по мелкому, ответ по крупному. Если поля родителя в схеме ещё нет, его добавляют миграцией метаданных без остановки поиска.

Миграция без простоя строится на двух параллельных индексах. Старый обслуживает трафик, новый наполняется связями в фоне, переключение идёт по совпадению выдачи на контрольном наборе запросов. Откат — возврат указателя: прежний индекс живёт до конца проверки.

Гибридная схема нужна, когда корпус неоднороден. Новые документы сразу индексируются парами «фрагмент — родитель», архив достраивается обходом по расписанию, поэтому свежие поступления не ждут обработки всего массива.

Полная переиндексация оправдана только при битом разбиении на фрагменты: куски рвут предложения, перекрытия нет, метаданные не несут структуры. Контроль результата — context recall на отложенной выборке реальных запросов и доля ответов, где родительский блок целиком уложился в окно контекста.

Частые вопросы инженеров: что ломается на практике

Метод закрывает конкретный класс сбоев: в индекс попадает короткий фрагмент, и ответ теряет детали, которые в документе были. Parent Document Retriever ищет по мелким фрагментам, а в контекст подаёт родительский документ целиком — в наших замерах полнота найденного контекста выросла на 19%. Цена у схемы тоже есть, и вопросы про неё инженеры задают первыми.

Не начнём ли мы подавать один и тот же текст несколько раз?

Да, если в выдачу попали разные фрагменты одного документа. Снимается дедупликацией по идентификатору родителя до сборки контекста: оставляем один экземпляр с наибольшим весом, а освободившееся место добираем документами, которые в выборку не попали. Ограничение метода — фиксированный бюджет контекста, поэтому дедупликацию и усечение считают вместе, а не по отдельности.

Насколько вырастет объём хранения?

Растёт, потому что рядом с фрагментом лежит его родитель. Относительно схемы с одними фрагментами это увеличение в один-два раза, точная величина зависит от длины родителя и перекрытия при нарезке. Управляется конфигурацией: родитель хранится в одном экземпляре, фрагменты ссылаются на него, редкие документы выносятся в холодное хранилище и не занимают быстрый индекс.

Как измерять качество, если эталонной разметки нет?

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

Обсудим задачу: как мы приходим к плану внедрения

План внедрения строится не на общих словах, а на вашей фактуре: без неё любая оценка сроков превращается в гадание. Поэтому обсуждение задачи начинаем с короткого перечня того, что нужно от вашей стороны, и сразу фиксируем, что вернём взамен.

  • Выборка реальных запросов пользователей за последний период и документов, на которые эти ответы должны были опираться, — на ней проверяем, возвращает ли поиск родительский фрагмент целиком, а не обрывок фразы.
  • Список мест, где сейчас уходит не туда: обращения в поддержку, ручные правки операторов, повторные уточняющие вопросы.
  • Правила доступа к разделам базы — кому что видно и что нельзя выносить за пределы вашего контура.
  • Эксперт с вашей стороны, который подтвердит корректность ответов на проверочном наборе и снимет спорные случаи.
  • Числовые критерии приёмки: доля запросов, где нужный фрагмент попал в подборку, и доля ответов со ссылкой на источник.
  • Ограничения по среде: контур размещения, объём базы, частота её обновления и способ синхронизации.

В ответ вы получаете оценку сроков по этапам, план внедрения и порядок пилотного запуска: сначала прототип поиска на вашей же выборке, затем пилот на одном подразделении с замером метрик, и только после этого — расширение на остальные команды. Каждый этап заканчивается проверяемым результатом и точкой возврата к предыдущему состоянию индекса, поэтому решение можно остановить без потери уже работающего поиска.

Опишите задачу — вернёмся с оценкой и планом.

Направления AI-разработки

Последние работы

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