Реранкинг с использованием моделей эмбеддингов
Python-код для переранжирования в RAG
Пересортировка — это второй этап в системах генерации с расширением поиска (RAG) системы, расположенный между этапом извлечения и генерации.

Таким образом Flux-1 dev представляет Электрические кубы в цифровом пространстве.
Для полного руководства по созданию систем RAG см. Учебник по генерации с расширением поиска (RAG): архитектура, реализация и руководство для продакшена.
В этой статье рассматривается пересортировка с использованием моделей встраивания. В качестве альтернативных подходов вы также можете ознакомиться со статьями Пересортировка текстов с помощью Ollama и Qwen3 Embedding LLM — на Go и Пересортировка документов с помощью Ollama и модели пересортировки Qwen3 — на Go.
Извлечение с пересортировкой
Если мы изначально храним документы в виде встраиваний (embeddings) в векторной базе данных, то процесс извлечения сразу же предоставит нам список похожих документов.
Автономная пересортировка
Однако, если мы сначала загрузим документы из интернета, ответ поисковой системы может быть искажен предпочтениями/алгоритмами поискового провайдера, спонсируемым контентом, SEO-оптимизацией и т.д., поэтому нам необходима пост-поисковая пересортировка.
Мой подход был следующим:
- получение встраиваний для поискового запроса;
- получение встраиваний для каждого документа (документ все равно не ожидался больше 8k токенов);
- вычисление сходства между запросом и встраиваниями каждого документа;
- сортировка документов по этому сходству.
Здесь нет векторной базы данных, поехали.
Пример кода
Используем Langchain для подключения к Ollama и функцию cosine_similarity из Langchain.
Вы можете фильтровать по метрике сходства, но имейте в виду, что для разных предметных областей и моделей встраивания LLM пороговые значения будут отличаться.
Буду рад, если этот фрагмент кода окажется полезным для вас. Лицензия: Копируйте/Вставляйте/Используйте как угодно. Ура.
from langchain_core.documents import Document
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.utils.math import cosine_similarity
import numpy as np
def cosine_distance(a: np.ndarray, b: np.ndarray) -> np.ndarray:
return 1.0 - cosine_similarity(a, b)
def compute_score(vectors: np.ndarray) -> float:
score = cosine_distance(vectors[0].reshape(1, -1), vectors[1].reshape(1, -1)).item()
return score
def list_to_array(lst):
return np.array(lst, dtype=float)
def compute_scorel(lists) -> float:
v1 = list_to_array(lists[0])
v2 = list_to_array(lists[1])
return compute_score([v1, v2])
def filter_docs(emb_model_name, docs, query, num_docs):
content_arr = [doc.page_content for doc in docs]
ollama_emb = OllamaEmbeddings(
model=emb_model_name
)
docs_embs = ollama_emb.embed_documents(content_arr)
query_embs = ollama_emb.embed_query(query)
sims = []
for i, emb in enumerate(docs_embs):
idx = docs[i].id
s = compute_scorel([query_embs, docs_embs[i]])
simstr = str(round(s, 4))
docs[i].metadata["sim"] = simstr
sim = {
"idx": idx,
"i": i,
"sim": s,
}
sims.append(sim)
sims.sort(key=sortFn)
sorted_docs = [docs[x["i"]] for x in sims]
filtered_docs = sorted_docs[:num_docs]
return filtered_docs
Лучшие модели встраивания
Для моих задач на данный момент лучшей моделью встраивания является bge-large:335m-en-v1.5-fp16.
Второе место разделили nomic-embed-text:137m-v1.5-fp16 и jina/jina-embeddings-v2-base-en:latest.
Однако проведите собственные тесты для своей предметной области и запросов.
Полезные ссылки
- Модели встраивания и пересортировки Qwen3 в Ollama: передовая производительность
- https://en.wikipedia.org/wiki/Retrieval-augmented_generation
- Шпаргалка по Python
- Как Ollama обрабатывает параллельные запросы
- Написание эффективных промптов для LLM
- Тестирование LLM: gemma2, qwen2 и Mistral Nemo
- Установка и настройка Ollama
- Сравнение LLM: Mistral Small, Gemma 2, Qwen 2.5, Mistral Nemo, LLama3 и Phi
- Шпаргалка по Conda
- Шпаргалка по Ollama
- Слоистые Lambda-функции с AWS SAM и Python
- Тест: как Ollama использует производительность процессора Intel и эффективные ядра