Внедрил в
PersMarket гибридный поиск. Занятная штука.
Ведь как раньше было?
Скажем, вы ищете вакансию (ну или товар в WB) через текстовую строку
"тестировщик". На сервере БД выполняет SQL-запрос с условием
WHERE description LIKE '%тестировщик%'
Это легко программируется, просто ищется, нативно подхватывается многостраничность.
Но есть в таком подходе минус: вы искали слово "тестировщик" - вы только его и найдете. Это может быть приемлемо, например, для тегов, имен собственных и аббревиатур - "Docker", "DDD", "CRM". Но для обычного текста даст очень грубые результаты.
Я использую
PostgreSQL, в нем есть особый тип поля -
tsvector, для более продвинутого подхода. В него можно собрать векторное представление текстовых данных для
полнотекстового поиска. Это дает сразу кучу ништяков:
▪️разные формы слова ("бежал", "бежит") станут одной лексемой
▪️меньше лишних слов типа предлогов, которые для поиска не важны
▪️специальный индекс, который заметно ускоряет поиск
Выглядит это так:
'python':134A 'rabbitmq':118A 'redi':112A 'review':81A 'saa':15A 'schedul':106A 'servic':145A 'throughput':71A 'авторизац':62A 'архитектур':27A,50A,83A 'асинхрон':54A 'аутентификац':60A 'ваканс':5A 'взаимодейств':55A 'влиян':25A 'внутрен':44A 'высоконагружен':39A,99A
Но и этого уже мало. С появлением нейросетей появилась еще одно интересное развитие темы - поиск по смыслу. Снаружи выглядит как магия ✨
Каждый текст с помощью ИИ превращается в векторное представление, так называемый
embedding. Это многомерный вектор, отражающий смысл текста. В PostgreSQL для этого тоже есть свой тип данных -
vector.
В нем много цифр:
[3.0517578e-05,0.041046143,-0.036010742,-0.022735596,0.018463135,-0.0036640167,0.014862061,0.0010919571,0.00969696,-0.006175995,0.012413025,-0.05609131,0.023406982,-0.006580353,0.041656494,0.032470703,-0.0869751,0.0071144104,0.011909485,0.034179688,0.02305603,0.027496338]
Алгоритм такой:
▪️текст вакансии (название + описание) через ИИ превращаем в эмбеддинг
▪️поисковый запрос тоже через ИИ превращаем в эмбеддинг
▪️сам поиск измеряет косинусное расстояние между этими эмбеддингами и сортирует по "векторной близости"
Генерацию эмбеддингов можно делать через API, например, в том же OpenAI через модель
text-embedding-3-small, либо даже через локальную опенсорсную модель типа
intfloat/multilingual-e5-small, которая, по слухам, даже без GPU работает.
Что еще можно делать с эмбеддингами?
Можно их использовать в RAG-системах. Типичный пример - заставить ИИ-чат-бота давать ответы по базе знаний вашего продукта. Все статьи базы знаний превращаем в эмбеддинги и добавляем из при запросах к ИИ. Модель ищет ответ не где-то в интернете, а конкретно в ваших статьях. Полезно для автоматической поддержки.
Но у поиска по смыслу тоже есть минус - они может пропустить точные совпадения слов, например, аббревиатур.
Поэтому на PersMarket сейчас работает
гибридный поиск по алгоритму
Reciprocal Rank Fusion (
RRF). Такой поиск совмещает две выборки -
семантическую и
смысловую, а результаты ранжирует по их позициям в выборках.
В общем, поиск заиграл новыми красками. Заодно теперь в каждой вакансии есть "похожие вакансии". И по таким же принципам можно будет строить рекомендательную систему для индивидуального подбора. Но это тема отдельной диссертации.
#database #ai #persmarket