Zuletzt aktualisiert:

Benchmark: Claude-Sub (claude -p) vs. Gemini für die AI-Jobs (07.06.2026)

Frage

Wir nutzen für die meisten AI-Jobs OpenRouter gemini-3.1-flash-lite (kostet pro Call), obwohl die Claude-Subscription vorhanden ist. Lohnt der Umstieg auf die Sub, um Geld zu sparen — jetzt, wo wir wissen, dass die alte „claude -p ist langsam"-Messung am Extended Thinking + Dev-Ballast lag?

Kurzantwort

Nein, nicht für die latenz-sensiblen Text-Jobs. Selbst voll optimiert (Thinking aus via MAX_THINKING_TOKENS=0, kein Dev-Ballast via --setting-sources project,local) ist die claude-CLI 5–20× langsamer als Gemini. Grund ist ein fixer Per-Call-Overhead von ~4–5 s (schwerer Basis-System-Prompt + Prozess-Init/Auth pro Aufruf), der sich nicht wegoptimieren lässt. Gemini-flash-lite bekommt nur den User-Prompt und antwortet in Sekundenbruchteilen.

Messungen (gleicher Prompt, Wall-Clock)

Task Gemini (OpenRouter) Claude-fast (Sub, Thinking aus, lean)
portion (winzig: 1 Lebensmittel → {portion_g, portion_name}) 0,4 s ~6–8 s (API ttft allein 3,8 s)
estimate (winzig: Freitext → kcal/Makros) ~0,5 s ~5,6 s
ideas (groß: Vorrat-Kontext → 3 Gericht-Vorschläge) 3,4 s ~17,9 s

Claude-Modellwahl ändert wenig: Opus statt Sonnet war bei der PDF-Extraktion gleich schnell (45 s vs 44 s). Ein „fast mode" (/fast, Opus mit schnellerer Ausgabe) existiert nur interaktiv, nicht im Headless-claude -p (fast_mode_state: off).

Einordnung

Idee: persistente Session statt Prozess-pro-Job?

Gemessen, woher die ~6 s pro Mini-Call kommen:

Block Zeit persistente Session hilft?
Prozess-Spawn (claude --version) 0,12 s — (vernachlässigbar)
CLI-Init (Settings/Tools/MCP laden, System-Prompt bauen, Cache aufsetzen) ~4 s ja — fällt weg
Reine API-Zeit (ttft ~2 s, Haiku) ~2 s teils (Cache bleibt warm)

Bei 3 Calls hintereinander blieb cache_creation jedes Mal ~13.000 Token (neu erzeugt, nicht gelesen) — separate claude -p-Prozesse teilen den Prompt-Cache nicht. Eine persistente Session (eine lebende claude-Instanz im stream-json-Input-Modus, je Job ein Turn, Kontext dazwischen zurücksetzen) würde die ~4 s Init sparen UND den System-Prompt-Cache warmhalten → Mini-Tasks grob ~6 s → ~2 s.

Warum es trotzdem (noch) nicht gebaut wird:

Fazit der Idee: technisch tragfähig, aber Over-Engineering für das aktuelle Volumen. Falls die claude-CLI-Jobs (receipt_pdf) je häufig/latenzkritisch werden, ist die persistente Session der richtige Hebel — dann mit der Agent-SDK (saubere Sessions statt stream-json-Bastelei).

Nachtrag: receipt_pdf läuft jetzt auf Gemini (geschärfter Prompt + LLM-Judge)

Für die Bon-Extraktion gilt das Latenz-Argument umgekehrt: Gemini liest die PDF nativ und ist ~9 s vs ~44 s (Claude-Read) bei gleicher Qualität. Daher wurde job_receipt_pdf auf das ADR-37-Muster umgestellt: Gemini zuerst (PDF-file-Block), claude-CLI+Read als Fallback — beide mit demselben geschärften Prompt.

Prompt-Schärfung (aus PDF-Analyse + 4× Lauf + Claude-as-Judge): - Rabattzeilen ("K Card XTRA Rabatt", "Artikelrabatt") → is_discount=true, KEIN Katalog-Artikel (sonst Phantom-Produkte). receipt_import überspringt Food-Matching für is_discount/Regex. - Pfand vs Leergut: "Pfandartikel" positiv, "Leergut" negativ, beide is_deposit. - is_weight nur bei echter X,XXX kg x €/kg-Ware; Gewicht IM Namen ("Huhn 1,4kg", "Nutella 450g") ist KEINE Gewichtsware. - Große Mengen (z.B. "60 * 0,33") sind echt (Party-Einkauf), nicht "korrigieren".

Verifikation: 4/4 Gemini-Läufe identisch (57 Pos, Σ=170,38 centgenau, 0 Phantom, 0 kg). Claude-Sonnet als unabhängiger Judge: „korrekt, alle 57 Positionen vollständig und korrekt erfasst." Ende-zu-Ende durch den Worker: 10 s (Gemini), Fallback-getestet (53 s Claude, ebenfalls korrekt).

Falle: or_chat hatte max_tokens=3000 default → bei 57 Positionen schnitt Gemini das JSON ab → Parse-Fehler → Fallback. Behoben: max_tokens durchgereicht, receipt_pdf nutzt 8000.

Kosten: ~$0,005/Bon (Cent-Bereich). EXPECTED_S[receipt_pdf] von 50 → 15.

Entscheidung


Bezug: ADR-37 (OpenRouter-zuerst), BENCHMARK-OPENROUTER-2026-06-06 (Vormessung, noch MIT Thinking/Ballast), Commit e72465b (fast=True).