Chunk - единица поиска, а не хранения
Поиск должен вернуть минимальный фрагмент, достаточный для ответа и проверки. Целый документ размывает similarity, а слишком короткий кусок теряет условия, исключения и субъект действия.
Fixed-size как baseline
Окно по токенам быстро внедряется и удобно для эксперимента. Оно полезно как контрольный вариант, но режет таблицы, списки и предложения. Размер задавайте токенами конкретной embedding-модели, а не символами.
Structure-aware разбиение
Для Markdown и HTML сохраняйте hierarchy заголовков; для договоров - разделы и пункты; для кода - функции и классы; для таблиц - заголовки колонок вместе со строками. Структура документа часто сильнее произвольной семантической границы.
Overlap - ограниченный пластырь
Перекрытие помогает фактам на границе, но раздувает индекс и возвращает дубликаты. Начните с небольшого overlap, измерьте boundary failures и добавляйте его только там, где это улучшает recall.
Parent-child retrieval
Индексируйте небольшие child chunks, но после совпадения поднимайте более широкий parent context. Так retrieval остаётся точным, а генератор получает соседние условия. Ограничивайте parent размер, чтобы один результат не занял весь context budget.
Metadata обязательна
Каждый chunk должен знать document_id, version, section path, page, timestamps, ACL и позицию. Эти поля нужны для фильтров, цитат, удаления, дедупликации и восстановления соседнего контекста.
Таблицы и сканы требуют отдельного пути
OCR сначала должен сохранить порядок чтения и связь заголовков с ячейками. Большую таблицу полезно представить как исходную структуру, row-level chunks и текстовое описание - с ссылкой на один source object.
Как подобрать параметры
Соберите вопросы разных типов и пометьте релевантные passages. Сравните Recall@k, число дубликатов, context precision, качество ответа, latency и стоимость. Меняйте один фактор за эксперимент и версионируйте chunking policy.