# Embeddings API для семантического поиска

Разбираем, как использовать Embeddings API для семантического поиска: подготовить фрагменты, построить векторный индекс и измерить качество retrieval.

Канонический URL: https://llmtokenapi.ru/blog/embeddings-api-dlya-semanticheskogo-poiska
Опубликовано: 2026-09-02T15:11:36.639Z
Автор: Команда LLMTOKENAPI

Embeddings API для семантического поиска превращает текстовые фрагменты и пользовательский запрос в числовые векторы, после чего система находит близкие по смыслу элементы. В LLMTOKENAPI для этого используется `POST /v1/embeddings`: один ключ, OpenAI-совместимое тело запроса и актуальная embedding-модель из публичного каталога.

## Что именно дают embeddings

Embedding — числовое представление текста. Близкие по смыслу фразы обычно оказываются ближе друг к другу в векторном пространстве, даже если они используют разные слова. Поэтому запрос «как вернуть оплату» может найти фрагмент документа «правила оформления возврата», хотя точного совпадения ключевой фразы нет.

Официальное описание [embedding-моделей OpenAI](https://developers.openai.com/api/docs/models/text-embedding-3-large) также относит такие представления к задачам поиска, кластеризации, рекомендаций и классификации. Важно: embedding не пишет ответ и не проверяет факт. Он помогает выбрать кандидатов, которые затем показывает приложение или передаёт языковой модели.

## Подготовьте документы к индексации

Не отправляйте большой документ одним вектором. Разбейте его на самостоятельные фрагменты, которые сохраняют законченную мысль: абзац инструкции, описание функции, пункт регламента. Вместе с текстом храните metadata — ID документа, URL, заголовок раздела, дату обновления и права доступа.

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

Перед индексацией удалите навигацию, повторяющиеся подписи и технический шум. Иначе ближайшими соседями запроса станут одинаковые меню и футеры, а не полезное содержание.

## Вызовите POST /v1/embeddings

Ключу нужен scope `embeddings:read`. Endpoint принимает строку, массив строк или массивы token ID; для обычного приложения проще отправлять текст. Базовый запрос выглядит так:

```bash
curl https://api.llmtokenapi.ru/v1/embeddings \
  -H "Authorization: Bearer $LLMTOKENAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-small",
    "input": [
      "Возврат оформляется через личный кабинет.",
      "Срок обработки обращения указан в статусе заявки."
    ],
    "encoding_format": "float"
  }'
```

Модель из примера доступна на момент публикации. Перед внедрением проверьте `GET /v1/models`, потому что публичный каталог является источником истины. API возвращает массив векторов и usage по входным токенам; порядок результатов соответствует входам.

Параметр `dimensions` используйте только для модели, которая поддерживает выбранную размерность. Если такой необходимости нет, оставьте значение по умолчанию и храните все векторы коллекции в одном формате.

## Постройте индекс и поиск

Каждому фрагменту сопоставьте полученный вектор и сохраните его в vector database вместе с metadata. При пользовательском запросе выполните тот же вызов embeddings, затем найдите ближайшие векторы по выбранной метрике сходства, например cosine similarity.

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

Практический retrieval обычно включает четыре шага: фильтр доступа по metadata, векторный поиск, удаление дублей и выбор нескольких лучших фрагментов. Порог сходства и число результатов подбирайте на реальных вопросах, а не по одному красивому примеру.

## Совместите семантический и точный поиск

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

Гибридный подход особенно полезен в технической документации. Запрос `insufficient_scope` должен найти точный код, а запрос «ключу не хватает прав» — смысловое объяснение той же ошибки. Оба сигнала можно объединить до финального top-k.

## Не забудьте права доступа и обновления

Фильтруйте документы по организации, проекту и роли до выдачи результатов. Нельзя сначала получить чужие фрагменты, а потом надеяться, что языковая модель их проигнорирует. Metadata-фильтр должен быть частью retrieval-запроса.

При изменении исходного документа пересчитывайте только затронутые фрагменты, но удаляйте устаревшие векторы атомарно. Для этого удобно хранить версию документа и хэш нормализованного текста. Если меняется embedding-модель, создайте новую коллекцию, заполните её и переключите чтение после проверки — так поиск не останется наполовину переиндексированным.

## Оценивайте качество на вопросах пользователей

Соберите небольшой набор запросов с ожидаемыми релевантными фрагментами. Для каждого измеряйте, попал ли правильный документ в top-3 или top-10, и проверяйте случаи, где система уверенно возвращает нерелевантный текст. Отдельно тестируйте опечатки, синонимы, короткие запросы и точные идентификаторы.

Embeddings отвечают только за retrieval. Полный RAG добавляет формирование ответа, цитаты, контроль контекста и оценку генерации — этот процесс разобран в статье [«RAG по документам компании»](/blog/rag-po-dokumentam-kompanii). Начните с измеримого семантического поиска: если нужные фрагменты не находятся, более сложный prompt проблему не исправит.
