Production RAG: ingestion, embedding, retrieval, reranking, eval
Эксперт12 мин чтенияИИ для бизнеса

Production RAG: ingestion, embedding, retrieval, reranking, eval

Production-пайплайн RAG — это шесть стадий, у каждой свои паттерны, определяющие качество. Архитектура, выборы на каждой стадии и дисциплина итеративной оценки, которая отличает работающий RAG от разочаровывающего.

Что вы сможете сделать

Оценить архитектурный подход, возможные сбои и защитные меры до разработки.

AI Expert TeamОпубликовано: 15 мая 2026 г.
Сохраняется только в этом браузере.
В этой статье

Если вы выкатили простую RAG-систему, вы знаете паттерн: нарезать документы на чанки, заэмбеддить, положить в векторную БД, на запрос достать top-k, засунуть в промпт. Для демо работает. В продакшене часто разочаровывает.

Разрыв между demo-RAG и production-RAG огромен. Реальные документы грязные. Реальные запросы неоднозначные. Качество дико варьируется по типам запросов. Стоимость и latency — реальные ограничения. Обновления и версионирование имеют значение.

Эта статья — о том, как выглядит production-grade RAG-пайплайн: шесть стадий, паттерны на каждой и дисциплина оценки, которая отличает работающие системы от разочаровывающих.

Пайплайн

У production RAG-системы шесть логических стадий:

[Documents]
    ↓
1. Ingestion (parsing, cleaning, metadata extraction)
    ↓
2. Chunking (splitting into retrieval units)
    ↓
3. Embedding (vectors + storage)
    ↓
[Query]
    ↓
4. Retrieval (semantic + lexical + filters)
    ↓
5. Reranking (top-k → top-N)
    ↓
6. Generation (LLM + context)
    ↓
[Response]

У каждой стадии — свои проблемы качества. Улучшение любой одной улучшает всю систему.

Пройдём по каждой.

Стадия 1: ingestion

Мусор на входе — мусор на выходе. Качество вашего ingestion определяет потолок всего, что идёт ниже.

Типы источников, с которыми вы столкнётесь:

  • PDF (в основном худший).
  • Word-документы.
  • HTML-страницы.
  • Markdown.
  • Таблицы.
  • Слайды (PowerPoint, Google Slides).
  • Письма.
  • Код.
  • Структурированные данные (CSV, JSON).

У каждого свои сложности парсинга.

Парсинг PDF. PDF — формат презентации, а не данных. Они печально известны сложностью парсинга. Стратегии:

  • Текстовые PDF: pdfplumber, pymupdf, unstructured. Работают для чистого текста.
  • Сканированные PDF: OCR с Tesseract, Google Cloud Vision или AWS Textract.
  • Layout-aware: LayoutLM, Mathpix или LLM-парсинг (GPT-4 vision) для сложных макетов (таблицы, несколько колонок).

Современный подход для сложных PDF: использовать LLM с поддержкой зрения для OCR и структурирования контента. Стоит дороже, но качество драматически лучше традиционного OCR.

Обработка таблиц. Таблицы в неструктурированном тексте — боль. Варианты:

  • Конвертировать в markdown-таблицы (сохраняет структуру).
  • Линеаризовать в прозу («Row 1: customer A had 50 orders…»).
  • Считать отдельными извлекаемыми единицами со структурированной схемой.

Правильный выбор зависит от того, какие запросы вы будете получать.

Извлечение метаданных. У каждого документа есть метаданные, которые важны:

  • Заголовок, автор, дата, версия.
  • Тема, категория, теги.
  • Source URL или местоположение.
  • Права / видимость.

Захватывайте это на ingestion. Это станет параметрами фильтрации на retrieval.

Очистка. Срезайте boilerplate:

  • Header-ы/footer-ы, повторяющиеся на каждой странице.
  • Навигация, реклама, баннеры с cookie.
  • Страницы оглавления.
  • Пустые или дублированные параграфы.

Чистый корпус retrieve-ится лучше. Boilerplate приводит к ложным срабатываниям.

Проверки качества.

  • Извлёк ли парсер реально текст? (Некоторые PDF возвращают пустые строки.)
  • Есть ли проблемы с кодировкой?
  • Сохранены ли таблицы?
  • Подписаны ли картинки или пропущены?

Встройте sanity-чеки в ingestion-пайплайн. Ловите битые парсы до того, как они загрязнят индекс.

Стадия 2: chunking

У вас есть чистые документы. Теперь делите их на retrieval-единицы (чанки).

Фундаментальный компромисс:

  • Мелкие чанки: точный retrieval (сфокусированный на вопросе), но без контекста.
  • Крупные чанки: больше контекста, но менее точно (нужная часть закопана).

Обе крайности теряют качество. Sweet spot варьируется по типу контента.

Распространённые стратегии:

Фиксированный размер с overlap. Резать на чанки по N токенов (300–800 токенов) с overlap 50–100 токенов. Просто, работает как baseline.

Sentence-aware. Резать по границам предложений (используя nltk, spaCy или аналог). Избегает разрывов в середине предложения.

По параграфам. Каждый параграф — чанк. Работает для документов с хорошо структурированными параграфами.

Иерархический (мелкий + крупный). Два индекса:

  • Мелкие чанки (300 токенов) для точного retrieval.
  • Крупные чанки (1500 токенов) или целые секции для контекста. На retrieval — достаём мелкие; в LLM подаём родительский крупный.

Учёт структуры документа. Используйте структуру документа (заголовки, секции) для формирования чанков. Каждая секция — чанк, иерархия сохраняется.

Семантический chunking. Используйте эмбеддинги, чтобы найти естественные точки разрыва (где меняется тема). Дороже, но даёт лучшие чанки для некоторого контента.

LLM-summarization chunking. Длинные документы суммируются в иерархические чанки на нескольких уровнях (резюме параграфа, резюме секции, резюме документа). LLM генерирует это один раз при ingestion.

Правильная стратегия зависит от контента. Статьи и вики: параграфы или иерархия. Код: уровень функций. Разговоры: по репликам. Технические доки: учёт структуры.

Метаданные чанков. Каждый чанк должен нести:

  • ID и URL исходного документа.
  • Путь секции (chapter > section > subsection).
  • Номер страницы (для цитирования).
  • Заголовки выше этого чанка (для контекста).
  • Метаданные уровня документа (дата, автор, тип).

Эти метаданные позволяют фильтровать и цитировать в финальном ответе.

Стадия 3: embedding

Превращаем чанки в векторы.

Выбор embedding-модели.

В 2026:

  • OpenAI text-embedding-3-large: сильный универсал, дорогой.
  • Voyage Voyage-3: конкурентоспособен, часто лучше на техническом контенте.
  • Cohere embed-v4: сильный мультиязычный.
  • BAAI bge-large: сильный open-source.
  • Nomic embed-text: хороший open-source, бесплатный для self-host.
  • Доменно-специализированные модели: для кода (Voyage Code, OpenAI text-embedding-3-large тоже работает для кода), юридический, медицинский и т. д.

Выбор модели: тестируйте на своём домене. Не считайте, что лидер ладдерборда лучший для ваших данных.

Размерность embedding. Модели предлагают 256–3072 измерений. Выше размерность = выше качество, выше стоимость/хранение. Для большинства случаев sweet spot 768–1536.

Версионирование. Embedding-модели обновляются; вы можете захотеть переключиться. Планируйте это:

  • Отслеживайте, какая версия модели произвела каждый вектор.
  • Заново эмбеддите всё при миграции (или используйте dual-index переход).
  • Не смешивайте векторы разных моделей в одном поиске.

Стоимость. Эмбеддинг миллионов чанков стоит денег. €0.10–€0.50 за миллион токенов (зависит от провайдера). Для больших корпусов считайте заранее.

Хранение. Векторы большие. 1M чанков × 1536 измерений × 4 байта = 6GB. Планируйте хранилище соответственно.

Стадия 4: retrieval

Приходит запрос. Нужно найти релевантные чанки.

Векторный поиск (dense retrieval). Эмбеддим запрос, ищем ближайших соседей. Ловит семантическое сходство. Стандарт.

Поиск по ключевым словам (BM25 / lexical). Традиционный текстовый поиск. Ловит точные совпадения, редкие термины, конкретные имена. Часто дополняет векторный.

Гибридный поиск. Запускаем оба, сливаем результаты. Reciprocal Rank Fusion (RRF) — стандартный подход к слиянию.

def reciprocal_rank_fusion(rankings, k=60):
    scores = {}
    for ranking in rankings:
        for rank, doc_id in enumerate(ranking):
            scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
    return sorted(scores.items(), key=lambda x: -x[1])

На практике гибрид обыгрывает чисто векторный или чисто keyword-поиск на большинстве бенчмарков. Используйте по умолчанию.

Фильтрация по метаданным. Фильтруйте retrieval по метаданным до скоринга. «Только документы с 2025+». «Только документы из доступного пользователю набора». «Только документы типа policy».

Критично для мульти-тенантных систем: каждый запрос ограничен документами, доступными тенанту.

Понимание запроса. Препроцессинг запроса:

  • Коррекция опечаток. «engineerin» → «engineering».
  • Раскрытие аббревиатур. «MFA» → «Multi-Factor Authentication MFA».
  • Синонимы / расширение запроса. Генерируем альтернативные формулировки; ищем по каждой.
  • Декомпозиция. Многосоставные вопросы разбиваются на подзапросы, каждый retrieve-ится отдельно.

Эти шаги препроцессинга значительно улучшают retrieval на реальных запросах.

HyDE (Hypothetical Document Embeddings). Сгенерировать с помощью LLM фейковый «идеальный ответ». Заэмбеддить его. Использовать результат как retrieval-запрос. Часто работает лучше, чем эмбеддинг вопроса напрямую, потому что фейковый ответ ближе к реальным документам-ответам.

def hyde_retrieve(query, k=20):
    hypothetical = llm("Write a passage answering: " + query)
    embedding = embed(hypothetical)
    return vector_search(embedding, k=k)

Компромисс: дополнительный LLM-вызов на запрос (latency, стоимость). Стоит того для сложных запросов; перебор для простых.

Multi-vector retrieval. Вместо одного вектора на чанк — несколько (например, один для чанка, один для резюме, один для гипотетических вопросов). Добавляет хранение и сложность, но улучшает retrieval для некоторого контента.

Стадия 5: reranking

После начального retrieval (top-k, k=20–50) используйте reranker, чтобы более аккуратно оценить кандидатов.

Зачем rerank?

Начальный retrieval быстрый, но неточный. Векторная близость — грубая прокси для релевантности. Reranker (обычно cross-encoder модель) читает запрос и каждого кандидата вместе, выдавая более точную оценку.

Варианты reranker:

  • Cohere Rerank. Индустриальный стандарт. Хорошее качество, хостируемое.
  • Voyage Rerank. Сильный конкурент.
  • BGE Rerank-large. Open-source, бесплатный для self-host.
  • MiniLM cross-encoders. Меньше, быстрее, ниже качество.
  • LLM-based reranking. Используем маленькую LLM для скоринга пар query-кандидат. Самое высокое качество, самая высокая стоимость.

Эффект.

По нашему опыту, добавление reranking улучшает качество end-задачи на 10–20% в большинстве RAG-систем. Почти всегда стоит того по latency и стоимости.

Типичная конфигурация:

  • Достать 30–50 кандидатов гибридным поиском.
  • Rerank до top 5–10.
  • Передать топ-результаты в LLM.

Адаптивный reranking.

Для запросов, где топ-1 результат имеет высокое векторное сходство (явное совпадение), reranking пропускайте. Для запросов с близкими скорами (несколько кандидатов вровень) — rerank-ите агрессивно.

Стадия 6: генерация

LLM производит ответ, используя retrieved-контекст.

Структура промпта:

You are an assistant answering questions based on the provided context.

Context:
[Document 1 - title, URL]
[chunk 1 content]
[Document 2 - title, URL]
[chunk 2 content]
...

User question: {query}

Instructions:
- Answer based only on the provided context.
- If the context doesn't contain the answer, say so. Don't make up information.
- Cite sources using [Source N] notation.
- Be concise but complete.

Паттерны промпта, которые имеют значение:

  • Тегирование источников. Каждый чанк контекста тегируется источником для цитирования.
  • Инструкции по grounding. Явно говорим модели использовать только контекст.
  • Требование цитирования. Принуждаем к цитированию. Ловит галлюцинации.
  • Fallback-инструкция. «If the context doesn't have the answer, say so.» Предотвращает confabulation.

Обработка цитирования.

Распространённый паттерн: включить ссылки на источники в ответ. UI рендерит их как кликабельные.

"The company's remote work policy allows up to 4 days/week from home [1].
[1]: https://wiki.company.com/policies/remote-work"

Это делает ответ верифицируемым. Пользователи больше доверяют grounded-ответам.

Управление размером контекста.

Длинные контексты деградируют. Большинство моделей лучше работают со сфокусированными контекстами (5–10 высокорелевантных чанков), а не со свалкой всего. Качество падает с распуханием контекста.

Если приходится включать много контекста, суммируйте менее релевантные элементы, а не включайте их целиком.

Оценка на каждой стадии

Нельзя оптимизировать то, что не измеряешь. Каждой стадии нужны свои evals.

Eval ingestion. Распарсились ли документы корректно? Сэмплируйте документы; проверьте, что ключевой контент сохранён.

Eval chunking. Правильного ли размера чанки? Сохраняют ли контекст? Рвутся ли по разумным границам?

Eval embedding. Эмбеддятся ли похожие концепции похоже? На тест-сете заведомо похожих и заведомо разных пар — соответствует ли cosine similarity ожиданиям?

Eval retrieval. Для данного запроса — есть ли релевантные чанки в top-K? Типичная метрика: recall@K (какой % запросов имеет хотя бы один релевантный чанк в top K).

Eval reranking. Среди retrieved-кандидатов — ставит ли reranker самый релевантный первым? Метрика: NDCG (normalized discounted cumulative gain) или MRR (mean reciprocal rank).

Eval генерации. При данном контексте и запросе — выдаёт ли LLM корректный ответ? Метрики: faithfulness (использует ли ответ контекст?), correctness (верен ли ответ?), helpfulness (отвечает ли он на намерение пользователя?).

End-to-end eval. При реальном запросе — выдаёт ли система правильный ответ? Самое важное; зависит от всех стадий.

Вам нужны тест-сеты для каждой стадии. Типичный bootstrap:

  • Собрать 50–100 запросов с известно-хорошими ответами.
  • Для каждого запроса определить, какой документ(ы) содержит ответ.
  • Использовать это для оценки retrieval (достали ли мы нужные документы?) и генерации (верен ли ответ?).

Инструменты: Ragas, TruLens, кастомные наборы. Конкретный инструмент менее важен, чем сам факт запуска evals.

Операционные вопросы

Несколько production-реалий:

Indexing-пайплайны. Приходят новые документы. Re-embed. Обновить индексы. Обработать удаления и обновления. Этот пайплайн работает постоянно, не только на сетапе. Стройте его как систему, а не как одноразовый скрипт.

Latency.

Типичная разбивка:

  • Embedding (запрос): 50–200 мс.
  • Векторный поиск: 50–200 мс.
  • Reranking: 200–500 мс (зависит от K).
  • Генерация: 1–5 с (зависит от контекста и модели).
  • Итого: 1.5–6 с.

Оптимизация:

  • Кэшировать эмбеддинги частых запросов.
  • Кэшировать reranking для повторяющихся пар query-candidate.
  • Стримить генерацию.
  • Параллелить, где возможно.

Для latency < 2 с обычно нужны быстрая embedding-модель, быстрая векторная БД и либо быстрый reranker, либо пропуск reranking для закэшированных/простых запросов.

Стоимость.

Стоимость на запрос:

  • Embedding: ~€0.0001.
  • Векторный поиск: ~€0.0001 (зависит от инфраструктуры).
  • Reranking: €0.001–0.01 (зависит от модели).
  • Генерация: €0.005–0.05 (зависит от модели и контекста).
  • Итого: ~€0.01–0.05 на запрос.

На масштабе это складывается. Миллион запросов = €10K–50K.

Оптимизация стоимости:

  • Кэшировать.
  • Использовать более дешёвые модели там, где качество позволяет.
  • Сжимать контекст (резюме вместо полных чанков).

Обновления. Документы меняются. Паттерны:

  • Версионирование: у каждого документа есть версия; старые версии хранятся или удаляются по политике.
  • Инкрементальное: новые версии re-chunk-ятся и re-embed-ятся; старые чанки удаляются.
  • Diff-aware: только изменённые секции переобрабатываются.

Для сценариев с большим объёмом обновлений это существенно.

Права. RAG над приватными данными: у документов есть контроли доступа; retrieval должен их уважать.

  • Фильтрация по метаданным (у каждого чанка есть метаданные accessible-by).
  • Tenant-изолированные индексы для жёсткой изоляции.
  • Audit logging того, кто к чему обращался.

Не доверяйте LLM энфорсить права. Энфорсите на retrieval.

Типичные режимы провалов

Несколько паттернов, которые мы видим в провальных RAG-системах:

Провал 1: плохой chunking. Чанки рвутся посреди мысли, таблица разбита между чанками, заголовки отделены от своего содержания. Фикс: лучшая стратегия chunking.

Провал 2: retrieval промахивается мимо ответа. Релевантный чанк существует, но не находится. Часто — несоответствие запроса и документа. Фикс: HyDE, расширение запроса, лучшие эмбеддинги.

Провал 3: правильные чанки, неверный порядок. Релевантный чанк извлечён, но ранжирован низко. LLM использует более высокоранжированные нерелевантные чанки. Фикс: reranking.

Провал 4: правильные чанки, галлюцинация. Чанки правильные, но LLM придумывает дополнительную информацию. Фикс: более строгий grounding-промпт, требования цитирования, более низкая температура.

Провал 5: правильные чанки, неверный ответ. Чанки содержат ответ, но LLM извлекает неверную часть. Фикс: лучший промпт генерации, возможно — модель побольше.

Провал 6: устаревшие данные. Индекс не обновлялся. Фикс: непрерывный ingestion-пайплайн.

Провал 7: утечки прав. Пользователи видят чанки, которые им не положены. Фикс: энфорсить фильтрацию на retrieval; audit.

Провал 8: разгон затрат. Latency и стоимость выросли с ростом корпуса и трафика. Фикс: кэширование, маршрутизация моделей, возможно — архитектурные изменения.

Разобранный пример: RAG для корпоративной базы знаний

Чтобы было конкретно: типичная RAG-система над корпоративной базой знаний.

Корпус: ~50 000 документов (wiki-страницы, политики, runbook-и, заметки встреч, slack-треды).

Пайплайн:

  1. Ingestion: - Notion: экспорт через API. - Slack: archive export, отфильтрованный до релевантных каналов. - Google Drive: API-экспорт согласованных папок. - Очистка: убрать сообщения только из эмодзи, boilerplate-подписи.
  1. Chunking: - Иерархический: мелкие чанки уровня параграфа, родительские чанки уровня секции. - ~250K общих чанков на мелком уровне. - Метаданные: источник, путь секции, last_updated, accessible_to.
  1. Embedding: - Voyage-3 embeddings, 1024 измерения. - Хранение в Pinecone (managed). - Еженедельный re-embedding для изменённых документов.
  1. Retrieval: - Гибридный: векторный поиск + BM25 (через гибрид Pinecone). - HyDE для запроса. - Фильтр по метаданным для доступности. - Top 30 извлекается.
  1. Reranking: - Cohere Rerank. - Top 30 → top 8.
  1. Генерация: - Claude 4 Sonnet. - Top 8 родительских чанков (не мелких) подаются как контекст. - Цитирование требуется в ответе.

Eval:

  • 100 вручную составленных пар query/answer.
  • Retrieval recall@30: ~92%.
  • Корректность финального ответа: ~85%.
  • Faithfulness (без галлюцинаций): ~95%.

Операции:

  • Ежедневный инкрементальный ingestion.
  • Еженедельный полный re-embedding для изменённых документов.
  • Per-query observability.
  • Ежемесячный re-run eval; мониторинг трендов.
  • Ежеквартальный обзор query log для поиска новых паттернов провалов.

Стоимость:

  • Embedding: ~€500/месяц (в steady-state).
  • Хостинг векторной БД: ~€800/месяц (Pinecone).
  • Retrieval + генерация на запрос: ~€0.02.
  • Итого: ~€2 500/месяц + €0.02 × объём запросов.

Для большинства компаний это полностью оправдано приростом продуктивности.

План 90-дневной сборки RAG

Если стартуете с нуля:

Дни 1–30: MVP.

  • Определить корпус и основной use case.
  • Базовый ingestion (один источник).
  • Базовый chunking (фиксированный размер с overlap).
  • Стандартная embedding-модель.
  • Только векторный поиск (без rerank).
  • Простой промпт генерации.

Дни 31–60: качество.

  • Вручную собрать eval-сет (50–100 запросов).
  • Определить режимы провалов.
  • Добавить reranking.
  • Добавить гибридный поиск.
  • Улучшить chunking.

Дни 61–90: операции.

  • Непрерывный ingestion-пайплайн.
  • Observability.
  • Автоматизация eval.
  • Права/auth.
  • Мониторинг стоимости.

Через 90 дней у вас система, которую можно не просто демонстрировать, а реально использовать. Реальные пользователи могут на неё опереться.

Главный вывод

Production RAG — это шестистадийный пайплайн с проблемами качества на каждой стадии. Паттерны, которые отличают работающие системы от разочаровывающих:

  • Ingestion: тщательный парсинг, сохранение структуры, захват метаданных.
  • Chunking: подходящая стратегия для типа контента, часто иерархическая.
  • Embedding: качественная модель, версионирование, план миграции.
  • Retrieval: гибрид по умолчанию, понимание запроса, фильтрация по метаданным.
  • Reranking: почти всегда того стоит.
  • Генерация: grounding, цитирование, fallback для неизвестного.
  • Eval: на каждой стадии, постоянно.

Это не опциональный полишинг. Это разница между RAG, который попадает в 60% качества ответа, и RAG, который попадает в 90%.

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

Читать дальше

Продолжайте тот же учебный путь со следующими практическими статьями.