Ollama embed — это вызов POST /api/embed на вашем сервере Ollama: текст уходит в модель эмбеддингов, а возвращается числовой вектор, по которому поиск находит близкие по смыслу фрагменты. Для базы регламентов или переписки такой вектор заменяет поиск по совпадению слов, и сотрудник находит абзац, даже когда спрашивает другими словами. Сама модель эмбеддингов молчит, а решения остаются за людьми и сервером: она только ранжирует кандидатов, и выдачу сверяет человек. Схема годится, когда документы остаются на вашем сервере и задача сводится к поиску нужного места в тексте.
Вызов и вектор
Эмбеддинги из Ollama получают одним запросом /api/embed с полями model и input; в input допускается строка или массив строк, а вектор приходит нормированным до единичной длины.
По документации Ollama, поле input принимает одну строку или список строк, поэтому весь пакет фрагментов отправляют одним вызовом. Ответ содержит векторы в том же порядке, в каком вы передали тексты. Документация указывает, что /api/embed возвращает L2-нормированные векторы, а для большинства задач поиска по смыслу рекомендует косинусную близость. Практический вывод для кода: сравнивайте векторы одной формулой в индексе и в запросе, а порядок ответа сопоставляйте с порядком входа по номеру позиции.
В качестве моделей документация перечисляет, например, embeddinggemma, qwen3-embedding и all-minilm; размерность вектора зависит от выбора модели и обычно лежит в пределах от 384 до 1024 значений. Перед вызовом загрузите модель командой ollama pull, подробности о версиях и хранении весов собраны в статье про ollama pull. Разбор конкретного семейства Qwen3 и состава корпоративного корпуса вы найдёте в отдельном материале про Qwen3 Embedding; здесь описан сам вызов Ollama и способ проверить выдачу.
Важное правило из документации: для индексации и для запроса используйте одну и ту же модель. Векторы разных моделей лежат в разных пространствах, и сравнение между ними даёт случайный порядок, а сервер промолчит и ошибки в ответе скроет. Название модели и её размерность записывайте рядом с индексом, чтобы через полгода любой инженер видел, чем собрана база.
Что отправлять
Полные документы в модель эмбеддингов отправлять неудобно: вектор усредняет смысл всего текста, и выдача размывается. Скрипт на вашей стороне режет документ на фрагменты, сохраняет у каждого заголовок раздела, название файла и ссылку на источник, затем отправляет пакет в /api/embed. Нарезку, очистку и удаление лишних полей выполняет код, и результат повторяется от запуска к запуску.
- Фрагмент по смысловому разделу: пункт регламента, шаг инструкции, ответ из переписки.
- Заголовок и путь к файлу в метаданных фрагмента, а сам вектор считается по тексту вместе с заголовком.
- Версия документа в метаданных, чтобы устаревший пункт удалялся при обновлении.
- Пометка уровня доступа у каждого фрагмента: решение о показе принимает сервер.
Пакетная отправка экономит сетевые вызовы, но у неё есть предел, который задаёт память сервера и выбранная модель. Начните с небольшого пакета, замерьте время ответа на вашем оборудовании и увеличивайте число фрагментов по шагам. Если вызов оборвался на середине, скрипт повторяет только неподтверждённую часть: хэш текста из таблицы ниже подсказывает, какие фрагменты уже получили вектор.
Размер фрагмента подбирают на тестовых вопросах, а число, взятое из чужого руководства, годится лишь как отправная точка. Слишком короткий кусок теряет контекст, слишком длинный смешивает несколько тем. Для таблиц и списков с номерами лучше хранить строку вместе с шапкой, иначе вектор описывает набор чисел без смысла. Если часть документов написана на английском, а вопросы задают по-русски, проверьте выбранную модель на таких парах отдельно.
Хранилище и смена модели
Векторы нужно где-то хранить и быстро сравнивать. Для небольшой базы хватает файла или таблицы в PostgreSQL с расширением, для большой нужна векторная база; критерии выбора разобраны в статье про выбор векторной базы, а вариант на стандартной СУБД описан в материале про pgvector. Ollama выдаёт одни векторы, а хранение остаётся за вами: индекс, обновление и удаление лежат на вашем сервисе.
| Что записать | Зачем | Что случится при смене модели |
|---|---|---|
| Имя и тег модели | Воспроизвести индекс | Старые векторы устарели, индекс собирают заново |
| Размерность вектора | Проверить схему таблицы | Колонка с прежней размерностью откажется принимать новые векторы |
| Хэш текста фрагмента | Пересчитывать только изменённое | Хэш остаётся прежним, а векторы считают заново |
| Версия тестового набора | Сравнить качество до и после | Результаты двух моделей кладут рядом |
Смену модели планируйте как миграцию: параллельный индекс на новой модели, прогон тестового набора, переключение запросов и только затем удаление старого. Пока идёт переиндексация, поиск работает на прежнем индексе. Если собрать новые векторы в старую таблицу, смешанная база выдаёт перекошенный порядок результатов, и причину придётся искать долго.
Какие документы вы бы первыми сделали доступными для смыслового поиска?
Тест на своих вопросах
Качество поиска определяет тест на ваших документах, рейтинги моделей в интернете играют вторую роль. Набор готовит человек, который знает базу: вопросы реальных сотрудников и фрагмент, где лежит правильный ответ. Подсчёт попаданий выполняет скрипт, модель в проверке отсутствует.
- Соберите двадцать-тридцать вопросов в формулировках сотрудников, без языка авторов регламентов, и у каждого отметьте нужный фрагмент.
- Посчитайте векторы вопросов тем же вызовом /api/embed и той же моделью, что использована при индексации.
- Для каждого вопроса возьмите несколько ближайших фрагментов по косинусной близости и проверьте, есть ли среди них отмеченный.
- Отдельно просмотрите промахи глазами: причина бывает в нарезке, в отсутствии заголовка или в синонимах, которых нет в тексте.
- Добавьте контрольные вопросы без ответа в базе: выдача для них должна выглядеть слабой, а сервис обязан отвечать «ответа в документах нет».
Подробнее о пороге близости и случаях, когда выдача пуста, написано в статье про оценку релевантности и нулевую выдачу. Сравнивая две модели, меняйте только модель: нарезка и вопросы остаются прежними, иначе вывод о причине улучшения окажется случайным.
Права и запуск
Эмбеддинги слепы к личности спрашивающего. Если в базе лежат приказы, договоры и переписка с разными уровнями доступа, фильтр по правам обязан срабатывать на сервере до выдачи фрагмента пользователю или в модель. Хранить уровень доступа в метаданных недостаточно: сервис сверяет его с учётной записью сотрудника при каждом запросе. Этот принцип совпадает с общим правилом для агентов, описанным в материале про права, секреты и проверку.
Адрес /api/embed закрывайте от внешней сети: Ollama по умолчанию слушает локальный интерфейс, а выставлять его наружу без прокладки с авторизацией нельзя. Подключение сервисов к локальному серверу разобрано в статье про Ollama API. В журнал пишите идентификаторы фрагментов и технические статусы, а тексты документов оставляйте в исходной системе.
Расход ресурсов тоже проверяют заранее: модели эмбеддингов легче чат-моделей, но при ночной переиндексации тысяч фрагментов нагрузка на сервер заметна. Разведите во времени пересчёт индекса и рабочие запросы сотрудников, а при совместной работе чата и поиска сравните варианты на одном сервере в статье про выбор между vLLM и Ollama.
Возьмите один раздел базы, например регламент отпусков, нарежьте его и пропустите через /api/embed. Составьте двадцать вопросов, посчитайте попадания и покажите промахи владельцу документа. Когда нужен проектный маршрут с правами и приёмкой, обсудите с нами поиск по вашим документам; состав работ определим после знакомства с базой.