12

Продвинутые RAG-паттерны в n8n

Я собрал свой первый RAG-бот по всем канонам. Взял Google Sheets с базой знаний в формате «Вопрос-Ответ», прикрутил Supabase для векторного хранения, а в центре поставил n8n, чтобы связать все это воедино. Запустил.

Первые два ответа — успех. Бот мгновенно находил нужную информацию и давал четкие, релевантные ответы. Я уже предвкушал, как эта штука закроет 80% рутинных вопросов для вымышленного отдела технической поддержки. А на третьем вопросе, чуть более сложном, система поплыла... Он взял кусок из одного документа, кусок из другого и синтезировал уверенный, но абсолютно неверный ответ.

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

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

Почему «простой» RAG не работает

Базовая механика RAG (Retrieval-Augmented Generation) проста и состоит из четырех шагов:

  1. Загрузка: Вы берете свои документы (статьи, тикеты, FAQ) и нарезаете их на небольшие куски (чанки).

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

  3. Поиск: Когда приходит вопрос пользователя, он тоже превращается в вектор. Система ищет в базе данных наиболее близкие по смыслу векторы чанков. Это как Ctrl+F, но по смыслу, а не по буквам.

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

В нашем workflow из n8n это блок «Simple RAG». Цепочка выглядит так: Chat Input → Embeddings → Search in Supabase → Basic LLM Chain.

У этого подхода есть три врожденных дефекта:

  • Семантический разрыв. Пользователь спрашивает: «как починить оплату?». В базе знаний у вас статья называется «Устранение проблем с транзакциями». Для человека это синонимы, но для векторного поиска — это могут быть достаточно далекие друг от друга векторы, и релевантный документ просто не найдется.

  • Сложные вопросы. Запрос «Какие есть тарифы и как перейти на новый?» по сути содержит два вопроса. Простой поиск, скорее всего, найдет информацию либо про тарифы, либо про процесс перехода, но не про то и другое вместе. Ответ будет неполным.

  • Нерелевантный контекст. Иногда поиск находит документ, который лишь косвенно касается темы. Но LLM сказали генерировать ответ на основе этого контекста — он сгенерирует. Получается «вода» или откровенная чушь.

Чтобы это исправить, нам нужно прокачать нашего бота, добавив ему несколько новых «модулей» в его пайплайн. Если вы ещё не успели создать векторную базу в Supabase, можете воспользоваться готовым SQL шаблоном (у n8n есть особые требования к формату векторов внутри базы Supabase).

Четыре апгрейда для нашего RAG-пайплайна в n8n

Я разберу четыре паттерна, которые превращают нашего «ленивого» бота в толкового ассистента.

Query Transformation

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

Решение: Вместо того чтобы сразу отправлять «сырой» запрос пользователя на поиск, мы сначала отдаем его LLM с простой задачей: переформулируй. Мы заставляем LLM поработать «переводчиком» с человеческого на язык, более понятный для векторного поиска. Новый модуль преобразует нечеткий запрос в несколько канонических, точных формулировок.

Цепочка немного меняется:
User Input → LLM Chain (Query Transformation) → Search in Supabase.

Prompt для первой LLM-ноды: «Вы искусственный интеллект, задача которого переформулировать запросы пользователей для улучшения поиска... Перефразируйте его, чтобы он был более точным, подробным...». Так, запрос «оплата не пашет» превратится в «как исправить ошибку при проведении платежа», что с гораздо большей вероятностью найдет нужный документ.

Query Decomposition

Проблема: Пользователь задает не один вопрос, а несколько. Например: «Как мне обновить подписку, какие есть способы оплаты и где найти чек после этого?»

Решение: Учим LLM не отвечать, а декомпозировать. То есть разбивать один сложный вопрос на несколько простых, самодостаточных под-вопросов. А уже потом мы ищем ответы на каждый из них по отдельности и собираем весь найденный контекст вместе для финального ответа.

Это блок «Query Decomposition (RAG)». Пайплайн здесь становится заметно сложнее:
LLM Chain (Query Decomposition) → Split Out → Loop → Aggregate → Basic LLM Chain.

  1. Query Decomposition: Первая LLM-нода получает промпт: «Твоя задача — разбить сложный вопрос на несколько простых... Верни результат в виде строгого JSON-массива строк». На выходе мы получаем массив ["Как обновить подписку?", "Какие есть способы оплаты?", "Где найти чек после оплаты?"].

  2. Split Out и Loop: Мы разбираем этот массив на отдельные элементы и в цикле для каждого под-вопроса выполняем векторный поиск в Supabase.

  3. Aggregate: После цикла мы собираем все найденные чанки из разных документов в один большой кусок контекста.

  4. Basic LLM Chain: И только теперь, собрав всю релевантную информацию по всем частям исходного вопроса, мы отправляем ее в финальную LLM для генерации связного ответа.

Score Filter

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

Решение: Ввести простой, но эффективный контроль качества. Каждый документ, который возвращает векторный поиск, имеет score — числовой показатель его релевантности запросу. Мы можем просто установить порог и отсекать все, что не дотягивает до нужного уровня уверенности.

Это самый простой в реализации, но один из самых важных апгрейдов. Смотрим на блок «... + Score Filter». Сразу после ноды Search in Supabase мы добавляем ноду Filter. В ее настройках мы прописываем простое условие: пропускать дальше только те документы, у которых {{ $json.score }} больше, чем 0.5 (или 0.7 — это значение нужно подбирать экспериментально под вашу базу).

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

Предварительный генератор контекста

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

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

Для этого используется отдельная ветка workflow «Supabase Vector Creates + Context Generator».
Get Data → LLM Chain (Context) → Supabase Vector Store.

  1. Get Data: Берем очередную строку из нашей Google-таблицы.

  2. LLM Chain (Context): Отправляем ее в LLM с промптом вроде: «Дай краткий, лаконичный контекст для этого фрагмента, чтобы улучшить его поиск. Отвечай только контекстом и ничем больше».

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

Подводные камни

Обычно такие подходы дают +10-30% к качеству (цифры на основе моего датасета). Звучит здорово, но за все приходится платить. Эти апгрейды – не бесплатные.

  • Цена и скорость. Каждый дополнительный вызов LLM (для трансформации, декомпозиции, генерации контекста) – это дополнительные центы и секунды задержки. Бот становится умнее, но медленнее и дороже. Простой RAG отвечает за 2-3 секунды. RAG с декомпозицией сложного вопроса может думать и 10, и 15 секунд. Это нужно учитывать.

  • Сложность и хрупкость. Наш красивый линейный workflow превратился в сложный, ветвящийся граф. Появляются новые точки отказа. Например, если в шаге декомпозиции LLM решит добавить к JSON-массиву вежливое «Вот ваш список вопросов:», нода парсинга сломается, и вся цепочка остановится. Тут требуется уже больше отладки и мониторинга.

  • Настройка. Нет никаких «магических» значений. Порог отсечки score, промпты для трансформации, модели для разных задач — все это требует экспериментов и подгонки под вашу конкретную базу знаний и типичные вопросы пользователей. Благо не так давно в n8n появилась новая фича – Evaluation, позволяет легко тестировать ваши AI-цепочки и понимать как изменяется качество ответов. Мои мысли и советы по этой фиче.

Как итог

Создание по-настояшему умного RAG-ассистента – это не про выбор самой «умной» LLM на рынке. Это про построение правильного пайплайна обработки запроса. Простой RAG – подходит для простых и примитивных систем. Если хотите что-то более сложное – нужны доработки и дополнительные модули. Именно они превращают «примитивный» поисковик в ассистента, который действительно пытается понять, что от него хотят.

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

Искусственный интеллект

6.3K постов12.1K подписчика

Правила сообщества

ВНИМАНИЕ! В сообществе запрещена публикация генеративного контента без детального описания промтов и процесса получения публикуемого результата.


Разрешено:


- Делиться вопросами, мыслями, гипотезами, юмором на эту тему.

- Делиться статьями, понятными большинству аудитории Пикабу.

- Делиться опытом создания моделей машинного обучения.

- Рассказывать, как работает та или иная фиговина в анализе данных.

- Век жить, век учиться.


Запрещено:


I) Невостребованный контент

  I.1) Создавать контент, сложный для понимания. Такие посты уйдут в минуса лишь потому, что большинству неинтересно пробрасывать градиенты в каждом тензоре реккурентной сетки с AdaGrad оптимизатором.

  I.2) Создавать контент на "олбанском языке" / нарочно игнорируя правила РЯ даже в шутку. Это ведет к нечитаемости контента.

  I.3) Добавлять посты, которые содержат лишь генеративный контент или нейросетевой Арт без какой-то дополнительной полезной или интересной информации по теме, без промтов или описания методик создания и т.д.


II) Нетематический контент

  II.1) Создавать контент, несвязанный с Data Science, математикой, программированием.

  II.2) Создавать контент, входящий в противоречие существующей базе теорем математики. Например, "Земля плоская" или "Любое действительное число представимо в виде дроби двух целых".

  II.3) Создавать контент, входящий в противоречие с правилами Пикабу.


III) Непотребный контент

  III.1) Эротика, порнография (даже с NSFW).

  III.2) Жесть.


За нарушение I - предупреждение

За нарушение II - предупреждение и перемещение поста в общую ленту

За нарушение III - бан

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества