Negation in Semantic Search: Warum 'Hemd ohne Streifen' schwieriger ist als gedacht
Warum finden Suchmaschinen bei der Suche nach "Hemd ohne Streifen" auch gestreifte Hemden? Ein Blick auf die Grenzen von Embeddings und wie ein hybrider Multi-Stage-Ansatz das Problem löst.
Negation in Semantic Search: Warum "Hemd ohne Streifen" schwieriger ist als gedacht
Dieser Artikel basiert auf einem Vortrag, der voraussichtlich auf der decompiled.de 2026 (12. März) gehalten wird.
Stellen Sie sich vor: Sie suchen in einem Online-Shop nach einem "blauen Hemd ohne Streifen". Die moderne KI-gestützte Suche versteht, dass Sie ein Hemd möchten. Sie versteht auch "blau" und "Streifen". Aber sie zeigt Ihnen trotzdem gestreifte Hemden an.
Willkommen zum größten blinden Fleck von Embedding-basierten Suchsystemen: Negation.
Das Problem: Embeddings verstehen kein "ohne"
Moderne semantische Suche basiert auf Dense Retrieval – Texte werden in hochdimensionale Vektoren (Embeddings) umgewandelt, und ähnliche Bedeutungen landen nahe beieinander im Vektorraum.
Das funktioniert hervorragend für:
- "blaues Hemd" findet auch "marineblaues Oberteil"
- "Softwareentwicklung" findet auch "IT-Dienstleistungen"
- "günstiger Laptop" findet auch "preiswertes Notebook"
Aber es versagt bei:
- "Hemd ohne Streifen" – findet auch gestreifte Hemden
- "Hotel nicht am Strand" – findet Strandhotels
- "Wohnung ohne Balkon" – zeigt Balkone
Warum? Weil "Hemd ohne Streifen" und "Hemd mit Streifen" semantisch extrem ähnlich sind. Beide handeln von Hemden und Streifen. Die Negation "ohne" kippt die Bedeutung komplett – aber im Embedding-Raum sind die Vektoren fast identisch.
Die Mathematik hinter dem Problem
Um zu verstehen, warum Embeddings an Negation scheitern, müssen wir einen Blick auf die zugrunde liegende Mathematik werfen.
Cosinus-Ähnlichkeit: Das Herzstück der Vektorsuche
Die Ähnlichkeit zwischen zwei Embedding-Vektoren wird typischerweise über die Cosinus-Ähnlichkeit gemessen:
Geometrisch betrachtet misst diese Formel den Winkel zwischen zwei Vektoren:
- cos = 1: Vektoren zeigen in dieselbe Richtung (identische Bedeutung)
- cos = 0: Vektoren stehen senkrecht zueinander (keine Beziehung)
- cos = -1: Vektoren zeigen in entgegengesetzte Richtungen
Warum "ohne" im Vektorraum verloren geht
Ein Bi-Encoder (z.B. all-MiniLM-L6-v2 oder e5-large) komprimiert einen ganzen Satz in einen einzigen Vektor mit 384–1024 Dimensionen. Die Herausforderung dabei:
"Hemd mit Streifen" → vec_a ∈ ℝ^768
"Hemd ohne Streifen" → vec_b ∈ ℝ^768
Beide Sätze teilen sich:
- Das Konzept "Hemd" (dominant im Vektor)
- Das Konzept "Streifen" (stark präsent)
- Grammatische Struktur (ähnliche Token-Positionen)
Das Wort "ohne" trägt nur einen winzigen Teil zum Gesamtvektor bei – und dieser Teil wird beim Mean-Pooling über alle Token-Embeddings förmlich verwässert:
┌─────────────────────────────────────────┐
│ "Hemd ohne Streifen" │
│ │
│ [Hemd] [ohne] [Streifen] │
│ ↓ ↓ ↓ │
│ e_1 e_2 e_3 │
│ ↘ ↓ ↙ │
│ Mean Pooling │
│ ↓ │
│ final_embedding ∈ ℝ^768 │
└─────────────────────────────────────────┘
Das Token "ohne" macht nur ~33% der Eingabe aus, aber seine semantische Bedeutung (Negation!) sollte 100% des Ergebnisses bestimmen. Diese asymmetrische Wichtigkeit kann ein einfaches Mittelwert-Pooling nicht erfassen.
Ein konkretes Beispiel mit Zahlen
Nehmen wir an, unser Embedding-Modell produziert (stark vereinfacht) folgende 4-dimensionalen Vektoren:
"Hemd mit Streifen": [0.82, 0.71, 0.45, 0.12] (Hemd, Streifen, Muster, ...)
"Hemd ohne Streifen": [0.81, 0.68, 0.42, 0.15] (fast identisch!)
Die Cosinus-Ähnlichkeit zwischen beiden:
Das ergibt eine Ähnlichkeit von ~0.997 – praktisch identische Vektoren! Für das Retrieval-System sind beide Anfragen kaum unterscheidbar.
Die Demo: "Shirt Without Stripes"
Um dieses Problem greifbar zu machen, haben wir einen Proof-of-Concept entwickelt: Eine E-Commerce-Suche mit 40 Hemden – einige gestreift, einige einfarbig.
Die Suchanfrage: "shirt without stripes"
Dense-only Ergebnis (klassische Vektorsuche)
| # | Titel | Pattern |
|---|---|---|
| 29 | Blue Shirt No Stripes | solid |
| 19 | Patternless Sky Blue Shirt | solid |
| 37 | Black Striped Button-Down | striped |
| 38 | Azure Solid Shirt | solid |
| 3 | Navy Striped Casual Shirt | striped |
| 21 | Stripeless Navy Shirt | solid |
| 31 | Grey Striped Tee | striped |
Das Problem ist offensichtlich: Gestreifte Hemden erscheinen mitten in den Ergebnissen – obwohl explizit nach "without stripes" gesucht wurde.
Die Lösung: Ein Hybrid Multi-Stage Pipeline
Die Erkenntnis: Kein einzelnes System löst alle Probleme. Die Antwort liegt in der Kombination verschiedener Retrieval-Methoden, die jeweils ihre Stärken einbringen.
Unsere 4-Stufen-Pipeline
┌─────────────────────────────────────────────────────────┐
│ Stage 1: Dense Retrieval (Bi-Encoder) │
│ → Semantisches Verständnis, ~30 Kandidaten │
├─────────────────────────────────────────────────────────┤
│ Stage 2: ColBERT Multi-Vector (optional) │
│ → Token-Level Matching für Phrasen │
├─────────────────────────────────────────────────────────┤
│ Stage 3: Sparse Rule-Based Filter │
│ → Harte Constraints: Negation, Preis, Farbe │
├─────────────────────────────────────────────────────────┤
│ Stage 4: Cross-Encoder Re-Ranking │
│ → Finale Präzision durch paarweise Bewertung │
└─────────────────────────────────────────────────────────┘
Stage 1: Dense Retrieval – Semantischer Recall
Der erste Schritt nutzt einen Bi-Encoder (z.B. all-MiniLM-L6-v2), um alle Produkte in 384-dimensionale Vektoren zu kodieren. Bei einer Suchanfrage wird der Query-Vektor mit allen Produkt-Vektoren verglichen.
Stärke: Versteht Synonyme und Bedeutung Schwäche: Ignoriert Negation
Stage 2: ColBERT – Token-Level Matching (Late Interaction)
ColBERT (Contextualized Late Interaction over BERT) verfolgt einen fundamental anderen Ansatz: Statt einen einzigen Vektor pro Dokument zu erstellen, behält es Embeddings für jedes Token.
Die Ähnlichkeit wird über Maximum Similarity (MaxSim) berechnet:
Dabei ist das Embedding des i-ten Query-Tokens und das Embedding des j-ten Dokument-Tokens.
Visualisierung der MaxSim-Berechnung
Query: "shirt without stripes"
↓
[shirt] [without] [stripes]
q₁ q₂ q₃
Document: "Blue solid shirt, no patterns"
↓
[Blue] [solid] [shirt] [no] [patterns]
d₁ d₂ d₃ d₄ d₅
Ähnlichkeitsmatrix (Dot Products):
d₁ d₂ d₃ d₄ d₅
q₁ 0.21 0.34 0.95 0.18 0.28 → max = 0.95
q₂ 0.12 0.22 0.15 0.78 0.31 → max = 0.78
q₃ 0.25 0.19 0.21 0.35 0.82 → max = 0.82
─────────
MaxSim = 0.95 + 0.78 + 0.82 = 2.55
Der entscheidende Vorteil: "without" (q₂) findet seinen besten Match mit "no" (d₄) – das Modell hat gelernt, dass diese Tokens semantisch verwandt sind. Bei einem Bi-Encoder wäre diese feinkörnige Information im aggregierten Vektor verloren gegangen.
Vorteil für Negation: Die Phrase "without stripes" wird als zusammenhängende Einheit besser erfasst, weil jedes Token seinen eigenen "besten Partner" im Dokument finden kann.
Stage 3: Sparse Filter – Harte Constraints
Hier passiert die eigentliche Magie für Negation. Ein einfacher Query Parser extrahiert:
# Eingabe: "shirt without stripes"
ParsedQuery(
must_terms=["shirt"],
must_not_terms=["stripes"], # ← Negation erkannt!
color=None,
price_under=None
)
Der Parser erkennt Negations-Cues wie:
- "without", "no", "not"
- "-less" Suffix (z.B. "stripeless")
- Deutsche Varianten: "ohne", "kein"
Die gefilterten Kandidaten werden dann hart ausgeschlossen:
# Synonym-Expansion
"stripes" → ["stripe", "striped", "pinstripe", "pinstriped"]
# Alle Produkte mit diesen Begriffen entfernen
result = result[~result["title"].str.contains(pattern)]
Stärke: Garantiert keine False Positives Schwäche: Kein Ranking, nur Ja/Nein
Stage 4: Cross-Encoder – Finale Präzision
Nach dem Filtern bleiben vielleicht 15 Produkte übrig – alle ohne Streifen. Aber wie sortieren wir sie?
Ein Cross-Encoder (z.B. ms-marco-MiniLM oder BGE-reranker) bewertet jedes Paar aus Query und Produkt-Text direkt:
pairs = [
("shirt without stripes", "Blue Shirt No Stripes. Blue shirt..."),
("shirt without stripes", "Azure Solid Shirt. Azure shade..."),
...
]
scores = cross_encoder.predict(pairs)
Warum Cross-Encoder so viel genauer sind
Der fundamentale Unterschied zu Bi-Encodern liegt in der Attention-Architektur:
Bi-Encoder: Cross-Encoder:
┌─────────┐ ┌─────────┐ ┌────────────────────────┐
│ Query │ │ Doc │ │ [CLS] Query [SEP] Doc │
│ ↓ │ │ ↓ │ │ ↓ │
│Encoder A│ │Encoder A│ │ 12-Layer BERT │
│ ↓ │ │ ↓ │ │ (Full Cross-Attention)│
│ vec_q │ │ vec_d │ │ ↓ │
└────┬────┘ └────┬────┘ │ Relevance Score │
│ │ └────────────────────────┘
└──cosine()───┘
Interaktion: KEINE Interaktion: VOLLSTÄNDIG
(unabhängig kodiert) (jedes Token sieht alles)
Beim Cross-Encoder kann jedes Query-Token auf jedes Dokument-Token "aufmerksam" sein (und umgekehrt). Das ermöglicht komplexe Reasoning-Patterns wie:
- "without" im Query + "striped" im Dokument → negativer Einfluss
- "blue" im Query + "azure" im Dokument → positiver Einfluss
Stärke: Höchste Präzision durch vollständige paarweise Bewertung Schwäche: O(n²) Komplexität – nur für Top-k Kandidaten praktikabel (typisch: 50-200)
Ergebnis: Hybrid schlägt Dense-only
Nach Anwendung aller vier Stufen:
| # | Titel | Pattern | Score |
|---|---|---|---|
| 29 | Blue Shirt No Stripes | solid | 0.94 |
| 19 | Patternless Sky Blue Shirt | solid | 0.91 |
| 38 | Azure Solid Shirt | solid | 0.88 |
| 21 | Stripeless Navy Shirt | solid | 0.85 |
| 28 | Black Pattern-Free Shirt | solid | 0.82 |
Kein einziges gestreiftes Hemd – und die relevantesten Treffer (die "no stripes" explizit erwähnen) stehen ganz oben.
Score-Fusion: Wie kombiniert man verschiedene Signale?
Ein oft übersehenes Problem: Wie kombiniert man Scores aus verschiedenen Retrieval-Stufen? BM25-Scores haben eine andere Skala als Cosinus-Ähnlichkeiten!
Reciprocal Rank Fusion (RRF)
Die elegante Lösung: Verwende Ränge statt Rohscores. Ränge sind immer 1, 2, 3, ... – unabhängig von der Scoring-Skala.
Dabei ist eine Konstante (typisch: 20-60), die bestimmt, wie stark Top-Ränge bevorzugt werden.
Beispiel: Ein Dokument auf Rang 1 bei BM25 und Rang 5 bei Dense-Retrieval:
Dokumente, die in mehreren Listen weit oben stehen, akkumulieren hohe RRF-Scores – ein robustes Voting-System.
Die wichtigsten Erkenntnisse
1. Vektordatenbanken allein können keine Negation
Embedding-basierte Suche ist mächtig, aber sie hat konzeptionelle Grenzen. "ohne" und "mit" sind semantisch fast identisch – nur der Kontext unterscheidet sie.
Mathematisch gesprochen: Die Negation ist ein niedrigdimensionales Signal in einem hochdimensionalen Raum. Beim Mean-Pooling über 512+ Tokens geht dieses Signal im Rauschen unter.
2. Pragmatismus schlägt Purismus
Wir hätten eine komplexe formale Grammatik implementieren können. Stattdessen reichen einfache Regex-Patterns für die häufigsten Negations-Cues:
NEGATION_CUES = ["without", "no", "not", "without any", "ohne", "kein"]
NEGATION_SUFFIXES = ["-less", "-free"]
Das deckt 95% der realen Suchanfragen ab – ein klassisches Pareto-Prinzip.
3. Synonym-Expansion ist kritisch
"stripes" ≠ "striped" ≠ "pinstripe" in der Textsuche. Ohne Expansion würde ein Produkt mit "striped" im Titel durch den Filter rutschen.
Für robuste Expansion kann man entweder:
- Manuelle Synonym-Listen pflegen
- Word-Embeddings für automatische Expansion nutzen (alle Wörter mit cos > 0.7 zum Seed-Term)
- Stemming/Lemmatisierung als Preprocessing
4. Multi-Stage ist der Schlüssel
Jede Stufe hat ihre Stärke und ihre optimale Position in der Pipeline:
| Stufe | Methode | Kandidaten | Stärke |
|---|---|---|---|
| 1 | Dense Bi-Encoder | 10.000 → 100 | Semantischer Recall |
| 2 | ColBERT (optional) | 100 → 50 | Token-Level Präzision |
| 3 | Sparse Filter | 50 → 30 | Harte Constraints |
| 4 | Cross-Encoder | 30 → 10 | Finale Präzision |
Die Kombination liefert bessere Ergebnisse als jede einzelne Methode – und bleibt dabei skalierbar.
Komplexitätsanalyse: Warum Multi-Stage skaliert
Ein häufiges Missverständnis: "Mehr Stufen = langsamer". In Wirklichkeit ist das Gegenteil der Fall.
Naive Suche mit Cross-Encoder:
- 10.000 Dokumente × Cross-Encoder-Inference = 10.000 × ~50ms = 8+ Minuten
Multi-Stage Pipeline:
- Dense Retrieval (ANN): 10.000 → 100 in ~5ms (Vektorindex)
- Sparse Filter: 100 → 30 in ~1ms (Regex)
- Cross-Encoder: 30 × 50ms = 1.5 Sekunden
Gesamtzeit: ~1.5s statt 8 Minuten – eine Beschleunigung um Faktor 300!
Wann ist dieser Ansatz sinnvoll?
Der Hybrid-Ansatz eignet sich besonders für:
- E-Commerce-Suche mit komplexen Filtern (Preis, Farbe, Negation)
- Dokumentensuche mit Ausschlusskriterien ("Verträge ohne Kündigungsklausel")
- Ausschreibungsportale – genau das setzen wir bei BidLyzer um
- Juristische Recherche ("Urteile ohne Freispruch")
- Medizinische Suche ("Medikamente ohne Penicillin-Allergen")
Die entscheidende Frage: Brauche ich Multi-Stage?
Ein einfacher Entscheidungsbaum:
Haben Sie nur Synonym-Probleme?
├─ Ja → Dense Retrieval reicht
└─ Nein
├─ Haben Sie Negations-Anforderungen?
│ └─ Ja → Sie brauchen Sparse Filter
├─ Ist Präzision kritischer als Recall?
│ └─ Ja → Cross-Encoder hinzufügen
└─ Haben Sie mehrsprachige Anfragen?
└─ Ja → ColBERT mit multilingualen Modellen
Offene Forschungsfragen
Dieses Problem ist keineswegs gelöst. Aktive Forschungsrichtungen:
-
Instruction-tuned Embeddings: Modelle wie E5-Instruct oder BGE-M3 können mit Prompt-Prefixen ("Find documents that do NOT contain...") trainiert werden – aber die Ergebnisse sind noch inkonsistent.
-
Contrastive Learning für Negation: Spezielle Trainingsdaten mit Negations-Paaren könnten Embeddings "negationsaware" machen.
-
Sparse-Dense Hybride: SPLADE und ähnliche Modelle lernen automatisch Term-Expansionen – aber auch sie strugglen mit expliziter Negation.
-
LLM-basierte Reranker: Große Sprachmodelle als finale Reranker verstehen Negation besser, sind aber (noch) zu langsam für Production.
Fazit
Semantic Search ist kein gelöstes Problem. Die aktuelle Generation von Embedding-Modellen hat fundamentale mathematische Grenzen – insbesondere bei:
- Negation ("ohne", "nicht", "kein")
- Numerische Vergleiche ("unter 50€", "mehr als 3 Zimmer")
- Komplexe logische Anfragen ("A und B, aber nicht C")
Die gute Nachricht: Mit einem durchdachten Multi-Stage-Ansatz lassen sich diese Grenzen elegant umgehen. Dense Retrieval liefert den semantischen Recall, ColBERT verfeinert auf Token-Ebene, regelbasierte Filter garantieren harte Constraints, und Cross-Encoder sorgen für präzises Ranking.
Das Ergebnis: Eine Suche, die endlich versteht, dass "Hemd ohne Streifen" wirklich ein Hemd ohne Streifen sein soll.
Dieser Artikel basiert auf Forschung und Entwicklung für unsere BidLyzer-Plattform. Ein ausführlicher Vortrag zu diesem Thema wird voraussichtlich auf der decompiled.de 2026 (12. März) präsentiert.
Die hier beschriebenen Methoden fließen in unsere Arbeit bei der KI-gestützten Suche & Retrieval ein.
Kontaktieren Sie uns, wenn Sie ähnliche Herausforderungen in Ihrem Suchsystem haben.
Klingt nach Ihrem Thema?
30 Minuten Erstgespräch, wenn dieser Beitrag eine konkrete Frage zu Ihrer Ausgangslage aufgeworfen hat. Kostenfrei und fachlich fokussiert.
Erstgespräch vereinbaren