Перейти к содержимому

Как работает RAG система. Объяснение простыми словами

Представьте, что у вас есть очень умный сотрудник. Он знает много общих вещей: историю, математику, языки, основы программирования. Но он никогда не работал именно в вашей компании. Он не знает ваших клиентов, не читал ваши договоры, не помнит решения, которые вы принимали на прошлой неделе.

Если вы спросите его “Какая скидка положена клиенту Иванову по нашему договору номер 47?”, он не ответит. Не потому что он глупый, а потому что у него нет доступа к вашим документам.

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

Интерактивная схема

Как работает RAG система

Шесть этапов от вопроса пользователя до ответа на основе ваших документов

01 / 06
01 Вопрос пользователя

Пользователь задаёт вопрос на естественном языке. Система пока не знает, где искать ответ.

Пример «Могу ли я вернуть кофеварку, купленную позавчера?»
Векторная база
найдено отобрано
Ожидание запроса
Векторная база содержит чанки документов. Цветом отмечены найденные и отобранные фрагменты.

Векторная база: как компьютер понимает смысл

Заголовок раздела «Векторная база: как компьютер понимает смысл»

Обычный поиск по словам устроен примитивно. Если вы ищете “автомобиль”, он найдёт документы со словом “автомобиль”. Но не найдёт документы, где написано “машина” или “транспортное средство”. Хотя для человека это одно и то же.

Ещё хуже с длинными запросами. Если клиент спрашивает “Что делать, если посылка не пришла?”, обычный поиск будет искать документы со всеми этими словами сразу. А в инструкции, которая ему нужна, написано “Порядок действий при недоставке отправления”. Ни одного общего слова. Поиск ничего не найдёт.

Векторная база работает иначе. Она не ищет совпадения слов, она ищет совпадения смысла.

Чтобы понять, как это устроено, представьте карту города. Каждое здание на карте имеет координаты: широту и долготу. Зная координаты двух зданий, можно посчитать, насколько они близки друг к другу.

С текстом векторная база делает то же самое. Каждое предложение или абзац она превращает в набор чисел (вектор). Эти числа это как бы координаты текста в пространстве смыслов. Только координат не две, а несколько сотен или даже тысяч.

Тексты с похожим смыслом получают близкие координаты. “Автомобиль сломался” и “машина не заводится” окажутся почти в одной точке, хотя слова разные. А “автомобиль сломался” и “автомобиль красивого цвета” окажутся далеко друг от друга, хотя слово “автомобиль” есть в обоих.

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

Допустим, в вашей базе есть три фрагмента:

  1. “Возврат товара возможен в течение 14 дней с момента покупки”
  2. “Расписание работы магазина: с 9 до 21 без выходных”
  3. “Стоимость доставки рассчитывается исходя из веса и расстояния” Клиент спрашивает: “Могу ли я вернуть кофеварку, купленную позавчера?”

Обычный поиск не найдёт ничего, потому что слов “кофеварка” и “позавчера” в базе нет. А векторный поиск спокойно найдёт первый фрагмент, потому что смысл вопроса и смысл фрагмента совпадают.

Модель эмбеддингов: переводчик смысла в числа

Заголовок раздела «Модель эмбеддингов: переводчик смысла в числа»

То, что превращает текст в вектор, называется моделью эмбеддингов. Это отдельная нейросеть, обученная понимать смысл текста.

И вот тут начинаются нюансы, которые часто недооценивают.

Большинство популярных моделей эмбеддингов обучались в основном на английских текстах из интернета. С обычным русским языком они справляются неплохо, но как только начинается узкая тематика, качество падает.

Простой пример. Слово “контрагент” в юридическом контексте имеет совершенно конкретное значение. Слова “уступка” и “цессия” в юриспруденции означают одно и то же. В медицине “ОРВИ” и “острое респираторное вирусное заболевание” это синонимы. А “тромб” и “тромбоз” нет, это разные понятия.

Универсальная модель этих тонкостей может не знать. И тогда поиск начинает промахиваться: на запрос про цессию находит документы про продажу машины, потому что в обычном языке “уступить” означает именно это.

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

Почему нельзя загрузить документ целиком

Заголовок раздела «Почему нельзя загрузить документ целиком»

Векторная база работает не с целыми документами, а с их фрагментами. Эти фрагменты называются чанками (chunks, куски).

Возникает вопрос: зачем резать? Почему бы не загружать документы целиком?

Причин несколько. Во-первых, у моделей эмбеддингов есть ограничение на размер текста, который они могут обработать за один раз. Во-вторых, чем больше текста, тем более “размытым” получается вектор. Если в одном куске и про возврат товара, и про доставку, и про график работы, то его смысл усреднится, и поиск по любому из этих вопросов будет работать плохо.

Представьте, что вы ищете книгу про садоводство в библиотеке, где все книги склеены в одну толстенную энциклопедию. Найти что то конкретное практически невозможно. Поэтому документы режут.

Размер чанка это компромисс. Слишком маленькие куски теряют контекст: фраза “Это запрещено по пункту 3.2” в отрыве от документа бесполезна. Слишком большие куски размывают смысл и плохо ищутся.

Обычно чанки делают размером от 200 до 1000 слов. Но цифра это полдела. Важнее то, как именно резать.

Самый простой способ: резать по фиксированному количеству символов. Берём 500 символов, режем, берём следующие 500. Этот способ ужасно работает, потому что разрезает предложения и мысли посередине. Чанк может закончиться на “согласно пункту” и продолжиться в следующем чанке словами “8.3 настоящего договора”. Ни один из них по отдельности не имеет смысла.

Способ получше: резать по предложениям и абзацам. Граница чанка обязательно совпадает с концом предложения, а лучше абзаца. Это намного лучше, но всё равно случаются неудачные разрывы.

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

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

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

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

Объём контекста: сколько информации видит модель за раз

Заголовок раздела «Объём контекста: сколько информации видит модель за раз»

Когда умный сотрудник получает задание ответить на вопрос, ему передают вопрос и найденные фрагменты документов. Всё это вместе и есть контекст. Объём контекста это сколько текста модель может “видеть” одновременно.

Современные модели могут обрабатывать огромные объёмы. Сотни тысяч слов за раз, это сравнимо с толстой книгой. Может показаться, что это решает все проблемы: можно просто загружать в модель всю базу знаний целиком и не возиться с векторным поиском.

На практике так делать нельзя по нескольким причинам.

Первая причина это деньги. За каждый запрос в LLM платят пропорционально объёму текста. Если в каждый запрос загружать всю базу из 10 000 страниц, каждый ответ клиенту будет стоить как обед в ресторане. Это нежизнеспособно.

Вторая причина это скорость. Чем больше текста модель должна “прочитать”, тем дольше она думает. Ответ на вопрос будет приходить не за секунды, а за минуты.

Третья причина самая интересная. Модели хуже работают с длинным контекстом. Этот эффект называется “lost in the middle” (потеряно в середине). Если важная информация находится в середине большого объёма текста, модель часто её не замечает. Она хорошо помнит начало и конец, но середина “проваливается”.

Поэтому правильный подход не “дать модели больше текста”, а “дать модели меньше текста, но именно тот, который нужен”. Это и есть задача RAG системы: найти и подать на стол только релевантные фрагменты.

Векторный поиск это мощно, но не волшебно. У него есть свои слабости, о которых важно знать.

Векторный поиск ищет по смыслу, и иногда это работает против вас. Если клиент ищет “артикул XJ-447-B”, векторный поиск может вернуть документы про другие артикулы, потому что они “похожи по смыслу”. А нужен именно этот, точное совпадение.

То же самое с именами, кодами, датами, юридическими номерами. Векторы плохо различают “договор 47” и “договор 48”, потому что смысл слов почти одинаков.

Если в базе написано “процедура возврата товара”, а клиент пишет на жаргоне “как мне отыграть назад”, векторный поиск может не справиться. Особенно если модель эмбеддингов плохо знает разговорный язык.

Эти слабости лечатся комбинированием двух подходов. Параллельно с векторным поиском работает классический поиск по словам (его называют BM25 или полнотекстовый). Векторный находит по смыслу, классический по точным словам. Результаты обоих объединяются.

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

Допустим, поиск нашёл 20 потенциально подходящих фрагментов. Какие из них действительно нужны для ответа на вопрос? Передавать модели все 20 это много текста, дорого и плохо для качества (помните про “lost in the middle”?).

Здесь подключается реранкинг. Это отдельная модель, которая берёт вопрос и каждый из найденных фрагментов и оценивает, насколько фрагмент действительно подходит. По результатам она пересортировывает кандидатов так, чтобы самые релевантные оказались сверху. Дальше в LLM передают, например, только топ 5.

Аналогия из жизни. Когда вы ищете в интернете, поисковая система сначала находит тысячи страниц по вашему запросу, а потом сортирует их так, чтобы самые полезные оказались на первой странице. Реранкер делает то же самое для RAG системы.

Это один из самых выгодных способов улучшить качество ответов. Реранкеры относительно дешёвы и часто дают заметный прирост точности.

Пользовательские вопросы редко бывают идеально сформулированными. Они короткие, обрывочные, с местоимениями, с опечатками. “А этот тоже так можно?” Что значит “этот”? Что значит “так”?

Хорошая RAG система не работает с исходным вопросом напрямую. Она его сначала обрабатывает.

Самый простой приём: переписать вопрос с учётом контекста разговора. Если до этого обсуждался возврат стиральной машины, а пользователь спросил “А этот тоже так можно?”, система превращает это в “Можно ли вернуть стиральную машину?” и уже с этим вопросом идёт в поиск.

Более сложные приёмы: разбить сложный вопрос на несколько простых, поискать по каждому отдельно. Или сгенерировать “гипотетический идеальный ответ” и искать в базе документы, похожие на него (подход называется HyDE). Парадоксально, но иногда поиск по придуманному ответу работает лучше, чем по вопросу, потому что ответ ближе по форме к тому, что лежит в базе.

Метаданные и разметка: паспорт каждого фрагмента

Заголовок раздела «Метаданные и разметка: паспорт каждого фрагмента»

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

Что обычно хранят: из какого документа взят фрагмент, дата документа, автор, тип (договор, инструкция, политика), раздел, версия, теги, права доступа.

Зачем это нужно? Чтобы можно было фильтровать поиск. Клиент спрашивает “Какие условия по договору 2024 года?” Без метаданных система может найти и условия из договора 2019 года, и потом всё это перемешать в ответе. С метаданными она ограничит поиск только документами 2024 года.

Хорошая разметка это работа, которая делается до запуска системы и часто требует ручного труда. Кто то должен пройтись по документам, понять их структуру, проставить теги, разделить по типам.

В небольших проектах это можно делать вручную. В больших используют автоматическую разметку нейросетями, но всё равно с проверкой. Качество разметки прямо влияет на качество системы.

Простой пример полезной разметки. У вас в базе 500 договоров. У каждого есть тип (поставка, услуги, аренда), стороны, дата, сумма, статус (действующий, расторгнут). Если всё это размечено и хранится как метаданные, можно делать запросы вида “Покажи условия оплаты по действующим договорам поставки на сумму больше 1 миллиона”. Без разметки такой запрос невозможен.

Векторный поиск находит отдельные куски текста. Но в реальных данных всё связано. Договор ссылается на приложение. Приложение упоминает контрагента. У контрагента есть история взаимодействий. Эти связи между объектами часто содержат ключевую информацию.

Простой пример. Клиент спрашивает: “Какие у нас риски по проекту X?” Чтобы ответить, нужно знать, кто участники проекта, какие у них обязательства, какие были проблемы в прошлых проектах с этими же участниками. Это связи между сущностями, и обычный векторный поиск их не видит.

Граф знаний это представление данных в виде сети. Объекты (люди, компании, договоры, продукты) это узлы. Связи между ними это рёбра. Граф позволяет отвечать на вопросы вида “Найди всех клиентов, у которых были просрочки, и которые сейчас закупают у нас новые услуги”.

Связка векторной базы с графом знаний называется GraphRAG. Векторная база отвечает на вопросы по содержанию текстов. Граф отвечает на вопросы по структуре отношений. Вместе они дают принципиально другой уровень понимания.

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

LLM иногда выдумывают. Это называется галлюцинациями. Модель может уверенно заявить, что в договоре есть пункт, которого там на самом деле нет. Или придумать сумму, которой не было в документах.

Происходит это потому, что модель в первую очередь языковая. Её задача порождать связный, правдоподобно звучащий текст. Если в найденных фрагментах нет точного ответа, модель может “достроить” его из общих знаний или просто выдумать.

В консьюмерских чат ботах с этим мирятся. В корпоративной системе галлюцинация может стоить дорого: клиенту пообещали скидку, которой нет, контрагенту назвали условия, которых нет в договоре.

Несколько приёмов работают вместе.

Первое: правильная инструкция модели. В системном промпте чётко говорится: “Отвечай только на основе предоставленных фрагментов. Если в них нет ответа, скажи ‘не знаю’.” Это не панацея, но снижает риск.

Второе: цитирование. Система не просто даёт ответ, а указывает, из какого документа и какого фрагмента взята каждая часть ответа. Это позволяет проверить достоверность и сразу видно, если модель сослалась на пустоту.

Третье: повторная проверка. После того как модель сформулировала ответ, его прогоняют через ещё один вызов модели с вопросом “Этот ответ полностью подтверждается приведёнными источниками?” Если нет, ответ либо переформулируют, либо отклоняют.

Четвёртое: оценка уверенности. Система может явно говорить пользователю: “Я нашёл прямой ответ в документе X” или “Я не уверен, но возможно ответ такой…”. Это намного честнее, чем уверенно врать.

Метрики качества: без них развивать систему невозможно

Заголовок раздела «Метрики качества: без них развивать систему невозможно»

Когда RAG систему запускают, она работает на одних вопросах хорошо, на других плохо. Без замеров улучшения превращаются в гадание: что то поменяли, кажется стало лучше, или нет, или хуже на других вопросах?

Поэтому нужны метрики и эталонные наборы вопросов.

Несколько ключевых показателей.

Recall (полнота поиска): из всех документов, где есть ответ на вопрос, сколько процентов нашёл поиск? Если 100, значит не упустили ничего. Если 60, значит почти половину нужных документов поиск не вернул.

Precision (точность поиска): из тех документов, что вернул поиск, сколько реально релевантных? Если 100, значит мусора в результатах нет.

Faithfulness (верность источникам): насколько ответ модели соответствует тому, что было в найденных документах? Если модель выдумала или исказила, метрика падает.

Answer relevancy (релевантность ответа): отвечает ли модель именно на заданный вопрос, или уходит в сторону?

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

Это постоянный процесс. RAG система это не “сделал и забыл”, это живой продукт, который требует мониторинга и улучшений.

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

В RAG системе это значит, что нужны процессы для:

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

Обновления существующих. Если документ изменился, старые чанки нужно удалить из базы, новые добавить. Иначе система будет давать ответы по устаревшим версиям.

Удаления устаревших. Документы с истекшим сроком действия должны или удаляться, или помечаться как неактуальные.

Версионирования. Иногда нужна история: “что было написано в политике на январь 2024?” Это требует хранения версий.

Без этих процессов база начинает быстро деградировать. Через полгода после запуска система отвечает по документам, которых уже нет, и ничего не знает про новые. Поэтому процесс обновления это часть проекта, его нужно проектировать сразу.

Если в системе хранятся корпоративные документы, разные люди должны видеть разное. Бухгалтер не должен видеть кадровые документы. Сотрудник одного отдела не должен видеть переписку другого. Внешний клиент не должен видеть внутренние инструкции.

В RAG системе это решается на уровне метаданных. У каждого чанка хранится информация о правах доступа. При поиске система фильтрует результаты в зависимости от того, кто задаёт вопрос.

Если этого не сделать, система превращается в инструмент утечек: достаточно правильно сформулировать вопрос, и можно вытащить любые данные. Поэтому контроль доступа это не “потом докрутим”, это часть архитектуры с самого начала.

Каждый ответ RAG системы стоит денег. Конкретно:

Эмбеддинг запроса: превратить вопрос в вектор. Дёшево.

Поиск в базе: технически почти бесплатно, но база стоит денег на хранении.

Реранкинг: запуск отдельной модели на нескольких десятках кандидатов. Недорого, но не бесплатно.

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

При тысячах запросов в день суммы становятся ощутимыми. Поэтому стоимость это инженерный параметр, его важно отслеживать.

Время от вопроса до ответа складывается из тех же этапов. Эмбеддинг быстрый. Поиск быстрый. Реранкинг занимает доли секунды. А вот генерация может занять от 2 до 30 секунд в зависимости от модели и размера ответа.

Если система должна отвечать “мгновенно” (в чате с клиентом), это накладывает ограничения. Возможно, придётся использовать модель попроще и побыстрее, или применять стриминг ответа.

Качество, скорость, стоимость. Можно оптимизировать любые два из трёх, но не все три сразу. Это разговор, который полезно вести с заказчиком на старте: что важнее?

Если важна скорость и стоимость, придётся жертвовать качеством (модель попроще, меньше этапов).

Если важно качество и скорость, придётся платить (топовая модель, мощная инфраструктура).

Если важно качество и стоимость, придётся терпеть задержки (можно использовать более дешёвые модели, но больше этапов и проверок).

RAG это не одна технология, а связка из десятка компонентов, каждый из которых можно сделать хорошо или плохо.

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

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

Когда говорят “сделать чат бота по нашим документам за неделю”, обычно имеют в виду самую примитивную версию: загрузили документы в векторную базу, прикрутили модель. Такая версия будет работать процентов на 40 от потенциала. Для демонстрации сойдёт, для боевого применения нет.

Хорошая RAG система это результат итераций, измерений, настройки каждого компонента под конкретный домен. Это инженерная работа, которая окупается, если данные действительно ценные, а вопросы пользователей действительно важные.

Главная мысль, которую полезно держать в голове: качество финальных ответов это произведение качеств всех этапов. Если поиск работает на 80%, реранкинг на 80%, генерация на 80%, итоговое качество получается около 50%. Чтобы система отвечала хорошо, каждый этап должен работать хорошо. Поэтому и внимания каждый этап заслуживает.

Калькулятор

Сколько стоит обработка запроса

Стоимость в условных единицах. Покрутите настройки и оцените, насколько широк разброс между минимальной и максимальной конфигурацией

0.00 у.е. за запрос
0 у.е. за 1000 запросов
×1
от минимальной
Усл. ед. / 1000 запросов
Лёгкая Средняя Мощная
500слов
5
Реранкинг Доп. этап отбора, повышает качество и стоимость
Цены показаны в условных единицах и подобраны для иллюстрации разброса. Реальные ценники у провайдеров моделей меняются часто и зависят от объёма, контракта и валюты, важен не абсолют, а сам масштаб разницы между конфигурациями.