Гайд · TNWS AI
Как разбить длинные документы на чанки в Haystack DocumentSplitter
Подбираем 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, позволяющий связать чанк с исходным документом. Некоторые хранилища имеют ограниченную поддержку метаданных перекрытия.
Нумерованный порядок работы
- Определите единицу разбиения по типу источника: для инструкции с пунктами разумно начать с абзаца, для короткой FAQ — с предложения.
- Соберите контрольные вопросы, где условие и исключение стоят на границе соседних фрагментов.
- Выберите split_length и split_overlap как измеряемые параметры эксперимента, а не как универсальную константу.
- Проверьте количество частей, source_id и наличие условий в полученных фрагментах.
- После индексации измерьте полноту извлечения на контрольных вопросах и скорректируйте настройки.
Готовый шаблон
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?
Нет, проверьте его влияние на полноту и дублирование.
Читайте также
Как ограничить поиск документами одного клиента в Haystack
Фильтр meta.tenant в retriever, тест на утечку чужого документа и границы серверной авторизации.
Как настроить смысловой поиск в Haystack InMemoryEmbeddingRetriever
Индексируем документы и запрос одной embedding-моделью, проверяем размерность, top_k и качество на перефразировках.
Как избежать дублей документов в Haystack через DocumentWriter и DuplicatePolicy
Повторная индексация без случайных дублей: стабильные ID, режимы OVERWRITE, SKIP и FAIL и проверка числа записей.
Комментарии
Пока тихо. Скажите первое слово