Ponowne rankowanie za pomocą modeli osadzeń
Kod Pythona do ponownego rankingu w RAG.
Reranking to drugi krok w systemach RAG (Retrieval Augmented Generation), znajdujący się bezpośrednio między pobieraniem (Retrieving) a generowaniem (Generating).

Tak wyobraża sobie Elektryczne sześciany w przestrzeni cyfrowej model Flux-1 dev.
Pełny przewodnik po budowaniu systemów RAG znajdziesz w Tutoriale Retrieval-Augmented Generation (RAG): Architektura, Implementacja i Wdrożenie.
Ten artykuł dotyczy rerankingu z wykorzystaniem modeli embedding. Jako alternatywne podejścia sprawdź również Reranking tekstów z Ollama i modelem Qwen3 Embedding LLM - w Go oraz Reranking dokumentów z Ollama i modelem Qwen3 Reranker - w Go.
Pobieranie z rerankingiem
Jeśli od początku przechowujemy dokumenty w postaci wektorów (embeddings) w bazie wektorowej, pobieranie natychmiast zwróci listę podobnych dokumentów.
Samodzielny reranking
Jeśli jednak najpierw pobierzemy dokumenty z internetu, odpowiedź systemu wyszukiwania może być wpływać preferencje lub algorytmy dostawcy wyszukiwania, treści sponsorowane, optymalizacja SEO itp., dlatego konieczne jest stosowanie rerankingu po wyszukiwaniu.
To, co robiłem:
- uzyskiwanie wektorów (embeddings) dla zapytania wyszukiwania,
- uzyskiwanie wektorów dla każdego dokumentu (dokument nie miał przekraczać 8k tokenów),
- obliczanie podobieństwa między zapytaniem a wektorem każdego dokumentu,
- sortowanie dokumentów według tego podobieństwa.
Tutaj nie ma bazy wektorowej, ruszamy.
Przykładowy kod
Korzystam z Langchain do połączenia z Ollama oraz funkcji cosine_similarity z Langchain. Możesz filtrować według miary podobieństwa, ale pamiętaj, że dla różnych domen i modeli LLM embedding próg ten będzie inny.
Będę wdzięczny, jeśli ten fragment kodu okaże się dla Ciebie przydatny. Licencja: Kopiuj/Wklej/UżyjJakKolisz. Pozdrawiam.
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
Najlepsze modele embedding
Do moich zadań najlepszym modelem embedding jest obecnie bge-large:335m-en-v1.5-fp16.
Drugie miejsce zajęły nomic-embed-text:137m-v1.5-fp16 oraz jina/jina-embeddings-v2-base-en:latest.
Pamiętaj jednak o przeprowadzeniu własnych testów dla swojej domeny i zapytań.
Przydatne linki
- Modele Qwen3 Embedding & Reranker na Ollama: Stan Sztuki
- https://en.wikipedia.org/wiki/Retrieval-augmented_generation
- Python Cheatsheet
- Jak Ollama obsługuje żądania równoległe
- Pisanie skutecznych promptów dla LLM
- Testy LLM: gemma2, qwen2 i Mistral Nemo
- Instalacja i konfiguracja Ollama
- Porównanie LLM: Mistral Small, Gemma 2, Qwen 2.5, Mistral Nemo, LLama3 i Phi
- Conda Cheatsheet
- Ollama cheatsheet
- Layered Lambdas z AWS SAM i Pythonem
- Test: Jak Ollama wykorzystuje wydajność CPU Intel i rdzenie wydajnościowe