Vektordatenbanken
- Speicherung und Verwaltung von Vektordaten
- Effiziente Suche nächstgelegener Nachbarn
- Ähnlichkeitssuche (ANN) statt exakter Gleichheit
- ANN - Approximate Nearest Neighbors
- Semantische Suche
- Distanzmaße
- Index-Strukturen
- Auch in hochdimensionalen Vektorräumen
- Anwendung in Zusammenhang mit
- Semantischen Vektoreinbettungen (Embeddings)
- Großen Sprachmodellen (Large Language Models, LLM)
- Retrieval Augmented Generation (RAG)
Das Grundprinzip
Vektoreinbettungen
- Vektor = Zahlenfeld fester Länge
- Zweidimensional: (3, 5): Vektor der in der Ebene
- Dreidimensional: (3, 5, 1): Vektor im Raum
- 1536-dimensional: (1.7, 2.9, 0.9, ..., 3.4, 4,7): OpenAI-Texteinbettung
- Einbettungen: Umwandlung von Datenobjekten in Vektoren
- Texte, Bilder, Audio, Video
- Erfassung der Bedeutung der Objekte
- Ähnlichkeiten von Wörtern, Bildern usw.

(
Quelle)
- Mathematische Repräsentation von Datenobjekten
- Komprimierte, einheitliche Darstellung
- Bewahren Beziehungen in den Daten
- Ergebnis tiefer neuronaler Netze (Deep Learning)

(
Quelle)
Was ist ein Embedding?
- Neuronales Netz kodiert Daten als Zahlenvektoren (dense representation)
- Semantisch ähnliche Inhalte → nahe beieinander im Vektorraum
- Dimensionen: 384 (sentence-transformers) bis 3072 (text-embedding-3-large)
- Jede Dimension repräsentiert ein abstraktes Merkmal
Bekannte Modelle
- Text: OpenAI text-embedding-3-*, sentence-transformers, E5, GTE
- Bilder: CLIP, ViT, ResNet-Features
- Code: CodeBERT, StarCoder-Embeddings
- Multimodal: CLIP (Text + Bild in gleichem Raum)
Beispiel Satzeinbettungen
Sentence Transformers

(Quelle)

Explained: Tokens and Embeddings in LLMs (link)
Distanzmetriken
Ähnlichkeiten / Distanzen
Cosinus-Ähnlichkeit
- Misst den Winkel zwischen zwei Vektoren (0° = identisch)
- Unabhängig von der Länge (Magnitude) der Vektoren
- Wertebereich: −1 (entgegengesetzt) bis +1 (identisch)
- Standard für Text-Embeddings
Euklidischer Abstand (L2)
- Gerade Linie im hochdimensionalen Raum
- Sensitiv gegenüber der Vektorgröße
- Geeignet für normalisierte Vektoren und Bildsuche
Dot Product (Skalarprodukt)
- Kombiniert Richtung und Magnitude
- Bei normierten Vektoren identisch mit Cosinus
- Sehr schnell berechenbar (SIMD-optimiert)
Berechnung
Verteilung im n-dimensionalen Raum
Parameter
- Verteilung von 50 Datenpunkten
- Seitenlänge eines Teilwürfels: 0.2 Einheiten
- Füllgrad der Teilwürfel nimmt drastisch ab
Ein-dimensional
Füllgrad Teilwürfel: 20%
Zwei-dimensional
Füllgrad Teilwürfel: 4%
Drei-dimensional
Füllgrad Teilwürfel: 0.8%
Allgemeines Verhalten
Verhalten der Verteilung bei 20% Seitenlänge
- Ein-dimensional: ca. 20% Datenpunkte
- Zwei-dimensional: ca. 4% Datenpunkte
- Drei-dimensional: ca. 0.8% Datenpunkte
- n>10-dimensional: sehr dünn besiedelter Datenraum
784-dimensional: für 20% der Datenpunkte ist über 99,9% Seitenlänge erforderlich
Distanzen im n-dimensinalen Raum
Je mehr Dimensionen, desto
- größer die Abstände
- ähnlicher die Abstände
Fluch der Dimensionalität
Euklidische Distanz verliert an Bedeutung
Suchstrategien in Vektordatenbanken
Exakte Suche (Brute Force)
- Vergleich des Query-Vektors mit allen n Vektoren
- Komplexität: O(n · d) – linear in Datenmenge und Dimension
- Korrekt, aber bei n = 10 Mio. Vektoren zu langsam
- Einsatz: kleine Datenmengen (< 10.000 Vektoren), Prototyping
Approximate Nearest Neighbor (ANN)
- Findet nahezu exakte Nachbarn sehr viel schneller
- Genauigkeit: Recall@10
- Nimm die 10 nächsten approximierten Nachbarn
- Vergleich diese mit den tatsächlich 10 nächsten Nachbarn
- Prozent der approximierten Nachbarn in tatsächlich nächsten Nachbarn
- Ziel: Maximierung des Recall@10
- In RAG
- Minimum brauchbar: 80%
- Gut: 90%
- Sehr gut: 95%
- Index muss einmalig gebaut werden (Preprocessing, Finetuning)
Lineare Suche
Lineare Suche
- Berechne Distanz des Query-Vektors zu allen Vektoren in der DB
- Liefere Vektor mit geringstem Abstand

(
Quelle)
Inverted File Index
- Partitionierung des Datenraums auf Basis von Clustering, z.B 256 Cluster
- 256 Zentroide
- Berechne Distanz des Query-Vektors zu allen Zentroiden
- Lineare Suche in der Partition des gefundenen Zentroiden
- Liefert Näherungswerte
- Drastische Reduktion der Suchvorgänge

(
Quelle)
- Verbesserung der Genauigkeit: mehrere nächste Zentroide, nprobe
- Tradeoff: je größer nprobe, desto genauer aber auch langsamer
- Effizient für sehr große Datenmengen (100 Mio.+ Vektoren)
Skalare Quantitisierung
- Reduzierung der Genauigkeit der Vektoren
- Spart Speicherplatz, z.B. 8-fach bei float64 zu int8
- Schnellere Abstandsberechnungen auf int8 als auf float64
- Mehr Vektoren passen in RAM
- Kleinere Indices

(
Quelle)
Produkt-Quantitisierung
- Zerlegung in Subvektoren - Unterräume
- Clustering auf Unterräume
- Kodierung der Subvektoren durch ID des Zentroiden, reproduction value
- Speicherung der Koordinaten der Zentroide
- Kompression
- Originalvektor: 1024 * 32 bits = 4096 bytes
- 8 Subvektoren, 256 Zentroide
- Kodierter Vektor: 8 * 8 bits = 8 bytes
- Faktor 512x Speichersparnis
- Inferenz siehe Quelle

(
Quelle)
Hierarchical Navigable Small Worlds (HNSW)
- Umwandlung der Vektoren in einen Graph
- Abstände zwischen Vektoren als Kanten
- Multi-Ebenen-Graph
- Hierarchische Suche im Graphen

(
Quelle)
- Mehrschichtiger Graph: oben grob, unten fein
- Obere Layer: wenige Knoten, Langstreckenverbindungen (Navigation)
- Untere Layer: alle Knoten, dichte lokale Verbindungen (Präzision)
- Suche startet am Entry Point ganz oben und navigiert nach unten
- Suchkomplexität: O(log n)
RAG: Retrieval-Augmented Generation
Hybride Suche
Kombination von Vektorsuche und klassischen Suchalgorithmen wie BM25, wie sie in Suchmaschinen verwendet wird.
BM25 bewertet ein Dokument bzgl. seiner Relevanz für die Suchanfrage
- Wie oft ein Wort in einem Dokument vorkommt
- Wie selten ein Wort in der gesamten Dokumentensammlung vorkommt
- Wie lang das Dokument ist
Favorisiert
- Dokumente die das Wort enthalten
- Dokumente, die das Wort häufiger enthalten, aber mit Kappung, d.h. 10 Auftreten ist nicht 10mal besser
- Dokumente die Worte enthalten, die selten in der Dokumentensammlung vorkommen
Idee
- Vektorsuche allein: brücksichtigt Semantik aber nicht unbedingt Schlüsselwörter
- BM25 Gut bzgl. Schlüsselwörter, kann aber nicht Semantik berücksichtigen
- Hybrid: Kombination beider Verfahren
Kombination der Ergebnisse
- BM25 liefert Ranking A
- Vektorsuche liefert Ranking B
- Beide Rankings werden fusioniert, z.B. mittels Reciprocal Rank Fusion (RRF)
Reciprocal Rank Fusion (RRF)
- Dokumente mit hohem Rang (kleine Zahl) bekommen viel Score
- Dokumente, die in beiden Rankings vorkommen, werden bevorzugt
- Ranglistenfusion: jede Methode liefert eine Rangliste
- RRF(d) = 1/(k + rank-bm25(d)) + 1/(k + rank-vectors(d))
- k = 60 (Typischer Wert), Normalisierungsparameter
- n = Länge der Rangliste, z.B. 100
- rank-bm25(d) = Rang von Dokument d in der BM25-Rangliste oder ∞ falls nicht gefunden
- rank-vectors(d) = Rang von Dokument d in der Vektorsuche-Rangliste oder ∞ falls nicht gefunden
- Rechenbeispiele
| Dokument |
rank-bm25(d) |
rank-vectors(d) |
RRF(d) |
Platz |
| A |
1 |
1 |
0,032786885 |
1 |
| B |
5 |
5 |
0,030769231 |
2 |
| C |
1 |
10 |
0,030679157 |
3 |
| D |
1 |
∞ |
0,016394443 |
4 |
| E |
∞ |
∞ |
0 |
5 |
- Methode robust gegenüber Ausreißer
- Funktioniert gut in praktischen Anwendungen
Anwendungsfälle
- E-Commerce: Produktname (BM25) + Stil (Vektor)
- Code-Suche: Funktionsname (BM25) + Logik (Vektor)
- Rechtliche Suche: Paragraphennummer + semantischer Kontext
Metadaten-Filterung
Warum Filterung?
- Vektoren haben Metadaten: Sprache, Datum, Kategorie, Autor
- Beispiel: "ähnliche Artikel WHERE sprache='de' AND jahr=2024"
Pre-Filtering
- Erst Metadaten filtern, dann ANN auf dem Subset
- Vorteil: präzise, kein Ergebnis außerhalb des Filters
- Nachteil: kleines Subset kann ANN-Qualität reduzieren
Post-Filtering
- Erst ANN (Top-k*), dann Metadaten filtern
- Vorteil: ANN auf vollem Index → hohe Qualität
- Nachteil: evtl. weniger als k Ergebnisse nach Filter
Vektordatenbanksysteme
Pinecone
- Managed Cloud VectorDB (Serverless & Pod-basiert)
- Serverless: automatisches Skalieren, Pay-per-Use
- Namespaces: logische Trennung von Datensätzen
- Metadaten-Filter direkt bei der Suche
- REST API + Python/JS/Java SDK
- Hybrid Search: Dense + Sparse Vektoren (BM25)
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="...")
pc.create_index("docs",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws",
region="us-east-1"))
idx = pc.Index("docs")
# Vektoren speichern
idx.upsert(vectors=[
{"id": "v1",
"values": [0.1, 0.7, ...],
"metadata": {"lang": "de"}}])
# Suchen
res = idx.query(
vector=[0.3, 0.5, ...], top_k=5,
filter={"lang": {"$eq": "de"}})
Weaviate
- Open-Source, selbst gehostet oder Weaviate Cloud
- Module: eingebaute Vektorisierung (text2vec, img2vec, CLIP)
- Hybrid Search: BM25 + Vektorsuche kombiniert
- GraphQL & REST & gRPC API
- Multi-Tenancy: isolierte Mandanten auf einer Instanz
- Generative Module: direkte LLM-Integration
import weaviate
client = weaviate.connect_to_local()
collection = client.collections.get(
"Article")
# Hybrid-Suche (BM25 + Vektor)
results = collection.query.hybrid(
query="Vektordatenbank Einführung",
alpha=0.75, # 0=BM25, 1=Vektor
limit=5,
return_properties=["title", "content"])
# Vektorsuche mit Filter
results = collection.query.near_text(
query="semantische Suche",
filters=weaviate.classes.query.Filter
.by_property("lang").equal("de"),
limit=5)
Chroma
- Leichtgewichtig: eingebettet in Python (SQLite + HNSW)
- Oder als persistenter Server betreibbar
- Ideal für Prototypen, LangChain-/LlamaIndex-Integration
- Automatische Vektorisierung über Embedding-Funktion
- Metadaten-Filter mit
where-Klausel
- Kein eigenes Schema erforderlich
import chromadb
client = chromadb.PersistentClient(
path="./vectordb")
col = client.get_or_create_collection(
"docs")
col.add(
documents=["Paris ist die Hauptstadt Frankreichs",
"Berlin ist in Deutschland"],
metadatas=[{"lang": "de"},
{"lang": "de"}],
ids=["doc1", "doc2"])
results = col.query(
query_texts=["Frankreich Hauptstadt"],
n_results=2,
where={"lang": "de"})
Qdrant
- In Rust geschrieben – hohe Performance, geringer Speicherverbrauch
- Reichhaltiges Payload-Filtering: Nested-Strukturen, Geo, Volltextsuche
- Quantisierung: Scalar (SQ8), Binary (BQ), Product (PQ)
- On-Disk-Indexierung für sehr große Collections
- GRPC + REST API, Python/JS/Rust/Go SDK
- Cloud-Angebot: Qdrant Cloud
from qdrant_client import QdrantClient
from qdrant_client.models import (
Distance, VectorParams,
PointStruct, Filter, FieldCondition,
MatchValue)
client = QdrantClient(":memory:")
client.create_collection("docs",
vectors_config=VectorParams(
size=768,
distance=Distance.COSINE))
client.upsert("docs", points=[
PointStruct(id=1, vector=[...],
payload={"lang": "de",
"year": 2024})])
results = client.search("docs",
query_vector=[...], limit=5,
query_filter=Filter(must=[
FieldCondition(key="lang",
match=MatchValue(value="de"))
]))
pgvector: Vektoren in PostgreSQL
- PostgreSQL-Extension: Vektoren als nativer Spaltentyp
- Volle SQL-Unterstützung: JOINs, Transaktionen, ACID
- Indizes: IVFFlat und HNSW
- Distanzoperatoren:
<=> Cosine, <-> L2, <#> Inner Product
- pgvectorscale: höhere Skalierung mit DiskANN
- Ideal: bestehende PostgreSQL-Infrastruktur wiederverwenden
-- Extension aktivieren
CREATE EXTENSION vector;
-- Tabelle mit Vektorfeld
CREATE TABLE docs (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
);
-- HNSW-Index (Cosine)
CREATE INDEX ON docs
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- Ähnlichkeitssuche Top-5
SELECT content,
embedding <=> '[0.1, 0.7, ...]' AS dist
FROM docs
ORDER BY dist
LIMIT 5;
LangChain: VectorStore-Integration
Dokumente indexieren
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain.text_splitter import (
RecursiveCharacterTextSplitter)
# Dokumente aufteilen
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(docs)
# Einbetten & in VectorDB speichern
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./db")
Suchen & RAG
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
# Ähnlichkeitssuche
results = vectorstore.similarity_search(
"Was ist HNSW?", k=5)
# RAG-Chain aufbauen
from langchain_openai import ChatOpenAI
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o")
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
prompt = ChatPromptTemplate.from_template(
"Beantworte die Frage basierend auf dem Kontext:\n\n{context}\n\nFrage: {input}"
)
qa_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, qa_chain)
result = rag_chain.invoke({"input": "Was ist ein Vektorindex?"})
print(result["answer"])