🔎 RAG: генерация, дополненная поиском

RAG (Retrieval-Augmented Generation, генерация, дополненная поиском) — это схема, при которой модель перед ответом подгружает релевантные фрагменты из вашей базы знаний, а уже потом формулирует ответ, опираясь на них. Это самый распространённый и самый полезный паттерн в корпоративном AI: именно он превращает «умную, но не знающую ваших реалий» модель в систему, которая отвечает по вашим документам.

Одно предложение

RAG = «модель не пытается вспомнить ответ из головы, а сначала ищет нужное в вашей базе, читает найденное и только потом отвечает». Это и точнее, и дешевле, и безопаснее (08-gallyutsinatsii-i-nadezhnost).


Зачем нужен RAG

Модель «от производителя» знает то, что было в её обучающих данных, и не знает вашего. RAG решает сразу несколько проблем:

ПроблемаЧто даёт RAG
Модель не знает ваши документыПодтягивает фрагменты из вашей базы
Знания устарелиБазу обновляете вы — без переобучения модели
Нужны источники (аудит)Можно показать, из какого фрагмента взят ответ
Высокий риск галлюцинацийЗаземляет модель в проверенных текстах (08-gallyutsinatsii-i-nadezhnost)
Контекст ограниченДаёт только релевантное, а не весь архив (02-tokens-context-window)

Полный конвейер RAG

RAG — это не «одна функция», а два процесса: разовая индексация (подготовка базы) и постоянный запрос (поиск + генерация).

flowchart TD
    subgraph IDX["🗄 Индексация (один раз + обновления)"]
        D["📄 Документы"] --> CH["✂ Чанкинг<br/>(нарезка на фрагменты)"]
        CH --> EM["🔢 Embedding-модель<br/>(текст → вектор)"]
        EM --> VDB[("🗃 Векторная база<br/>+ текст фрагмента<br/>+ метаданные")]
    end
    subgraph Q["🔍 Запрос (каждый раз)"]
        UQ["❓ Вопрос пользователя"] --> QEM["🔢 Embedding<br/>вопроса"]
        QEM --> RET["🔎 Поиск top-K<br/>похожих фрагментов"]
        VDB --> RET
        RET --> RR["📊 Реранжирование<br/>(уточнение порядка)"]
        RR --> GEN["🧠 LLM генерирует ответ<br/>по найденным фрагментам"]
        GEN --> ANS["✅ Ответ + источники"]
    end

Этап 1. Чанкинг (chunking)

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

  • Слишком мелкий — теряется контекст смысла.
  • Слишком крупный — в модель попадает много шума, дороже, хуже точность.
  • Часто используют 200–800 токенов с перекрытием (overlap), чтобы не разрезать мысль пополам.

Не режьте «по символам»

Умный чанкинг учитывает структуру документа: разделы договора, абзацы, заголовки. Для юридических текстов осмысленная нарезка (по пунктам/статьям) даёт заметный прирост качества поиска.

Этап 2. Embedding (эмбеддинг)

Каждый чанк пропускается через embedding-модель, которая превращает текст в вектор (02-tokens-context-window). Это отдельная, лёгкая и дешёвая модель — не та большая LLM, что генерирует ответ.

Этап 3. Векторная база (vector database)

Векторы вместе с исходным текстом чанка и метаданными (название документа, дата, раздел) складируются в векторной базе, оптимизированной под поиск «близких по смыслу» векторов.

БазаОсобенность
QdrantПопулярная, пишется на Rust, есть open-source и cloud
MilvusЗаточена под масштаб
pgvectorРасширение PostgreSQL — удобно, если БД уже есть
Pinecone / Weaviate / ChromaОблочные и встраиваемые варианты

Почему метаданные важны

Без метаданных поиск вернёт «похожий по смыслу» чанк, но вы не узнаете, из какого он документа и актуален ли. С метаданными можно фильтровать: «ищи только в действующих договорах 2026 года», «только в политике конфиденциальности». Фильтр по метаданным — дешёвый и сильный рычаг точности.

Этап 4. Поиск (retrieval)

Вопрос пользователя тоже превращается в вектор, и база возвращает top-K самых близких по смыслу чанков (K обычно 3–10).

Чистый векторный поиск — не всегда лучшее

Векторный поиск силён в смысле, но слаб в точных терминах: название «Приложение № 14» или номер дела он может не найти. Поэтому в production чаще используют гибридный поиск: векторный (по смыслу) + классический по ключевым словам (BM25) — и объединяют результаты.

Этап 5. Реранжирование (reranking)

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

Этап 6. Генерация

Найденные фрагменты вставляются в промпт, и LLM формулирует ответ с опорой на них. Здесь же работает инструкция «не выдумывай, ссылайся на источник» (07-prompt-engineering, 08-gallyutsinatsii-i-nadezhnost).

RAG vs Fine-tuning vs Длинный контекст

Самый частый вопрос на архитектурных-review. Простое правило:

flowchart TD
    Q{"В чём задача?"}
    Q -->|«Модель не знает наши документы/нормы»| RAG["🔎 RAG<br/>(даёт знания в момент)"]:::good
    Q -->|«Модель не ведёт себя как надо:<br/>стиль, формат, роль»| FT["🏭 Fine-tuning<br/>(или промпт)"]:::good
    Q -->|«Документ небольшой и один,<br/>нужно прочесть целиком»| LC["📏 Длинный контекст<br/>(загрузить целиком)"]:::good
    classDef good fill:#e8f5e9,stroke:#4caf50;

Почему RAG обычно побеждает

  • Знания обновляются без переобучения — просто перетрите базу.
  • Можно показать источник (аудит, доверие).
  • Дешевле, чем держать огромный контекст в каждом запросе (06-stoimost-i-ekonomika). Fine-tuning не «даёт знания» в смысле фактов — он подстраивает поведение. Длинный контекст хорош, но дорог и страдает «потерей середины» (02-tokens-context-window).

Продвинутые варианты

  • Hybrid search — векторный + ключевый (BM25) поиск. Стандарт для production.
  • Reranking — отдельный этап уточнения порядка. Часто даёт +10–20% к качеству.
  • GraphRAG — поверх текста строится граф связей (сущности, отношения); полезно для сложных запросов «кто с кем связан через что». Дороже в индексации.
  • Agentic RAG — поиском управляет агент: сам решает, нужен ли поиск, сколько раундов, в каких источниках; может уточнять запрос. Самый мощный, но и самый дорогой вариант.
  • Multi-vector / parent-child — ищут по мелким чанкам, а в модель отдают более крупный родительский фрагмент (чтобы сохранить контекст).

Где RAG ломается

Типовые провалы

  • Плохой чанкинг — смысл разрезан, поиск находит «не то».
  • Слабая embedding-модель или не подходящая к языку/домену.
  • Нет реранкера — релевантный фрагмент застрял на 5-м месте и не попал в выдачу.
  • Устаревшая база — ответ по старой версии документа.
  • Нет фильтров по метаданным — модель отвечает по черновику вместо действующего.
  • Ошибки не измеряют — без RAG-eval (например, RAGAS) вы не знаете, что система работает плохо, пока не поздно.

Качество RAG — что мерить

МетрикаЧто показывает
Retrieval hit-rate / MRRНашёлся ли нужный фрагмент и насколько высоко
Faithfulness (точность по источнику)Нет ли в ответе выдумок сверх найденного
Answer relevancyОтвет по теме вопроса
Context precision / recallКачество отобранного контекста

RAGAS и аналоги

Существуют фреймворки (RAGAS и подобные), которые автоматически оценивают RAG-систему по этим метрикам, часто с помощью LLM-as-Judge (14-ocenka-kachestva). Не запускайте RAG в production без такой оценки.


📌 Что запомнить

  • RAG = «сначала поиск по вашей базе, потом генерация с опорой на найденное».
  • Конвейер: чанки → эмбеддинги → векторная база → поиск (гибридный) → реранжирование → генерация.
  • Качество держится на: умном чанкинге, подходящей embedding-модели, метаданных, реранкере.
  • RAG даёт знания, fine-tuning — поведение, длинный контекст — для разового чтения.
  • Продвинутые варианты: hybrid search, GraphRAG, Agentic RAG.
  • Не запускать без RAG-eval (RAGAS, LLM-as-Judge).

Дальше: 🤖 Архитектура AI-агентов → — что превращает LLM из «ответчика» в «деятеля».