feat: AutoContext-Suche grundlegend verbessern + Embedding-Debug-Tool

Hybrid-Suche (Vektor + FTS5-Keyword), Recency-Boost, Query-Erweiterung
(letzte 2-3 User-Messages), Chunk-Overlapping, FullText-Speicherung,
konfigurierbares Embedding-Modell/MaxSeqLen, deduplizierter AutoContext-
Code (Streaming + CLI shared), Admin-Diagnose-Seite mit Re-Embed-Funktion.
Threshold von 0.45 auf 0.35 gesenkt (Hybrid-Suche ist präziser).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.6 committed 2026-04-01 08:50:41 +02:00
1 parent be6d33691a
commit 3f2baa1639
14 files changed
+1103 -61

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
# Plan: SentencePiece-Tokenizer-Support für multilinguales Embedding-Modell
## Ziel
`paraphrase-multilingual-MiniLM-L12-v2` als alternatives Embedding-Modell ermöglichen, indem der `EmbeddingService` neben WordPiece (BERT) auch SentencePiece (XLM-RoBERTa) Tokenizer unterstützt.
## Hintergrund
- Aktuell: `all-MiniLM-L6-v2` (BERT, WordPiece, `vocab.txt`, 384 Dims)
- Ziel-Modell: `paraphrase-multilingual-MiniLM-L12-v2` (XLM-RoBERTa, SentencePiece, `sentencepiece.bpe.model`, 384 Dims)
- Problem: Unser Tokenizer ist hardcoded auf WordPiece – Special Tokens (`[CLS]`/`[SEP]`), `token_type_ids`, `vocab.txt`
## Unterschiede zwischen den Tokenizern
| Aspekt | WordPiece (BERT) | SentencePiece (XLM-R) |
|---|---|---|
| Vocab-Datei | `vocab.txt` | `sentencepiece.bpe.model` |
| Special Tokens | `[CLS]`=101, `[SEP]`=102, `[PAD]`=0 | `<s>`=0, `</s>`=2, `<pad>`=1 |
| token_type_ids | Required (alle 0) | Nicht verwendet |
| Subword-Prefix | `##` | `▁` (U+2581) |
| Vocab-Groesse | ~30.522 | ~250.002 |
---
## Schritte
### Schritt 1: NuGet-Paket hinzufuegen
- `Microsoft.ML.Tokenizers.SentencePieceBpe` oder `SentencePieceSharp` evaluieren
- Kriterien: .NET 10 Kompatibilitaet, kein native-Dependency-Problem auf Linux, Lizenz
- Paket zu `gott.csproj` hinzufuegen
### Schritt 2: Tokenizer-Abstraktion in `EmbeddingService.cs`
- Interface oder Strategie-Pattern: `ITextTokenizer` mit Methode `Tokenize(string text, int maxLen) -> (long[] inputIds, long[] attentionMask, long[]? tokenTypeIds)`
- `WordPieceTokenizer` – bestehende Logik extrahieren (Zeilen 127-161)
- `SentencePieceTokenizer` – neue Implementierung
- Constructor-Logik: Wenn `vocab.txt` existiert -> WordPiece; wenn `sentencepiece.bpe.model` existiert -> SentencePiece
- Property `TokenizerType` fuer Debug/Logging
### Schritt 3: ONNX-Session Input anpassen
- WordPiece: 3 Inputs (`input_ids`, `attention_mask`, `token_type_ids`)
- SentencePiece: 2 Inputs (`input_ids`, `attention_mask`) – kein `token_type_ids`
- `GenerateEmbedding()` muss dynamisch die richtigen Inputs erstellen basierend auf Tokenizer-Typ
- ONNX Input-Names aus dem Modell lesen statt hardcoded (robuster)
### Schritt 4: Special Token IDs konfigurierbar machen
- `[CLS]`/`[SEP]` IDs vs. `<s>`/`</s>` IDs
- Am besten aus `special_tokens_map.json` oder `tokenizer_config.json` lesen, falls vorhanden
- Fallback: Hardcoded Mapping pro Tokenizer-Typ
### Schritt 5: Modell-Dateien bereitstellen
- Von HuggingFace herunterladen:
- `model.onnx` (ONNX-Export des Modells)
- `sentencepiece.bpe.model`
- Ablegen in `data/models/paraphrase-multilingual-MiniLM-L12-v2/`
- Server-Setting `EmbeddingModelDir` auf den neuen Ordner setzen
### Schritt 6: Re-Embed-Kompatibilitaet
- Dimensionen sind identisch (384) -> Keine DB-Schema-Aenderung noetig
- Re-Embed-Endpoint muss weiterhin funktionieren
- Beim Modell-Wechsel: **Alle** Embeddings muessen neu berechnet werden (altes Modell-Vektoren sind inkompatibel mit neuem Modell)
- Warnung im Admin-UI wenn Modell gewechselt wurde aber Re-Embed noch nicht gelaufen ist
### Schritt 7: Tests & Verifikation
- Embedding-Debug-Page nutzen: Gleiche Queries mit altem vs. neuem Modell vergleichen
- Testcases:
- Deutsche Query -> deutsche Messages ("weisst du was zum thema autocontext")
- Englische Query -> englische Messages ("skills")
- Gemischt -> gemischte Messages ("otter karten")
- Pruefen ob Scores sich verbessern (besonders fuer deutsche Queries)
---
## Betroffene Dateien
1. `gott.csproj` – NuGet-Paket
2. `Services/EmbeddingService.cs` – Tokenizer-Abstraktion, SentencePiece-Support
3. `wwwroot/js/embedding-debug.js` – ggf. Anzeige des aktiven Modells/Tokenizers
## Risiken
- **SentencePiece NuGet auf Linux**: Native Dependencies koennten Probleme machen -> vorher testen
- **Re-Embed Dauer**: 14k Messages mit 256 Tokens -> je nach CPU 5-30 Minuten
- **Dimensionen-Mismatch**: Falls ein zukuenftiges Modell andere Dims hat -> DB-Migration noetig (aktuell nicht, beide 384)
## Aufwand
- Geschaetzt: ~2-3 Stunden Implementierung
- Groesster Block: Tokenizer-Abstraktion sauber bauen