
Sprachbasiertes Detektiv-Verhörspiel. Mistral Large 3 + Voxtral STT + ElevenLabs TTS. Entwickelt für den Mistral Worldwide Hackathon 2026.

Ein sprachbasiertes Detektiv-Verhörspiel. Du bist der Detektiv. Mistral ist ein Verdächtiger, der lügt. Deine Aufgabe ist es, die Lüge allein durch Fragen zu entlarven.
Jeder Fall wird prozedural generiert – eine einzigartige Wirtschaftsstraftat, ein Verdächtiger, eine Deckgeschichte und eine verborgene Lüge. Der Verdächtige wird von Mistral Large gespielt, erhält eine vollständige Hintergrundgeschichte und wird angewiesen, die Deckgeschichte unter adversarialem Druck zu verteidigen. Keine zwei Fälle sind gleich.
Entwickelt für den Mistral Worldwide Hackathon 2026 (Online-Track).
„Mistral kann logisch denken. Ich habe es zum Lügen gebracht. Deine Aufgabe ist es, es zu ertappen.“
Die KI wird angewiesen, niemals zu gestehen, selbst bei maximalem Stress. Du gewinnst, indem du eine spezifische, genaue Anklage erhebst – nicht, indem du den Verdächtigen zum Einknicken bringst.
npm install
cp .env.example .env # Fülle deine API-Schlüssel ein
npm run dev # http://localhost:3000
MISTRAL_API_KEY= # Erforderlich – Fallgenerierung, Verhör, Bewertung, STT
ELEVENLABS_API_KEY= # Erforderlich – TTS für Verdächtigenstimme
ELEVENLABS_VOICE_ID= # Optional – spezifische ElevenLabs-Stimmen-ID
NEXT_PUBLIC_SUPABASE_URL= # Erforderlich – Supabase-Projekt-URL
NEXT_PUBLIC_SUPABASE_ANON_KEY= # Erforderlich – Supabase-Anon-Key (RLS-geschützt)
SUPABASE_SERVICE_ROLE_KEY= # Optional – Admin-Export-Endpunkt
EXPORT_SECRET= # Optional – Admin-Export-Authentifizierung
API-Schlüssel können auch auf der Einstellungsseite zur Laufzeit konfiguriert werden – die App wird ohne Schlüssel ausgeliefert, Spieler bringen ihre eigenen mit.
npm run dev # Dev-Server
npm run build # Produktions-Build
npm run start # Produktions-Server
npm run lint # ESLint
Ein unbegrenzter Timer-Modus ist ebenfalls verfügbar – auf schwer/Experte zieht der Verdächtige nach 4 aufeinanderfolgenden hochstressigen Austauschen einen Anwalt hinzu.
Hinweise werden bei Stressschwellen freigeschaltet, die über 1–9 verteilt sind, eingeschränkt durch:
Der Anklage-Button wird erst freigeschaltet, wenn alle erforderlichen Hinweise gesammelt wurden.
score = timeScore x difficultyMultiplier x efficiencyBonus x hintPenalty x accusationPenalty
timeScore = 1000 x sqrt(max(0, 1 - elapsed / (parTime x 2)))
multiplier = easy 1.0x, medium 1.5x, hard 2.0x, expert 2.5x
efficiencyBonus = 1.0-1.5x (weniger Fragen als par = Bonus)
hintPenalty = 0.85^hintsUsed
accusePenalty = max(0, 1 - wrongAccusations x 0.1)
Die Punktzahl wird serverseitig aus den zum Zeitpunkt des Gewinns eingefrorenen Statistiken berechnet – Client-Werte werden ignoriert.
app/
├── page.tsx # Titelbildschirm
├── cases/ # Fallauswahl – Orte + Schwierigkeitsgrad
├── game/
│ ├── page.tsx # Hauptspiel-Orchestrator
│ ├── hooks/ # useVoiceRecorder, useTTS, useGameTimer, useSfx, useSettings
│ ├── components/ # Dock, TopBar, CaseFile, SuspectZone, BriefingScreen, Dialoge
│ ├── win/ # Gewinnbildschirm + Initialeneingabe
│ └── lose/ # Verlustbildschirm
├── leaderboard/ # Top 20, Animation für neue Einträge
├── settings/ # API-Schlüssel-Konfiguration, Export, Einstellungen
├── help/ # Spielanleitung, Wertung, Über
├── about/ # Informationen zum Ersteller
└── api/
├── generate-case/ # GET – Mistral-Fallgenerierung
├── interrogate/ # POST – Spielerfrage → Verdächtigenantwort
├── accuse/ # POST – Anklagebewertung (separater Richter)
├── evaluate/ # POST – Gewinn-/Verlustanalyse
├── hint/ # POST – verschleierte Stressauslöser-Hinweise
├── tts/ # POST – ElevenLabs TTS
├── transcribe/ # POST – Voxtral STT
├── leaderboard/ # GET/POST – Supabase-Bestenliste
├── patterns/ # GET/POST – Sitzungsübergreifende Lernmuster
└── export/ # GET – Admin-JSONL-Export
src/lib/
├── mistral/ # Mistral-Client, Verhör, Bewertung, Fallgenerierung, Embeddings
├── game-session.ts # Serverseitiger Sitzungsspeicher, Gewinn-Tokens, Export
├── game-state.ts # Typdefinitionen
├── scoring.ts # Punkteberechnung + Detektivbewertungen
├── sanitize.ts # Eingabevalidierung, Injection-Erkennung
├── db.ts # Supabase-Client
└── rate-limit.ts # Pro-IP-Ratenbegrenzung
Das Spiel setzt adversarial KI gegen Spielereingaben ein – Sicherheit ist ein Kernfeature, kein nachträglicher Gedanke.
Eingabebereinigung: 30+ Regex-Injection-Muster, Unicode-Normalisierung (NFKD), Zero-Breitzeichen-Entfernung, Base64-Payload-Erkennung, Kauderwelsch-/Nicht-Englisch-Sperrung.
Ausgabeüberprüfung: KI-Antworten werden mit Fallgeheimnissen per Fuzzy-Matching (40%-Schwelle, Stop-Wörter gefiltert) abgeglichen. Durchgesickerte Antworten werden durch Ausweichmanöver ersetzt.
Richterisolierung: Die Anklagebewertung verwendet einen separaten Mistral-Aufruf mit dediziertem System-Prompt, randomisierten Begrenzungs-Tokens und entfernten Injection-Markern. Richteraufrufe verwenden niemals vom Spieler bereitgestellte API-Schlüssel.
Stressdurchsetzung: Serverseitige monotone Begrenzung – Stress steigt nur, maximal +1 pro Zug. Hinweisschwellen werden serverseitig erzwungen. KI kann Stress nicht erhöhen oder senken, um Spieltore zu umgehen.
Gewinn-Tokens: 128-Bit-Zufall, zeitlich abgesicherter Vergleich, einmalig verwendbar, 30-Minuten-TTL. Punktzahl wird aus serverseitigem Zustands-Snapshot berechnet – client-gemeldete Werte werden ignoriert.
Sitzungssicherheit: 192-Bit-Zufalls-IDs, Mutex-Sperren, 1-Stunden-TTL, maximal 5000 Sitzungen mit LRU-Eviction. Timer-Modus wird bei Erstellung festgelegt.
TTS-Validierung: Erfordert aktive Sitzung. Text muss mit einer aktuellen Assistenten-Nachricht übereinstimmen. Verhindert Missbrauch als kostenloser TTS-Proxy.
RAG-Vergiftungsabwehr: Sitzungsübergreifend erlernte Taktiken werden vor der Prompt-Einbindung durch Injection-Erkennung und Bereinigung gefiltert.
Abgeschlossene Spiele werden zur Analyse und Modellverbesserung in Supabase gespeichert:
GET /api/export?limit=100&offset=0&outcome=win&difficulty=hard mit Authorization: Bearer <EXPORT_SECRET>-HeaderEXPORT_SECRET=xxx npx tsx scripts/export-data.ts --output=data/export.jsonlNoir-Detektiv-Ästhetik. Dunkel, minimalistisch, typografisch. JetBrains Mono. Pixel-Art-Hintergründe und Verdächtigen-Porträts. Keine Chat-Blasen – Dialoge erscheinen als gestalteter Text in der Szene.
Erstelle eine leaderboard-Tabelle:
CREATE TABLE leaderboard (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
player_name text NOT NULL,
case_number text,
case_setting text,
suspect_name text,
time_remaining int,
stress_level int,
clues_found int,
hints_used int,
accusations_used int,
detective_rating text,
score int NOT NULL,
created_at timestamptz DEFAULT now()
);
ALTER TABLE leaderboard ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public read" ON leaderboard FOR SELECT USING (true);
CREATE POLICY "Public insert" ON leaderboard FOR INSERT WITH CHECK (true);
Optionale Tabelle game_exports für Trainingsdaten:
CREATE TABLE game_exports (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
session_id text UNIQUE NOT NULL,
case_data jsonb NOT NULL,
conversation jsonb NOT NULL,
outcome text NOT NULL,
difficulty text NOT NULL,
setting text,
stats jsonb NOT NULL,
accusation_text text,
accusation_correct boolean,
created_at timestamptz DEFAULT now()
);
ALTER TABLE game_exports ENABLE ROW LEVEL SECURITY;
CREATE POLICY "anon_insert" ON game_exports FOR INSERT TO anon WITH CHECK (true);
CREATE POLICY "no_public_read" ON game_exports FOR SELECT TO anon USING (false);
Optionale Tabelle interrogation_patterns für sitzungsübergreifendes Lernen:
CREATE TABLE interrogation_patterns (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
session_id text UNIQUE NOT NULL,
setting text,
difficulty text NOT NULL,
outcome text NOT NULL,
questions jsonb,
effective_questions jsonb,
max_stress int,
clues_found int,
time_elapsed int,
embedding vector(1024),
created_at timestamptz DEFAULT now()
);
ALTER TABLE interrogation_patterns ENABLE ROW LEVEL SECURITY;
CREATE POLICY "anon_insert" ON interrogation_patterns FOR INSERT TO anon WITH CHECK (true);
CREATE POLICY "anon_read" ON interrogation_patterns FOR SELECT TO anon USING (true);
Mistral Worldwide Hackathon 2026 – Online-Track, Kategorie „Anything Goes“.
Bewertungskriterien: Kreativität/Einzigartigkeit (am wichtigsten), Zukunftspotenzial, technische Umsetzung, Pitch-Qualität.
Sonderpreise: Best Mistral Vibe (AirPods), Best Voice AI (ElevenLabs 6-Monats-Abo).
Sponsoren: Mistral, ElevenLabs, NVIDIA, AWS, Hugging Face, Jump Trading, Weights & Biases, Giant, Raise, Tilde Research, White Circle.
Die meisten Hackathon-KI-Projekte sind Assistenten oder Chatbots. Dieses Projekt dreht den Spieß um – die KI hilft dir nicht, sie belügt dich. Der Spieler agiert adversarial gegenüber dem Modell, nicht kooperativ. Das schafft eine grundlegend andere Interaktion: Du suchst nach Widersprüchen, übst Druck aus und liest Verhaltenssignale, anstatt um Hilfe zu bitten.
Das Spiel generiert auch Trainingsdaten. Jede abgeschlossene Sitzung – gestellte Fragen, Stressverlauf, welche Taktiken funktionierten, welche nicht – ist als JSONL exportierbar. Das schafft eine Rückkopplungsschleife: Spiel das Spiel, exportiere die Daten, verfeinere das Modell, mach es schwerer zu ertappen.
Jason Poindexter – Solo-Einreichung, Online-Track aus Barcelona.
| Level | Hinweise | Timer | Verhalten des Verdächtigen |
|---|
| Einfach | 2 | 5 Min | Offensichtliche Lüge, nervös |
| Mittel | 3 | 7 Min | Fassbare Lüge, gefasst |
| Schwer | 4 | 9 Min | Subtile Lüge, geschickter Ausweicher |
| Experte | 5 | 10 Min | Tief vergrabene Lüge, manipulativ |