# LM Studio Embeddings API: локальная индексация и проверка поиска

Источник: https://modelium.tech/zhurnal/lm-studio-embeddings-api/

LM Studio предоставляет OpenAI-совместимый endpoint `/v1/embeddings` для загруженной embedding-модели: он возвращает векторы текстов, но не готовый поиск или ответ по документам. Сначала выберите модель, запустите локальный сервер и проверьте форму ответа, затем сравните векторы нескольких вымышленных фрагментов и вопросов. Пример с Nomic предназначен для проверки API: его карточка указывает английский язык, поэтому качество поиска по русским документам нельзя предполагать без отдельного теста.

**Проверено по документации 28 сентября 2026 года.** API LM Studio и карточки Nomic сверены с первоисточниками; у карточек модели закреплены ревизии `0188c9bf` и `e9b67630`. Modelium не запускал сервер, не загружал веса и не измерял качество поиска. Команды ниже — инструкция для вашего стенда, а не отчёт о нашем прогоне. [s1](#src-s1) [s7](#src-s7) [s8](#src-s8)

## Что делает Embeddings API и чего он не делает?

LM Studio документирует OpenAI-совместимый `POST /v1/embeddings`. На вход передаётся текст или массив текстов и идентификатор embedding-модели; в ответе ожидаются числовые векторы. Это не чат-модель, не хранилище документов и не готовая RAG-система: индекс, поиск ближайших фрагментов, контроль доступа к документам и генерацию ответа надо организовать отдельно. [s1](#src-s1) [s4](#src-s4)

Практический маршрут: **документы → фрагменты → embedding-модель → локальный LM Studio → векторы → сравнение с запросом → проверка найденного фрагмента → при необходимости отдельная генерация ответа**. В этом гайде намеренно используется маленький набор вымышленных текстов вместо клиентских данных. Переходите к реальной базе только после проверки релевантности и сетевой изоляции на своём оборудовании. [s1](#src-s1) [s2](#src-s2)

## Как подготовить модель, железо и локальный сервер?

Установите LM Studio и возьмите embedding-модель в доступном для вашего runtime формате. Команда `lms get` позволяет искать и скачивать модели; флаг `--gguf` ограничивает поиск GGUF-файлами. Например, карточка **Nomic Embed Text v1.5 GGUF** описывает файлы для llama.cpp и помечает язык как `en`. Используйте её **для учебного англоязычного теста API**, а не как неподтверждённую рекомендацию для русского документооборота. Наличие файлов GGUF и публикация лицензии Apache-2.0 на карточке не доказывают пригодность каждой конкретной конфигурации LM Studio или качество выдачи; проверьте выбранный файл и применимые условия перед производством. [s6](#src-s6) [s7](#src-s7)

В приложении выберите и загрузите скачанную embedding-модель. REST-метод LM Studio `/api/v1/models/load` допускает `embedding` и возвращает тип загруженной модели; если используете этот метод вместо интерфейса, подставьте **фактический** ID, а не угаданный по имени файла. Не выводите минимум RAM/VRAM из размера GGUF: доступность зависит от файла, runtime, разгрузки слоёв и вашей системы. В этом материале аппаратный порог не измерен. [s4](#src-s4) [s7](#src-s7)

На вкладке Developer включите **Start server** или выполните `lms server start`. По документации локальный адрес по умолчанию — `http://localhost:1234`; не включайте доступ из локальной сети, если он не нужен. Запросите список доступных серверу моделей и запишите в журнал точный ID загруженной embedding-модели. Но `GET /v1/models` при включённой загрузке по требованию может показывать и просто скачанные модели: один список не доказывает, что веса уже в памяти или что данная модель вернёт embedding. [s2](#src-s2) [s3](#src-s3)

lms server startcurl -fsS http://127.0.0.1:1234/v1/models

По умолчанию LM Studio не требует API-токен; в Server Settings можно включить обязательную аутентификацию и выдать токен с нужными правами. Не выставляйте порт наружу только потому, что тест с loopback работает. Если токен включён, передавайте `Authorization: Bearer <ваш-токен>` в запросах ниже; тест без этого заголовка должен быть отвергнут. Первый поиск/загрузка модели может обращаться к сети; loopback входящего API не означает офлайн-режим всей машины. [s5](#src-s5) [s6](#src-s6)

## Как получить и проверить векторы?

Укажите фактический ID из сервера, подставив его вместо значения-заглушки. Для Nomic автор модели требует добавлять `search_document:` к индексируемым текстам и `search_query:` к вопросам. Не отправляйте голые строки и не предполагайте, что API сам добавит префикс: передайте его явно. Образец LM Studio использует локальный `base_url=http://localhost:1234/v1` для OpenAI-клиента. [s1](#src-s1) [s7](#src-s7) [s8](#src-s8)

export LM_EMBED_MODEL='ПОДСТАВЬТЕ_ID_ЗАГРУЖЕННОЙ_EMBEDDING_МОДЕЛИ'curl -fsS http://127.0.0.1:1234/v1/embeddings \  -H 'Content-Type: application/json' \  -d "$(python3 -c 'import json,os; print(json.dumps({"model":os.environ["LM_EMBED_MODEL"],"input":["search_document: The invoice contains a supplier tax ID.","search_document: The team meets on Monday."]}))')"

Убедитесь, что ответ содержит `data` с **двумя** элементами и в каждом `embedding` есть непустой вектор конечных чисел одинаковой размерности. Ошибка типа «модель не поддерживает embeddings» означает, что выбрана не та модель или несовместимый формат/runtime; HTTP 200 без проверки формы ещё не подтверждает пригодность результата. Количество, размерность, точный ID и конфигурацию нужно сохранить вместе с индексом. [s1](#src-s1) [s4](#src-s4)

## Как на своём компьютере проверить ближайший фрагмент?

Составьте три вымышленных англоязычных фрагмента: счёт с налоговым идентификатором, расписание встречи и акт с суммой. До запуска запишите ожидаемый первый фрагмент для двух вопросов: про идентификатор — счёт, про сумму акта — акт. Следующий сценарий отправляет документы и запросы в **одну и ту же** модель, вычисляет косинусную близость и показывает порядок. Это проверка, которую должен выполнить читатель; конкретное ранжирование здесь не измерялось. Префиксы следуют карточке модели. [s1](#src-s1) [s7](#src-s7) [s8](#src-s8)

python3 - <<'PY'import json, math, os, urllib.requestmodel = os.environ['LM_EMBED_MODEL']base = 'http://127.0.0.1:1234/v1/embeddings'docs = [    'The invoice contains a supplier tax ID.',    'The team meets on Monday.',    'The delivery acceptance note contains the total amount.',]questions = [    ('Where is the supplier tax ID?', 0),    ('Which record contains the total amount?', 2),]def embed(texts):    payload = json.dumps({'model': model, 'input': texts}).encode()    req = urllib.request.Request(base, payload, {'Content-Type': 'application/json'})    with urllib.request.urlopen(req, timeout=120) as response:        data = json.load(response)['data']    data = sorted(data, key=lambda item: item['index'])    vectors = [item['embedding'] for item in data]    assert len(vectors) == len(texts) and vectors and len(vectors[0]) > 0    assert all(len(v) == len(vectors[0]) and all(math.isfinite(x) for x in v) for v in vectors)    return vectorsdef cosine(a, b):    na = math.sqrt(sum(x*x for x in a))    nb = math.sqrt(sum(x*x for x in b))    assert na > 0 and nb > 0    return sum(x*y for x, y in zip(a, b)) / (na*nb)dv = embed(['search_document: ' + text for text in docs])qv = embed(['search_query: ' + q for q, _ in questions])for (question, expected), vector in zip(questions, qv):    scores = [cosine(vector, item) for item in dv]    ranking = sorted(range(len(docs)), key=lambda i: scores[i], reverse=True)    print(json.dumps({'question': question, 'expected_first': expected,                      'actual_first': ranking[0], 'ranking': ranking,                      'scores': scores, 'dimensions': len(vector)}))PY

Если ожидаемый фрагмент не оказался первым, не называйте этот опыт удачным: проверьте ID модели, префиксы, порядок `data[*].index`, размерность, текст и разбиение документов. Этот учебный тест не является оценкой качества RAG в бизнесе. Для русских УПД, счетов и актов **не переносите** результат английского примера: карточка Nomic GGUF маркирована `en`. Выберите модель с документированной поддержкой нужного языка и проверенным форматом запуска, разметьте отдельный набор русских запросов и ожидаемых фрагментов, посчитайте recall@k = «число запросов с нужным фрагментом в первых k» / «число размеченных запросов» и разберите ошибки вручную. [s7](#src-s7) [s8](#src-s8)

## Какие ограничения важно сохранить при внедрении?

Все фрагменты индекса и запросы должны проходить через одну согласованную модель, формат префиксов и размерность. При смене модели или предобработки индекс надо пересчитать; иначе сравнение векторов перестанет быть контролируемым экспериментом. API, возвращающий вектор, не доказывает отсутствие исходящих запросов при подготовке модели или безопасность доступа к чужим документам. Для артикула или точного реквизита сравните векторный поиск с [гибридным поиском](/zhurnal/gibridnyy-poisk-rag/): смысловая близость не гарантирует точное посимвольное совпадение. [s1](#src-s1) [s7](#src-s7)

После проверки остановите сервер через интерфейс или `lms server stop`, убедитесь, что `127.0.0.1:1234` больше не отвечает, и сохраните ID/версию модели, формат GGUF, параметры загрузки, входные тексты, размерность, ранжирование и дату прогона. Если нужен другой runtime, сравните отдельный [гайд vLLM Embeddings API](/zhurnal/vllm-embeddings-api/); основной следующий шаг для этого материала — [протокол оценки поиска на собственных документах](/zhurnal/ocenka-kachestva-rag/). [s2](#src-s2) [s4](#src-s4)

## Источники

1. [LM Studio — OpenAI-compatible Embeddings](https://lmstudio.ai/docs/developer/openai-compat/embeddings) — получено 2026-09-28
2. [LM Studio — Local API server](https://lmstudio.ai/docs/developer/core/server) — получено 2026-09-28
3. [LM Studio — OpenAI-compatible List Models](https://lmstudio.ai/docs/developer/openai-compat/models) — получено 2026-09-28
4. [LM Studio — REST Load a model](https://lmstudio.ai/docs/developer/rest/load) — получено 2026-09-28
5. [LM Studio — API Token Authentication](https://lmstudio.ai/docs/developer/core/authentication) — получено 2026-09-28
6. [LM Studio — lms get CLI](https://lmstudio.ai/docs/cli/local-models/get) — получено 2026-09-28
7. [Nomic Embed Text v1.5 GGUF — карточка на закреплённой ревизии](https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF/blob/0188c9bf409793f810680a5a431e7b899c46104c/README.md) — получено 2026-09-28
8. [Nomic Embed Text v1.5 — оригинальная карточка и префиксы](https://huggingface.co/nomic-ai/nomic-embed-text-v1.5/blob/e9b6763023c676ca8431644204f50c2b100d9aab/README.md) — получено 2026-09-28
