Проблема поиска в потоке сообщений

Городские Telegram-чаты представляют собой бесконечный поток данных без четкой структуры. В одной ленте могут одновременно встретиться поиск квартиры, рекламные объявления, курс валют и обсуждение потерянных вещей. Главная сложность здесь — поиск по ключевым словам. Пользователи используют синонимы, разные языки и разные формулировки для одного и того же предмета. Например, запрос «нужен тихий байк» и сообщение «продам скутер» по смыслу близки, но не содержат одинаковых слов.

Другая проблема — семантическая путаница. Запросы «сниму квартиру» и «сдам квартиру» описывают один и тот же объект, но имеют противоположные цели. Если система не сможет их различить, она выдаст пользователю не тот результат.

Два режима поиска: смысл против точности

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

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

Преобразование текста в структурированные данные

Индексировать сырой текст напрямую неэффективно. Перед поиском каждое сообщение превращается в «событие» с набором признаков: кратким резюме, категорией, намерением (intent), временем и предметом обсуждения. Это позволяет системе понимать, что именно происходит в сообщении, не полагаясь только на текст.

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

Разделение спроса и предложения

Одна из самых критичных задач — правильно определить тип сообщения. Существует два основных класса: запрос (request) и предложение (offer). Ошибка в этом месте может привести к тому, что бизнес получит уведомление о конкуренте вместо потенциального клиента. Например, фраза «ищу фотографа» — это запрос, а «снимаю свадьбы» — это предложение услуги.

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

Фильтрация и актуальность данных

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

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

Что это значит

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