Wektory tekstowe dla RAG i wyszukiwania – Python, Ollama, API kompatybilne z OpenAI

RAG embeddings – Python, Ollama, API OpenAI.

Page content

Jeśli pracujesz nad generacją wspieraną odzyskiwaniem (RAG), ta sekcja wyjaśnia wektory tekstowe (embeddings) prostym językiem — czym są, jak pasują do wyszukiwania i odzyskiwania informacji, oraz jak wywołać dwa popularne lokalne rozwiązania z Pythonu przy użyciu Ollama lub kompatybilnego z OpenAI interfejsu HTTP (jakiego używają serwery oparte na llama.cpp).

Wektory tekstowe i odzyskiwanie

Dla klientów Go i porównań SDK Ollama zobacz SDK Go dla Ollama — porównanie z przykładami.

Czym jest wektor tekstowy (embedding)?

Wektor tekstowy (embedding) to wektor (lista liczb zmiennoprzecinkowych) generowany przez model wektorowy. Model ten mapuje tekst o zmiennej długości na przestrzeń o stałej wymiarowości, tak aby teksty o podobnym znaczeniu znajdowały się blisko siebie zgodnie z miarą odległości lub podobieństwa (często podobieństwo kosinusowe dla wektorów unormowanych w normie L2).

Wektory tekstowe nie są tym samym co ID tokenów ani to samo co zakończenie czatu. To warstwa reprezentacji, której używa się do wyszukiwania, grupowania, usuwania duplikatów oraz — w RAG — do odzyskiwania informacji.

Typowe przypadki użycia

Przypadek użycia Rola wektorów
Wyszukiwanie semantyczne / odzyskiwanie w RAG Utworzenie wektorów dla zapytań i fragmentów dokumentów; sortowanie według podobieństwa, aby pobrać odpowiednie fragmenty.
Ponowne rankowanie z modelami wektorowymi Utworzenie wektora dla zapytania i każdego kandydata; ocenianie par na podstawie podobieństwa (zobacz Ponowne rankowanie z modelami wektorowymi).
Grupowanie i usuwanie duplikatów Grupowanie lub usuwanie duplikatów elementów w przestrzeni wektorowej bez ręcznego oznaczania każdego przykładu.
Ocena w stylu klasyfikacji Porównywanie tekstu z opisami prototypowymi lub nazwami klas w tej samej przestrzeni (wzorce zależą od modelu).

Dla ustawień multimodalnych (obraz-tekst i powiązane koncepcje) zobacz Wektory międzymodalne.

Wektory w potoku RAG

Typowa ścieżka offline wygląda tak:

  1. Podział dokumentów (wielkość, nakładanie się i struktura mają znaczenie — zobacz Strategie podziału w RAG).
  2. Wektorowanie każdego fragmentu; opcjonalnie przechowywanie metadanych (identyfikator źródła, sekcja, ACL).
  3. Indeksowanie wektorów w pamięci, w indeksie biblioteki lub bazie danych wektorowej (kompromisy opisano w Sklepy wektorowe dla RAG — porównanie).

W czasie zapytania:

  1. Utwórz wektor dla zapytania użytkownika (jeden krótki łańcuch lub mała partia).
  2. Odzyskaj k najpodobniejszych fragmentów za pomocą wyszukiwania wektorowego (opcjonalnie z wyszukiwaniem hybrydowym/słowym).
  3. Zbuduj prompt z odzyskanych surowych fragmentów tekstu i wywołaj swój model czatu.

Ważna nuansa — duże modele językowe w interfejsach czatu zużywają tekst (i narzędzia), a nie dowolne tensory wektorów. Używasz wektorów do wyboru, który tekst wstrzyknąć. Jeśli widzisz „zapytaj LLM o wcześniej obliczone wektory", w praktyce oznacza to odzyskaj za pomocą wektorów, a następnie wyślij wybrany tekst do LLM.

Uzyskanie wektorów z Ollama (Python)

Ollama udostępnia interfejs HTTP. Dla wektorów wywołaj POST /api/embed na hostcie Ollama (domyślnie http://127.0.0.1:11434). JSON w ciele żądania zawiera nazwę model oraz input (łańcuch lub lista łańcuchów). Odpowiedź zawiera embeddings, listę wektorów odpowiadających Twoim danym wejściowym.

Zainstaluj httpx (lub użyj requests w ten sam sposób).

import httpx

OLLAMA = "http://127.0.0.1:11434"
MODEL = "nomic-embed-text"  # zastąp modelem wektorowym, który pobrałeś

def embed_ollama(texts: list[str]) -> list[list[float]]:
    r = httpx.post(
        f"{OLLAMA}/api/embed",
        json={"model": MODEL, "input": texts},
        timeout=120.0,
    )
    r.raise_for_status()
    data = r.json()
    return data["embeddings"]

if __name__ == "__main__":
    q = "Czym jest generacja wspierana odzyskiwaniem?"
    chunks = [
        "RAG łączy odzyskiwanie z generacją.",
        "Wektory mapują tekst do przestrzeni wektorowej dla wyszukiwania podobieństw.",
    ]
    qv = embed_ollama([q])[0]
    doc_vs = embed_ollama(chunks)
    print(len(qv), len(doc_vs), len(doc_vs[0]))

Uwagi operacyjne

Uzyskanie wektorów z serwera kompatybilnego z OpenAI (Python)

Wiele lokalnych serwerów (w tym popularne instalacje HTTP llama.cpp) udostępnia trasy kompatybilne z OpenAI, takie jak POST /v1/embeddings. Możesz użyć oficjalnego pakietu Python openai i wskazać base_url na korzeń …/v1 swojego serwera.

from openai import OpenAI

# Przykład — zastąp host, port i ID modelu wartościami Twojego serwera
client = OpenAI(
    base_url="http://127.0.0.1:8080/v1",
    api_key="not-needed",  # wiele lokalnych serwerów ignoruje to
)

def embed_openai_compatible(text: str, model: str) -> list[float]:
    r = client.embeddings.create(model=model, input=text)
    return r.data[0].embedding

if __name__ == "__main__":
    v = embed_openai_compatible("hello from llama.cpp", "your-embedding-model-id")
    print(len(v))

Dlaczego trzymać oba wzorce na jednej stronie? Koncepcje (podział, wektorowanie, indeksowanie, zapytanie, odzyskiwanie tekstu) są identyczne; zmienia się tylko powierzchnia HTTP. Jeden artykuł w stylu warsztatowym unika duplikowania tej samej narracji pod dwoma URL-ami.

Przechowywanie wektorów i zapytywanie ich

Co najmniej musisz przechowywać trzy rzeczy dla każdego fragmentu — wektor, tekst oraz metadane (ID źródła, przesunięcia, ACL). Dla szybkiego prototypu możesz trzymać wszystko w liście Pythona i użyć podobieństwa kosinusowego z NumPy lub scikit-learn. Dla rosnących danych użyj bazy danych wektorowej lub indeksu biblioteki (FAISS itp.); zobacz Sklepy wektorowe dla RAG — porównanie dla kompromisów na poziomie produktów.

Pojęciowa pętla zapytania:

  1. query_vec = embed(query)
  2. neighbors = index.search(query_vec, k)
  3. context = "\n\n".join(chunk.text for chunk in neighbors)
  4. Wyślij context oraz pytanie użytkownika do swojego interfejsu czatu.

Ponowne rankowanie po odzyskaniu

Model ponownie rankujący (często cross-encoder lub drugi model oceniający) może ponownie posortować najlepszych kandydatów po odzyskaniu wektorowym. Ta strona zawiera przykłady w Pythonie i Go, w tym Ponowne rankowanie z modelami wektorowymi oraz Ponowne rankowanie z Ollama i Qwen3 Embedding w Go.

Na tej stronie — powiązane artykuły

Temat Artykuł
Pełna architektura RAG Tutorial RAG — architektura, implementacja, produkcja
Podział przed wektorowaniem Strategie podziału w RAG
Wybór bazy danych wektorowej Sklepy wektorowe dla RAG — porównanie
Qwen3 na Ollama Qwen3 Embedding & Reranker na Ollama
Międzymodalne Wektory międzymodalne
Ollama CLI i wskazówki Składnice Ollama
Go + Ollama Używanie Ollama w Go — porównanie SDK

Przydatne linki