ESPNWho's on the CFP bubble? Did Week 8 burst the Big 12's two-bid dreams?Bollywood HungamaAli Abbas Zafar wraps up shooting for Ahaan Panday-Sharvari starrer Beparwah; says returning to YRF feels like “coming back home”Daily MaverickWINNING: Anna Trapido is Food Writer of the YearThe Jerusalem PostIsraeli Hollywood star Gal Gadot votes in 26th Israeli Knesset electionsPunchFRSC sends 19,560 number plates to FCT after delay complaintsUN NewsKenya: 20 Ebola contacts released from quarantineInquirerEstrada’s camp refutes Bonoan’s P7-B insertion claim anewThe Straits TimesDinner will never be Over at competitive eater Zermatt Neo’s new restaurantCapital FMFormer Kiambu governor Waititu, co-accused plead for leniency in sentencingZDF heuteAktuelle Pressemitteilungen des ZDFGhaflaRuto Breaks Ground on KSh70 Billion Cement Plant in KituiBBC NewsUK and EU officials to discuss freedom of movement
The Daily Newsstand · Free, Always
Tuesday, October 27, 2026

Как починить RAG

Translate

Привет! Я Катя Пославская, занимаюсь RAG-системами и ИИ-агентами в KTS.

За время работы с RAG я убедилась, что после вдохновляющих результатов прототипирования на фрагменте данных многие компании отказываются от вывода RAG-ассистента в прод. Причины просты: вау-эффект разбивается о реальность, когда мы подключаемся к полной корпоративной базе, большой, постоянно растущей, шумной. Кто-то видел актуальный корпоративный Confluence, в котором каждая статья точно описывает существующий процесс, оперативно выходят новые актуальные статьи, а устаревшее отправляется в архив или удаляется? Вот и я такого Confluence не видела. А что делать, когда у нас много владельцев контента, много источников данных, высокие риски выдачи неверного ответа клиенту?

Я строю RAG-системы для корпоративных заказчиков больше двух лет и успела освоить некоторые техники их «приручения», которые помогают минимизировать проблемы и успешно поддерживать решения в проде. Сегодня мы разберём тонкости настройки ассистента от чанков до генерации, а также лекарства от типичных поломок на проде. 

Сразу дам маленький спойлер про галлюцинации, в которых постоянно упрекают LLM: на практике чаще всего в них виновата НЕ модель.

Оглавление

Классический и агентский RAG

Детально излагать концепцию RAG не буду, на Хабре уже есть простое и подробное объяснение. Если коротко, то это система ограничения LLM, чтобы модель отвечала по внутренней базе знаний компании, а не по тем документам, на которых обучалась. Для этого на вопрос пользователя система находит в базе  фрагменты, максимально близкие к теме запроса, и подкладывает эти фрагменты в контекст LLM.

Классический RAG-пайплайн работает в один проход: пришёл запрос, система один раз сходила в базу, сгенерировала ответ и остановилась. Такой пайплайн просто строить и тестировать, а стоимость эксплуатации у него предсказуемая.

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

Примечание

Тут есть нюанс с терминологией. Строго говоря, агентским пайплайн становится, только когда всем процессом управляет LLM, то есть когда наш пайплайн недетерминирован. Например, мы решили увеличить качество ответов системы для сложных запросов и дополнили классический RAG конвейер шагом по оценке качества промежуточного ответа с помощью маленькой LLM и одним повторным поиском в базе при низком качестве промежуточного ответа. В этом случае пайплайн всё ещё является классическим, а не агентским, поскольку набор, количество и порядок шагов поиска и генерации детерминированы, то есть «зашиты» в системе.

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

На практике хорошо работает гибридный подход с дешёвой моделью-маршрутизатором, которая выбирает, отправить ли запрос в классический или в агентский RAG. Примерно 80% вопросов пользователей простые, их выгодно пускать по классическому пайплайну. Оставшиеся сложные уходят в агентский. Начинать проект сразу с агентского RAG я не советую. Даже когда заранее видно, что простой схемы не хватит, классический пайплайн всё равно понадобится как baseline для сравнения.

Тонкости работы с данными 

Успешная работа RAG-систем в первую очередь зависит от качества данных. Они должны быть актуальными, непротиворечивыми, полными. Однако очень часто сам разработчик мало может помочь с этим, тут нужно время экспертов, которого по опыту никогда не хватает на «генеральную уборку каталога». У нас для этой процедуры есть модуль Data Validator, который служит помощником аналитику: ищет в базе знаний дубликаты, противоречия и предлагает вариант их обработки (объединение, архивация неактуального и прочее). Наше решение является не повсеместным, поэтому зачастую ML-щик вынужден работать с тем, что уже есть. В этом случае, ключевым аспектом работы является корректная обработка данных.

В RAG-системе данные подготавливаются на этапе индексации: она обычно включает чанкинг (разбиение на фрагменты), векторизацию и построение хранилища (например, векторный или графовый индекс).

Индексация

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

Чанкинг

Документы вроде огромной статьи из Confluence или стостраничного PDF для поиска не годятся из-за своих размеров, поэтому их режут на фрагменты, они же чанки. Вариантов нарезки текста на чанки несколько: можно просто делить его на равные по длине куски, можно по структурным блокам (если они есть, как в markdown, например), можно попросить LLM выделить смысловые блоки и резать по границам, которые она определила. Последний подход удорожает индексацию, но на плохо структурированных документах, где вперемешку идут текст, таблицы и скриншоты, LLM-чанкинг даёт хороший прирост качества. Заодно чанки получаются разделёнными по смыслу, и в них не подмешивается лишний контекст.

Размер чанка в токенах зависит от задач RAG-системы. Для базы вопросов и ответов хватает около 200 токенов на чанк, вопрос с ответом целиком помещаются в один фрагмент. Для обычных информативных статей на русском языке я ориентируюсь примерно на 1000 токенов, для плотных юридических документов беру ещё больше.

Длина чанка и тип данных могут быть критичны для успешного поиска. Мне встречался RAG-ассистент, который регулярно выдавал несусветные ответы, хотя модель и остальные параметры были адекватные. Выяснилось, что база была нарезана фрагментами по 100 токенов. Для русского языка это совсем мало, а контент был насыщенный: инструкции с функциями Excel и пояснениями к ним. Нарезка на такие мелкие куски превращала их в бессвязные обрывки формул и фрагментов описаний. При поиске к запросу подтягивалась каша, из которой модель никак не могла собрать содержательный ответ.

Соседние чанки обязательно делают с нахлёстом, обычно около 10% размера, например, 100 токенов при чанке в 1000. Так смысл не рвётся на стыках фрагментов.

Типы индексов

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

Полнотекстовый индекс отлично справляется с поиском по ключевым словам и терминам и строится вокруг частотности слов. Для него чанки превращаются в разреженные векторы (обычно используется алгоритм BM25). 

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

Кроме семантического, полнотекстового и гибридного есть ещё графовый индекс. Для его создания LLM извлекает из документов сущности и отношения между ними, далее формируются связанные группы и смысловые описания к ним и строится граф. Лучше всего графовый поиск работает на multihop-запросах, где ответ приходится собирать из нескольких разрозненных источников. Пример из банковской практики: пользователь спрашивает у RAG-ассистента примерные условия по кредиту для его конкретного случая, но ни одна статья не содержит полного ответа. В этом случае граф поможет модели связать условия из одного документа с особыми обстоятельствами клиента из другого и льготами сотрудника из третьего.

Правда, между собой мы называем графы «путём через Мордор». Их сложнее создавать, дороже поддерживать, и при каждом добавлении документов граф приходится перестраивать. Совет здесь простой: начинайте с гибридного поиска, а к графам переходите, только если при хорошо размеченных данных качество ответов всё равно хромает.

Векторизация 

В семантическом индексе выбор векторизатора/эмбеддера сильно зависит от контура. Там, где разрешён доступ к внешним API, мы используем OpenAI text-embedding-3-large. В закрытых контурах берём BGE-M3, по нашему опыту это лучшая open-source модель и универсальный выбор. Ещё часто применяется E5. Qwen Embedding мы тоже пробовали, но на наших задачах она отработала хуже BGE-M3.

Для полнотекстового поиска вообще не используется векторизатор, BM25 (или другой алгоритм) строит для каждого чанка разрежённый вектор, размерность которого равна размеру словаря, а ненулевые значения – это веса терминов по их важности в документах.

Поиск

Мы рассмотрим самый типовой кейс гибридного поиска, когда поиск совершается сразу по семантическому и полнотекстовому индексам.

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

  2. Затем запрос пользователя трансформируется в плотный вектор (семантический поиск) и в разреженный (поиск по ключевым словам). Естественно используем мы тот же векторизатор или алгоритм, что и при создании индекса. 

  3. Поиск в семантическом индексе обычно ведут по косинусной близости векторов запроса и чанков базы. Для полнотекстового поиска движок проходит по инвертированному индексу, то есть вытаскивает списки чанков, где встречаются термины/ключевые слова и для каждого чанка считает суммарный скор. При гибридном поиске два списка результатов сливаются в один алгоритмом Reciprocal Rank Fusion и передаются дальше по конвейеру, скажем, топ-10 кандидатов..

  4. Следующим этапом часто ставят реранкер (чаще всего cross-encoder), который переупорядочивает чанки из топа, оптимизируя выдачу. Модель-трансформер проходит по списку и для каждой пары «запрос – кандидат» выдаёт скор смысловой релевантности. Фрагменты сортируются по скору и на генерацию отправляются, например, топ‑3–5 самых важных.

Уязвимости поиска Top-N 

  1. Число N фиксировано. При маленьком N, очевидно, проседает охват, но и слишком большое значение N не панацея. Если нужный чанк оказался на позиции N+1, отстав на доли процента от соседа, в контекст он не попадёт. Простым увеличением N мы проблему не решим, так как большое значение N увеличит стоимость и время ответа системы. Кроме того, большее количество чанков будет неизбежно подмешивать и больше шума в контекст, снижая качество ответов.

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

  3. Нет целостного представления базы. На общие вопросы типа «О каких темах ты можешь рассказать?» система не может перечислить больше, чем N тем, так как всей базы она физически не видит. Сильнее всего страдают сложные multi-hop запросы, которые требуют обнаружить неочевидные связи, которых нет в отдельном чанке. 

Генерация

На последнем этапе многое решает промпт. В него явно встраивают найденные чанки, роль, задачу и ограничения, а также правила работы с источниками. Мы, например, часто требуем ссылку на источник после каждого факта. Единого стандарта нет, шаблон всегда подгоняется под конкретную систему, а потом шлифуется и шлифуется. 

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

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

Оценка качества

Научный подход к оценке RAG кажется эффективным, но разбивается о реалии практических кейсов. Например, для оценки качества поиска предлагают рассчитывать Recall@K, т.е. долю случаев, когда нужный чанк попал в топ. Если Recall@10 < 0.7, остальные метрики можно не смотреть. Кроме того, оценивают метрики NDCG и MRR, которые показывают, насколько высоко релевантные документы стоят в выдаче. Для генерации метрик ещё больше, от релевантности и полноты ответа до частоты галлюцинаций и корректности цитат. 

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

В заказной разработке всё немного иначе, потому что у типового заказчика RAG-системы нет ни датасетов, ни представления о метриках. Клиенту надо, «чтобы работало с точностью 95%», – что бы это ни значило :) Кропотливо размеченные по всем правилам датасеты подрядчик не соберет без помощи экспертов заказчика, у которых и так постоянная нагрузка. Ассистента ведь и внедряют, чтобы их разгрузить.

Что делать в такой ситуации? На практике используют LLM-as-a-judge, когда модель-судья оценивает качество ответов системы относительно эталонного ответа. Если сервис в каком-то виде уже функционирует (например, техподдержка, которую осуществляют люди), оптимально взять реальные исторические запросы из текущего сервиса, в тех же формулировках, в каких их задавали пользователи, и ответы сотрудника. Для нового сервиса, по которому нет исторических данных, очень желательно, чтобы заказчик сам предоставил хотя бы 20 примеров вопросов и эталонных ответов к ним для калибровки системы. В противном случае все тестовые данные придётся синтезировать. Оптимально синтезировать хотя бы с какими-то вводными по ожидаемым типовым запросам пользователей (user stories). Дальше эти вопросы необходимо прогнать через систему и полученные ответы отправить эксперту заказчика на корректировку: насколько вопросы адекватны, а ответы корректны. По опыту у специалистов вызывает гораздо меньше сопротивления исправлять черновик, чем писать собственный «эталонный ответ». 

Тестовый набор вопрос – ответ системы – эталонный ответ отправляется LLM-судье, которого просят оценить качество ответа системы по сравнению с эталоном. Модель может работать по бинарной шкале «хорошо/плохо», но я предпочитаю шкалу от 1 до 10, по нашим экспериментам она более информативна и стабильнее воспроизводится от запуска к запуску. Шкалу и условия вы задаёте в промпте LLM-судьи: за что снижать оценку, когда ставить единицу, когда десятку.

Когда система оказывается на проде, её можно мониторить похожим образом. Для этого продолжайте создавать новые датасеты тем же способом: копите вопросы реальных людей, гоняйте их через систему и LLM-судью, валидируйте через экспертов (не все, а случайные 5–10% или самые проблемные), проверяйте ответы системы на отклонения от эталона. И ещё важнее пользоваться теми же эталонными датасетами перед релизом любых изменений. Если вы поменяли парсер таблиц или размер чанка, прогоните систему по датасету и убедитесь, что она не регрессировала.

И напоследок: на пользовательские оценки (ответ хороший/плохой) полагаться не стоит. Люди очень редко ставят лайки/дизлайки ответу и ещё реже пишут что-то содержательное в комментарии, если ответ их не устроил. Единичка без контекста бесполезна, поскольку неясно ошиблась ли система и в чём нужно исправление. Так что CSI в оценке точности RAG-системы в лучшем случае вторичен.

Что ломается

Деградация со временем

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

Чистить базу вручную дорого, и заказчик не будет заниматься этим никогда, поэтому мы собрали свой дата-валидатор под эту задачу. Он ищет в базе дубликаты, близкие документы и противоречия и подсвечивает подозрительные места, а человек решает, что с ними делать. Валидатору можно задавать уровень скепсиса; чем он выше, тем больше потенциальных ошибок он найдёт, и эксперту придётся проверять их все вручную. Но, к примеру, два разных числа в одном шаблонном банковском документе валидатор заметит даже при низком уровне скепсиса. Баланс между нагрузкой на эксперта и потребностью в хирургической точности приходится искать эмпирически.

Ещё качество может упасть, когда у системы меняется аудитория, и новые пользователи начинают задавать новые вопросы. Их поведение сложно спрогнозировать заранее, так что из их вопросов придется просто собирать новые датасеты и тюнить систему уже на них. Можно, конечно, заранее сделать датасеты из предположительных вопросов новых клиентов, но точность такого подхода сомнительна. Если бы вы точно знали, о чём вас спросят, вы бы написали FAQ, а не строили RAG. Так что при смене аудитории качество ответов в любом случае пострадает.

Просто низкое качество

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

  1. Сначала проверьте чанки, которые находятся по запросу. Возможно, в выборку Top-N вообще не попадает нужный факт. Тогда нужно чинить поиск.

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

Поиск первым делом лечат переписыванием запроса, о нём я уже говорила. Ещё помогает разделение баз по доменам: если в компании есть IT, HR и юридический блоки, их можно смело разделять, потому что вопросов на стыке доменов почти не бывает. Вместо одной базы сделайте три, встройте маршрутизатор/классификатор, и по каждой из них система будет отвечать точнее. Заодно это закрывает перекрёстное загрязнение, когда финансовая информация просачивается в ответы на HR-вопросы. Если маршрутизация запросов не помогает, прикрутите фильтрацию по метаданным. В крайнем случае идите через граф. Под чутким присмотром Саурона.

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

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

Заключение

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

Заодно порекомендую статьи своих коллег. Там не про RAG, а про инфраструктуру для моделей и их тестирование. Для работы с ML в закрытом контуре точно пригодится:

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.