Журнал ·
Что такое RAG и почему это не векторная база
RAG — это поиск плюс генерация, а векторная база — только одна деталь поиска. Из чего состоит RAG-пайплайн, где он ломается и как его проверять.
RAG (retrieval-augmented generation) — это когда модель отвечает не по памяти, а по документам, которые система нашла под конкретный вопрос и положила в промпт. Достать нужное, вставить в контекст, ответить по нему со ссылками на источник.
Векторная база в этой схеме — одна деталь поиска. Важная, но не главная. Путать её с RAG целиком — настолько частая ошибка, что в нашей программе она входит в список критических: гейт уровня L4 не сдаётся, пока человек считает, что «RAG = векторная БД», при любых баллах за остальное.
Из чего на самом деле состоит RAG
Если разложить систему на этапы, получится конвейер, где у каждого звена своя причина сломаться:
заранее: документы → парсинг и очистка → чанкинг → индексы на каждый вопрос: вопрос → поиск по индексам → реранкинг → сборка контекста → ответ с цитатами
- Парсинг. PDF с таблицами, сканы, DOCX с колонтитулами. Если таблица превратилась в кашу из чисел, никакой поиск её потом не спасёт.
- Чанкинг. Куски слишком мелкие — теряется смысл, слишком крупные — в контекст уходит мусор вокруг нужного абзаца. Хорошая нарезка учитывает структуру документа: разделы, заголовки, пункты договора.
- Индексация. Здесь и появляется векторный индекс: тексты превращаются в эмбеддинги и укладываются так, чтобы быстро находить ближайшие по смыслу. Рядом обычно живёт и классический словесный индекс, и метаданные: дата, автор, кому документ можно показывать.
- Поиск и переупорядочивание. Сначала быстро набрать кандидатов, потом точнее отсортировать их реранкером.
- Сборка контекста и генерация. Что положить в промпт, в каком порядке, как попросить модель ссылаться на источники и честно говорить «в документах этого нет».
Векторная база закрывает ровно одну строку этого списка.
Где поиск по смыслу промахивается
Эмбеддинги хорошо находят «похожее по смыслу» и плохо — «точно вот это». Спросите систему про артикул, номер приказа или код ошибки, и векторный поиск охотно вернёт документ про соседний артикул: по смыслу они почти одинаковые. Классический поиск по ключевым словам (BM25) такие запросы берёт уверенно, зато не понимает перефразирования.
Поэтому в рабочих системах поиск обычно гибридный: оба способа ищут параллельно, результаты объединяются, а реранкер окончательно расставляет кандидатов по местам. В программе это отдельный модуль на уровне L5, сразу после базового RAG.
Есть и то, чего векторный индекс не делает вообще. Например, права доступа: если сотрудник не должен видеть зарплатную ведомость, фильтровать её нужно до того, как кусок попадёт в контекст модели, а не надеяться, что модель «не скажет».
Ответ неверный — кто виноват: поиск или модель?
Это главный вопрос отладки RAG, и задать его можно только если оценивать этапы раздельно.
Для поиска считают метрики вроде recall@k (попал ли нужный документ в первые k результатов), MRR и nDCG (насколько высоко он оказался). Для генерации — faithfulness: опирается ли ответ на то, что лежит в контексте, или модель дописала от себя.
На практике картина часто такая: модель отвечает уверенно и неправильно, а в контексте нужного фрагмента просто не было. Это не «галлюцинация модели», а провал поиска, и лечится он чанкингом, гибридным поиском или фильтрами, а не сменой модели на более дорогую.
Чтобы это увидеть, нужен эталонный набор: реальные вопросы пользователей и для каждого — документ, где лежит ответ. В нашей программе такой набор собирают ещё до RAG, в проекте семантического поиска на уровне L3, и потом прогоняют после каждого изменения. Улучшение без числа на выходе не засчитывается: «стало лучше» — тоже критическая ошибка.
Документы — это тоже ввод
Всё, что попадает в контекст, модель читает как текст, в том числе инструкции. Если в базу знаний попал документ со строкой «игнорируй предыдущие указания и…», это непрямая prompt injection — атака через данные, а не через вопрос пользователя. Поэтому первая модель угроз в программе появляется именно на уровне RAG, вместе с оценкой: каждый новый источник документов — новая поверхность атаки.
Когда RAG не нужен
RAG отвечает на вопрос «где взять факты». Если факты не нужны, а нужно поменять поведение модели — тон, формат, стиль работы с задачей, — это другая задача: промпт, а иногда дообучение.
Обратная ошибка встречается так же часто: дообучить модель на документах компании, «чтобы она их знала». Дообучение плохо подходит для добавления фактов: их не обновить без нового обучения и не проверить источник ответа. Свежие, приватные и проверяемые факты — работа RAG.
Бывает и так, что документов немного и они целиком помещаются в контекст. Тогда сложный поиск может быть лишним, и честное сравнение вариантов — промпт, RAG, длинный контекст, дообучение, инструменты — записывается в архитектурное решение (ADR) с альтернативами. Как выбирать между ними — в статье «Промпт, RAG или fine-tuning».
Коротко о частых вопросах
Можно ли сделать RAG без векторной базы? Да. Поиск может быть полнотекстовым, по SQL-фильтрам, по API внешней системы. «Retrieval» — это любой способ достать нужное, а не конкретная технология хранения.
Какую векторную базу выбрать? Сначала — что вы будете с ней делать: объём корпуса, нужны ли фильтры по метаданным и права доступа, где она будет работать. Выбор фиксируется в ADR с альтернативами; критерии выбора важнее названия продукта, а продукты меняются быстрее, чем критерии.
С чего начать проверку уже работающего RAG? Возьмите 15–20 реальных вопросов, для каждого запишите, в каком документе ответ, и посмотрите, попадает ли этот документ в выдачу поиска. Если не попадает — проблема до модели, и чинить нужно её.
Если хотите разобраться руками
На уровне L4 строится RAG-система с ответами-цитатами, раздельной оценкой поиска и генерации и мини-моделью угроз, а гейт уровня — починить сломанный RAG с дефектами в чанкинге, поиске и промпте. На L5 к ней добавляются гибридный поиск, реранкинг, фильтрация по доступу и работа с длинным контекстом.
