Эмбеддинги и гибридный поиск
Базовые эмбеддинги и семантический поиск (4 провайдера, хранение векторов, /api/embed/*) описаны на странице «Эмбеддинги (семантический поиск)». Здесь — про то, что достроено поверх: гибридный поиск, сочетающий векторное сходство и обычный SQL-фильтр в одном запросе.
Проблема, которую он решает
/api/embed/search отвечает «строка 42 в таблице articles больше всего похожа на запрос» — но чтобы получить сами данные строки, нужен второй запрос. И никак не скомбинировать «похоже на X» с «где category = 'news'» одним вызовом — приходилось делать это в два прохода.
POST /api/vector/search
Один HTTP-вызов делает всё сразу:
- Векторизует текст запроса (с кэшированием повторных запросов);
- Ищет топ-K по косинусному сходству в системной таблице эмбеддингов;
- Делает
SELECT * FROM <table> WHERE pk IN (...)с опциональным дополнительнымWHERE— и возвращает строки вместе с их similarity-скором.
curl -X POST $URL/api/vector/search -H "X-Token: $TOK" -d '{
"table": "products",
"text": "тёплая зимняя куртка",
"k": 10,
"where": "category = ''outerwear'' AND in_stock = true",
"candidate_multiplier": 3
}'
{
"hits": [
{"pk": "482", "score": 0.91, "row": {"id": 482, "name": "Пуховик зимний", "category": "outerwear"}}
]
}
Важный нюанс: сначала ранжирование, потом фильтр
Пайплайн берёт top-K по сходству, и только потом применяет WHERE — не наоборот. Если запросить k=10 и WHERE отфильтрует 7 из них, в ответе будет 3 строки, а не 10 из более широкой выборки. Для этого есть candidate_multiplier: если ожидаете, что WHERE отсеет примерно половину, поставьте 3 — тогда движок сначала возьмёт top-30 по сходству, а уже затем отфильтрует.
Чего пока нет: векторной функции внутри произвольного SQL (ORDER BY similarity(emb, 'x') в обычном SELECT) — для этого нужна отдельная функция в парсере SQL, это отдельный пункт в планах, не часть текущего гибридного эндпоинта.