Когда RAG-система отвечает плохо, виноватой обычно объявляют модель. Документы к этому моменту нередко успевают испортить дело заранее.
Плоский корпус
Документы почти без разбора отправляются в индекс.
- слабые заголовки
- механическая нарезка
- почти нет метаданных
- дубликаты и устаревшие версии проходят дальше
Подготовленный корпус
Корпус сохраняет структуру, идентичность и подсказки для поиска.
- фрагменты не забывают, из какого документа пришли
- заголовки несут реальный сигнал
- фильтры сокращают пространство поиска
- слабые источники ловятся ещё на этапе загрузки
Нарезка — это решение поиска, не мелочь
Многие до сих пор говорят о нарезке как о подготовке. Это одно из главных решений во всей системе.
Хороший фрагмент точно матчится к вопросу, не теряет смысл сам по себе, сохраняет достаточно контекста и идентичности, чтобы ему можно было доверять. Поэтому механическая нарезка по фиксированному размеру стареет плохо.
Здоровее начинать со структуры самого документа. Markdown по заголовкам. Политики по разделам. Договоры по clauses и definitions. Судебные тексты по facts, reasoning и holding. Документы с таблицами и схемами по layout-aware извлечению.
Лимиты по токенам всё равно нужны. Говорить первой должна структура.
Сильные заголовки тихо улучшают поиск
Один из самых простых апгрейдов и один из самых недооценённых. Нормальные заголовки у фрагментов.
Фрагмент с названием Section 4 почти ничего не даёт поиску. Фрагмент с названием Notice periods for termination in enterprise plans работает иначе. И поиск, и генератор получают ясный сигнал.
Не эффектно. Полезно.
Очень многое в поиске держится на мелких сигналах:
- заголовок документа
- путь по разделам
- название подраздела
- версия или effective date
- тип источника
Если здесь шум, векторному индексу приходится компенсировать то, что этап подготовки данных должен был сделать раньше.
Parent-child даёт один из лучших компромиссов
Маленькие фрагменты ищутся лучше. Большие фрагменты удобнее читать модели. Противоречие никуда не делось.
Parent-child retrieval остаётся одним из самых чистых решений. Индексируем маленькие дочерние фрагменты для поиска. На чтение возвращаем более крупный родительский раздел. Не теряем связь между ними до самого ответа.
Система получает лучшую полноту, но не заставляет модель отвечать по набору оторванных фраз, которые хорошо эмбеддятся и плохо живут отдельно. Для привязки к источнику это полезно. Доказательство остаётся частью понятного раздела, а не абзацем, который нашёлся, но забыл, откуда он.
Метаданные сужают поиск
RAG кажется умнее просто потому, что ищет в меньшем и более уместном пространстве.
Полезный набор: источник или репозиторий, тип документа, дата версии или вступления в силу, язык, продуктовая или доменная область, уровень чувствительности.
К поиску можно добавлять фильтры, а не надеяться, что модель сама рассортирует на этапе ответа. Без этого слоя модель тратит дорогие токены на проблемы, которые надо было снять на этапе подготовки корпуса.
Sentence-window работает после порядка в корпусе
Sentence-window retrieval и похожие точные приёмы помогают, когда важна маленькая фактическая деталь. Работает когда корпус очищен, идентичность фрагментов сохранена, система умеет расширяться от найденного предложения к локальному контексту.
Если корпус дублированный, устаревший или поломан при парсинге, система точнее вытаскивает неправильное место. Не улучшение.
Reranking — второй этап, не первая магия
Reranker заметно поднимает качество. Плохой корпус он не спасёт.
Порядок:
- привести данные в порядок
- получить широкий, но вменяемый top-k
- сделать reranking
- передавать модели самый маленький защищаемый набор источников
Перепутаешь — reranker с достоинством выбирает из мусора.
Контроль качества корпуса отдельно от answer evals
У серьёзной RAG-системы должен быть свой corpus QA. Не всё сводится к тому, как красиво выглядит финальный ответ.
Отдельные проверки на дубликаты документов, устаревшие версии, проваленный OCR или сломанный парсинг, отсутствующие заголовки, фрагменты без идентичности документа, испорченные таблицы, отсутствующие effective dates где критично.
Работа скучная. Дешевле бесконечных попыток компенсировать плохой индекс промптом.
Проблемы поиска — проблемы подготовки
Когда говорят «поиск нестабилен», или «reranker странно себя ведёт», или «модель не попадает в суть», часто имеется в виду что документы порезаны плохо, заголовки слабые, остались дубликаты, метаданных нет, потерялась идентичность документа.
Система кажется загадочной. Она не загадочная. Она недоделана.
Лучший вопрос — не «какой размер фрагмента?»
Полезнее так:
Какая единица документа должна оставаться понятной и полезной, если её вытащили отдельно?
Ответ зависит от домена. Техническая документация — section под heading. Договор — clause вместе с локальными definitions. Регуляторный текст — section path плюс метаданные о версии и дате.
Универсального размера нет. Есть удачное или неудачное соответствие конкретному корпусу.
Что бы я правил первым
Если бы RAG ощущался шатким и у меня было только одно утро, я бы начал так:
- убрал дубликаты и устаревшие версии
- привёл в порядок заголовки и путь по разделам
- сохранил связку parent-child
- добавил фильтры по главным измерениям корпуса
- посмотрел на сбои поиска до всяких правок в промпте
Модель может действительно требовать доработки. Но документы обычно идут первыми.
Что ещё почитать
- Какие преобразования запроса действительно помогают в RAG
- Как строить юридические QA-системы, которым можно доверять