Гайд · TNWS AI

Как разбить длинные документы на чанки в Haystack DocumentSplitter

Haystack 3.1Python#Haystack#RAG#Python
5 мин—

Подбираем split_by, split_length и overlap; сохраняем связь чанка с исходником и проверяем граничные факты.

Применимость и задача

Поисковый запрос: «как разбить документы на чанки Haystack DocumentSplitter». Материал сверён с официальной документацией Haystack 3.1 19 сентября 2026 года. Примеры рассчитаны на Python и пакет haystack-ai; для векторного примера дополнительно нужен пакет sentence-transformers-haystack. Демонстрационное InMemoryDocumentStore не рекомендовано разработчиком для production. Интерфейс командной строки ниже — Python API, а не названия пунктов графического меню.

DocumentSplitter разбивает список Document по словам, предложениям, абзацам, страницам, строкам, точкам или функциям. split_length задаёт размер в единицах split_by, а split_overlap — перекрытие в тех же единицах. В метаданных частей сохраняется source_id, позволяющий связать чанк с исходным документом. Некоторые хранилища имеют ограниченную поддержку метаданных перекрытия.

Нумерованный порядок работы

  1. Определите единицу разбиения по типу источника: для инструкции с пунктами разумно начать с абзаца, для короткой FAQ — с предложения.
  2. Соберите контрольные вопросы, где условие и исключение стоят на границе соседних фрагментов.
  3. Выберите split_length и split_overlap как измеряемые параметры эксперимента, а не как универсальную константу.
  4. Проверьте количество частей, source_id и наличие условий в полученных фрагментах.
  5. После индексации измерьте полноту извлечения на контрольных вопросах и скорректируйте настройки.

Готовый шаблон

from haystack import Document
from haystack.components.preprocessors import DocumentSplitter

doc = Document(content="Срок возврата 14 дней. Исключение: цифровой товар. "
                       "Обратитесь в поддержку при споре.", meta={"policy": "R7"})
splitter = DocumentSplitter(split_by="sentence", split_length=2,
                            split_overlap=1)
parts = splitter.run(documents=[doc])["documents"]
for part in parts:
    print(part.content, part.meta.get("source_id"), part.meta.get("policy"))

Пример предназначен для контролируемого теста на своих данных. Установите зависимости в отдельном окружении и зафиксируйте версии; при использовании локальной embedding-модели отдельно проверьте её доступность и разрешённость для вашего проекта. Код был проверен на синтаксис Python, но его вызовы Haystack в данном материале не выдаются за выполненный runtime-тест.

Вход и ожидаемый результат

Вход: три предложения политики, второе — исключение о цифровом товаре. Ожидаются короткие фрагменты, где соседнее предложение может повторяться из-за overlap=1; каждый должен сохранять связь с R7 и исходным документом. Количество частей и точные границы зависят от правил сегментации, поэтому тестируйте наличие условия и исключения, а не жёстко задавайте непроверенную разбивку.

Помимо положительного кейса записывайте отрицательный: отсутствие факта, чужой документ, пустой файл или несовместимая редакция правила в зависимости от задачи. Храните ожидаемые ID и смысл результата отдельно от вывода программы. Если пример не прошёл, выясните, на каком шаге данные впервые разошлись: загрузка, обработка, извлечение или построение ответа. Нельзя исправлять результат одной только формулировкой ответа, если нужный факт никогда не поступил в контекст.

Разбор ограничений и ошибок

Ошибка на границе чанков особенно опасна для правил с отрицанием. Если поиск возвращает «Срок возврата 14 дней», но не извлекает «Исключение: цифровой товар», модель может дать неверный ответ при внешне убедительной цитате. Перекрытие повышает шанс видеть соседнее предложение, но также увеличивает количество хранимого текста и риск повторов в промпте. Сравнивайте baseline без перекрытия и выбранный вариант на одинаковом размеченном наборе запросов. Размерность слова или предложения не означает размерность токена конкретной модели: перед отправкой контекста отдельно измеряйте фактический prompt budget. При индексации храните версию исходного документа, чтобы более новая редакция правила не смешалась со старой. source_id помогает восстановить происхождение, однако сам по себе не даёт прав доступа или URL первоисточника — добавляйте нужные метаданные приложения отдельно.

Проверочный сценарий на реальном корпусе

Проверяйте смешанные источники: страницы с таблицами, пунктами списка и сканами после OCR. Простая сегментация по предложениям способна оставить заголовок условия в предыдущем чанке, а значения таблицы — в следующем. Для таблицы нужен отдельный способ извлечения или сохранение блоков целиком. Выберите пять вопросов с точным ответом, включая запрос о цифровом товаре, и запишите требуемые source IDs. Если поиск не находит правильный фрагмент, сначала исследуйте состав чанков, затем embedding или BM25; смена модели не исправит отсутствие текста. Не привязывайте UI-ссылку к порядковому номеру чанка: при редактировании корпуса порядок меняется. Лучше хранить стабильный ID источника и позицию фрагмента. При переходе на внешнее хранилище проверьте его поддержку overlap-метаданных по официальному руководству интеграции.

Критерии приёмки

  • Исключение попадает в извлекаемый фрагмент.
  • source_id и пользовательские метаданные не потеряны.
  • Размер контекста не превосходит бюджет модели.

Не принимайте демонстрационный вывод за статистику качества. Для рабочего приложения повторите эти проверки на обезличенном наборе документов, измерьте результат после изменения версии корпуса и запретите доступ к источникам вне полномочий пользователя. Корректный ответ HTTP вашего сервиса не означает корректный ответ RAG-системы; последнее устанавливается сопоставлением факта с разрешённым источником.

Типичные ошибки: чего не делать

  • Не путать split_length в предложениях с числом токенов.
  • Не полагаться на overlap как на исправление плохого OCR.
  • Не ссылаться на неустойчивый порядковый номер чанка.

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

FAQ

Какая единица split_by допустима?

Среди вариантов есть word, sentence, passage, page и line.

Зачем source_id?

Для связи части с исходным документом.

Всегда ли нужен overlap?

Нет, проверьте его влияние на полноту и дублирование.

Официальные источники

Частые вопросы

Какая единица split_by допустима?

Среди вариантов есть word, sentence, passage, page и line.

Зачем source_id?

Для связи части с исходным документом.

Всегда ли нужен overlap?

Нет, проверьте его влияние на полноту и дублирование.

Читайте также

Комментарии

Пока тихо. Скажите первое слово