Учебник

Как выбрать модель эмбеддингов для поиска по базе знаний

Ваши менеджеры тратят часы на поиск ответов в документах, а клиенты жалуются на долгое обслуживание. Разбираем, как выбрать модель эмбеддингов (векторных представлений текста), чтобы RAG-ассистент находил нужное с первой попытки. Без сложной математики - только практика: какая модель подходит для русского языка, сколько это стоит и как проверить на своих данных за 30 минут.

Макс Космов··7 мин чтения

Ваш менеджер по работе с клиентами тратит 4 часа в день на поиск ответов в договорах, прайсах и инструкциях - и всё равно половину находит с трудом. Клиент ждёт, NPS падает, вы теряете деньги. Решение - RAG-ассистент, который ищет по базе знаний. Но качество поиска упирается в одну штуку: модель эмбеддингов (она превращает текст в числа, чтобы искать по смыслу, а не по точному совпадению). Неправильный выбор - ассистент отвечает невпопад. Правильный - 8 из 10 запросов решаются за секунду.

Разберём на примере стройфирмы с 500 типовыми договорами, сметами и актами. Ваша база знаний - это 50 000 документов. Чтобы ассистент находил нужный пункт за секунду, каждый документ нужно превратить в набор чисел - эмбеддинг (векторное представление текста). Два похожих документа дают близкие наборы чисел, два разных - далёкие. Выбор модели эмбеддингов - это выбор «мозга» для поиска. Плохая модель - и ассистент не найдёт «порядок сдачи работ» даже если документ есть. Хорошая - найдёт за 0.2 секунды.

Что такое эмбеддинг простыми словами

Эмбеддинг - это просто список чисел, который кодирует смысл текста. Например, фраза «тёплые сапоги на зиму» превращается в 1024 числа. Фраза «зимние ботинки утеплённые до -30°C» - в похожий набор. А «рецепт борща» - в совсем другой. Поиск сравнивает эти наборы и выдаёт ближайшие по смыслу.

Для стройфирмы: запрос «как оформить допсоглашение» превращается в вектор. Поиск находит 10 договоров, чьи векторы ближе всего к этому запросу - даже если в документах написано «дополнительное соглашение к договору подряда».

Почему размерность (количество чисел) важна? Больше чисел - тоньше различие смыслов, но больше памяти и медленнее поиск. text-embedding-3-large от OpenAI даёт 3072 числа. Его можно сжать до 256 - памяти уйдёт в 12 раз меньше, а качество упадёт всего на 3-5%.

Bi-encoder и cross-encoder: что выбрать для бизнеса

Для RAG нужен bi-encoder (двойной кодировщик). Он создаёт векторы запроса и документа независимо. Вы заранее считаете векторы всех 50 000 документов и сохраняете. Потом каждый запрос просто сравнивается с ними - быстро и дёшево.

Cross-encoder (совместный кодировщик) обрабатывает пару «запрос + документ» вместе - точнее, но в 10-50 раз медленнее. Его используют для финального ранжирования, когда уже отобрали 20 кандидатов. Для старта bi-encoder достаточно.

Вот как выглядит код для bi-encoder (не пугайтесь - менеджер сможет скопировать и запустить с нашей инструкцией):

from sentence_transformers import SentenceTransformer
import numpy as np

model = SentenceTransformer('BAAI/bge-m3')

texts = [
 "Как настроить HNSW индекс в Qdrant?",
 "Qdrant HNSW ef_construction параметры",
 "Рецепт борща с говядиной"
]

embeddings = model.encode(texts, normalize_embeddings=True)
# shape: (3, 1024)

# cosine similarity (для нормализованных векторов = dot product)
similarity_01 = np.dot(embeddings[0], embeddings[1]) # ~0.82
similarity_02 = np.dot(embeddings[0], embeddings[2]) # ~0.12
print(f"Похожие тексты: {similarity_01:.3f}")
print(f"Несвязанные тексты: {similarity_02:.3f}")

Результат: два технических текста про Qdrant дают 0.82 (высокая похожесть), технический текст и рецепт - 0.12 (низкая).

Метрики похожести: cosine, dot product, L2

От выбора метрики зависит, найдёт ли ассистент правильный ответ на первом месте. Три основные:

  • Cosine similarity (косинусная похожесть) - угол между векторами. Не зависит от длины. Стандарт для текстов.
  • Dot product (скалярное произведение) - учитывает длину. Используют, когда модель специально обучена под него.
  • L2 (евклидово расстояние) - геометрическое расстояние. Чаще для изображений.

Практическое правило: если не уверены - берите cosine similarity с нормализованными векторами. Ошибиться сложнее.

Вот как настроить коллекцию в Qdrant (векторная база данных) под BGE-M3:

from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance

client = QdrantClient(":memory:")
client.create_collection(
 collection_name="knowledge_base",
 vectors_config=VectorParams(
 size=1024, # BGE-M3
 distance=Distance.COSINE
 )
)

Сравнение моделей: что выбрать под свой бюджет

MTEB (Massive Text Embedding Benchmark) - это стандартный тест качества. Версия v2 2026 года включает 287 задач на 100+ языках. Вот лидеры:

Модель MTEB v2 Размерность Стоимость
Qwen3-Embedding-8B 70.6 4096 self-hosted
Cohere embed-v4 65.2 1536 $0.10/1M токенов
text-embedding-3-large 64.6 3072 $0.13/1M токенов
BGE-M3 63.0 1024 self-hosted
text-embedding-3-small 62.3 1536 $0.02/1M токенов
E5-mistral-7b 64.0 4096 self-hosted

Важно: MTEB усредняет по сотням задач. На вашем корпусе (договоры на русском, медицинские протоколы) порядок может измениться. Qwen3-Embedding-8B лидирует, но требует GPU с 16+ ГБ памяти.

Пример из практики: медицинская клиника с базой протоколов лечения. На общем бенчмарке побеждает одна модель. На их текстах с латынью - BGE-M3 показывает лучший результат, потому что обучался на более разнообразных данных.

OpenAI text-embedding-3: small против large

Выбор между small и large - это баланс цены и качества. Для 90% проектов small хватает.

  • text-embedding-3-small: 1536 измерений, цена $0.02/1M токенов. Можно урезать до 512 или 256 - памяти меньше, качество почти не падает.
  • text-embedding-3-large: 3072 измерения, $0.13/1M токенов. Даёт прирост на сложных задачах, где нужно различать тонкие отличия.

Вот как вызвать API OpenAI с сжатием:

from openai import OpenAI

client = OpenAI()

response = client.embeddings.create(
 model="text-embedding-3-small",
 input="Как настроить гибридный поиск в Qdrant?",
 dimensions=512
)

vector = response.data[0].embedding
print(f"Размерность: {len(vector)}") # 512
print(f"Стоимость: ~$0.02/1M токенов")

Матрица принятия решений:

  • Прототип / менее 100 тысяч документов: text-embedding-3-small (512 dims)
  • боевая среда / русский язык / бюджет ограничен: BGE-M3 self-hosted
  • боевая среда / английский / нужна максимальная точность: text-embedding-3-large или Cohere embed-v4

Open-source альтернативы: BGE-M3, E5-mistral-7b, Qwen3-Embedding-8B

Self-hosted (самостоятельно развёрнутые) модели - это нулевая стоимость за каждый запрос и полный контроль над данными. Для компаний с требованиями по защите данных - ключевой аргумент.

BGE-M3 от BAAI - главный выбор для русскоязычных проектов. Поддерживает dense retrieval (поиск по смыслу), sparse retrieval (поиск по ключевым словам) и multi-vector одновременно. Размерность 1024, балл MTEB 63.0 - конкурентоспособно с платными API. На GPU A100 80GB даёт около 1500 текстов в секунду.

Вот как получить два типа векторов для гибридного поиска:

from FlagEmbedding import BGEM3FlagModel

model = BGEM3FlagModel('BAAI/bge-m3', use_fp16=True)

output = model.encode(
 ['Как работает HNSW индекс?'],
 return_dense=True,
 return_sparse=True,
 return_colbert_vecs=False
)

dense_vecs = output['dense_vecs'] # shape (1, 1024)
lexical_weights = output['lexical_weights'] # sparse BM25-style

E5-mistral-7b от Microsoft - модель на базе Mistral 7B с 4096 измерениями. Поддерживает instruction-prefix: «Represent this sentence for searching relevant passages: {query}» - это улучшает поиск на 1-3%.

Qwen3-Embedding-8B - новый лидер по бенчмаркам 2026 года. 70.6 по MTEB v2, поддерживает управление через системный запрос. Требует около 16 ГБ памяти GPU. Для команд с собственным GPU-кластером - лучший выбор по соотношению качество/стоимость.

Multilingual RAG: когда нужен BGE-M3 вместо Cohere embed-v4

Cohere embed-v4 отлично работает для английского и ведущих европейских языков. Для русского, украинского, казахского, арабского, китайского - BGE-M3 стабильно показывает более высокий Recall на практике, несмотря на более низкий общий балл MTEB.

Причина: MTEB v2 взвешен по языкам неравномерно, английские задачи имеют больший вес. BGE-M3 специально обучался на сбалансированном корпусе из 100+ языков, включая 50 миллионов+ русскоязычных пар.

Пример: ритейлер с базой отзывов и описаний товаров на русском, украинском и казахском. Cohere даёт хороший результат для русского, но теряет качество на украинском и казахском. BGE-M3 обрабатывает все три языка с сопоставимым качеством.

Как проверить качество на своих данных за 30 минут

MTEB - это хорошо, но реальный тест - на ваших данных. Корпоративный русскоязычный документооборот имеет другое распределение, чем академические датасеты.

Минимальный тест:

  1. Возьмите 50-100 вопросов из реальных запросов пользователей.
  2. Для каждого вопроса вручную отметьте 1-3 правильных фрагмента из базы.
  3. Запустите поиск с каждой моделью, считайте Recall@5 и Recall@10.

Вот код для автоматического теста:

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

def evaluate_recall_at_k(model_name, questions, corpus, golden_ids, k=5):
 model = SentenceTransformer(model_name)

 corpus_embs = model.encode(corpus, normalize_embeddings=True)
 query_embs = model.encode(questions, normalize_embeddings=True)

 scores = cosine_similarity(query_embs, corpus_embs)
 recalls = []

 for i, golden in enumerate(golden_ids):
 top_k = np.argsort(scores[i])[::-1][:k]
 hit = any(g in top_k for g in golden)
 recalls.append(float(hit))

 return np.mean(recalls)

r_bge = evaluate_recall_at_k('BAAI/bge-m3', questions, corpus, golden_ids)
r_openai = evaluate_recall_at_k('text-embedding-3-small', questions, corpus, golden_ids)
print(f"BGE-M3 Recall@5: {r_bge:.3f}")
print(f"text-embedding-3-small Recall@5: {r_openai:.3f}")

30 минут на этот тест сэкономят недели дебага «почему RAG отвечает невпопад».

Типичные ошибки

Доверять только MTEB без теста на своих данных. MTEB не знает про ваши документы. Корпоративная база на русском с аббревиатурами и жаргоном - совсем не то, на чём обучались модели-лидеры рейтинга.

Смешивать эмбеддинги от разных моделей в одной базе. Векторные пространства разных моделей несовместимы. Похожесть между вектором от BGE-M3 и вектором от text-embedding-3-small ничего не означает. При смене модели придётся переиндексировать всю базу.

Выбирать максимальную размерность без нужды. 3072-мерный вектор требует в 3 раза больше памяти и в 2 раза медленнее при поиске, чем 1024-мерный. При сжатии text-embedding-3-large с 3072 до 512 через MRL теряется 4-5% Recall, но экономится в 6 раз больше памяти.

Не использовать нормализацию. Без normalize_embeddings=True cosine similarity считается неправильно. Всегда нормализуйте перед сохранением в базу.

Частые вопросы

Почему модель-лидер MTEB проигрывает на моих данных?

MTEB усредняет 287 задач, большинство на английском и академических данных. Корпоративный русскоязычный документооборот или медицинские протоколы имеют другое распределение. Всегда проверяйте на собственном наборе минимум из 50 вопросов - это единственная реальная мера качества для вашей задачи.

Можно ли смешивать эмбеддинги от разных моделей в одной базе?

Нет. Векторные пространства разных моделей несовместимы. При смене модели придётся переиндексировать всю базу. Qdrant и Weaviate поддерживают несколько именованных векторных полей для хранения эмбеддингов от разных моделей параллельно - так можно тестировать A/B без полной миграции.

Как размерность вектора влияет на скорость и точность поиска?

Линейная зависимость по памяти: 3072-мерный вектор в 3 раза тяжелее 1024-мерного. По скорости при HNSW-индексе разница около 20-40%. При сжатии text-embedding-3-large с 3072 до 512 через MRL теряется 4-5% Recall, но экономится в 6 раз больше памяти. Конкретные числа зависят от корпуса.

Стоит ли переходить на Qwen3-Embedding-8B с OpenAI?

Если есть GPU с 16 ГБ+ памяти и объём индексации больше 10 миллионов токенов в месяц - математика сходится. При $0.13/1M токенов text-embedding-3-large стоит $1300 за 10M токенов, аренда A100 на месяц - $800-1200. Учитывайте инженерные затраты на поддержку инфраструктуры.

Что лучше для русского языка - BGE-M3 или E5?

BGE-M3 стабильнее для русского: 100 языков в обучении, специальные многоязычные негативные примеры. E5-mistral-7b лучше на английском. Для смешанных корпусов (русский + английский код + документация) BGE-M3 или Qwen3-Embedding-8B предпочтительнее.

Что делать дальше

  1. Возьмите 50 реальных вопросов от ваших клиентов.
  2. Отметьте правильные ответы в вашей базе знаний.
  3. Запустите тест из раздела «Как проверить качество на своих данных за 30 минут» с BGE-M3 и text-embedding-3-small.
  4. Выберите модель с лучшим Recall@5.

Потом - выберите, где хранить векторы: практическое сравнение Qdrant, pgvector, Pinecone и Weaviate по скорости, цене и функциям.

AI Компас (t.me/kosmoslab_ai) - канал для предпринимателей в РФ и СНГ, которые применяют AI в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.