164 lines
4.6 KiB
Markdown
164 lines
4.6 KiB
Markdown
|
|
# Analyse: Retrieval-Unterschiede zwischen Dev und Prod
|
||
|
|
|
||
|
|
**Datum**: 2026-01-12
|
||
|
|
**Version**: v4.5.10
|
||
|
|
**Status**: 🔴 Kritisch
|
||
|
|
|
||
|
|
## Problemstellung
|
||
|
|
|
||
|
|
Bei identischer Codebasis und identischen Daten liefert das Dev-System Suchergebnisse, während das Prod-System keine Ergebnisse findet.
|
||
|
|
|
||
|
|
## Identifizierte Ursachen
|
||
|
|
|
||
|
|
### 1. 🔴 **KRITISCH: Inkonsistente Collection-Präfix-Konfiguration**
|
||
|
|
|
||
|
|
**Problem**: Zwei verschiedene Umgebungsvariablen werden für den Collection-Präfix verwendet:
|
||
|
|
|
||
|
|
1. **`app/config.py` (Zeile 24)**:
|
||
|
|
```python
|
||
|
|
COLLECTION_PREFIX: str = os.getenv("MINDNET_PREFIX", "mindnet_dev")
|
||
|
|
```
|
||
|
|
- Verwendet `MINDNET_PREFIX` als Umgebungsvariable
|
||
|
|
- Default: `"mindnet_dev"`
|
||
|
|
|
||
|
|
2. **`app/core/database/qdrant.py` (Zeile 47)**:
|
||
|
|
```python
|
||
|
|
prefix = os.getenv("COLLECTION_PREFIX") or "mindnet"
|
||
|
|
```
|
||
|
|
- Verwendet `COLLECTION_PREFIX` als Umgebungsvariable
|
||
|
|
- Default: `"mindnet"`
|
||
|
|
|
||
|
|
**Auswirkung**:
|
||
|
|
- **Retriever verwendet `QdrantConfig.from_env()`**, das `COLLECTION_PREFIX` liest
|
||
|
|
- **Ingestion verwendet `Settings.COLLECTION_PREFIX`**, das `MINDNET_PREFIX` liest
|
||
|
|
- **Resultat**: Daten werden in verschiedene Collections geschrieben/gesucht:
|
||
|
|
- Dev: `mindnet_dev_chunks`, `mindnet_dev_notes`, `mindnet_dev_edges`
|
||
|
|
- Prod: `mindnet_chunks`, `mindnet_notes`, `mindnet_edges`
|
||
|
|
|
||
|
|
### 2. ⚠️ **Mögliche weitere Ursachen**
|
||
|
|
|
||
|
|
#### 2.1 Unterschiedliche Embedding-Modelle
|
||
|
|
- **Prüfen**: `MINDNET_EMBEDDING_MODEL` in Dev vs. Prod
|
||
|
|
- **Auswirkung**: Unterschiedliche Vektoren → unterschiedliche Similarity-Scores
|
||
|
|
|
||
|
|
#### 2.2 Unterschiedliche Vektor-Dimensionen
|
||
|
|
- **Prüfen**: `VECTOR_DIM` in Dev vs. Prod
|
||
|
|
- **Auswirkung**: Dimension-Mismatch → Suche schlägt fehl
|
||
|
|
|
||
|
|
#### 2.3 Unterschiedliche Qdrant-Instanzen
|
||
|
|
- **Prüfen**: `QDRANT_URL` / `QDRANT_HOST` in Dev vs. Prod
|
||
|
|
- **Auswirkung**: Daten liegen in verschiedenen Datenbanken
|
||
|
|
|
||
|
|
#### 2.4 Unterschiedliche Score-Thresholds
|
||
|
|
- **Prüfen**: Filter-Logik oder Mindest-Scores
|
||
|
|
- **Auswirkung**: Ergebnisse werden gefiltert, bevor sie zurückgegeben werden
|
||
|
|
|
||
|
|
## Diagnose-Checkliste
|
||
|
|
|
||
|
|
### ✅ Sofort prüfen:
|
||
|
|
|
||
|
|
1. **Collection-Präfix-Verifikation**:
|
||
|
|
```bash
|
||
|
|
# Dev
|
||
|
|
echo $COLLECTION_PREFIX
|
||
|
|
echo $MINDNET_PREFIX
|
||
|
|
|
||
|
|
# Prod
|
||
|
|
echo $COLLECTION_PREFIX
|
||
|
|
echo $MINDNET_PREFIX
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Qdrant Collections prüfen**:
|
||
|
|
```python
|
||
|
|
# In beiden Systemen ausführen
|
||
|
|
from app.core.database.qdrant import get_client, QdrantConfig
|
||
|
|
cfg = QdrantConfig.from_env()
|
||
|
|
client = get_client(cfg)
|
||
|
|
print(f"Prefix: {cfg.prefix}")
|
||
|
|
print(f"Collections: {client.get_collections().collections}")
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Embedding-Modell prüfen**:
|
||
|
|
```bash
|
||
|
|
# Dev
|
||
|
|
echo $MINDNET_EMBEDDING_MODEL
|
||
|
|
echo $VECTOR_DIM
|
||
|
|
|
||
|
|
# Prod
|
||
|
|
echo $MINDNET_EMBEDDING_MODEL
|
||
|
|
echo $VECTOR_DIM
|
||
|
|
```
|
||
|
|
|
||
|
|
4. **Qdrant-Verbindung prüfen**:
|
||
|
|
```bash
|
||
|
|
# Dev
|
||
|
|
echo $QDRANT_URL
|
||
|
|
echo $QDRANT_HOST
|
||
|
|
echo $QDRANT_PORT
|
||
|
|
|
||
|
|
# Prod
|
||
|
|
echo $QDRANT_URL
|
||
|
|
echo $QDRANT_HOST
|
||
|
|
echo $QDRANT_PORT
|
||
|
|
```
|
||
|
|
|
||
|
|
## Lösungsvorschläge
|
||
|
|
|
||
|
|
### Option 1: Harmonisierung der Umgebungsvariablen (Empfohlen)
|
||
|
|
|
||
|
|
**Ziel**: Eine einzige Umgebungsvariable für den Collection-Präfix verwenden.
|
||
|
|
|
||
|
|
**Änderungen**:
|
||
|
|
1. **`app/core/database/qdrant.py`**:
|
||
|
|
```python
|
||
|
|
prefix = os.getenv("COLLECTION_PREFIX") or os.getenv("MINDNET_PREFIX") or "mindnet"
|
||
|
|
```
|
||
|
|
- Unterstützt beide Variablen (Abwärtskompatibilität)
|
||
|
|
- `COLLECTION_PREFIX` hat Priorität
|
||
|
|
|
||
|
|
2. **`app/config.py`**:
|
||
|
|
```python
|
||
|
|
COLLECTION_PREFIX: str = os.getenv("COLLECTION_PREFIX") or os.getenv("MINDNET_PREFIX") or "mindnet_dev"
|
||
|
|
```
|
||
|
|
- Unterstützt beide Variablen
|
||
|
|
- `COLLECTION_PREFIX` hat Priorität
|
||
|
|
|
||
|
|
3. **Dokumentation**: Klarstellen, dass `COLLECTION_PREFIX` die primäre Variable ist
|
||
|
|
|
||
|
|
### Option 2: Explizite Konfiguration in .env
|
||
|
|
|
||
|
|
**Ziel**: Beide Systeme verwenden explizit gesetzte `COLLECTION_PREFIX` Werte.
|
||
|
|
|
||
|
|
**Dev `.env`**:
|
||
|
|
```env
|
||
|
|
COLLECTION_PREFIX=mindnet_dev
|
||
|
|
```
|
||
|
|
|
||
|
|
**Prod `.env`**:
|
||
|
|
```env
|
||
|
|
COLLECTION_PREFIX=mindnet
|
||
|
|
```
|
||
|
|
|
||
|
|
### Option 3: Daten-Migration
|
||
|
|
|
||
|
|
**Ziel**: Daten von einer Collection in die andere migrieren.
|
||
|
|
|
||
|
|
**Vorgehen**:
|
||
|
|
1. Identifizieren, welche Collection die "richtigen" Daten enthält
|
||
|
|
2. Daten von Dev nach Prod migrieren (oder umgekehrt)
|
||
|
|
3. Collection-Präfix harmonisieren
|
||
|
|
|
||
|
|
## Sofortmaßnahmen
|
||
|
|
|
||
|
|
1. ✅ **Prüfen**: Welche Collections existieren in beiden Systemen?
|
||
|
|
2. ✅ **Prüfen**: Welche Umgebungsvariablen sind gesetzt?
|
||
|
|
3. ✅ **Prüfen**: Welche Collection enthält die Daten?
|
||
|
|
4. ✅ **Fix**: Collection-Präfix-Konfiguration harmonisieren
|
||
|
|
5. ✅ **Test**: Retrieval in beiden Systemen verifizieren
|
||
|
|
|
||
|
|
## Erwartetes Ergebnis nach Fix
|
||
|
|
|
||
|
|
- ✅ Beide Systeme verwenden dieselbe Collection-Präfix-Logik
|
||
|
|
- ✅ Retrieval findet Daten in beiden Systemen
|
||
|
|
- ✅ Konsistente Konfiguration zwischen Ingestion und Retrieval
|