MAATRIX / Блог / RAGFlow: RAG с разбором сложных документов

RAGFlow: RAG с разбором сложных документов

MAATRIX

Если ваш RAG отвечает невпопад именно на вопросы по таблицам, финансовым отчётам или техническим спецификациям — дело почти наверняка не в модели, а в том, как документ был порезан на фрагменты до того, как попал в векторную базу. Большинство самодельных пайплайнов режут текст по числу символов или токенов, не глядя на структуру документа — и это отлично работает для простого линейного текста, но рвётся на таблицах, вложенных разделах и многоколоночных PDF. RAGFlow — инструмент, который вместо этого сначала разбирает макет документа, а уже потом режет его на смысловые куски. Разберём, зачем это нужно и как понять, нужно ли это именно вам.

Где ломается наивный чанкинг

Классическая схема «разбить текст на куски по 500 токенов с перехлёстом в 50» не знает, что такое таблица, заголовок раздела или колонка PDF. Она видит поток символов и режет его механически. На простом линейном тексте — статья, письмо, инструкция без таблиц — это почти не заметно: смысл каждого куска обычно самодостаточен. Но как только в документе появляется структура сложнее «абзац за абзацем», начинаются проблемы.

Три типичных случая:

  • Таблица разрезана посередине. Строка разреза попадает между строкой таблицы и заголовками её столбцов. В индекс уходит фрагмент с цифрами без единиц измерения и без понятия, что означает каждый столбец — просто ряд чисел «12,4 / 8,1 / -3,2» без контекста.
  • Заголовок раздела оторван от содержимого. Заголовок «3.2 Ограничения гарантии» попадает в конец одного чанка, а текст под ним — в начало следующего, уже без привязки к номеру раздела и без явного понимания моделью, что это именно ограничения гарантии, а не общий текст договора.
  • Порядок текста в двухколоночном PDF перепутан. Если PDF свёрстан в две колонки, а парсер читает файл строка за строкой слева направо без понимания макета, куски первой и второй колонки чередуются построчно — получается текст, в котором предложения из разных смысловых блоков склеены случайным образом.

Подробнее о том, как чанкинг ломает конкретный пайплайн и какие симптомы на это указывают, разобрано в статье про проблему в чанкинге, из-за которой RAG выдаёт чушь — там разбор ближе к диагностике на живом проекте, здесь же речь именно про инструмент, который решает эту проблему на этапе парсинга документа.

Почему это бьёт по качеству ответа, а не по модели

Здесь важно разделить два разных этапа RAG-пайплайна: подготовку данных (загрузка, разбор структуры, чанкинг, индексация) и генерацию ответа (поиск релевантных кусков, передача их модели, генерация текста). Качество модели — GPT-4, Claude, Llama, локальная 7B или облачный флагман — не имеет значения, если на вход ей передан фрагмент, вырванный из структуры документа некорректно.

Представьте: пользователь спрашивает «какая маржинальность у продукта B во втором квартале», а найденный по векторному поиску фрагмент — это оторванная от заголовков строка таблицы «Продукт B | 14,2 | 9,8 | -1,3» без указания, какая колонка соответствует какому кварталу и что вообще означают эти числа. Модель физически не может дать корректный ответ на основе такого фрагмента — она либо честно скажет, что не может определить, либо, что хуже, придумает правдоподобно звучащую догадку. Это не галлюцинация в классическом смысле — модель добросовестно работает с тем, что ей дали, а дали ей испорченные данные. Проблема на этапе подготовки, и чинить её нужно там же, а не тюнингом промпта или заменой модели на более крупную.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть ИИ на сервере

Что делает RAGFlow иначе: разбор макета до чанкинга

RAGFlow — открытый инструмент для построения RAG-пайплайнов, у которого главная особенность — собственный движок разбора документов (в проекте он называется DeepDoc), работающий до этапа чанкинга, а не после него. Вместо того чтобы сразу резать текст по длине, RAGFlow сначала строит модель макета страницы: распознаёт, где заголовок, где абзац, где таблица, где рисунок или диаграмма, где колонтитул, а где реальный контент.

Практически это выглядит так:

  1. Layout-анализ страницы. Для PDF и отсканированных документов используется модель распознавания макета — она размечает страницу на блоки (заголовок, параграф, таблица, изображение, список) до извлечения текста, а не после.
  2. OCR для сканов и изображений. Если документ — скан или содержит текст на изображениях (диаграммы со встроенными подписями, скриншоты таблиц), OCR-слой извлекает текст с привязкой к его положению на странице.
  3. Восстановление порядка чтения. Для многоколоночных макетов layout-анализ определяет границы колонок и восстанавливает правильный порядок текста — колонка целиком, потом следующая, а не построчно вперемешку.
  4. Таблицы как структурная единица. Таблица распознаётся целиком, со строками и столбцами, и на этапе сериализации в текст (для передачи модели) заголовки столбцов сохраняются вместе со строками — так модель получает не голые числа, а понятные пары «столбец: значение».
  5. Шаблоны чанкинга по типу документа. RAGFlow предлагает несколько стратегий разбиения на куски — «general» (обычный текст), «paper» (структура научной статьи с разделами), «laws» (номерная структура договоров и нормативных актов), «table» (табличные данные), «manual» (техническая документация с иерархией разделов) и другие — так граница чанка чаще совпадает с реальной смысловой границей документа, а не с произвольной позицией по счётчику символов.

Это не отменяет базовую идею retrieval-augmented generation — поиск релевантных фрагментов по векторному сходству и передача их модели вместе с вопросом остаётся той же. Если нужна теория самого RAG-пайплайна с нуля — от эмбеддингов до генерации ответа — она разобрана в статье про RAG-пайплайн с практическим примером. Здесь же акцент именно на этапе, который в базовой теории часто описывают одной строкой «разбейте документ на чанки», а на практике эта строка и есть источник половины проблем с качеством.

Таблицы: что именно решает разбор структуры

Возьмём конкретный пример — финансовый отчёт с таблицей по кварталам:

Продукт      | Q1 2026 | Q2 2026 | Q3 2026
Продукт A    |    12.4  |    14.1  |    13.8
Продукт B    |     9.8  |    -1.3  |     2.5

При наивном чанкинге по фиксированному числу символов граница чанка может пройти между строкой заголовков и первой строкой данных — и в индекс попадёт кусок вида «Продукт A | 12.4 | 14.1 | 13.8» без единой подсказки, что означают три числа. При запросе «какая маржинальность продукта A в Q2» векторный поиск может найти этот фрагмент по смысловой близости слова «маржинальность» где-то в окружающем тексте, но сама строка с цифрами для модели остаётся набором чисел без опоры.

RAGFlow при сериализации таблицы в текст для индексации сохраняет связь заголовков столбцов со значениями строк — например, представляя строку как «Продукт A: Q1 2026 = 12.4, Q2 2026 = 14.1, Q3 2026 = 13.8» или сохраняя таблицу целиком как один смысловой блок вместо разрезания её произвольными границами чанка. Это не волшебство и не гарантия идеального результата на любой таблице — сложные таблицы с объединёнными ячейками, вложенными заголовками в несколько уровней или нестандартной вёрсткой всё ещё могут разбираться с ошибками, это стоит проверить на своих реальных файлах, а не считать решённым по умолчанию.

Многоколоночный PDF и порядок текста

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

Layout-aware разбор в RAGFlow сначала определяет границы колонок на странице, а затем извлекает текст колонка за колонкой в правильном порядке чтения. Это критично именно для качества последующего чанкинга: если исходный текст уже перемешан на входе, никакая стратегия нарезки на куски это не исправит — мусор на входе даёт мусор на выходе независимо от того, насколько умно вы режете уже испорченный текст.

Установка и первый прогон на сервере

RAGFlow разворачивается через Docker Compose и требует нескольких сервисов вместе: сам движок, Elasticsearch (или аналог для полнотекстового и векторного поиска), MySQL для метаданных, MinIO для хранения файлов, Redis для очередей. Это заметно тяжелее одного контейнера, поэтому для комфортной работы стоит закладывать сервер с запасом по оперативной памяти — сколько именно, зависит от объёма документов и параллельной нагрузки, ориентируйтесь на актуальные требования в README репозитория проекта на момент установки, а не на цифры из статей полугодовой давности.

Базовый ход установки (проверяйте актуальные шаги в официальном репозитории — процесс может измениться):

git clone https://github.com/infiniflow/ragflow.git
cd ragflow/docker

# скопировать и при необходимости отредактировать переменные окружения
cp .env.example .env

# поднять стек сервисов
docker compose -f docker-compose.yml up -d

# проверить, что все контейнеры поднялись
docker compose -f docker-compose.yml ps

После запуска веб-интерфейс обычно доступен на порту, указанном в .env (по умолчанию — 80 или 9380 в зависимости от версии). Дальше через интерфейс: создаёте базу знаний, загружаете документы, выбираете шаблон разбора (general/paper/table/manual/laws и другие в зависимости от типа файлов), запускаете парсинг — и уже на этом этапе можно посмотреть, как именно система разбила документ на куски, прежде чем подключать его к чат-боту или API.

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

Когда специализированный парсинг оправдан, а когда — нет

Не любой RAG-проект нуждается в разборе макета документа. Прежде чем разворачивать дополнительный стек сервисов, стоит честно оценить, что представляют собой ваши реальные документы:

  • Если документы — преимущественно простой линейный текст (статьи, письма, инструкции без таблиц и сложной вложенности) — обычное разбиение по фиксированному размеру фрагмента, скорее всего, работает вполне достаточно хорошо, и специализированный парсинг добавит инфраструктурной сложности без заметного прироста качества.
  • Если документы содержат много таблиц и сложной структуры — финансовые отчёты, технические спецификации со схемами, договоры с нумерованными вложенными разделами, многоколоночные PDF — специализированный разбор структуры перед индексацией может дать заметно лучший практический результат именно на вопросах, которые упираются в эти таблицы и разделы.
  • Смешанный случай — самый частый. Большинство корпоративных баз знаний — это смесь: часть документов простые, часть сложные. Здесь разумно не переделывать весь пайплайн одним решением, а протестировать оба подхода на выборке своих реальных проблемных документов и сравнить, на каком варианте вопросы, которые раньше давали плохие ответы, начинают отвечаться корректно.

Общий принцип здесь тот же, что и при выборе модели для задачи: не полагаться на общие рекомендации из статей, а тестировать на своих данных и своих типичных запросах — методика такого тестирования (в приложении к выбору модели, но применимая и к выбору инструмента для RAG) разобрана в статье про методику выбора модели под задачу. Час-два на прогон 10-15 реальных проблемных документов через оба варианта чанкинга обычно быстро показывают, стоит ли специализация своих затрат на инфраструктуру.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть ИИ на сервере

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

RAGFlow заменяет весь RAG-пайплайн или это только модуль парсинга?

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

Работает ли RAGFlow с отсканированными документами без текстового слоя?

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

Нужен ли GPU для работы RAGFlow?

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

Стоит ли переходить на RAGFlow, если текущий самодельный RAG и так работает нормально?

Если качество ответов вас устраивает и документы простые — специальных причин мигрировать нет. Переход имеет смысл тестировать именно тогда, когда конкретные симптомы (таблицы, многоколоночные PDF, вложенные разделы) уже определены как источник плохих ответов.

Можно ли использовать RAGFlow только для парсинга, а векторную базу и генерацию оставить свои?

Технически можно выгружать распарсенные и разбитые на чанки документы и передавать их в свой собственный пайплайн индексации, не используя встроенный в RAGFlow поиск и чат — это требует немного больше ручной интеграции, но избавляет от необходимости переносить весь остальной стек.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →