ПРОТОК

LLM поверх поиска: как усилить Elasticsearch и контролировать расходы

LLM не обязана заменять Elasticsearch: классический поиск формирует кандидатов, а модель понимает смысл запроса и улучшает ранжирование. Разбираем архитектуру, метрики, пример API и котировки Протока.

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

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

Почему LLM не должна заменять поисковый движок

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

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

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

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

Практическая архитектура из нескольких слоёв

Базовый конвейер может выглядеть так:

  1. Сервис принимает исходный запрос.
  2. Нормализатор исправляет очевидные опечатки и выделяет параметры.
  3. Elasticsearch или другой поисковый индекс формирует набор кандидатов.
  4. Фильтры убирают неподходящие категории, регионы и условия.
  5. LLM анализирует запрос и короткий список кандидатов.
  6. Финальный ранжировщик возвращает пользователю наиболее релевантные варианты.

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

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

Где особенно заметен эффект от модели

Синонимы и разговорные формулировки

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

Неявные ограничения

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

Смешанные запросы

Фраза может содержать несколько задач: «настроить ноутбук и перенести фотографии». Модель способна определить, что это один комплексный сценарий или два направления, которые нужно показать отдельно.

Как не потерять контроль над качеством

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

  • классический поиск без модели;
  • классический поиск с LLM-извлечением параметров;
  • классический поиск с LLM-переранжированием;
  • комбинацию извлечения параметров и переранжирования.

Для измерения подойдут precision@k, recall@k, NDCG@k, доля запросов без результата и среднее время ответа. Отдельно стоит отслеживать стоимость одного поиска: число входных и выходных токенов, долю запросов с повторным использованием кеша, количество обращений к модели.

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

Котировки моделей и выбор режима

Для разных этапов поиска подходят разные модели. На дату публикации в Протоке доступны, например, такие котировки за 1M токенов:

  • GLM-5.2 — 3,66 ₽ за вход и 11,50 ₽ за выход;
  • GPT-5.6 Luna — 5,98 ₽ за вход и 35,88 ₽ за выход;
  • GPT-5.6 Terra — 8,42 ₽ за вход и 50,49 ₽ за выход;
  • GPT-5.6 Sol — 13,60 ₽ за вход и 81,58 ₽ за выход;
  • GLM-5.3 — 20,47 ₽ за вход и 64,34 ₽ за выход.

Для массового извлечения параметров из коротких запросов можно начать с GLM-5.2: у него самая низкая из перечисленных котировок входных и выходных токенов. Для более сложного переранжирования имеет смысл сравнить несколько моделей на одном наборе данных. GPT-5.6 Luna и GPT-5.6 Terra позволяют проверить, как меняется качество при другой конфигурации расходов, а GLM-5.3 и GPT-5.6 Sol — использовать в более требовательных сценариях.

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

Пример запроса через API Протока

OpenAI-совместимый клиент можно подключить, изменив base_url на https://dualchat.pro/v1. Ключ создаётся в кабинете Протока, в разделе «Ключи». В параметре model указывается slug модели из котировок, а не её отображаемое имя.

from openai import OpenAI

client = OpenAI(
    api_key="sk-dc-...",
    base_url="https://dualchat.pro/v1",
)

response = client.chat.completions.create(
    model="glm-5.2",
    temperature=0,
    messages=[
        {
            "role": "system",
            "content": (
                "Выдели намерение и ограничения поискового запроса. "
                "Верни только JSON без пояснений."
            ),
        },
        {
            "role": "user",
            "content": "Нужен репетитор по математике для ОГЭ вечером онлайн",
        },
    ],
)

print(response.choices[0].message.content)

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

Как начать эксперимент без перестройки системы

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

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

Вывод

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

Сравнить модели и актуальные котировки можно в Протоке. Документация API доступна по адресу https://dualchat.pro/docs?utm_source=blog&utm_medium=article&utm_campaign=llm-poverh-poiska-elasticsearch, а полный список моделей и цен — на странице https://dualchat.pro/models?utm_source=blog&utm_medium=article&utm_campaign=llm-poverh-poiska-elasticsearch. Попробуйте подключить один поисковый сценарий, сравните качество и стоимость на своей выборке, а затем масштабируйте только подтверждённые решения.

← все материалы