Привет, Habr!
Эта статья — первый шаг в серии материалов о технологии RAG. Здесь мы разберёмся, что это вообще такое, зачем она появилась и почему её так часто требуют в вакансиях. К концу статьи у вас должно сложиться целостное понимание, когда RAG действительно нужен, какие архитектуры бывают и где чаще всего возникают ошибки.
В статье мы разберём:
почему вообще появился RAG;
что такое RAG в общем смысле;
основные способы расширения контекста модели;
кому RAG действительно нужен (и кому нет);
как устроен RAG и как работает в принципе;
где и почему RAG чаще всего ломается;
заключение и о чём будет следующая часть серии.
Параллельно с серией статей я веду открытый проект с реализацией RAG-системы, поэтому многие примеры будут опираться на реальный код и практический опыт. С самой реализацией можно ознакомиться здесь.
Не будем растягивать вступление и перейдём ближе к делу. Если по ходу возникнут вопросы или дополнения — жду в комментариях.
Почему вообще появился RAG
Использование больших языковых моделей (LLM) стало массовым, и практически каждый, кто с ними работал, сталкивался с одной и той же проблемой — галлюцинациями.
Пример галлюцинации

Несмотря на то, что ответ кажется хорошим, но если разобраться, то окажется, что Xiaomi CyberOne разработка 2022 года, и сейчас не так актуальна, а у Huawei разработки Atlas вообще не существует.
Галлюцинации LLM
Особенно заметно это на слабых или универсальных моделях, но причина не в «плохом качестве» как таковом. Обычно галлюцинации возникают по двум фундаментальным причинам:
у модели нет необходимой информации, чтобы корректно ответить на вопрос;
модель оптимизирована под генерацию правдоподобного ответа, а не под отказ от ответа.
LLM изначально обучаются на больших, но ограниченных по охвату и актуальности датасетах. Они хорошо отвечают на общие вопросы, но начинают ошибаться, когда речь идёт о:
узких предметных областях;
внутренних регламентах компаний;
конфиденциальной информации;
свежих или постоянно обновляемых данных.
Модель в таких ситуациях не знает, что она не знает. Её задача — продолжить текст максимально правдоподобно, даже если для этого приходится додумывать.
Именно для решения этой проблемы и появился RAG.
Что такое RAG: общее определение
RAG (Retrieval-Augmented Generation) — это подход, при котором большая языковая модель перед генерацией ответа получает дополнительный контекст из внешнего источника знаний: базы данных, документов, логов, API и т.д.
Проще говоря, модель:
сначала ищет релевантную информацию;
затем использует найденные данные при формировании ответа.
Важно: RAG не делает модель умнее. Он делает её более информированной и, как следствие, более надёжной.
На примере
Допустим, нам нужно создать систему, хорошо разбирающуюся в узкой и специфической области — например, в народной медицине: травах, настоях, рецептах, противопоказаниях.
Универсальные LLM что-то об этом знают, но:
знания поверхностны;
источники неявны;
ответы часто обобщённые и неточные.
Здесь есть несколько путей:
Собрать большой датасет и дообучить модель. Это сложный, дорогой и долгий путь: сбор данных, очистка, обучение, поддержка.
Fine-tuning (дообучение модели), может подходить под эту задачу, но имеет свои ограничения, которые мы рассмотрим ниже.
Создать базу знаний и построить умный поиск по ней. Мы собираем документы, структурируем их, настраиваем поиск релевантной информации и передаём найденный контекст в LLM — локальную или через API.
Последний путь и есть RAG.
Модель остаётся универсальной, но при каждом запросе получает конкретные знания, относящиеся именно к нашему вопросу. Это не гарантирует верный ответ, но гарантирует ответ на основе конкретных данных (которые мы загрузили в базу знаний).
Также стоит отметить, что RAG бывает разным по источнику данных:
RAG, основанный на данных, заранее загруженных в собственную базу знаний;
RAG, основанный на данных, получаемых из внешних систем, например, через поиск в интернете.
Второй вариант обычно считается более «грязным»: источники данных не отобраны заранее, информация не очищена и не проверена, а воспроизводимость результата значительно ниже.
Это важно: формально оба варианта — RAG, но инженерно это совершенно разные системы.
Основные способы расширения контекста модели
Прежде чем отвечать на вопрос кому и когда нужен и не нужен RAG важно сказать, какие существуют альтернативные способы расширения контекста модели. Я выделю 4 основных:
Полное обучение модели с нуля
Является самым дорогостоящим по времени и средствам способом. Такой подход оправдан в редких случаях:
есть огромные объёмы данных
нужен полный контроль
бюджет не критичен
На практике же это:
дорого;
долго;
сложно в поддержке;
требует повторного обучения при обновлении данных.
Для большинства прикладных задач это избыточное решение.
2. Fine-tuning (дообучение готовой модели)
Fine-tuning считается одним из универсальных решений, которое исключает большие минусы полного обучения модели с нуля.
Этот подход хорошо работает в ситуациях когда:
данные относительно стабильны;
модель можно дообучать;
важна адаптация модели под конкретную предметную область, а не только поиск информации.
Но я бы выделил 3 больших ограничения данного способа:
fine-tuning становится не практичным, когда данные часто изменяются;
во многих случаях мы не можем вообще использовать дообучение, например при использовании модели по API или если дообучение модели запрещено лицензией;
нельзя обеспечить прозрачность источников, модель не может на них сослаться.
3. Prompt engineering
Самый простой и доступный путь — попытаться «научить» модель через инструкции и примеры прямо в prompt.
Это работает:
для прототипов;
для простых задач;
при небольшом объёме данных.
Но такой подход плохо масштабируется:
есть жёсткие ограничения на размер контекста;
знания не структурированы;
поддержка длинных промптов быстро превращается в хаос.
4. RAG
Вот мы и подошли к способу, который рассматривается в этой статье. RAG разделяет знания и модель. Модель получает знания только тогда, когда они действительно необходимы, и именно те, которые относятся к текущему запросу. Это даёт несколько важных свойств:
данные можно обновлять без переобучения модели;
источники информации находятся под контролем;
ответы можно привязывать к конкретным документам;
система становится воспроизводимой.
Важно понимать: RAG не делает модель «умнее». Он даёт ей актуальные данные, на основе которых формируется ответ на конкретный вопрос.
А есть ли минусы?
Да, есть.
Во-первых, RAG — это уже не просто модель, а полноценная система. Архитектурно она сложнее: появляется несколько этапов, и ошибка на любом из них может привести к тому, что нужные данные просто не будут найдены.
Во-вторых, при использовании RAG запрос не сразу попадает в LLM. Он проходит этапы обработки и поиска контекста, что увеличивает время ответа по сравнению с прямым запросом к модели.
Также важно помнить, что RAG не отменяет ограничений контекстного окна. В модель всё равно нельзя передать «всё сразу», поэтому приходится выбирать, какую информацию считать наиболее важной.
И последний момент — безопасность. Если архитектура продумана неаккуратно, RAG может привести к утечкам данных, так как модель начинает работать с реальным содержимым базы знаний.
Кому RAG действительно нужен (и кому нет)
RAG имеет смысл использовать в тех случаях, когда:
данные специфичны, и используемая LLM не обладает знаниями в данной области, а другие способы адаптации либо неприменимы, либо менее удобны;
важна точность информации и необходимость опираться на конкретные источники, а не на обобщённые знания модели;
требуется явная привязка ответа к документам или данным, на основе которых он был сформирован;
данные часто обновляются, и переобучение модели становится нецелесообразным.
RAG, как правило, не нужен, если:
отсутствуют собственные данные — в этом случае просто нечего использовать как базу знаний;
данных мало, и они без проблем помещаются в prompt;
задача носит творческий характер и не требует строгой фактологической точности;
система используется как ассистент общего назначения;
полное обучение модели или fine-tuning оказываются более удобным и оправданным решением.
Как устроен RAG и как работает в принципе
Рассмотрим внутреннее устройство RAG и путь от запроса пользователя до ответа LLM.
В упрощённом виде RAG — это последовательный пайплайн, состоящий из нескольких неотъемлемых частей.
Ingest
На этом этапе происходит загрузка исходных данных и их предварительная обработка.
Обычно сюда входят:
нормализация текста;
очистка от мусора и артефактов форматирования;
приведение данных к единому виду.
От качества подготовки данных напрямую зависит качество поиска и итогового ответа.
Chunking
После нормализации данные разбиваются на чанки — небольшие фрагменты текста, с которыми дальше работает система.
На практике используются два основных подхода:
разбиение по структурно-логическим блокам
(например, по заголовкам, абзацам или специальным символам);разбиение по фиксированному размеру.
Чаще всего размер чанка подбирается эмпирически и зависит от данных и используемого эмбеддера. В типичных RAG-сценариях это порядка 400–600 символов. Слишком большие чанки размывают контекст, слишком маленькие — теряют смысл.
Также часто используется overlap (перекрытие чанков): часть текста из конца предыдущего чанка добавляется в следующий. Например, 150 символов перекрытия и 450 новых. Это позволяет сохранить связность информации между соседними чанками.
Эмбеддинги
После чанкинга каждый фрагмент текста преобразуется в вектор с помощью эмбеддера. Именно на этом этапе текст становится пригодным для семантического поиска.
На данный момент в русскоязычном сегменте наиболее актуальными считаются:
intfloat/multilingual-e5-base (или large) — универсальный retrieval-эмбеддер, хорошо работающий �� русским языком;
deepvk/USER-bge-m3 — модель, ориентированная на русскую семантику.
Важно, что один и тот же эмбеддер используется и для документов, и для пользовательских запросов, чтобы они находились в одном векторном пространстве и могли корректно сравниваться.
Векторная база данных
Векторная БД используется для хранения эмбеддингов и быстрого поиска ближайших по смыслу чанков.
Выбор конкретного решения зависит от объёма данных, требований к фильтрации и сложности инфраструктуры. На практике чаще всего встречаются:
Chroma — простой вариант для локальных и pet-проектов;
Qdrant — одна из самых сильных open-source ВБД: поддерживает фильтрации, ANN-поиск, стабильный REST/gRPC API, но требует большего внимания к DevOps;
Weaviate — имеет встроенные embedding-пайплайны и GraphQL-интерфейс;
Pinecone — SaaS-решение, удобное в использовании, но завязанное на внешний сервис.
Retrieval
Поиск информации в RAG-системах может быть реализован по-разному.
В самом простом варианте используется семантический retrieval — поиск по векторному сходству между запросом пользователя и чанками документов. Такой подход хорошо работает с переформулировками и схожими по смыслу запросами.
На практике часто используется гибридный retrieval, который сочетает семантический поиск и классический лексический поиск, последний выполняется с использованием Elasticsearch или OpenSearch (также отмечу, что Elasticsearch или OpenSearch могут выполнять и семантический поиск, но они показывают результат ниже чем специализированные БД, о которых было написано выше). Это позволяет учитывать не только смысл, но и точные совпадения по словам, числам, именам и редким терминам. Гибридный подход делает поиск более устойчивым и снижает количество «тихих» промахов.
Важно понимать, что retrieval — не обязательно финальный этап. В продакшен-RAG к нему часто добавляются дополнительные шаги.
Одним из таких шагов является rerank — повторная переоценка найденных чанков с помощью более точной, но более тяжёлой модели. Она позволяет отфильтровать нерелевантные фрагменты и отсортировать результаты по реальной близости к запросу.
Также может применяться компрессия контекста — сжатие или очистка найденных фрагментов перед передачей их в LLM. Это помогает убрать дубликаты, шум и второстепенную информацию, а также уложиться в ограничения контекстного окна.
В зависимости от архитектуры, пайплайн RAG может дополняться и другими этапами: фильтрацией по метаданным, контролем доступа, объединением соседних чанков и так далее. Конкретный набор шагов зависит от требований к точности, скорости и безопасности системы.
Теперь рассмотрим путь от запроса пользователя до ответа модели. В базовом виде этот процесс можно представить следующим образом:

Картинка взята из этой статьи. Хороший материал, рекомендую к ознакомлению.
RAG включает следующие этапы:
Обработка пользовательского запроса
Система получает запрос пользователя и выполняет его предварительную обработку. Конкретные шаги зависят от архитектуры, но в более качественных RAG-системах на этом этапе могут выполняться:
обогащение запроса;
генерация нескольких вариантов формулировки;
декомпозиция запроса на подзапросы;
добавление контекста предыдущих запросов;
генерация гипотетического ответа LLM для улучшения поиска.
Цель этого этапа — сформировать запрос, по которому система сможет максимально точно найти релевантные данные.
2. Векторизация запроса
Далее запрос преобразуется в вектор с помощью эмбеддера для дальнейшего семантического поиска.
3. Поиск по базе знаний (Retrieval)
После получения вектора запроса выполняется поиск по базе знаний. В зависимости от архитектуры, retrieval может быть:
семантическим (по векторному сходству);
лексическим (по ключевым словам) (при чисто лексическом поиске векторная БД не нужна, и структура системы несколько отличается);
гибридным, сочетающим оба подхода.
На этом этапе также может выполняться фильтрация чанков по метаданным: источнику, типу документа, правам доступа и другим ограничениям.
4. Отбор и подготовка контекста
Найденные фрагменты текста формируют предварительный контекст. В продакшен-RAG на этом этапе часто добавляются дополнительные шаги, о которых мы говорили выше.
Цель этого этапа — передать в LLM только действительно полезные данные.
5. Генерация ответа
Подготовленный контекст передаётся в LLM, после чего формируется итоговый ответ. При этом модель может использовать как информацию из переданного контекста, так и общие знания, полученные в процессе обучения.
Однако важно понимать, что именно контекст, полученный на этапах retrieval и отбора, задаёт рамки ответа и определяет, какие факты и детали будут использованы в первую очередь.
Где и почему RAG чаще всего ломается
RAG может сломаться на любом из этапов пайплайна. Ниже — проблемы, с которыми я сталкивался на практике.
Выбор слабого эмбеддера.
Плохой эмбеддер = плохой поиск. Если модель плохо отображает семантику данных в векторном пространстве, retrieval начинает возвращать нерелевантные чанки, и дальше система уже не может это исправить.Неправильный подбор размера чанков.
На одном из этапов я использовал слишком большие чанки. В результате контекст начинал «размываться»: векторы становились менее информативными, а поиск — менее точным. Размер чанка напрямую влияет на качество retrieval и требует подбора под конкретные данные и эмбеддер.Отсутствие гибридного поиска.
Изначально я пробовал реализацию с чисто семантическим поиском, но она быстро показала свои ограничения сразу по нескольким причинам:
данные были специфичными, и даже сильный эмбеддер не всегда корректно с ними справлялся;
семантический поиск плохо работает с короткими запросами, точными терминами, датами и именами.
Добавление лексического слоя и переход к гибридному поиску заметно повысили точность найденного контекста.
Также важна постобработка результатов.
Даже если retrieval работает относительно неплохо, RAG может ломаться на этапе подготовки контекста. Если нет ни фильтрации, ни reranking, ни других механизмов отбора, в модель передаётся слишком много шума, и качество ответа резко падает.
Заключение и о чём будет следующая часть серии
В этой статье я разобрал, что такое RAG как технология, зачем он появился и как в принципе устроен его пайплайн.
В следующих частях серии я буду разбирать отдельные компоненты RAG подробнее. В скором времени планируется статья про ACL (Access Control Lists) в RAG.
Так что следите за моими публикациями, надеюсь они будут для вас полезными, если есть вопросы\замечания по этой статье и не только, то жду вас в комментариях!
