RAG Content Pipeline: от сырых документов к базе знаний

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

В этой связке PFRAG работает как входной цех для контента, а RAG — как индекс и API для вопросов по базе знаний. Разделение не такое эффектное, как сценарий «загрузил файл и сразу спросил», зато оно честнее относится к реальным документам: они редко приходят чистыми, одинаковыми и готовыми к поиску.

Какие источники попадают в pipeline

PFRAG подтверждённо работает с ручной загрузкой файлов и парсингом сайтов. Входной контент может прийти из разных мест:

  • PDF, DOCX и PPTX-документы;
  • изображения PNG, JPG и JPEG, где нужен OCR;
  • HTML и TXT-файлы;
  • Markdown после первичной обработки;
  • URL и сайты, которые обходятся BFS-парсером с ограничением глубины и числа страниц;
  • документы, найденные на страницах сайта.

Для RAG-контента это важное отличие от простого upload endpoint. Источники почти никогда не похожи на аккуратно подготовленную документацию: сайт может принести навигационный шум, PDF — картинки и таблицы, а несколько файлов могут повторять одни и те же регламенты. Pipeline нужен именно для этого промежутка между «у нас есть пачка материалов» и «у нас есть база знаний, по которой можно спрашивать».

Шаг 1. Приём и учёт файлов

После загрузки или парсинга сайта PFRAG сохраняет файл, создаёт запись в PostgreSQL и ведёт статус обработки. Это не бюрократия ради статусов, а способ не смешивать разные состояния одного и того же материала: сырой файл, черновой Markdown, очищенный Markdown и уже проиндексированную версию.

Типичный путь файла:

  1. uploaded — файл принят, но ещё не обработан.
  2. processing_primary — идёт OCR или извлечение текста.
  3. ready_to_ai — черновой Markdown готов к LLM-очистке.
  4. processing_final — идёт нормализация текста.
  5. ready_to_ingest — материал готов к отправке в RAG.
  6. ingested — файл добавлен в LightRAG.

Такая дорожная карта помогает быстро понять, где именно документ застрял: на OCR, на LLM-очистке, на dedup или при загрузке в индекс. Для оператора это разница между «что-то не работает» и конкретной точкой, которую можно проверить.

Шаг 2. Primary processing

Primary processing превращает файл в черновой Markdown. Это первый перевод документа на язык, с которым дальше удобно работать pipeline: для PDF, DOCX и PPTX используются инструменты извлечения текста и OCR, для изображений — распознавание, для HTML — извлечение текста через парсинг страницы.

У этого этапа есть два режима:

  • default — обычное извлечение текста;
  • pdf — извлечение текста вместе с картинками и плейсхолдерами вида [[IMG_###]].

PDF-режим нужен, когда документ важно не только проиндексировать, но и потом восстановить в читаемый PDF с картинками после очистки или перевода. То есть pipeline не выбрасывает визуальный контекст там, где он всё ещё нужен для финального документа.

Шаг 3. Final processing

На этапе Final processing PFRAG берёт черновой Markdown и прогоняет его через LLM. В проекте предусмотрены именованные промпты, настройки модели и параметры генерации: temperature, top_p, top_k, repetition_penalty, presence_penalty, max_tokens.

Практический смысл этого этапа — не «улучшить текст вообще» и не переписать документ на новый лад, а привести материал к более ровному виду для индексации. Чем понятнее и чище исходный Markdown, тем меньше случайного шума попадёт в чанки и retrieval:

  • убрать служебный шум;
  • нормализовать таблицы;
  • сохранить важные заголовки и структуру;
  • не сломать плейсхолдеры картинок в PDF-режиме;
  • получить clean_md, который можно безопаснее отправлять в RAG.

Шаг 4. Дедупликация

Перед индексом важно убрать повторы. В PFRAG есть несколько режимов дедупликации:

  • vector_and_line — векторная и построчная дедупликация;
  • vector_only — поиск похожих чанков по embeddings, cosine similarity и Jaccard;
  • line_only — удаление повторяющихся строк;
  • template_only — удаление строк по шаблону;
  • full_dupl — удаление файлов, помеченных как полные дубликаты.

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

Шаг 5. Ingestion в RAG

После очистки PFRAG отправляет clean_md в RAG-контур. Если очищенной версии нет, может использоваться raw_md, но рабочая идея pipeline — доводить материал до ready_to_ingest и только потом индексировать. Это точка, где подготовленный текст становится частью базы знаний, а не просто лежит как загруженный файл.

RAG-сервер принимает документы через ingestion endpoint, проверяет дубликаты по хешу, извлекает текст для поддержанных форматов и запускает фоновую индексацию в LightRAG. На этом этапе текст разбивается на чанки, получает embeddings, сохраняется в Qdrant, а графовые сущности и связи уходят в Neo4j.

Шаг 6. Чат и API

После индексации база знаний становится доступна через чат. RAG-контур поддерживает обычный JSON endpoint, SSE-стриминг и WebSocket. Это позволяет подключить web-чат, Telegram-бота, внутренний сервис или API-to-API интеграцию.

Для пользователя весь сложный путь выглядит проще: загрузить документы, дождаться обработки и задать вопрос. Но качество ответа складывается раньше, чем пользователь открывает чат: оно зависит от OCR, очистки, дедупликации, чанкинга и режима поиска.

Что получается на выходе

RAG Content Pipeline — это не один endpoint для загрузки файла, а цепочка с понятными зонами ответственности. PFRAG делает контент пригодным для индексации: принимает разные источники, очищает и нормализует материал, убирает повторы и доводит документ до состояния ready_to_ingest. RAG превращает подготовленный текст в базу знаний и отвечает на вопросы с учётом векторного и графового поиска.