§ БЛОГ

Переранжирование в workflow: новая нода Staqflow — правильный фрагмент первым

В Staqflow появился узел «Переранжирование»: он не ищет, а пересортировывает готовую выдачу. Векторный поиск сравнивает два заранее посчитанных вектора и отвечает «про то же самое»; переранжировщик читает запрос и документ в паре и отвечает «это отвечает на вопрос». Семь моделей через OpenRouter плюс свой сервер.

Переранжирование в workflow: новая нода Staqflow — правильный фрагмент первым

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

Фрагмент был найден правильно: он действительно про возврат и действительно про дни. Ошибка не в поиске, а в порядке.

В Staqflow появился узел «Переранжирование». Он не ищет — он пересортировывает то, что нашли до него.

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

Почему векторный поиск ошибается порядком

Векторный поиск кодирует запрос и документ по отдельности: каждый превращается в свой вектор, и сравниваются уже два готовых числа-набора. Это очень быстро — векторы документов посчитаны заранее, — но грубо. Близость векторов означает «про то же самое», а не «отвечает на вопрос».

Переранжировщик устроен иначе: он читает запрос и документ в паре, вместе, одним проходом. Поэтому он замечает то, что вектору не видно: что в одном фрагменте «дни» — это срок возврата товара, а в другом — срок перевода денег.

Расплата — цена. Каждую пару нужно посчитать отдельно, и по миллиону документов так не пройтись. Отсюда место переранжировщика в конвейере: он работает не вместо поиска, а после него, по коротенькому списку кандидатов.

Тот самый пример в числах

На вопросе про возврат разница видна прямо в оценках. Векторный поиск дал неверному фрагменту 0.611, а нужному — 0.595: почти одинаково, и наверх случайно вышел не тот. Переранжировщик оценил их как 0.623 и 0.295 — разрыв стал разительным, и нужный фрагмент встал первым.

Это и есть весь смысл узла: не «найти больше», а «поставить правильный первым».

Где он стоит в процессе

Схема всегда одна и та же:

Запрос → поиск → переранжирование → ответ.

  1. Пользователь задал вопрос.
  2. Векторный поиск или обычный поиск по базе вернул два-три десятка кандидатов — быстро и дёшево.
  3. Узел переранжирования пересортировал их и оставил лучших.
  4. Верхние три-пять фрагментов ушли в языковую модель как контекст для ответа.

Без третьего шага модель получает контекст, в котором на первом месте может лежать что угодно похожее. С ним — ровно то, что отвечает на вопрос.

Как настроить

  1. Добавьте подключение. Провайдер здесь один — OpenRouter, и через него доступны семь переранжировщиков: модели Cohere, Voyage, Qwen и NVIDIA, причём одна из них бесплатная. Отдельно есть свой сервер: TEI и Infinity отвечают на той же ручке, так что локальную модель можно подключить как есть.
  2. Поставьте узел «Переранжирование» и выберите модель. Полегче — дешевле и быстрее, потяжелее — судит точнее.
  3. Задайте запрос. Это главная особенность узла: запрос один на всю пачку элементов, а не свой у каждого. Иначе сравнивать документы между собой было бы нечем.
  4. Укажите поле с текстом. По умолчанию text, но путь можно написать через точку: payload.text. Это не мелочь — векторный поиск возвращает текст внутри payload, и без вложенного пути между поиском и ранжированием пришлось бы ставить лишний узел-раскладчик.
  5. Оставьте лучших. По умолчанию пять: остальные кандидаты отбрасываются, дальше по процессу идут только они.

В параметрах — имя поля для оценки (по умолчанию она кладётся рядом с данными элемента) и таймаут.

Что приходит на выход

Те же элементы, что пришли, — со всеми своими полями, — но в новом порядке и с добавленной оценкой. Ничего не теряется: если к фрагменту был привязан идентификатор документа или ссылка на исходник, они останутся на месте.

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

Как проверить, что он помогает

Переранжирование — редкий случай, когда пользу видно измеримо, без ощущений «вроде лучше».

  1. Соберите десяток настоящих вопросов, на которые ответ в базе точно есть, и для каждого запишите, какой фрагмент правильный.
  2. Прогоните процесс без узла и запишите, на каком месте оказался нужный фрагмент.
  3. Включите переранжирование и прогоните те же вопросы ещё раз.

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

Когда он нужен, а когда нет

Нужен, если:

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

Не нужен, если:

  • база маленькая и ответ находится и так;
  • кандидатов и без него два-три — пересортировать нечего;
  • запрос точный и структурный: артикул, номер заказа, дата. Тут обычный поиск по полю и точнее, и бесплатен.

Сценарии автоматизации

Ответы поддержки по базе знаний

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

Поиск по договорам и регламентам

Юрист спрашивает «что у нас по неустойке за просрочку поставки» → поиск поднимает два десятка похожих пунктов из разных договоров → переранжировщик ставит первыми те, что действительно про неустойку, а не просто про поставку.

Подбор похожих обращений

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

Каталог и подбор товара

Запрос «тихий пылесос для квартиры с животными» → поиск по описаниям → переранжирование по смыслу запроса, а не по совпадению слов «тихий» и «животные» в тексте.

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

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

Сколько это стоит

Переранжировщик считает каждую пару «запрос — документ» отдельно, поэтому цена растёт с числом кандидатов, а не с размером базы. Двадцать кандидатов — двадцать пар; миллион документов в базе на цену не влияет, потому что до ранжировщика они не доезжают.

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

В Staqflow оплачивается только работа процесса — токены за CPU-секунды. Тарифы — на странице цен.

Частые вопросы

Чем переранжирование отличается от векторного поиска?

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

Может ли он заменить поиск?

Нет. Он не умеет искать: ему нужно передать список. По миллиону документов пройтись парами невозможно ни по времени, ни по деньгам.

Какие модели доступны?

Семь через OpenRouter — Cohere, Voyage, Qwen и NVIDIA, одна из них бесплатная. Плюс своя модель на своём сервере: TEI и Infinity говорят на той же ручке.

Сколько кандидатов подавать на вход?

Обычно двадцать-тридцать, оставлять три-пять. Точные числа зависят от того, сколько контекста принимает ваша языковая модель.

Почему запрос один на всю пачку?

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

Текст лежит внутри вложенного поля — что делать?

Ничего: путь пишется через точку, например payload.text. Именно так текст приходит из векторной базы, и раскладывать его отдельным узлом не нужно.

Попробуйте

  1. Создайте аккаунт — карта не нужна.
  2. Добавьте переранжирование в готовый процесс поиска: между поиском и языковой моделью, «оставить лучших» — три.
  3. Или опишите задачу ИИ-клиенту через MCP: «Найди в базе знаний двадцать фрагментов, переранжируй и ответь по трём лучшим».

Остальные узлы, из которых собирается такой процесс, — в каталоге интеграций.