Семантический поиск
Поля автоэмбеддинга, гибридное ранжирование через alpha и случаи, когда лучше явный векторный запрос.
Поиск по ключевым словам находит документы, где встречаются те же токены. Семантический поиск находит документы с тем же смыслом: «сколько стоит pro» совпадает со страницей «Тарифы». AACSearch поддерживает оба подхода в одном индексе, и один запрос может их смешивать.
Два способа получить вектор
| Подход | Кто считает вектор | Когда использовать |
|---|---|---|
| Автоэмбеддинг | Движок, по указанным вами полям | Нужен семантический поиск без собственного конвейера эмбеддингов |
| Явные векторы | Вы, до индексации | Эмбеддинги уже есть или нужна модель, недоступная узлу |
Обоим нужно поле float[]. Разница в том, кто его заполняет.
Поле автоэмбеддинга
Объявите векторное поле с блоком embed при создании индекса:
{
"name": "Documentation",
"slug": "documentation",
"fields": [
{
"name": "embedding",
"type": "float[]",
"embed": {
"from": ["title", "content"],
"model": "openai/text-embedding-3-small"
},
"optional": true
}
]
}from принимает от 1 до 4 исходных полей. Модель должна быть доступна поисковому узлу. Для стандартных моделей OpenAI без собственного URL может использоваться управляемая авторизация платформы. Пользовательский адрес получает только явно заданные учётные данные заказчика. Встроенные модели и другие провайдеры не получают серверный ключ OpenAI.
Ключи провайдеров и учётные данные в URL хранятся в зашифрованном виде и скрываются в ответах со схемами. Старые открытые значения остаются читаемыми для совместимости; команда ротации шифрует их. Изменение модели, исходных полей, адреса или ключа требует перестроения индекса.
Платформа проверяет два правила: поле должно быть float[] и не может быть объявлено дважды — нельзя указать embedding и в fields, и в settings.vector.
Документы отправляются без вектора. Движок считает эмбеддинг по title и content во время индексации:
curl -sS -X POST "$AAC_API/indexes/documentation/documents" \
-H "Authorization: Bearer $AAC_KEY" \
-H "Content-Type: application/json" \
-d '{
"documents": [
{ "external_id": "pricing", "title": "Тарифы", "content": "Pro стоит 29 USD в месяц и включает 500 000 поисков." }
],
"action": "upsert"
}'Если позже изменить поля from или модель, потребуется переиндексация: эмбеддинги считаются в момент записи.
Гибридный поиск с alpha
curl -sS -G "$AAC_API/indexes/documentation/search" \
-H "Authorization: Bearer $AAC_KEY" \
--data-urlencode "q=что входит в тариф pro" \
--data-urlencode "semantic=true" \
--data-urlencode "alpha=0.6" \
--data-urlencode "per_page=5"Что делает платформа при semantic=true:
- Ищет поле автоэмбеддинга у индекса. Не нашла —
400 INVALID_QUERYс сообщениемIndex "…" has no auto-embedding field; add one in the schema to use semantic search. - Добавляет поле эмбеддинга в
query_by. - Принудительно включает
prefix=false, потому что удалённый эмбеддер не умеет искать по префиксу. - Добавляет
vector_query=<field>:([], k:<per_page>, alpha:<alpha>)— пустой вектор означает, что движок сам построит эмбеддинг текста запроса, аkравен размеру страницы (не более 250).
alpha задаёт пропорцию: 0 — только ключевые слова, 1 — только вектор, значение по умолчанию 0.5 — равная смесь. Начинайте с 0.5 и повышайте, когда пользователи формулируют вопросы, а не ключевые слова; понижайте, когда должны побеждать точные термины (артикулы, коды ошибок).
{
"index": "documentation",
"query": "что входит в тариф pro",
"language": "ru",
"found": 3,
"out_of": 137,
"hits": [
{
"id": "pricing",
"score": 6890,
"document": { "title": "Тарифы", "external_id": "pricing" },
"highlights": []
}
],
"request_id": "req_6a8c0e2b4d6f8a0c2e4b6d8f"
}У гибридных результатов часто нет подсветки: у векторного совпадения нет токена, который можно отметить. При semantic=true рендерите document.title и сохранённый фрагмент, а не полагайтесь на highlights.
Явные векторы
Если вы считаете эмбеддинги сами, объявите размерность и метрику вместо блока embed:
{
"fields": [
{
"name": "embedding",
"type": "float[]",
"numDim": 1536,
"vecDist": "cosine",
"optional": true
}
]
}Затем передавайте embedding в каждом документе и ищите по вектору:
curl -sS -G "$AAC_API/indexes/documentation/search" \
-H "Authorization: Bearer $AAC_KEY" \
--data-urlencode "q=тариф pro" \
--data-urlencode "vector_query=embedding:([0.0123,-0.0441,0.0872], k:10, alpha:0.5)" \
--data-urlencode "per_page=10"vector_query должен соответствовать виду field:([numbers], k:…, alpha:…); параметры k-NN проверяются до обращения к движку, а некорректное выражение даёт 400 INVALID_QUERY с сообщением vector_query must look like embedding:([0.1,0.2], k:10, alpha:0.6).
numDim принимает 1–4096, vecDist — cosine (по умолчанию), ip или l2.
Ограничения тарифов
| Возможность | Флаг тарифа | Комментарий |
|---|---|---|
semantic=true | hybridSearch | Недоступно на Free |
vector_query | vectorSearch | Недоступно на Free |
| Автоэмбеддинг при индексации | движок ≥ 30 | Проверьте GET /capabilities → features.autoEmbedding |
Запрос, использующий функцию, которой нет в тарифе, падает, а не деградирует молча: набор результатов только по ключевым словам в ответ на семантический запрос выглядит как ошибка релевантности.
Практические советы
- Коротко индексируйте, коротко ищите. Автоэмбеддинг усредняет поля
from; полеcontentна 200 КБ размывает вектор. Лучше отдельное полеsummaryна одно-два предложения. - Ключевые слова — для точности. Держите
alphaниже 1, если в корпусе есть артикулы и названия. - Переиндексируйте после смены модели. Старые документы останутся со старыми векторами, а смесь двух пространств эмбеддингов даёт бессмысленный ранжинг.
- Измеряйте долю пустых выдач.
/analytics/overviewпоказывает её до и после, а/analytics/experimentsсравнивает два профиля на одном и том же трафике. - Фасеты продолжают работать. Фильтры и фасеты применяются к набору кандидатов до ранжирования, поэтому гибридный поиск не ломает категорийный обзор.
Ключи провайдера и секреты в его URL в схемах и планах миграций показываются как ***. Сохранение маски для прежнего провайдера и адреса сохраняет учётные данные. При смене провайдера или адреса введите их заново. Изменение другого поля не должно требовать копирования ключа из настроек.