Naar inhoud springen
21/30Hoofdstuk 21 van 30

Multimodale pricing: wat afbeeldingen, audio en video echt kosten

Drie modellen rekenen voor dezelfde 500 foto’s tot 5,5× anders — en de goedkoopste wisselt zodra iemand ze verkleint.

Op deze pagina

Hier is één taak, op drie manieren geprijsd: beschrijf vijfhonderd productfoto’s, met één kort onderschrift per foto. Dezelfde foto’s, dezelfde instructie, dezelfde antwoordlengte. Het enige dat verandert, is welk model ze leest.

fotogpt-5.6-lunagemini-3.1-flash-liteclaude-haiku-4.5
800 × 600$0.0848$0.1638$0.4380
1024 × 768$0.1200$0.1638$0.6370
1280 × 960$0.1718$0.1638$0.9010
1600 × 1200$0.2558$0.1638$0.9010
4000 × 3000$0.3220$0.1638$0.9010

Drie dingen in die tabel zijn het waard om bij stil te staan.

Het goedkoopste model verandert tussen de derde en de vierde rij, voor dezelfde taak, omdat iemand de foto’s heeft verkleind. Vraag om een alinea in plaats van een onderschrift en het snijpunt verschuift opnieuw: bij 1280 × 960 wint Gemini voor een onderschrift van veertig tokens en OpenAI voor een alinea van vierhonderd tokens.

De Gemini-kolom beweegt helemaal niet, in geen enkele rij: een foto van 4000 × 3000 kost precies hetzelfde als een foto van 640 × 480. Een foto van 4000 × 3000 kost precies hetzelfde als een foto van 640 × 480. Dat is geen limiet. Het is een gevolg van hoe het telt, en het betekent dat de meest gangbare kostenoptimalisatie in deze sector — downsamplen voordat je uploadt — zo uitpakt:

image tokens, 4000 × 3000 → 800 × 600kosten van de runbespaard
gpt-5.6-luna2.942 → 570$0.3220 → $0.084873,7 %
claude-haiku-4.51.564 → 638$0.9010 → $0.438051,4 %
gemini-3.1-flash-lite1.032 → 1.032$0.1638 → $0.16380,0 %

Geen van die getallen is een prijs die de leverancier publiceert. Alle drie moesten worden berekend, op basis van drie verschillende regels, omdat een foto nergens een factureerbare eenheid is: hij wordt eerst omgezet in tokens, via rekenwerk dat op drie incompatibele plekken is opgeschreven.

Hoofdstuk 16 bouwde de factuur voor tekst en stopte waar tekst stopt. Dit hoofdstuk is de rest van de factuur: afbeeldingen, spraak, transcriptie, video en ruwe compute, die samen in acht verschillende eenheden worden gefactureerd, plus de methode om dingen te vergelijken die niet in dezelfde maat worden verkocht.

Details tonen

Wat dit hoofdstuk nodig heeft uit de eerdere hoofdstukken.

  • Hoofdstuk 7 bouwde de tokenizer en de eenheid. Alles hier is een poging om iets dat geen tekst is naar die eenheid om te zetten.
  • Hoofdstuk 8 stelde vast wat een model consumeert: geen symbolen, maar vectoren in een embedding-ruimte. Daarom kan een afbeelding überhaupt in tokens worden geprijsd.
  • Hoofdstuk 16 bouwde computeCost, de prijslagen en de vijf token-buckets. Dit hoofdstuk breidt die functie uit in plaats van haar te vervangen.
  • Hoofdstuk 11 introduceerde LoRA als fine-tuning-techniek en Hoofdstuk 20 prijsde het als budgetbeslissing. Hier duikt het op bij een model dat geen taalmodel is.

Geen tensors, volgens de regel uit Hoofdstuk 14: dit gaat over tarieven, conversies en boekhouding, dus het is TypeScript.

Een transformer neemt een reeks vectoren. Het maakt hem niet uit waar die vandaan kwamen. Hoofdstuk 8 voerde hem embeddings die uit een token-id werden opgezocht; niets in de architectuur vereist die lookup.

Dus: knip de afbeelding in vaste vierkanten, maak van elk vierkant een lijst getallen en stuur elke lijst door één geleerde lineaire laag om een vector met de breedte van het model te krijgen. Een patch van 32 × 32 kleurpixels is 32×32×3=307232 \times 32 \times 3 = 3072 getallen; de projectie ERd×3072E \in \mathbb{R}^{d \times 3072} verandert die in één dd-dimensionale vector, precies de vorm waarin een tekst-token binnenkomt. Dat is alles, en het is het paper waarvan de titel het zegt: een afbeelding is 16 × 16 woorden waard.1 Voeg een positionele encoding toe zodat het model weet welk vierkant waar stond, verweef de resultaten met de tekst-embeddings, en de reeks die het model leest is deels afbeelding en deels zin.

Drie papers maakten er een product van. CLIP trainde een image encoder en een text encoder om het eens te worden, op vierhonderd miljoen gescrapete paren; daar stopte het idee dat pixels en woorden een ruimte kunnen delen met een hypothese zijn.2 Flamingo schroefde een bevroren vision encoder op een bevroren taalmodel met een paar getrainde bruglagen.3 LLaVA liet zien dat die brug één lineaire projectie kon zijn en dat instruction-following met gegenereerde data kon worden geleerd, waardoor elk open vision-language model sindsdien er grofweg hetzelfde uitziet.4

Het gevolg voor je factuur is direct en weinig glamoureus: de patches zijn posities in de reeks, dus het zijn input tokens, dus je betaalt ervoor tegen het inputtarief. Hoeveel het er zijn is rekenwerk, en elke provider doet het anders.

Drie regels, allemaal gepubliceerd, geen enkele hetzelfde

Link naar de sectie: Drie regels, allemaal gepubliceerd, geen enkele hetzelfde

Elke regel hieronder is geïmplementeerd op basis van de eigen documentatie van de provider en gecontroleerd tegen de uitgewerkte voorbeelden in diezelfde documentatie.

OpenAI bedekt de afbeelding met patches van 32 × 32 en vermenigvuldigt het aantal met een factor per model. Als het aantal patches het budget voor dat model en detailniveau overschrijdt, wordt de afbeelding omlaag geschaald tot hij past:

patches=w32×h32,shrink=322budgetwh\text{patches} = \left\lceil \frac{w}{32} \right\rceil \times \left\lceil \frac{h}{32} \right\rceil, \qquad \text{shrink} = \sqrt{\frac{32^2 \cdot \text{budget}}{w \cdot h}}

Anthropic bedekt hem met patches van 28 × 28, één visual token per stuk, en begrenst zowel de lange zijde als het aantal tokens — 1.568 pixels en 1.568 tokens op standard-tier modellen, 2.576 en 4.784 op de high-resolution tier. Te grote afbeeldingen worden geschaald naar de grootste maat die aan beide voorwaarden voldoet.5

Google telt pixels helemaal niet. Een afbeelding waarvan beide zijden 384 pixels of kleiner zijn kost vast 258 tokens. Alles wat groter is, wordt in tiles van 258 tokens gesneden, en het tile-raster komt uit een crop unit van min(w,h)/1.5\lfloor \min(w,h) / 1.5 \rfloor.6

imagetokens.tsTS
export function openaiImageTokens(
  w: number, h: number,
  { maxDim, patchBudget, multiplier }: { maxDim: number; patchBudget: number; multiplier: number },
) {
  const fit = Math.min(1, maxDim / Math.max(w, h));      // never enlarges
  w = Math.floor(w * fit); h = Math.floor(h * fit);
  let patches = Math.ceil(w / 32) * Math.ceil(h / 32);   
  if (patches > patchBudget) {
    const s = Math.sqrt((32 * 32 * patchBudget) / (w * h));
    const adj = s * Math.min(
      Math.floor((w * s) / 32) / ((w * s) / 32),
      Math.floor((h * s) / 32) / ((h * s) / 32));
    patches = Math.ceil(Math.floor(w * adj) / 32) * Math.ceil(Math.floor(h * adj) / 32);
  }
  return Math.ceil(patches * multiplier);                
}

export function anthropicVisualTokens(
  w: number, h: number,
  { maxLongEdge, maxTokens }: { maxLongEdge: number; maxTokens: number },
) {
  const tok = (a: number, b: number) => Math.ceil(a / 28) * Math.ceil(b / 28);
  const long = Math.max(w, h), short = Math.min(w, h);
  for (let L = Math.min(long, maxLongEdge); L >= 1; L--) {     
    const t = tok(L, Math.round((short * L) / long));
    if (t <= maxTokens) return t;                              
  }
  return 0;
}

export function geminiImageTokens(w: number, h: number) {
  if (w <= 384 && h <= 384) return 258;
  const crop = Math.floor(Math.min(w, h) / 1.5);               
  return Math.ceil(w / crop) * Math.ceil(h / crop) * 258;      
}

Draai elke regel tegen de getallen die de eigen leverancier afdrukt:

three implementations against three documentationsTEXT
OpenAI, gpt-5.4 at detail:high (2048 px, 2,500 patches, 1.2x)
  1024x1024 -> 1024 patches -> 1229 tokens   doc says 1229   MATCH
  2048x2048 -> 2500 patches -> 3000 tokens   doc says 3000   MATCH

Anthropic, the published table (one tier per row shown)
  200x200    std   64 @ 200x200     doc   64, not resized    OK
  1000x1000  std 1296 @ 1000x1000   doc 1296, not resized    OK
  1092x1092  std 1521 @ 1092x1092   doc 1521, not resized    OK
  1920x1080  std 1560 @ 1456x819    doc 1560, 1456x819       OK
  2000x1500  std 1564 @ 1269x952    doc 1564, 1269x952       OK
  3840x2160  hi  4784 @ 2576x1449   doc 4784, 2576x1449      OK

Google, the worked example
  960x540 -> crop 360 -> 3 x 2 = 6 tiles     doc says 6      MATCH

Negen overeenkomsten worden afgedrukt; de volledige run controleert er vijftien, omdat Anthropic’s tabel beide tiers voor alle zes maten geeft. De regels zijn nu van jou om op elke foto te draaien die je hebt, en dat is het punt: dit zijn de enige drie functies in dit hoofdstuk die je niet uit een prijspagina kunt halen.

Haal dezelfde 4:3-foto door alle drie op zes maten:

formaatOpenAI, highAnthropic, standaardAnthropic, high-resGemini
384 × 288130154154258
640 × 4803604144141.032
800 × 6005706386381.032
1600 × 12002.2801.5642.4941.032
3200 × 24002.9421.5644.7401.032
4000 × 30002.9421.5644.7401.032

Lees de laatste kolom van boven naar beneden. Zodra de afbeelding groter is dan 384 pixels verandert het getal nooit meer, en dat is geen toeval of limiet. Vul de crop unit terug in de tile-formule in, voor een afbeelding die minstens zo breed is als hij hoog is:

tiles=wh/1.5×hh/1.51.5wh×2\text{tiles} = \left\lceil \frac{w}{\lfloor h/1.5 \rfloor} \right\rceil \times \left\lceil \frac{h}{\lfloor h/1.5 \rfloor} \right\rceil \approx \left\lceil \frac{1.5\,w}{h} \right\rceil \times 2

De grootte valt weg. Google’s image tokens hangen af van de aspect ratio en van niets anders. Een 4:3-foto is vier tiles, of hij nu een thumbnail of een poster is. Dat ene algebraïsche feit is de volledige verklaring voor de nul in de besparingstabel hierboven, en geen enkele prijspagina zegt het.

De andere twee kolommen begrenzen in plaats daarvan, op verschillende hoogtes en om verschillende redenen — Anthropic bij een verklaard token-plafond, OpenAI bij een patch-budget na een pixellimiet — en daarom kruisen de drie curves elkaar bij verschillende maten.

Breek het nu. De voor de hand liggende manier om minder uit te geven aan een vision model is om om minder detail te vragen, dus stuur detail: "low":

gpt-5.4, the same photograph, two detail levelsTEXT
1600x1200   low = 2280   high = 2280   ratio 1.00
3200x2400   low = 3687   high = 2942   ratio 1.25

Om minder detail vragen kostte 25 % meer. Dit is geen bug en OpenAI zegt dat zelf in één regel van de sizing-tabel: op die modelfamilie gebruikt low een 2048-pixellimiet met een 6.144-patchbudget, terwijl high dezelfde pixellimiet gebruikt met een 2.500-patchbudget, „so it can use more tokens than high”.7 Het woord low benoemt een fidelity-instelling, geen prijs: op twee van de vijf gedocumenteerde modelfamilies levert het helemaal geen besparing op, en op een van die twee kost het meer.

Alles tot nu toe ging over een model dat een afbeelding leest. Er een maken draait op een mechanisme zonder tokens erin, en dat is de reden dat het per afbeelding wordt verkocht in plaats van per woord.

Een afbeelding maken: een prijs per afbeelding is een prijs per token

Link naar de sectie: Een afbeelding maken: een prijs per afbeelding is een prijs per token

Leveranciers publiceren image generation als een prijs per afbeelding. Dat is het niet. GPT Image-modellen stoten gespecialiseerde image tokens uit waarvan het aantal afhangt van de gevraagde grootte en kwaliteit; vermenigvuldig de gepubliceerde aantallen met GPT Image 1’s gepubliceerde image output-tarief van $40 per miljoen en vergelijk met de per-image prijzen op dezelfde pagina:

kwaliteit1024 × 10241024 × 15361536 × 1024
laag272 tok → $0.0109 ($0.011)408 tok → $0.0163 ($0.016)400 tok → $0.0160 ($0.016)
medium1.056 tok → $0.0422 ($0.042)1.584 tok → $0.0634 ($0.063)1.568 tok → $0.0627 ($0.063)
hoog4.160 tok → $0.1664 ($0.167)6.240 tok → $0.2496 ($0.25)6.208 tok → $0.2483 ($0.25)

Negen afgeleide cijfers tegenover negen gepubliceerde, elk paar overeenkomend tot binnen $0.002.11 Google is nog explicieter en doet de conversie zelf voor je op de prijspagina: image output voor $60 per miljoen tokens, „output images at 1K (1024x1024px) consume 1120 tokens and are equivalent to $0.067 per image”.12

Dus een prijs per afbeelding is een prijs per token met het aantal erin gevouwen. Dat is prima, en het verbergt iets. Neem de tabel van de huidige generatie en deel achteruit:

gpt-image-2, published price -> implied output tokens at $30/MTEXT
quality   1024x1024            1024x1536
low       $0.006 -> 200 tok    $0.005 -> 167 tok
medium    $0.053 -> 1767 tok   $0.041 -> 1367 tok
high      $0.211 -> 7033 tok   $0.165 -> 5500 tok

De grotere afbeelding is bij elke kwaliteit de goedkopere. Een canvas van 1024 × 1536 heeft 50 % meer pixels dan een canvas van 1024 × 1024 en kost 23 % minder tokens op medium. OpenAI markeert het in een zin die je zou overslaan — „a larger non-square resolution can sometimes produce fewer output tokens than a smaller or square resolution at the same quality setting” — en bij de vorige modelgeneratie liep het andersom, portrait kostte 50 % meer dan square.11 Elke standaardwaarde van 1024x1024 die vóór die wijziging is geschreven, is nu de dure optie.

Geluid, gefactureerd per seconde, per teken en per token

Link naar de sectie: Geluid, gefactureerd per seconde, per teken en per token

Vraag drie producten om dezelfde 519 tekens uit te spreken — ongeveer 38 seconden audio — en je krijgt drie eenheidssystemen van twee leveranciers:

modeleenheidprijs
tts-1per teken$15.00 per miljoen tekens → $0.007785
tts-1-hdper teken$30.00 per miljoen tekens → $0.015570
gemini-3.1-flash-ttsper audio token, 25 per seconde$20.00 per miljoen → $0.019319

Dezelfde leverancier verkoopt beide eenheden: OpenAI’s tts-1 wordt geprijsd per miljoen tekens, terwijl gpt-4o-mini-tts wordt geprijsd per miljoen tokens, $0.60 in en $12.00 uit.13 Dus „goedkoopste text-to-speech” is geen vraag met een antwoord totdat je zegt wat je laat uitspreken.

En de twee eenheden zijn blind voor tegengestelde dingen. Een prijs per teken kan duur niet zien: kies een langzame, bedachtzame stem, of voeg pauzes toe, en de rekening beweegt niet terwijl de audio langer wordt. Een prijs per seconde kan inhoud niet zien: dertig seconden kost hetzelfde, of het nu een dichte technische alinea is of iemand die tot tien telt. Verander de stem en precies één van je twee leveranciers prijst opnieuw.

Transcriptie loopt de andere kant op en is de eenvoudigste regel op de hele factuur — per minuut audio, vast:

transcribing 59.6 secondsTEXT
whisper                  $0.005960     ($0.006 / min)
gpt-transcribe           $0.004470     ($0.0045 / min)
gpt-4o-mini-transcribe   $0.002980     ($0.003 / min)
gpt-live-transcribe      $0.016887     ($0.017 / min)

Let op de laatste rij tegenover de derde: het live doen, terwijl de woorden binnenkomen, kost 5,7 keer zoveel als het doen op een afgerond bestand. Dat verschil is de prijs van niet kunnen batchen, en het maakt de volgende sectie duur.

Nu het getal dat beslist of voice een feature is of een product.

Het gesprek: een supportgesprek van tien beurten, 149 woorden, wat bij een verklaarde 150 woorden per minuut neerkomt op 59,6 seconden spraak — 21,2 uitgesproken door de beller, 38,4 teruggesproken. De token-conversies zijn die van de providers zelf. OpenAI: „audio tokens in user messages are 1 token per 100 ms of audio, while audio tokens in assistant messages are 1 token per 50 ms”.14 Google: 25 tokens per seconde, in beide richtingen, wat de prijspagina bevestigt door $12.00 per miljoen en $0.018 per minuut op dezelfde regel te publiceren.12

Het gesprek stapelt zich precies op zoals hoofdstuk 16 zei dat het zou doen, omdat het hetzelfde mechanisme is: „the entire conversation is sent to the model for each Response... thus turns later in the session will be more expensive”.14 Alleen wordt de geschiedenis nu gemeten in audio tokens.

beurtgebruikerassistantverse audio incached audio inaudio uitkosten
14,4 s9,2 s440184$0.013224
25,6 s9,6 s56228192$0.014211
35,2 s9,2 s52476184$0.013670
44,0 s4,8 s4071296$0.007749
52,0 s5,6 s20848112$0.008187

Nu de vergelijking die het product beslist, alle vier genormaliseerd naar een minuut:

per minuutversus tekst
gpt-realtime-2.1, geen caching$0.13125937,9×
gpt-realtime-2.1, geschiedenis cached$0.05742516,6×
gemini-3.1-flash-live, geen caching$0.0239656,9×
dezelfde woorden getypt, gpt-5.6-terra$0.003461

Achtendertig keer. Geen achtendertig procent. De identieke uitwisseling, gevoerd in geluid in plaats van tekst, is bijna twee ordes van grootte duurder, en niets van dat gat is een marge die iemand heeft gekozen te rekenen — het is de conversieratio. Eén seconde assistant-audio is twintig tokens. Diezelfde seconde draagt 2,5 woorden bij het verklaarde tempo, en het gemeten transcript komt uit op 1,26 tokens per woord, dus als tekst is het 3,15 tokens. Geluid is een 6,3 keer omvangrijker pakket voor dezelfde betekenis, en elk van zijn tokens wordt gefactureerd tegen 5,3 keer het text output-tarief en 16 keer het text input-tarief. Vermenigvuldig een omvangsratio met een prijsratio en de orde van grootte staat er al voordat de boekhouding begint.

Twee operationele gevolgen volgen rechtstreeks uit de tabel.

Audio caching is geen optimalisatie, het is het businessmodel. Cached audio input kost $0.40 per miljoen tegenover $32.00 vers — een korting van 98,75 % die de call halveert. De regel is die van hoofdstuk 16, onveranderd: de cache matcht een prefix, dus alles wat halverwege de call vooraan in het gesprek wordt ingevoegd vernietigt hem, en de natuurlijke plek om „de beller is nu geverifieerd” te plaatsen is precies daar.

En niets wat je in de client doet, haalt geluid van de factuur. De gebruiker praat door de assistant heen, je code stopt het afspelen, de speaker wordt stil. Alles wat al was gegenereerd, was al in rekening gebracht, omdat billing oploopt wanneer de response wordt gemaakt; en volgens de regel van hoofdstuk 16 wordt alles wat in het gesprek blijft bij elke volgende beurt opnieuw verstuurd, als input audio. Hoofdstuk 14 maakte dit punt over het afbreken van een tekststream. In voice kost het dertig keer meer.

Video, GPU-seconden en een prijs die geen prijs is

Link naar de sectie: Video, GPU-seconden en een prijs die geen prijs is

Video wordt door sommige leveranciers per seconde verkocht en door andere per clip, met tiers voor resolutie en soms voor duur. Die twee vormen verschillen niet alleen in gemak; ze kruisen elkaar.

model1 s2 s5 s10 s20 s
veo-3.1, per seconde, 1080p$0.400$0.800$2.000$4.000$8.000
veo-3.1-fast, per seconde, 1080p$0.120$0.240$0.600$1.200$2.400
sora-2, per seconde, 720p$0.100$0.200$0.500$1.000$2.000
hailuo-02, per clip, 1080p$0.480$0.480$0.480$0.480$0.480
mochi, per GPU-seconde$0.018$0.037$0.092$0.183$0.366

De leverancier per clip is duurder dan die per seconde onder 1,2 seconden en 16,7 keer goedkoper bij twintig. Geen ordening van die twee modellen overleeft een verandering in cliplengte, dus „welk videomodel is het goedkoopst” is geen vraag over modellen.

De laatste rij is erger, en is het eerlijke hart van dit hoofdstuk. mochi wordt gefactureerd op echte GPU-seconden — de gemeten prediction-tijd van de job — tegen $0.001400 per seconde op een A100 en $0.001525 op een H100, wat niets anders zijn dan de tarieven van de gehuurde machine.15 Dat is een perfect precies tarief en het is geen prijs, omdat de hoeveelheid waarmee het vermenigvuldigt onbekend is tot nadat je je hebt verbonden om te betalen. De rij hierboven gaat uit van twaalf GPU-seconden per seconde output; verviervoudig die aanname en hij verlaat de goedkoopste band, en pas bij zes keer landt hij in het midden van de tabel. Het is het enige tarief op deze pagina dat je niet in een offerte kunt zetten.

Dus: tokens, image tokens, tekens, minuten, videoseconden, hele clips, GPU-seconden, vaste eenheden. Acht grootheden, en de enige manier om ze op één as te zetten is een workload verklaren en die prijzen.

Dat is de uitbreiding op hoofdstuk 16’s computeCost — dezelfde tier-machinerie, nu met criteria die geen prompt-lengte zijn:

normalise.tsTS
export interface MediaCriteria {
  resolution?: string[]; quality?: string[];
  hasAudio?: boolean; maxDurationSeconds?: number;
}
export interface MediaTier { when?: MediaCriteria; price: number }
export type MediaRate = number | MediaTier[];

const matches = (when: MediaCriteria, u: Usage) => {
  const inList = (l?: string[], v?: string) => !l || (v !== undefined && l.includes(v));
  if (!inList(when.resolution, u.resolution)) return false;
  if (!inList(when.quality, u.quality)) return false;
  if (when.hasAudio !== undefined && when.hasAudio !== (u.hasAudio ?? false)) return false;
  if (when.maxDurationSeconds !== undefined
      && (u.videoSeconds ?? 0) > when.maxDurationSeconds) return false;   
  return true;
};

const mediaPrice = (rate: MediaRate | undefined, u: Usage): number => {
  if (rate === undefined) return 0;
  if (typeof rate === "number") return rate;
  for (const t of rate.filter((t) => t.when)) if (matches(t.when!, u)) return t.price;
  return rate.find((t) => !t.when)?.price ?? 0;      // the tier with no criteria is the default
};

export function computeCost(p: Pricing, u: Usage): number {
  let c = textCost(p, u);                             // Chapter 16, unchanged
  if (p.imageInputToken || p.imageOutputToken) {
    c += (u.imageInputTokens ?? 0) * (p.imageInputToken ?? 0)
       + (u.imageOutputTokens ?? 0) * (p.imageOutputToken ?? 0);
  } else if (p.imageUnit !== undefined) c += (u.images ?? 1) * mediaPrice(p.imageUnit, u);  
  if (p.videoSecond !== undefined) c += (u.videoSeconds ?? 0) * mediaPrice(p.videoSecond, u);
  if (p.videoUnit   !== undefined) c += (u.videoCount ?? 1)   * mediaPrice(p.videoUnit, u);
  c += (u.audioInputTokens ?? 0)       * (p.audioInputToken ?? 0)
     + (u.cachedAudioInputTokens ?? 0) * (p.cachedAudioInputToken ?? p.audioInputToken ?? 0)
     + (u.audioOutputTokens ?? 0)      * (p.audioOutputToken ?? 0)
     + (u.computeSeconds ?? 0)         * (p.computeSecond ?? 0)
     + (u.chars ?? 0)                  * (p.perChar ?? 0)
     + (u.minutes ?? 0)                * (p.perMinute ?? 0);
  return c;
}

De twee gemarkeerde regels zijn waar het breekt. Een tarief dat per eenheid wordt geciteerd vermenigvuldigt u.images ?? 1; een tarief dat per token wordt geciteerd vermenigvuldigt iets dat standaard nul is. Voer beide een lege usage — de vorm die je krijgt wanneer een meting faalde — en kijk:

the same missing measurement, priced by unitTEXT
per image (nano-banana-pro)     empty usage => $0.1500
per clip  (hailuo-02)           empty usage => $0.1500
per unit  (a cloned voice)      empty usage => $3.0000
per token (gpt-image-2)         empty usage => $0.0000
per second (veo-3.1)            empty usage => $0.0000
per GPU-second (mochi)          empty usage => $0.0000

Er gebeurde niets, zes keer, en het kostte één keer drie dollar en vijf keer niets. Dat is geen afrondingsverschil; het is een beslissing over wat een ontbrekend getal betekent, afzonderlijk genomen voor elke eenheid en nergens opgeschreven. De verstandige regel is dat een veld dat niemand heeft gemeten afwezig blijft, omdat „niet gemeten” en „gemeten en nul geworden” verschillende dingen zijn. Deze functie is het daar stilletjes niet mee eens.

De tweede fout is duur. Het clip-geprijsde tarief selecteert zijn tier met maxDurationSeconds tegenover u.videoSeconds ?? 0, dus een usage die nooit een duur registreerde matcht de kortste tier:

hailuo-02, 768pTEXT
duration recorded    ->  $0.45
duration missing     ->  $0.27

Veertig procent korting omdat niet bekend is hoe lang de video was. Beide bugs hebben dezelfde wortel: een default die voor gemak is gekozen binnen een functie waarvan de hele taak is exact te zijn.

Nu kosten berekenbaar zijn, heeft de vergelijking de andere helft nodig — een verklaarde representatieve workload, één per engine, publiek vermeld zodat een lezer het ermee oneens kan zijn:

workloads.tsTS
export const representative = {
  text:   { blend: [[{ promptTokens: 1e6 }, 0.25], [{ completionTokens: 1e6 }, 0.75]] },
  image:  { images: 1, imageInputTokens: 50, imageOutputTokens: 1500 },
  video:  { videoSeconds: 5, videoCount: 1, resolution: "1080p", hasAudio: true, computeSeconds: 60 },
  voice:  { chars: 1000, computeSeconds: 10 },
  stt:    { minutes: 1 },
};

Elke regel daarvan is een stelling. Tekst mengt een kwart input en driekwart output omdat echt gebruik naar output helt; een fiftyfiftymix rangschikt de modellen anders. De image-workload gaat uit van 1.500 output tokens, tussen OpenAI’s 1.056 voor een medium vierkant en zijn 1.584 voor een medium portrait. Video gaat uit van vijf seconden op 1080p, en we zagen net twee leveranciers van plek wisselen bij 1,2 seconden. De compute-entry gaat uit van zestig GPU-seconden omdat er niets anders is om aan te nemen.

Dat is de methode, en het is de enige eerlijke die beschikbaar is: je kunt prijzen in verschillende eenheden niet vergelijken; je kunt alleen de kosten vergelijken van een workload die je hebt opgeschreven. Elke tabel die multimodal modellen rangschikt zonder zijn workload af te drukken, rangschikt zijn eigen aannames.

Je kunt nu alles prijzen wat een model kan produceren, in welke eenheid het ook wordt verkocht, en hardop zeggen welke workload je vergelijking aannam. Dat sluit de factuur die hoofdstuk 16 opende, en het sluit deel III: alles van hoofdstuk 14 tot hier ging over één call — hoe je die maakt, wat je erin stopt, hoe je hem sampled, wat hij teruggeeft, wat hij kost.

Hoofdstuk 22 verandert de analyse-eenheid, en die verandering is duur. Een agent is niet één call; het is een lus die zelf beslist hoeveel calls hij maakt, en de rekenkunde van de laatste twee hoofdstukken verandert dat van een architectuurdiagram in een budget. Het begint door dezelfde vraag twee keer aan hetzelfde model te stellen, met de tweede keer één tool extra in de catalogus, en te meten wat die ene tool deed: één call werd twee, negenendertig input tokens werden 420.

Of dat het een agent maakt, hangt af van welke van twee gepubliceerde definities je opent, en die zijn het niet eens. Een ervan is het niet eens met zichzelf.


Elke prijs, formule en conversieratio in dit hoofdstuk is gelezen van de eigen pagina van de provider op 7 september 2026 en wordt met die datum geciteerd, omdat ze allemaal zullen bewegen. De token-aantallen, kosten en vergelijkingen zijn op die data berekend door de hierboven afgedrukte code, op één machine, zonder betaalde API-call — wat ook de eerlijke reden is dat er in dit hoofdstuk geen enkele latency-claim staat.

De image-token-functies, de kostentabellen, de voice-call-uitsplitsing en de empty-usage-resultaten zijn geproduceerd door de TypeScript die in dit hoofdstuk is afgedrukt, gedraaid op Node 22. De dialoog die voor de voice-vergelijking is gebruikt telt 149 woorden en is getokenized met tiktoken onder de o200k_base encoding op 188 tokens; de duur volgt uit een verklaard tempo van 150 woorden per minuut, wat een parameter van de vergelijking is en geen meting. Elk provider-cijfer draagt de voetnoot die de pagina noemt waar het vandaan kwam.

  1. Dosovitskiy, A. et al. An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale. arXiv:2010.11929 (2020). Patches, de lineaire projectie naar de embedding-dimensie en de position embeddings die het raster leesbaar maken voor een sequentiemodel.

  2. Radford, A. et al. Learning Transferable Visual Models From Natural Language Supervision. arXiv:2103.00020 (2021). Contrastive training van een image encoder en een text encoder op 400 miljoen paren, en de gedeelde ruimte die alles downstream aanneemt.

  3. Alayrac, J.-B. et al. Flamingo: a Visual Language Model for Few-Shot Learning. arXiv:2204.14198 (2022). Bevroren vision encoder, bevroren taalmodel, getrainde bruglagen — de architectuur die image understanding tot een chat-capability maakte.

  4. Liu, H., Li, C., Wu, Q. and Lee, Y. J. Visual Instruction Tuning. arXiv:2304.08485 (2023). Eén lineaire projectie als brug en gegenereerde instruction data als trainingsset; de reden dat open vision-language models naar één vorm convergeerden.

  5. Anthropic, Vision, platform.claude.com/docs/en/build-with-claude/vision, geraadpleegd 2026-09-07. „Claude views images in patches instead of pixels. Each patch is a 28×28-pixel block of the image, referred to as a visual token. An image, therefore, costs ⌈width / 28⌉ × ⌈height / 28⌉ visual tokens.” Ook de twee resolutietiers (standaard: 1568-pixel lange zijde, 1568 visual tokens; high-resolution, op Claude 4.7 en later: 2576 pixels en 4784 tokens), de downsizing-regel en de zesrijige tabel met maten en token-aantallen die hierboven is gereproduceerd. Modeltarieven van Anthropic, Pricing, platform.claude.com/docs/en/about-claude/pricing, dezelfde datum: Claude Haiku 4.5 op $1 en $5 per miljoen input en output tokens.

  6. Google, Image understanding, ai.google.dev/gemini-api/docs/image-understanding, geraadpleegd 2026-09-07. „258 tokens if both dimensions <= 384 pixels. Larger images are tiled into 768x768 pixel tiles, each costing 258 tokens”, met de crop-unit-formule — floor(min(width, height) / 1.5), dimensies erdoor gedeeld en met elkaar vermenigvuldigd — en het uitgewerkte voorbeeld van 960 × 540 dat 3 × 2 = 6 tiles geeft. Google noemt het „a rough formula”; de hierboven afgeleide schaalinvariantie is een eigenschap van de formule zoals gepubliceerd. Audio input op dezelfde familie is 32 tokens per seconde audio (ai.google.dev/gemini-api/docs/audio, dezelfde datum).

  7. OpenAI, Images and vision, developers.openai.com/api/docs/guides/images-vision, geraadpleegd 2026-09-07. Bron van de patch-gebaseerde regel (32 × 32 patches, patch_count = ceil(width/32)×ceil(height/32), de shrink_factor-formule en de integer-aanpassing, de 30.000-patch rejection limit); de model sizing-tabel, inclusief dat low op gpt-5.4 een 2048-pixellimiet en een 6.144-patchbudget gebruikt „so it can use more tokens than high”, tegenover het 2.500-patchbudget van high; de multiplier-tabel (1,2 voor de GPT-5.x-families, 1,62 voor gpt-4.1-mini, 2,46 voor gpt-4.1-nano); de twee uitgewerkte voorbeelden die hierboven zijn gereproduceerd (1024 × 1024 → 1229 tokens, 2048 × 2048 → 3000 tokens); de tile-gebaseerde regels voor oudere modellen (base plus 512-pixeltiles, 85 + 170 op gpt-4o); en de beperkingenlijst die in het vision-kader is geciteerd. 2

  8. Ho, J., Jain, A. and Abbeel, P. Denoising Diffusion Probabilistic Models. arXiv:2006.11239 (2020). Het forward noising schedule, de reparameterisatie die de objective verandert in het voorspellen van de toegevoegde ruis, en de sampling-lus.

  9. Rombach, R., Blattmann, A., Lorenz, D., Esser, P. and Ommer, B. High-Resolution Image Synthesis with Latent Diffusion Models. arXiv:2112.10752 (2022). Het diffusion-proces in een gecomprimeerde latent space draaien, wat het vaste aantal stappen betaalbaar genoeg maakte om per afbeelding te verkopen.

  10. Prince, S. J. D. Understanding Deep Learning (MIT Press, 2023), hoofdstuk 18. De verklaarde delegatie voor alles wat dit hoofdstuk oversloeg over diffusion — de variational bound, de noise schedules, classifier-free guidance en de sampler-families. Hu, E. et al., LoRA: Low-Rank Adaptation of Large Language Models, arXiv:2106.09685 (2021), is de adapter zelf, geïntroduceerd in hoofdstuk 11 op een taalmodel en hier gebruikt op een image model zonder verandering in de wiskunde. Radford, A. et al., Robust Speech Recognition via Large-Scale Weak Supervision (Whisper), arXiv:2212.04356 (2022), is het transcriptiemodel waarvan de prijs per minuut hierboven verschijnt.

  11. OpenAI, Image generation, developers.openai.com/api/docs/guides/image-generation, Pricing, developers.openai.com/api/docs/pricing, en de modelpagina voor gpt-image-1, allemaal geraadpleegd 2026-09-07. De modelpagina voor gpt-image-2 heeft geen pricing-sectie; de tarieven komen van de prijspagina hierboven. GPT Image 1’s pagina publiceert text input op $5.00, image input op $10.00 en image output op $40.00 per miljoen tokens naast de per-image tabel die in de afleiding hierboven is gebruikt. Ook: de output-token-tabel voor modellen vóór gpt-image-2 (272 / 408 / 400 low, 1056 / 1584 / 1568 medium, 4160 / 6240 / 6208 high, voor square, portrait en landscape); de per-image prijstabellen voor GPT Image 2, 1.5, 1 en 1 Mini gebruikt in de afleidingen hierboven; de zin „a larger non-square resolution can sometimes produce fewer output tokens than a smaller or square resolution at the same quality setting”; de noot dat elke gestreamde partial image 100 extra image output tokens kost; en gpt-image-2’s tarieven van $8.00 image input, $2.00 cached image input, $30.00 image output en $5.00 text input per miljoen tokens. Text model-tarieven gebruikt voor de vergelijkingen: gpt-5.6-terra op $2.00 input, $0.20 cached input en $12.00 output, gpt-5.6-luna op $0.20 en $1.20, standard tier, short context. Video: sora-2 op $0.10 per seconde op 720p en sora-2-pro op $0.30, $0.50 en $0.70 op 720p, 1024p en 1080p. Transcriptie: $0.006, $0.0045, $0.003 en $0.017 per minuut voor gpt-4o-transcribe, gpt-transcribe, gpt-4o-mini-transcribe en gpt-live-transcribe. 2

  12. Google, Gemini Developer API pricing, ai.google.dev/gemini-api/docs/pricing, geraadpleegd 2026-09-07. Gemini 3.1 Flash-Lite op $0.25 per miljoen input tokens (tekst, afbeelding en video) en $1.50 output. Gemini 3.1 Flash Image: image output op $60 per miljoen tokens, met de gepubliceerde equivalenten van 747, 1120, 1680 en 2520 tokens voor 0.5K-, 1K-, 2K- en 4K-afbeeldingen en hun per-image prijzen van $0.045, $0.067, $0.101 en $0.151. Gemini 3.1 Flash TTS: $1.00 text input, $20.00 audio output, „audio tokens correspond to 25 tokens per second of audio”. Gemini 3.1 Flash Live Preview: $0.75 tekst en „$3.00 or $0.005/min” audio input, „$4.50 (text) $12.00 or $0.018/min (audio)” output. Veo 3.1 per seconde met audio: $0.40 op 720p en 1080p en $0.60 op 4K standard; $0.10, $0.12 en $0.30 fast. Gemini Omni Flash factureert video output „at a rate of 5,792 tokens per second of 720p video”, wat dezelfde voetnoot omzet naar ongeveer $0.10 per seconde — de duidelijkste gepubliceerde verklaring ergens dat een media-prijs per seconde een token-prijs is. 2

  13. OpenAI-modelpagina’s voor tts-1, tts-1-hd en gpt-4o-mini-tts, developers.openai.com/api/docs/models, geraadpleegd 2026-09-07. tts-1 op $15.00 en tts-1-hd op $30.00 per miljoen tekens; gpt-4o-mini-tts op $0.60 per miljoen text input tokens en $12.00 per miljoen audio output tokens — dezelfde leverancier, dezelfde operatie, twee eenheden.

  14. OpenAI, Managing costs (Realtime API), developers.openai.com/api/docs/guides/realtime-costs, geraadpleegd 2026-09-07. „Audio tokens in user messages are 1 token per 100 ms of audio, while audio tokens in assistant messages are 1 token per 50ms of audio.” Ook: „The entire conversation is sent to the model for each Response... thus turns later in the session will be more expensive”; kosten lopen op wanneer een Response wordt gemaakt; het uitgewerkte voorbeeld met twee beurten waarvan de accumulatie in de tabel hierboven wordt gereproduceerd; en de response.done usage-payload met zijn input_token_details- en output_token_details-splits. Tarieven van de prijspagina, dezelfde datum: gpt-realtime-2.1 audio op $32.00 input, $0.40 cached input en $64.00 output per miljoen tokens, tekst op $4.00, $0.40 en $24.00, image input op $5.00. 2

  15. Replicate, Pricing, replicate.com/pricing, geraadpleegd 2026-09-07. Nvidia A100 (80GB) op $0.001400 per seconde en $5.04 per uur; Nvidia H100 op $0.001525 per seconde en $5.49 per uur.

Klaar om LIA te laten kiezen?

Bouw met elk AI-model op één plek — begin vandaag nog gratis.