~/writing/mistral-vibe-devex-audit
Sprachfassung
Was Mistrals Free Tier wirklich hergibt.
~13 Min. Hörzeit
Fürs Hören aufbereitete Fassung. Code, Tabellen und visuelle Abläufe sind in fortlaufende Erklärungen übersetzt.
← Vollständigen Artikel lesenVon der Free-Tier-Frage zum DevEx-Audit
Ich begann mit einer breiten Frage: Was bietet Mistral Entwicklerinnen und Entwicklern heute tatsächlich? Die Plattform umfasste Chat- und Coding-Modelle, kleinere lokal nutzbare Modelle, Audio, OCR, Moderation, Embeddings, Labs-Modelle und den CLI-Coding-Agenten Vibe. Das Free Tier machte daraus eine konkretere Frage: Was kann ein authentifizierter Free-Account tatsächlich aufrufen, über welche Schnittstelle und mit welchen Limits?
Vibe war der vernünftige Einstieg. Es ist ein lokaler CLI-Coding-Agent, unterstützt gehostete Mistral-Modelle, und der Free-Account bot Vibe-spezifische Nutzung. Ich benutzte ihn erst einmal wie eine Entwicklerin oder ein Entwickler und begann nicht mit künstlichen API-Tests. Daraus wurde ein DevEx-Audit.
Der Ablauf ist wichtig. Der Browser-Login gelang. Eine Anfrage an das ausgewählte Medium 3.5 scheiterte. Im Mistral-Konto existierte ein API- oder Vibe-Key, lokal fehlte aber ~/.vibe/.env. Ich erzeugte einen neuen Vibe-Key und legte ihn dort als MISTRAL_API_KEY ab. Die Authentifizierung funktionierte danach, die Anfrage scheiterte trotzdem. Vibes Debug-Ausgabe zeigte HTTP 429. Ein direkter API-Probe ergab für Medium 3.5 null RPM. Damit lautete die Frage: Was kann dieses Konto benutzen?
Zwei unabhängige Fehler
Vibe v2.25.1 startete auf meinem Mistral-Free-EU-Konto mit Medium 3.5. Der Browser-Setup-Ablauf meldete Erfolg, ein trivialer Prompt lieferte danach aber einen Authentifizierungs- oder API-Fehler. Auch ein erneutes vibe --setup meldete Erfolg. Online war ein Vibe-Credential vorhanden. Lokal fehlte die Datei ~/.vibe/.env.
Das war ein echter Provisionierungsfehler. Erfolgreiche Browser-Authentifizierung und verwendbare lokale CLI-Zugangsdaten sind getrennte Zustände. Der Setup-Ablauf stellte sie als einen erfolgreichen Vorgang dar. Das manuelle Einrichten des Keys und der lokalen Datei löste die Authentifizierung.
Die Anfrage blieb kaputt. Vibe wiederholte sie jetzt als rate-limited. Ich schickte direkt an /v1/chat/completions eine minimale Anfrage mit mistral-medium-latest, demselben Key und einem Token Ausgabe. Die API antwortete mit rate_limited, Code 1300 und HTTP 429. In den Headern standen sowohl Anfragelimit als auch verbleibende Anfragen auf null RPM.
Bevor ich das Free Tier oder die API für kaputt erklärte, brauchte ich einen Kontrolltest. Dieselbe Anfrage mit demselben Key an ministral-3b-latest ergab HTTP 200. Die Header zeigten 750 RPM, 1.300.000 TPM, 1.299.995 verbleibende Tokens und fünf Tokens Query-Kosten. Der Key war gültig, die API erreichbar und Chat funktionierte. Medium 3.5 hatte eine operative Freigabe von null.
Discovery reichte nicht
Vibes /model-Picker zeigte eine kleine Auswahl, aber nicht, ob das Konto ein Modell nutzen konnte, ob es ein Chat- oder Coding-Modell war, ob eine ID ein Alias war, ob das Limit über null lag oder ob eine weitere Kontoeinstellung nötig war. Deshalb fragte ich /v1/models authentifiziert ab. Der Endpunkt lieferte 46 IDs.
Der Katalog enthielt mehr als Namen: Fähigkeitsdaten wie completion_chat, Function Calling, Reasoning, Vision, OCR, Moderation, Audio-Transkription, Realtime-Transkription und Sprache. Außerdem enthielt er Alias-Beziehungen. Zu Medium 3.5 gehörten mistral-medium-latest, mehrere Versionsnamen, mistral-vibe-cli-latest, mistral-vibe-cli-with-tools und magistral-medium-latest. Small 4 enthielt mistral-small-latest, mistral-vibe-cli-fast und magistral-small-latest. Codestral 2508 enthielt codestral-latest, mistral-code-latest und mistral-code-fim-latest.
Der Katalog ist roher Provider-Zustand, keine Auswahloberfläche. Ich schrieb einen kleinen Fish-Probe, der den Katalog abruft, IDs dynamisch ermittelt, die kleinste Chat-Anfrage schickt, HTTP-Status und Rate-Limit-Header protokolliert, strukturierte Fehlertypen erhält und zwischen Anfragen wartet. Er unterschied HTTP 200, 400 invalid_model, 403 tier_not_allowed, 403 labs_not_enabled und 429 rate_limited, statt alles als nicht verfügbar zusammenzufassen.
Der erste Chat-orientierte Durchlauf fand Ministral 3B mit 750 RPM und 1,3 Millionen TPM, Ministral 8B mit 188 RPM und 625.000 TPM, Ministral 14B mit 30 RPM und 937.500 TPM, Codestral oder Mistral Code mit 125 RPM und 625.000 TPM und Voxtral Small mit 60 RPM und 50.000 TPM. Medium 3.5, Small 4 und die Vibe-CLI-Aliase hatten effektiv null RPM. Die dokumentierten, aber nicht im 46-ID-Katalog enthaltenen Modelle zai-glm-5-2 und mistral-large-latest antworteten mit 403 tier_not_allowed.
Ein späterer Probe für mistral-large-4 lieferte HTTP 403, tier_not_allowed, Code 1910. Modell-Slug, Endpoint und API-Key waren gültig, aber das getestete Subscription-Tier durfte das Modell nicht verwenden. Es gab keine Rate-Limit-Header, denn der Request erreichte kein nutzbares Modellkontingent. Auch ein eigener Vibe-Eintrag über den Standard-API-Provider trifft auf diese Tier-Sperre.
Den eigenen Probe korrigieren
Mein generischer Probe schickte jede ID an POST /v1/chat/completions. Mehrere antworteten 400 invalid_model. Das als Ausschluss im Free Tier zu lesen, hätte eine plausible, aber falsche Tabelle ergeben.
Die Capability-Metadaten erklärten den Fehler. Einige IDs gehörten zu Embeddings, OCR, Moderation, Transkription, Text-to-Speech oder Realtime-Transkription. Die Anfrage war ungültig, weil ich die falsche API-Frage stellte. 400 invalid_model vom Chat-Endpunkt bedeutete: Dieses Modell lässt sich nicht über diesen Endpunkt verwenden. Es bedeutete nicht: Dieses Konto darf das Modell nicht verwenden.
Ich wechselte von Modell-Probes zu Fähigkeits-Probes. Alle vier getesteten Embedding-IDs, codestral-embed, codestral-embed-2505, mistral-embed und mistral-embed-2312, lieferten an /v1/embeddings HTTP 200 mit 60 RPM. mistral-moderation-2603 lieferte an /v1/moderations HTTP 200 mit 100 RPM. Sieben getestete OCR-IDs, von mistral-ocr-2512 bis mistral-ocr-latest, lieferten mit einem gültigen Dokument an /v1/ocr HTTP 200. Für OCR sah ich keine entsprechenden RPM- oder TPM-Header und erfand deshalb keinen Quota-Wert.
Labs und Audio
Zwei Leanstral-IDs antworteten zunächst 403 labs_not_enabled. Der Fehler verwies auf Privacy, aber es gab zwei relevante Seiten: Vibe Privacy und API Privacy. Der Schalter lag unter API Privacy. Nach der Aktivierung funktionierten labs-leanstral-1-5 und labs-leanstral-1-5-1 sofort mit 38 RPM und 5.000.000 TPM. Das war zum Testzeitpunkt das höchste gemessene Chat-TPM-Budget dieses Free-Accounts. Vibe startete mit Medium 3.5 bei null RPM, während das coding-orientierte Labs-Modell nach einer versteckten Organisationseinstellung nutzbar war.
Für Audio erzeugte ich eine lokale WAV-Sinuswelle von einer Sekunde, damit der Test nicht von externem Material abhing. voxtral-mini-2602 und voxtral-mini-latest lieferten an /v1/audio/transcriptions HTTP 200. Die Header zeigten 60 RPM und 3.600 Audiosekunden pro Minute. Die Sekunde Audio wurde als eine Prompt-Audiosekunde und 375 Audio-Tokens verarbeitet. Eine leere Transkription war erwartbar, weil die Datei keine Sprache enthielt.
Statt eine Voice-ID fest einzubauen, fragte ich zuerst die Voice-API ab und fand 30 Preset-Voices. voxtral-mini-tts-2603 und voxtral-mini-tts-latest lieferten an /v1/audio/speech HTTP 200. Das beobachtete Limit lag bei 12.000 Eingabezeichen pro Minute.
Realtime-Transkription brauchte erneut ein anderes Protokoll. Ich nutzte Mistrals Realtime-Python-Client, erzeugte rohes PCM mit 16 Kilohertz und Mono und streamte es in ungefähr 240-Millisekunden-Stücken. voxtral-mini-transcribe-realtime-2602, voxtral-mini-realtime-2602 und voxtral-mini-realtime-latest schlossen jeweils eine echte Session ab: session.created, session.updated und transcription.done. Der Nutzungsbericht enthielt 23 Prompt-Tokens, 23 Completion-Tokens, 46 Tokens insgesamt und zwei Prompt-Audiosekunden.
Die beobachtete Fähigkeitskarte
Für diese Mistral-Free-EU-Organisation am 10. September 2026 war Leanstral 1.5 nach Labs-Opt-in mit 38 RPM und 5 Millionen TPM nutzbar. Ministral 3B, 14B und 8B waren mit 750 RPM und 1,3 Millionen TPM, 30 RPM und 937.500 TPM sowie 188 RPM und 625.000 TPM nutzbar. Codestral oder Mistral Code hatte 125 RPM und 625.000 TPM. Voxtral Small hatte 60 RPM und 50.000 TPM. Medium 3.5, Small 4 und die Vibe-CLI-Aliase hatten null RPM. GLM 5.2 und Large 3 waren tier-denied.
Embeddings, Moderation, OCR, Offline-Transkription, TTS, Realtime-Transkription und die Preset-Voice-Discovery waren verfügbar. Beobachtet wurden 60 RPM für Embeddings, 100 RPM für Moderation, 60 RPM plus 3.600 Audiosekunden pro Minute für Offline-Transkription, 12.000 Eingabezeichen pro Minute für TTS und 30 Preset-Voices. Das sind Beobachtungen für ein Konto, eine Organisation, eine Region und einen Zeitpunkt, keine Zusagen.
Die fehlende Verfügbarkeits-Abstraktion
Der Free-Account bot deutlich mehr, als der erste Vibe-Lauf vermuten ließ. Das Problem war die Lesbarkeit der Fähigkeiten. Bei einer einzigen Modellauswahl musste ich herausfinden, ob der Browser-Login die CLI eingerichtet hatte, ob der Key gültig war, ob 429 verbrauchte Quote oder null Freigabe bedeutete, ob eine ID kanonisch oder ein Alias war, welche Fähigkeit sie hatte, welcher Endpunkt diese Fähigkeit implementierte, ob Labs nötig war, ob 403 Labs deaktiviert oder den Tier verweigert bedeutete und welche Alternative sofort funktionieren konnte.
Die Bausteine existierten bereits: Katalog-IDs, Aliase und Capabilities, strukturierte Fehler wie labs_not_enabled, tier_not_allowed und rate_limited, Header für RPM, TPM, Audiosekunden und Eingabezeichen sowie Vibes Provider-, Modell- und Setup-Zustand. Es fehlte eine normalisierte ModelAvailability-Repräsentation zwischen Provider-Zustand und Entscheidungen für Entwicklerinnen und Entwickler.
Sie sollte kanonische Modell-ID, Aliase, Fähigkeiten, Status, beobachtete Limits, Labs-Zustand und den letzten relevanten Fehler enthalten. Dann könnten /model, Setup, Retry-Behandlung, Diagnose und Fallback-Vorschläge denselben Zustand verwenden. Ein Picker könnte Codestral, die Ministral-Modelle und Leanstral mit Limits als verfügbar anzeigen, Medium 3.5 und Small 4 als Null-RPM-Modelle markieren, Labs unter API Privacy erklären und nach einer Null-RPM-Anfrage Alternativen nennen.
Discovery darf nicht bedeuten, bei jedem Öffnen von /model alle 46 IDs zu testen. Setup kann den Katalog abrufen, normalisieren und cachen. Erfolgreiche Calls können Limits aktualisieren, relevante Fehler die Verfügbarkeit, und explizite Aktualisierung oder Cache-Ablauf den Provider-Zustand neu laden. /model sollte diesen gecachten, normalisierten Zustand darstellen und keine Sammlung Mistral-spezifischer Regeln werden.
Was ein brauchbarer Client sagen würde
Der Picker muss nicht jedes Rohdetail zeigen, aber den Zustand, den man für eine Entscheidung braucht. Für dieses Konto könnte er Codestral 2508 mit 125 RPM und 625.000 TPM aufführen, Ministral 3B mit 750 RPM und 1,3 Millionen TPM, Ministral 8B mit 188 RPM und 625.000 TPM, Ministral 14B mit 30 RPM und 937.500 TPM sowie Leanstral 1.5 mit 38 RPM und 5 Millionen TPM, markiert als Labs. Medium 3.5 und Small 4 gehören mit ihrer beobachteten Null-RPM-Freigabe in eine Gruppe nicht verfügbarer Modelle, statt wie normale Defaults auszusehen.
Auch Fehlermeldungen würden davon profitieren. Bei Leanstral kann der Client sagen, dass Labs für die Organisation deaktiviert ist, und direkt zu API Privacy führen. Bei Medium 3.5 kann er das beobachtete Limit von null Anfragen pro Minute nennen, Codestral und die verfügbaren Ministral-Modelle als Alternativen anbieten und zu /model schicken. Das versteckt Mistrals Zustand nicht. Es macht ihn handhabbar.
Die Repräsentation kann klein bleiben. Ein ModelAvailability-Datensatz für Codestral braucht kanonische ID, Aliase wie codestral-latest, mistral-code-latest und mistral-code-fim-latest, die Capabilities für Chat, Fill-in-the-Middle und Function Calling, den Status verfügbar sowie 125 RPM und 625.000 TPM. Der Datensatz für Medium 3.5 braucht seine Aliase, den Status Zero-Rate-Limit und null RPM. Ein Leanstral-Datensatz kann labs_disabled und eine Aktion für API Privacy tragen. Komponenten konsumieren diesen normalisierten Zustand, statt Provider-Fehler jeweils selbst zu übersetzen.
Dasselbe gilt für die spezialisierten APIs. Ein Katalogeintrag beschreibt eine Fähigkeit. Der Client wählt den Endpunkt oder das Protokoll, das sie umsetzt. Chat und Coding laufen über /v1/chat/completions. Embeddings über /v1/embeddings, Moderation über /v1/moderations, OCR über /v1/ocr, Offline-Transkription über /v1/audio/transcriptions und Sprachsynthese über /v1/audio/speech. Realtime-Transkription ist eine Streaming-Client-Session. Sie alle in einen Chat-Probe zu werfen, war der ursprüngliche Testfehler im Kleinen.
Das Audit behauptet nicht, dass ein Free-Tier-Katalog eine dauerhafte Freigabe garantiert. Limits und Verfügbarkeit hängen von Konto, Organisation, Region und Zeitpunkt ab. Es zeigt, dass ein Client Katalog-Discovery, Berechtigung, ein operatives Limit über null, die richtige Fähigkeit und den richtigen Endpunkt sowie Nutzbarkeit im lokalen Tool getrennt darstellen kann. Das sind verschiedene Zustände. Wenn sie auf ein grünes oder rotes Modell-Label reduziert werden, geht die relevante Information verloren.
Fazit und externe Validierung
Die Korrektur meines Probes ist wichtig, weil ein Fehler zuerst Evidenz über die Anfrage ist, die ihn erzeugt hat. Erfolgreicher Browser-Login bewies keine lokale Credential-Provisionierung. HTTP 429 bewies keine nur vorübergehend erschöpfte Quote. Eine von /v1/models gelieferte ID bewies keine Freigabe über null. 400 invalid_model am Chat-Endpunkt bewies kein unbenutzbares Modell. HTTP 403 stand nicht für einen universellen Zugriffsfehler.
Ich veröffentlichte die ersten Ergebnisse bei r/MistralAI und aktualisierte sie nach den Labs- und Spezialmodell-Tests. Reddit Insights zeigte den Beitrag kurz ungefähr auf Platz drei aller Zeiten im Subreddit, mit rund 1.400 Views und zehn Shares innerhalb der ersten 40 Minuten. Ein anderer Entwickler beschrieb unabhängig, zu viel Zeit mit Vibe-Authentifizierung verbracht zu haben, und stimmte zu, dass der Picker Modellverfügbarkeit direkt zeigen sollte. Die stärkere Evidenz bleiben HTTP-Antworten, Rate-Limit-Header, /v1/models-Metadaten, fähigkeitsspezifische API-Aufrufe und Realtime-Protokollereignisse.
Ein Developer-Tool muss die Plattform nicht verstecken. Es sollte ihren Zustand so verständlich machen, dass Entwicklerinnen und Entwickler die nächste Aktion wählen können, ohne Informationen reverse-engineeren zu müssen, die die Plattform bereits programmatisch bereitstellt.