# LLM Router Setup — Multi-Provider Enrichment
**Status:** ✅ Implementiert (nach Dottores Spezifikation)
---
## Was ist das?
Refactored **contact_enricher.py** nutzt jetzt einen **Multi-LLM Router** mit intelligenter Eskalation:
```
Level 1: gpt-5-nano ($0.05/M input) ← Billig starten
↓ Validierungsfehler → Eskalation
Level 2: gpt-5-mini ($0.25/M input) ← Mittel
↓ Validierungsfehler → Eskalation
Level 3: claude-haiku ($0.80/M input) ← Fallback (Qualität)
```
**Kostenersparnis:** ~60-70% vs. direktes Claude-Only-Enrichment
---
## Setup
### 1. Kopiere .env Template
```bash
cp .env.template .env
```
### 2. Fülle .env aus
```
OPENAI_API_KEY=sk-proj-...
OPENAI_MODEL_LOW=gpt-5-nano
OPENAI_MODEL_MID=gpt-5-mini
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_MODEL_HIGH=claude-haiku-4-5-20251001
```
### 3. Installiere Dependencies
```bash
pip install -r requirements.txt
```
---
## Verwendung (Identisch zu alt)
```bash
# Erste 50 Kontakte anreichern
python contact_enricher.py --batch 50
# Oder ganze Kampagne
python contact_enricher.py --campaign 6
# Statistiken + Performance-Check
python contact_enricher.py --batch 1
# → druckt Statistiken mit Router-Performance
```
---
## Harte Regeln (von Dottore)
1. ✅ **Kein valides JSON → kein Speichern**
- Validierung in `llm/validator.py`
- CRITICAL + IMPORTANT Felder sind Pflicht
2. ✅ **Jeder Provider genau 1 Versuch**
- Router versucht Nano, dann Mini, dann Claude
- Kein Retry auf gleichem Level
3. ✅ **Sofortige Eskalation bei Fehler**
- Validierungsfehler → nächstes Modell
- API-Fehler → nächstes Modell
4. ✅ **Validierungsquote nach 50 Requests**
- <70% success rate → Modell wird downpriorisiert
- Bleibt aber als Fallback aktiv
5. ✅ **3 Kontakte in Folge: alle Level fail → Prozess stoppen**
- Diese Kontakte → status `needs_manual`
- Keine weiteren API Calls (spart Kosten)
---
## Architektur
### Dateistruktur
```
llm/
├── __init__.py # Modul-Einstiegspunkt
├── base.py # Provider-Interface (abstrakt)
├── validator.py # Gestaffelte Validierung (CRITICAL/IMPORTANT/OPTIONAL)
├── logger.py # Audit-Logging pro Modell
├── openai_provider.py # OpenAI (Nano & Mini)
├── anthropic_provider.py # Anthropic (Claude Fallback)
└── router.py # Eskalationslogik & Performance-Control
```
### Logik-Flow
```
contact_enricher._enrich_contact()
│
├─→ Website scrapen (oder cache)
│
├─→ Prompt generieren (_build_enrichment_prompt)
│
├─→ run_enrichment(prompt, contact_id) [FROM llm/router.py]
│ │
│ ├─→ Level 1: OpenAI Nano
│ │ - extract() + JSON-parse
│ │ - validate() (CRITICAL + IMPORTANT)
│ │ - ✓ Erfolg → RETURN
│ │ - ✗ Fehler → Eskalation
│ │
│ ├─→ Level 2: OpenAI Mini
│ │ - [same as Level 1]
│ │
│ ├─→ Level 3: Claude Haiku
│ │ - [same as Level 1]
│ │
│ └─→ Alle Level fail → Error Handling
│ - consecutive_fails++
│ - Wenn >=3 → Prozess STOP
│ - Kontakt → needs_manual
│
├─→ Speichern (nur bei success=True)
│
└─→ Logging (model, tokens, success_rate, etc.)
```
---
## Validierung
**CRITICAL Felder** (ALLE müssen vorhanden sein):
- `pain_point` — das Problem der Firma
- `icp_recommended_product` — unser Angebot
- `company_description` — was die Firma macht
**IMPORTANT Felder** (mindestens 2/2 müssen vorhanden sein):
- `company_size` — Mitarbeiterzahl
- `headquarters` — Standort
**OPTIONAL Felder** (nice-to-have):
- `founding_year`, `technology_stack`, `key_products`, `linkedin_url`, etc.
→ Wenn Validierung feilt → nächstes Modell
---
## Performance-Monitoring
Nach 50 Kontakten:
```
Success Rate pro Modell:
- gpt-5-nano: 45/50 = 90% ✓ Weiterhin Level 1
- gpt-5-mini: 35/50 = 70% ✓ Grenzwert, ok
- gpt-5-mini: 32/50 = 64% ✗ <70% → Downpriorisiert
(bleibt aber als Fallback aktiv!)
```
→ Router passe sich automatisch an
---
## Statistiken
Nach Batch-Run:
```
=== Enrichment Statistics ===
gpt-5-nano: 45/50 (90.0%) | 500000 tokens
gpt-5-mini: 35/50 (70.0%) | 350000 tokens
claude-haiku: 5/50 (10.0%) | 100000 tokens
Router Status:
Consecutive failures: 0/3
Downprioritized models: ['gpt-5-mini']
```
---
## Fehlerbehandlung
### 3 Kontakte in Folge: FAIL
```
[123] ALL LEVELS FAILED. Consecutive failures: 3/3
→ Aborting enrichment process. Setting to needs_manual.
```
→ Prozess stoppt (spart Kosten!)
---
## API-Keys konfigurieren
### OpenAI
1. Gehe zu https://platform.openai.com/api-keys
2. Erstelle einen neuen Key
3. `.env`: `OPENAI_API_KEY=sk-proj-...`
### Anthropic
1. Gehe zu https://console.anthropic.com/
2. Erstelle einen neuen Key
3. `.env`: `ANTHROPIC_API_KEY=sk-ant-...`
---
## Kosten-Tracking
Jeder API Call wird geloggt mit:
- contact_id
- model_used
- level
- success (true/false)
- validation_result
- tokens_used
→ Später: Kosten-Dashboard möglich
---
## Problembehebung
**"OPENAI_API_KEY nicht gesetzt"**
→ Kopiere `.env.template` zu `.env` und fülle aus
**"Alle Level fehlgeschlagen"**
→ Kontakt wurde zu `needs_manual` gesetzt
→ Überprüfe: Website erreichbar? JSON-Format korrekt?
**"Modell wird downpriorisiert"**
→ Nach 50 Requests: <70% success rate
→ Normalverhalten, Fallback bleibt aktiv
---
## Nächste Schritte
1. ✅ Setup .env
2. ✅ `pip install -r requirements.txt`
3. ✅ Test: `python contact_enricher.py --batch 5`
4. ✅ Monitor: Schaue auf Statistiken
5. ✅ Scale: `python contact_enricher.py --campaign 6`
---
*Implementiert nach Dottores Spezifikation: 7 Punkte, Zero Ambiguity*