Software maken met Mistral AI: welke tools, welk model en welke IDE (november 2026)
Devstral is uit de API en Vibe draait standaard op een model dat stopt. Wat Mistral in november 2026 biedt om software te maken: Vibe in VS Code en PhpStorm, welk model voor welke taak, de prijzen, het EU-endpoint en een geteste PHP-aanroep.

Wie vandaag een tutorial volgt over programmeren met Mistral AI, installeert grote kans iets dat niet meer bestaat. Devstral 2, het codeermodel waarmee Mistral in december 2025 zijn codeeragent Vibe lanceerde, is sinds 31 juli 2026 uit de API verdwenen. De JetBrains-plugin Mistral Code is uitgefaseerd. En Mistral Medium 3.5, het model dat Vibe standaard gebruikt, staat sinds 31 oktober op de lijst van modellen die stoppen. Dat is drie dagen geleden.
Dat zegt niets over de kwaliteit van Mistral. Het zegt wel dat je bij deze leverancier anders moet bouwen dan je gewend bent. In dit artikel staat wat Mistral in november 2026 aanbiedt, welke tools en welke IDE je kiest, welk model bij welke taak hoort, wat het kost en waar je data heen gaat. Ik heb er ook een stuk PHP voor geschreven en gedraaid tegen een Mistral-model op mijn eigen laptop. Dat leverde een les op die in geen enkele handleiding staat.
Kort antwoord. Ja, je kunt goed software maken met Mistral, in twee rollen. Als programmeerhulp gebruik je Vibe: in de terminal, in VS Code, of in PhpStorm en andere JetBrains-IDE's via de AI Assistant. Zet daar zelf Mistral Large 4 in, want het standaardmodel wordt uitgefaseerd. In je eigen applicatie roep je de API aan: Mistral Small 4 voor bulkwerk, Large 4 voor moeilijke taken, en
api.eu.mistral.aials de verwerking in Europa moet blijven. Mistral heeft niet het beste codeermodel. Claude, GPT en Gemini scoren hoger. Wel het sterkste model dat je ook zelf mag draaien.
Feiten gecontroleerd op 3 november 2026, bij de documentatie, de changelog en de prijslijst van Mistral. De test in dit artikel draaide ik dezelfde dag lokaal met Ministral 3 8B. Tegen de betaalde API van Mistral heb ik niets gedraaid; waar ik iets niet zelf heb gezien, staat dat erbij.
Twee dingen die allebei "software maken met Mistral" heten
De vraag "kan ik software maken met Mistral?" gaat in de praktijk over twee verschillende dingen, en de meeste verwarring komt doordat ze door elkaar lopen.
Mistral als programmeerhulp. Een agent leest je code, past bestanden aan en draait commando's, terwijl jij meekijkt. Het product heet Vibe. Je betaalt meestal met een abonnement, en het resultaat is code die in je repository belandt. Daarna doet Mistral niets meer: je applicatie draait zonder Mistral.
Mistral als onderdeel van je software. Je applicatie stuurt zelf verzoeken naar een Mistral-model: een vacaturetekst omzetten naar velden, een klantvraag beantwoorden, een PDF uitlezen. Dat loopt via de API van Mistral AI Studio, en je betaalt per token. Hier gaan de gegevens van je gebruikers naar Mistral, niet alleen je broncode.

Je kunt de twee los van elkaar kiezen. Je kunt met Claude Code een applicatie bouwen die Mistral aanroept, of met Vibe een applicatie die OpenAI gebruikt. Wie "we gaan met Mistral werken" zegt, moet dus eerst zeggen welke van de twee.
Wat Mistral in november 2026 aanbiedt, en wat al verdwenen is
Op 28 mei 2026 hernoemde Mistral zijn chatdienst Le Chat tot Vibe. Vibe heeft sindsdien drie standen. Work is de assistent voor onderzoek, samenvattingen en documenten. Chat is de oude Le Chat. Code is de programmeeragent, en die bestaat in drie vormen: de command-line-tool, een extensie voor VS Code en Vibe Code Web, dat in een sandbox in de cloud op een GitHub-repository werkt.
Daarnaast is er Mistral AI Studio, het platform met de API, de API-sleutels en de instellingen voor je organisatie. Daar staan de modellen. Opvallend: Mistral verkoopt via die API inmiddels ook modellen van anderen. Z.ai GLM 5.3, GLM 5.3 Flash en DeepSeek V4.1 Flash staan gewoon in de modellenlijst, naast die van Mistral zelf.
De lijst van wat er verdween, is minstens zo leerzaam:
| Model | Uitgebracht | Uit de API | Vervanger volgens Mistral |
|---|---|---|---|
| Devstral Small 2 | december 2025 | 31 maart 2026 | Medium 3.5 |
| Devstral 2 | december 2025 | 31 juli 2026 | Medium 3.5 |
| Magistral Medium 1.2 | september 2025 | 31 juli 2026 | Medium 3.5 |
| Mistral Medium 3.5 | 28 april 2026 | 30 april 2027 (uitgefaseerd per 31 oktober) | Large 4 |
| Mistral Large 3 | december 2025 | 30 april 2027 (uitgefaseerd per 31 oktober) | Large 4 |
Devstral 2 was zo'n acht maanden beschikbaar. Medium 3.5 werd na zes maanden uitgefaseerd. De vervanger van de vervanger is Large 4. Wie in mei een applicatie bouwde op Devstral 2, moest die dus in de zomer omzetten naar Medium 3.5, en moet nu opnieuw.
De gewichten van open modellen verdwijnen niet: Devstral Small 2 kun je nog steeds downloaden en zelf draaien. Alleen de API-versie stopt. Voor je planning maakt dat weinig uit. Reken bij Mistral op een nieuw model per half jaar, en zet de modelnaam daarom in je configuratie, niet verspreid door je code. Verderop staat waarom een vaste testset dan het belangrijkste is wat je kunt bouwen.
Hoe goed programmeert Mistral? De onafhankelijke cijfers
Mistral Large 4 kwam op 6 oktober uit als preview en op 29 oktober met open gewichten. Het is een model van 1,05 biljoen parameters, waarvan er per token 52 miljard meedoen, met een contextvenster van een miljoen tokens. Over het model zelf schreef ik eerder een apart artikel. Hier gaat het om één vraag: hoe goed schrijft het code?
Artificial Analysis, een onafhankelijk meetbureau, test codeeragenten op echte programmeertaken. In de Coding Agent Index staat Large 4, gedraaid in Mistral Vibe, op 48 punten. GLM-5.3 haalt er 49, DeepSeek V4.1 Flash 46. Bij de open modellen hoort Large 4 daarmee bij de top. Het verschil zit in het verbruik: Large 4 had 8,5 miljoen tokens per taak nodig, GLM-5.3 15,9 miljoen. Bij een agent die per token betaalt, is dat bijna de helft van de rekening.
De brede vergelijking is minder vleiend. In de algemene Intelligence Index van hetzelfde bureau scoort Large 4 26 punten. Gemini 4 Carbon staat op 59, Claude Opus 5.5 op 58 en GPT-6 Astra op 57. Zeven open modellen scoren hoger dan Large 4. In een blinde voorkeurstest die Mistral zelf publiceert, verkozen beoordelaars de code van Large 4 in 22 procent van de vergelijkingen boven die van Claude Opus 5.5.
Let ook op hoe de cijfers van Mistral en van onafhankelijke testers uiteenlopen. Op Terminal-Bench 4.0 noemt Mistral 41 procent; Artificial Analysis mat 25 procent. Het verschil komt meestal uit de opstelling: andere instellingen, een andere agent eromheen, meer pogingen. Voor jouw keuze tellen de onafhankelijke metingen, en daarna vooral je eigen test.
Mijn conclusie: Large 4 is een degelijk codeermodel voor gewoon werk. Denk aan refactoren, tests schrijven, CRUD-code en een bug opsporen met een duidelijke foutmelding. Voor een wijziging die door twintig bestanden en drie lagen architectuur heen loopt, zijn de gesloten topmodellen nog duidelijk beter. Kies Mistral dus niet omdat een grafiek zegt dat het de beste is. Kies het omdat het Europees is, omdat je het model zelf mag draaien, of omdat het per taak goedkoop is. Dat zijn echte redenen.
Welke IDE? Vibe in VS Code, PhpStorm, Zed of de terminal
De programmeeragent van Mistral is Vibe. Er is geen apart Mistral-product per editor meer: het is overal dezelfde agent, met dezelfde instellingen in ~/.vibe/. Wat je kiest, hangt af van de editor waarin je al werkt.
VS Code: de enige officiële extensie
Voor VS Code heeft Mistral een eigen extensie: Mistral Vibe for VS Code, id mistralai.mistral-vibe-code. Je hebt VS Code 1.94 of nieuwer nodig. De agent zit in de extensie, dus je hoeft de command-line-tool niet apart te installeren. Bij het eerste gebruik plak je een API-sleutel; die komt in de sleutelbos van je besturingssysteem, of in ~/.vibe/.env als er geen sleutelbos is. Inloggen via de browser, zodat je je abonnement gebruikt in plaats van een sleutel, is volgens de documentatie onderweg naar de extensie. Instellingen en sessies deelt de extensie met de command-line-versie.
PhpStorm en andere JetBrains-IDE's: via ACP
Voor JetBrains is er geen losse Mistral-plugin. De oude Mistral Code-plugin is uitgefaseerd, en Mistral raadt af hem te gebruiken. De route is het Agent Client Protocol (ACP), een open standaard waarmee een editor met een externe agent praat. JetBrains bouwde dat in de AI Assistant in. Zo werkt het in PhpStorm, IntelliJ IDEA, WebStorm of PyCharm:
- Zorg voor versie 2025.3.2 of nieuwer, met de AI Assistant-plugin.
- Open Settings (
Ctrl+Alt+S, op de MacCmd+,) en ga naar Tools, AI Assistant, Agents. - Zoek "Mistral Vibe" en klik op Install.
- Open het AI Chat-venster en kies Mistral Vibe in de keuzelijst onder het invoerveld.
Een abonnement op JetBrains AI heb je daarvoor niet nodig; JetBrains schrijft dat ACP-agents zonder dat abonnement werken. Je betaalt alleen Mistral. Heb je Vibe al in de terminal of in VS Code ingesteld, dan gebruikt de JetBrains-versie dezelfde inloggegevens. Werk je dagelijks in PhpStorm, dan is dit de route. Ik gebruik zelf Claude Code in PhpStorm, en het principe is hetzelfde: de agent werkt in je project, jij beoordeelt de wijzigingen in de diff-weergave van de IDE.
Zed, en elke andere editor met ACP
Zed bedacht ACP. Daar installeer je eerst de command-line-tool, die het commando vibe-acp meelevert, en verwijs je in de Zed-instellingen onder agent_servers naar dat commando. Hetzelfde werkt in elke andere editor die ACP ondersteunt.
De terminal
De command-line-tool staat op PyPI als mistral-vibe; de nieuwste versie is 3.0.4, van 30 oktober 2026. Je hebt Python 3.12 of nieuwer nodig. Op Linux en macOS:
curl -LsSf https://mistral.ai/vibe/install.sh | bash Op Windows installeer je eerst uv en daarna:
uv tool install mistral-vibe Vibe werkt op Windows, maar Mistral richt zich volgens de eigen README officieel op Linux en macOS. Bij de eerste start kies je tussen inloggen via de browser, dan gebruik je je abonnement, en een API-sleutel. In mijn eerdere artikel over Vibe staat hoe de agent werkt en hoe je hem volledig lokaal laat draaien. Let op: de modelnamen in dat artikel (Devstral 2) zijn inmiddels uit de API verdwenen.
En automatisch aanvullen terwijl je typt?
Vibe is een agent die je een opdracht geeft. Het is geen aanvulling die tijdens het typen de rest van je regel voorstelt. Daarvoor heeft Mistral een apart model, Codestral, dat de code tussen je cursor en de rest van het bestand invult ("fill-in-the-middle"). Mistrals eigen plugin daarvoor bestaat voor JetBrains niet meer. Wil je Codestral als aanvulling, dan heb je een plugin van een andere partij nodig waarin je een eigen Mistral-sleutel kunt opgeven.
Vibe draait standaard op een model dat stopt: zet Large 4 er zelf in
Dit is het detail dat in de introductieartikelen ontbreekt. In de configuratiedocumentatie van Vibe staat: Vibe komt met één ingebouwd model, Mistral Medium 3.5. Datzelfde model staat sinds 31 oktober in de lijst van uitgefaseerde modellen, met 30 april 2027 als einddatum en Large 4 als vervanger. Het keuzemenu /model toont alleen de modellen die je zelf hebt ingesteld.
Large 4 zet je erin met een paar regels in ~/.vibe/config.toml:
[[models]]
name = "mistral-large-4"
provider = "mistral"
alias = "large-4"
active_model = "large-4"
# Standaard staat telemetrie aan
enable_telemetry = false
# Standaard past Vibe bestanden aan zonder te vragen ("accept-edits")
default_agent = "ask"
# Geen toegang tot bestanden buiten de projectmap
outside_workdir = "deny" De velden komen uit de configuratiedocumentatie van Vibe, de modelnaam uit de modelkaart van Large 4. Ik heb deze configuratie niet met een betaalde sleutel getest. Typ na het opslaan /model in Vibe en controleer of large-4 erbij staat.
De drie regels onderaan zijn een keuze, geen verplichting. Standaard verzamelt Vibe gebruiksgegevens, en de standaardmodus accept-edits schrijft wijzigingen direct in je bestanden; alleen voor shell-commando's vraagt Vibe toestemming. Begin je met een nieuwe agent, zet hem dan op ask tot je weet hoe hij zich gedraagt. En werk altijd vanuit een schone Git-werkmap, zodat git diff laat zien wat er veranderd is.
Abonnement of API-sleutel: wat kost programmeren met Vibe?
Voor Vibe kun je op twee manieren betalen. Met een abonnement:
| Plan | Prijs (excl. btw) | Voor programmeren |
|---|---|---|
| Free | gratis | een beperkt aantal codeersessies |
| Pro | $14,99 per maand | "all-day coding" in de terminal, de IDE en op het web, plus $15 per maand aan API-tegoed |
| Team | $24,99 per gebruiker per maand | hogere limieten, domeinverificatie, data-export |
| Studenten | $5,99 per maand | Pro, voor geverifieerde studenten, twaalf maanden |
Of met een API-sleutel, waarbij je per token betaalt. Een rekenvoorbeeld laat zien waarom dat voor dagelijks programmeren snel duurder is. Artificial Analysis mat 8,5 miljoen tokens per taak voor Large 4 in Vibe. Stel dat al die tokens invoer uit de cache zijn, het goedkoopste geval: 8,5 miljoen keer $0,07 per miljoen is $0,60 per taak. Zonder cache is het $5,95. Twintig taken per werkdag, twintig werkdagen per maand, zijn 400 taken: in het gunstigste geval zo'n $240 per maand, en dan zijn de uitvoertokens nog niet meegerekend.
Een benchmarktaak is niet jouw taak, dus lees dit als een orde van grootte. Het laat wel zien waarom een abonnement van $14,99 voor dagelijks werk de logische keuze is, zolang de limieten van het plan je niet tegenhouden. Een API-sleutel is handig voor automatisering, bijvoorbeeld een agent die in je CI-pijplijn draait, en voor wie de kosten per project wil zien.
Mistral in je eigen software: welk model voor welke taak
Voor de API is de keuze anders. Daar betaal je elke aanroep, dus het goedkoopste model dat de taak goed doet, wint. De prijzen per miljoen tokens, volgens de prijslijst van Mistral op 3 november 2026:
| Taak | Model | Invoer / uitvoer | Waarom |
|---|---|---|---|
| Agents, lange documenten, moeilijke afwegingen | Mistral Large 4 (mistral-large-4) | $0,70 / $2,10 (invoer uit de cache $0,07) | sterkste Mistral-model, venster van 1 miljoen tokens |
| Classificeren, velden uitlezen, samenvatten in bulk | Mistral Small 4 (mistral-small-2603) | $0,15 / $0,60 | bijna vijf keer goedkoper dan Large 4 bij invoer; open gewichten onder Apache 2.0 |
| Eenvoudige taken, of zelf draaien | Ministral 3 (3B, 8B, 14B) | $0,10 tot $0,20, invoer en uitvoer gelijk | Apache 2.0; de 8B draait op een laptop |
| Code aanvullen in je eigen tool | Codestral | $0,30 / $0,90 | gemaakt voor fill-in-the-middle |
| Zoeken op betekenis | Mistral Embed / Codestral Embed | $0,10 / $0,15 (alleen invoer) | tekst of code omzetten naar vectoren |
| PDF's en scans uitlezen | OCR 4.1 | $4 per 1.000 pagina's | met blokken en betrouwbaarheidsscores |
| Spraak naar tekst | Voxtral Mini Transcribe 3 | $0,0035 per minuut | met sprekerherkenning |
| Ongewenste invoer tegenhouden | Mistral Moderation 2 | gratis | ook detectie van jailbreakpogingen |
Batchverwerking, waarbij je de antwoorden niet direct nodig hebt, kost de helft. Een rekenvoorbeeld: 10.000 klantvragen, elk met 800 tokens invoer en 100 tokens uitvoer, laten indelen in categorieën. Met Small 4 kost dat 8 miljoen keer $0,15 plus 1 miljoen keer $0,60: $1,80. Met Large 4 is het $5,60 plus $2,10: $7,70. Via het Europese endpoint komt daar 10 procent bij. Als batch is het de helft.
Mijn advies: begin met Small 4 en stap alleen over op Large 4 als je testset laat zien dat het verschil de prijs waard is. Voor zoeken op betekenis werkt het net als in mijn artikel over een intelligente database met MySQL en PHP, alleen met een embeddingmodel van Mistral in plaats van OpenAI.
PHP en Mistral: geen officiële SDK, en dat hoeft ook niet
Mistral onderhoudt officiële SDK's voor Python (mistralai, versie 2, waarin de imports naar mistralai.client verhuisden) en TypeScript (@mistralai/mistralai). Een officiële PHP-SDK is er niet. Voor PHP heb je vier routes:
- Laravel: de officiële Laravel AI SDK (
laravel/ai, versie 1.3.0) ondersteunt Mistral voor tekst, spraak naar tekst en embeddings. Je zetMISTRAL_API_KEYin je.env. - Symfony: Symfony AI heeft een Mistral-koppeling,
symfony/ai-mistral-platform. Die staat op 1.0.0-BETA1, van 26 oktober 2026: nog een bèta. - Losse clients van de community: bijvoorbeeld
softcreatr/php-mistral-ai-sdkof, voor Laravel,helgesverre/mistral. Kijk voor gebruik hoe actief ze bijgehouden worden. - Gewoon HTTP: de API is een JSON-API. Eén functie met cURL is genoeg, en dan weet je precies wat er over de lijn gaat.
Voor dit artikel koos ik de laatste route. De functie hieronder praat met api.mistral.ai, met api.eu.mistral.ai en met een lokaal model in Ollama, omdat alle drie hetzelfde pad /v1/chat/completions en hetzelfde berichtformaat gebruiken.
mistral.php
<?php
declare(strict_types=1);
/**
* Eén functie voor de chat-API van Mistral.
* Werkt tegen api.mistral.ai, api.eu.mistral.ai en een lokaal model via Ollama:
* alle drie bieden /v1/chat/completions met hetzelfde berichtformaat.
*/
function mistral_chat(string $baseUrl, ?string $apiKey, array $payload): array
{
$headers = ['Content-Type: application/json'];
if ($apiKey) {
$headers[] = 'Authorization: Bearer ' . $apiKey;
}
$ch = curl_init(rtrim($baseUrl, '/') . '/v1/chat/completions');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($body === false) {
throw new RuntimeException("Geen verbinding: $error");
}
if ($status !== 200) {
throw new RuntimeException("HTTP $status: $body");
}
return json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} Wil je later toch een SDK of een Laravel-pakket, dan verandert alleen deze functie. De rest van je code merkt er niets van.
Getest: vacatureteksten omzetten naar JSON met Ministral 3 8B
Een taak die in bijna elke applicatie voorkomt: rommelige tekst omzetten naar velden die je in een database kunt zetten. Ik nam vijf verzonnen vacatureteksten, elk op een andere manier geschreven, en liet Ministral 3 8B er acht velden uit halen: functietitel, plaats, werkplek, minimum en maximum aantal uren, minimum en maximum salaris, en of dat salaris per uur, maand of jaar is.
De opstelling: Ollama 0.40.13 op mijn laptop (RTX 4070 Laptop met 8 GB videogeheugen), het model ministral-3:8b in 4 bits (6,0 GB, voor 92 procent op de gpu), PHP 8.2.35. Het model is open, onder Apache 2.0, en het draaien kostte niets. De vacatures:
vacatures.php
<?php
// Vijf verzonnen vacatureteksten, zoals ze in de praktijk binnenkomen: rommelig en elk anders.
return [
'V-101' => "Wij zoeken een Medior PHP Developer (Laravel) voor ons team in Utrecht. 32-40 uur. Salaris tussen €3.800 en €5.200 bruto per maand. Twee dagen per week thuiswerken is mogelijk.",
'V-102' => "Backend engineer gezocht! Je werkt volledig remote vanuit Nederland of België. Fulltime (40u). We bieden 55k tot 68k per jaar, afhankelijk van ervaring. Stack: Symfony, PostgreSQL.",
'V-103' => "Voor onze vestiging in Eindhoven zoeken we een junior webontwikkelaar, 24 uur per week, start per direct. Salarisindicatie: schaal 8 (cao), max. €3.400. Werken op kantoor.",
'V-104' => "Lead developer — Amsterdam (hybride). Je stuurt een team van zes aan. Salaris: marktconform. 36 uur.",
'V-105' => "Freelance opdracht: WordPress-specialist, 16 tot 20 uur per week, 6 maanden, volledig op afstand. Tarief €85 per uur.",
]; Het JSON-schema dat het model moet invullen. Mistral noemt dit structured outputs: het model kan alleen antwoorden in deze vorm.
schema.php
<?php
// Het JSON-schema dat het model moet invullen.
return [
'type' => 'object',
'properties' => [
'functietitel' => ['type' => 'string'],
'plaats' => ['type' => ['string', 'null']],
'werkplek' => ['type' => 'string', 'enum' => ['kantoor', 'hybride', 'remote']],
'uren_min' => ['type' => ['integer', 'null']],
'uren_max' => ['type' => ['integer', 'null']],
'salaris_min' => ['type' => ['integer', 'null']],
'salaris_max' => ['type' => ['integer', 'null']],
'salaris_per' => ['type' => ['string', 'null'], 'enum' => ['uur', 'maand', 'jaar', null]],
],
'required' => ['functietitel', 'plaats', 'werkplek', 'uren_min', 'uren_max', 'salaris_min', 'salaris_max', 'salaris_per'],
'additionalProperties' => false,
]; Ronde 1: de JSON klopt altijd, de inhoud niet
Met een korte systeemprompt ("Haal de gevraagde velden uit de vacaturetekst. Staat iets er niet expliciet in, vul dan null in. Reken niets om en gok niet.") gaf het model vijf keer geldige JSON. Op de 35 velden met feiten (de functietitel niet meegeteld) waren er 7 fout. Drie keer gedraaid, met temperature op 0: drie keer exact dezelfde antwoorden, dus ook drie keer dezelfde fouten.
- V-101 noemt "twee dagen per week thuiswerken". Het model vulde
kantoorin in plaats vanhybride. - V-103 noemt "max. €3.400". Het model maakte daar een salaris van precies 3.400 tot 3.400 van, een ondergrens die nergens staat.
- V-104 noemt 36 uur. Het model vulde 36 als minimum in en
nullals maximum, en gaf bij "marktconform" tochjaarals eenheid. - V-102 en V-105 noemen geen plaats. Het model schreef er tekst neer: "Remote (Nederland of België)" en "Onbekend (volledig op afstand)".
- Het uurtarief van €85 in V-105 ontbrak.
Structured outputs garanderen de vorm, niet de waarheid. Een schema houdt tekst in een getalveld tegen. Een fout getal in een getalveld houdt het niet tegen.
Ronde 2: uitleg in het schema verandert niets
De voor de hand liggende oplossing is uitleg toevoegen aan het schema. Bij elk veld een description: "hybride = deels thuis, deels op kantoor", "'max. X' heeft geen ondergrens: null". Het resultaat: dezelfde zeven fouten. Niet ongeveer dezelfde, maar tot op het teken dezelfde antwoorden, drie keer achter elkaar.
Mijn verklaring, en dat is een verklaring en geen meting: Ollama gebruikt het schema om de uitvoer te beperken, zodat het model alleen tekens kan kiezen die in het schema passen. De beschrijvingen komen daarbij niet in de prompt terecht. Het model leest ze dus nooit. Of de API van Mistral de beschrijvingen wel aan het model doorgeeft, heb ik niet getest. Ga er niet van uit zonder het zelf te controleren.
Ronde 3: de regels in de prompt helpen, en maken nieuwe fouten
Dezelfde regels, nu in de systeemprompt:
regels.txt
Haal de gevraagde velden uit de vacaturetekst. Staat iets er niet expliciet in, vul dan null in. Gok niet.
Regels per veld:
- plaats: alleen een plaatsnaam. Geen plaats genoemd: null.
- werkplek: kantoor, hybride (deels thuis, deels op kantoor) of remote (volledig op afstand).
- uren_min en uren_max: wordt één getal genoemd, vul dan bij allebei dat getal in.
- salaris_min: alleen als de tekst een ondergrens noemt. "max. X" heeft geen ondergrens: null.
- salaris_max: in hele euro's, "55k" is 55000. Een uurtarief telt ook als salaris.
- salaris_per: uur, maand of jaar. Geen bedrag genoemd: null. Dat hielp. V-101 werd hybride, V-103 kreeg geen verzonnen ondergrens meer, V-104 klopte helemaal en het uurtarief van V-105 kwam erin. Van de 35 velden waren er nog 4 fout. Maar alle vier waren nieuwe fouten, van een soort die er in ronde 1 niet was:
- Bij V-102 en V-105 schreef het model als plaats de tekst
"null", tussen aanhalingstekens. Dat is een string van vier letters, geen lege waarde. Eenif ($plaats === null)in je code slaat hem over. - Bij V-103 werd "max. €3.400" per maand ineens 34.000 per jaar. Het model rekende om, en rekende ook nog fout: twaalf keer 3.400 is 40.800. Kijk goed naar de regels hierboven: de zin "Reken niets om" uit ronde 1 staat er niet meer in. Die raakte ik kwijt bij het uitschrijven van de regels per veld. Eén weggevallen zin, en het model doet precies wat die zin tegenhield.
Een tweede les uit deze ronde, voor wie denkt dat temperatuur 0 alles vastzet: met de korte prompt uit ronde 1, maar als bestand met een regeleinde erachter, veranderden de antwoorden voor V-105, en niet ten goede: "volledig op afstand" werd kantoor. Eén onzichtbaar teken. Zet je prompts daarom in bestanden onder versiebeheer, en draai je testset na elke wijziging opnieuw.
Ronde 4: een controle in gewone PHP vangt de rest
Het model wordt niet betrouwbaarder door het strenger toe te spreken. Wat wel werkt: controleren wat terugkomt, met code die je zelf begrijpt. Drie regels, elk met een concrete reden: "null" als tekst wordt echt null, elk getal moet letterlijk in de brontekst staan, en een ondergrens mag niet boven de bovengrens liggen.
controle.php
<?php
declare(strict_types=1);
/**
* Controleert wat het model teruggaf, met gewone PHP.
* Geeft de opgeschoonde velden terug plus een lijst met waarschuwingen.
*/
function controleer(array $velden, string $tekst): array
{
$waarschuwingen = [];
// 1. Het woord "null" als tekst is geen null.
foreach ($velden as $veld => $waarde) {
if (is_string($waarde) && strtolower(trim($waarde)) === 'null') {
$velden[$veld] = null;
}
}
// 2. Elk bedrag en elk aantal uren moet in de brontekst staan.
$getallen = getallen_in($tekst);
foreach (['uren_min', 'uren_max', 'salaris_min', 'salaris_max'] as $veld) {
if ($velden[$veld] !== null && !in_array($velden[$veld], $getallen, true)) {
$waarschuwingen[] = "$veld = {$velden[$veld]} staat niet in de tekst";
}
}
// 3. Ondergrens niet boven bovengrens.
foreach (['uren', 'salaris'] as $soort) {
[$min, $max] = [$velden["{$soort}_min"], $velden["{$soort}_max"]];
if ($min !== null && $max !== null && $min > $max) {
$waarschuwingen[] = "{$soort}_min is hoger dan {$soort}_max";
}
}
return [$velden, $waarschuwingen];
}
/** Alle getallen in een tekst: "€3.800" wordt 3800, "55k" wordt 55000. */
function getallen_in(string $tekst): array
{
preg_match_all('/(\d{1,3}(?:\.\d{3})+|\d+)(k\b)?/i', $tekst, $m, PREG_SET_ORDER);
return array_map(
fn (array $g) => (int) str_replace('.', '', $g[1]) * (empty($g[2]) ? 1 : 1000),
$m
);
} Het script dat alles samenbrengt. Met de omgevingsvariabelen SCHEMA en PROMPT kun je de rondes hierboven herhalen; met MISTRAL_BASE_URL, MISTRAL_API_KEY en MISTRAL_MODEL draait hetzelfde script tegen de API van Mistral.
extract.php
<?php
declare(strict_types=1);
require __DIR__ . '/mistral.php';
require __DIR__ . '/controle.php';
// Lokaal (Ollama) of de API van Mistral: alleen deze drie regels verschillen.
$baseUrl = getenv('MISTRAL_BASE_URL') ?: 'http://localhost:11434';
$apiKey = getenv('MISTRAL_API_KEY') ?: null;
$model = getenv('MISTRAL_MODEL') ?: 'ministral-3:8b';
$schema = require __DIR__ . '/' . (getenv('SCHEMA') ?: 'schema.php');
$regels = file_get_contents(__DIR__ . '/' . (getenv('PROMPT') ?: 'regels.txt'));
$vacatures = require __DIR__ . '/vacatures.php';
foreach ($vacatures as $ref => $tekst) {
$start = microtime(true);
$response = mistral_chat($baseUrl, $apiKey, [
'model' => $model,
'temperature' => 0,
'messages' => [
['role' => 'system', 'content' => $regels],
['role' => 'user', 'content' => $tekst],
],
'response_format' => [
'type' => 'json_schema',
'json_schema' => ['name' => 'vacature', 'schema' => $schema, 'strict' => true],
],
]);
$seconden = microtime(true) - $start;
$velden = json_decode($response['choices'][0]['message']['content'], true, 512, JSON_THROW_ON_ERROR);
$ruw = json_encode($velden, JSON_UNESCAPED_UNICODE);
[$velden, $waarschuwingen] = controleer($velden, $tekst);
printf("%s (%.1f s): %s\n", $ref, $seconden, $ruw);
foreach ($waarschuwingen as $w) {
echo " LET OP: $w\n";
}
if (json_encode($velden, JSON_UNESCAPED_UNICODE) !== $ruw) {
echo " na controle: " . json_encode($velden, JSON_UNESCAPED_UNICODE) . "\n";
}
} De uitvoer, met de regels in de prompt en de controle erachter (ingekort waar de puntjes staan):
V-101 (2.5 s): {"functietitel":"Medior PHP Developer (Laravel)","plaats":"Utrecht","werkplek":"hybride","uren_min":32,"uren_max":40,"salaris_min":3800,"salaris_max":5200,"salaris_per":"maand"}
V-102 (2.3 s): {..."plaats":"null"...}
na controle: {..."plaats":null...}
V-103 (2.4 s): {..."salaris_min":null,"salaris_max":34000,"salaris_per":"jaar"}
LET OP: salaris_max = 34000 staat niet in de tekst
V-104 (2.1 s): {"functietitel":"Lead developer","plaats":"Amsterdam","werkplek":"hybride","uren_min":36,"uren_max":36,"salaris_min":null,"salaris_max":null,"salaris_per":null}
V-105 (2.2 s): {..."plaats":"null",..."salaris_max":85,"salaris_per":"uur"}
na controle: {..."plaats":null...} Twee fouten zijn automatisch hersteld. V-103 is gemarkeerd: daar moet een mens naar kijken. Er gaat geen fout meer ongemerkt de database in. Dat is de maatstaf die telt: niet hoeveel het model goed doet, maar hoeveel fouten je niet ziet.

Elke vacature kostte na het laden 2,1 tot 3,2 seconden. De allereerste aanroep duurde 45,6 seconden, omdat Ollama het model dan nog in het geheugen moest laden.
Twee kanttekeningen. Dit zijn vijf vacatures, geen onderzoek; de getallen laten zien welk soort fouten je kunt verwachten, niet hoe vaak. En Ministral 3 8B is het kleinste serieuze model in de lijst. Small 4 en Large 4 maken waarschijnlijk minder fouten, maar dat heb ik niet gemeten. Het punt blijft staan: elk model maakt fouten die een schema niet tegenhoudt, en de controle in PHP kost niets per aanroep.
Waar gaat je data heen? Een Europees bedrijf is nog geen Europese verwerking
Mistral is een Frans bedrijf, en voor veel organisaties is dat de reden om het te kiezen. Maar de standaard-API api.mistral.ai belooft in de documentatie geen vaste locatie voor de verwerking. Wil je dat je verzoeken in Europa verwerkt worden, dan gebruik je het regionale endpoint api.eu.mistral.ai, met datacenters in landen van de EU en de EFTA. Daar zitten drie voorwaarden aan:
- Het kost 1,1 keer de normale prijs, voor invoer, uitvoer en cache.
- De Agents API, batchverwerking en de Files API werken er niet. Function calling is de enige tool die je regionaal kunt gebruiken.
- Gegevens van je account, zoals je sleutels, de facturatie en de gebruiksstatistieken, kunnen buiten de regio verwerkt worden.
Waar je verzoek verwerkt wordt en of het daarna bewaard wordt, zijn twee aparte instellingen. Voor het tweede heeft Mistral zero data retention, los van het regionale endpoint. Wie alleen eu in de URL zet, heeft de helft geregeld.
Dan de training. Met het gratis API-plan (Experiment) kan Mistral je verzoeken gebruiken om modellen te trainen. Dat zet je uit in de Admin Console, onder Privacy. Op het betaalde Scale-plan staat dat standaard uit. Voor Vibe is er een eigen schakelaar; in het Vibe-artikel staat waarom je beide moet controleren.
De sterkste vorm van controle is het model zelf draaien. Ministral 3 en Small 4 staan onder Apache 2.0: doe ermee wat je wilt, ook commercieel. Large 4 valt onder de Mistral Ecosystem Open-Weight License. Intern gebruik is toegestaan, ook commercieel en ongeacht de omvang van je bedrijf. Bied je het model als dienst aan anderen aan ("model as a service"), dan heb je een aparte commerciële licentie nodig. Alleen: Large 4 is in 4 bits al 610 GB groot, en dat is alleen het geheugen voor de gewichten. Dat is een serverrack, geen werkstation. Welk model wel op een laptop past, staat in mijn meting met 16 GB.
Zo begin je deze week
Voor de programmeerhulp: maak een gratis account, zet in de Admin Console de training uit, en installeer Vibe in de editor die je al gebruikt: de extensie in VS Code, de agent via de AI Assistant in PhpStorm, of de command-line-tool. Zet Large 4 in je config.toml en begin in de modus ask. Ga pas naar Pro als het gratis plan je tegenhoudt.
Voor je applicatie: schrijf eerst de testset, dan pas de code. Twintig echte voorbeelden uit je eigen praktijk, met per veld het goede antwoord. Draai ze tegen Small 4 en tegen Large 4, tel de fouten per veld, en zet er een controle in PHP achter voor elke soort fout die je tegenkomt. Kies het endpoint op basis van waar de gegevens mogen komen, niet op basis van de vlag op het hoofdkantoor.
Die testset is ook je antwoord op het tempo van Mistral. Medium 3.5 stopt in april, en over een half jaar is er vast een opvolger van Large 4. Met een testset is een modelwissel een middag werk: script draaien, fouten tellen, beslissen. Zonder testset is het een gok die je met je gebruikers uitprobeert.
Mistral is in november 2026 niet de keuze voor wie het beste codeermodel zoekt. Het is de keuze voor wie wil kunnen vertrekken: naar het Europese endpoint, naar een eigen server, naar een ander model met dezelfde API. Dat lukt alleen als je testset er al ligt.
Verder lezen op deze site
- Mistral Large 4: een biljoen parameters uit Europa, en wat "open" hier nog niet betekent
- Mistral Vibe: de Europese codeeragent in je terminal, en waar je code heen gaat
- Een AI-agent bouwen in PHP: compleet voorbeeld met Composer, Claude en MCP
- Welk AI-model draai je op je eigen laptop? Gemeten op 16 GB, oktober 2026
Bronnen
- Mistral AI, Changelog (Vibe, 28 mei 2026; Medium 3.5; Large 4) en Models overview met de tabel van uitgefaseerde modellen; bekeken 3 november 2026
- Mistral AI, modelkaart Mistral Large 4 en API-prijzen; abonnementen Vibe; bekeken 3 november 2026
- Mistral AI, Vibe-documentatie: Vibe Code, installatie, configuratie, VS Code-extensie en Vibe in andere IDE's; mistral-vibe op PyPI (3.0.4)
- Mistral AI, Regional inference en helpcenter over training op je gegevens
- JetBrains, Bring your own AI agent to JetBrains IDEs en Agents in PhpStorm
- VentureBeat (Carl Franzen), Mistral Large 4 'Le Chonk' arrives as the top open model outside China, 29 oktober 2026: licentie en de cijfers van Artificial Analysis
- Laravel, Laravel AI SDK; Packagist: symfony/ai-mistral-platform, softcreatr/php-mistral-ai-sdk, helgesverre/mistral
- Ollama, ministral-3 (Apache 2.0, 3B/8B/14B)
- Eigen test, 3 november 2026: Ollama 0.40.13,
ministral-3:8b(Q4_K_M), PHP 8.2.35, RTX 4070 Laptop; vijf verzonnen vacatures


